aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea/firmament/gui/BarComponent.kt
blob: 8ef07535879281c03ec72924cefddfa35c945c24 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package moe.nea.firmament.gui

import com.mojang.blaze3d.systems.RenderSystem
import io.github.notenoughupdates.moulconfig.common.MyResourceLocation
import io.github.notenoughupdates.moulconfig.common.RenderContext
import io.github.notenoughupdates.moulconfig.gui.GuiComponent
import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext
import io.github.notenoughupdates.moulconfig.observer.GetSetter
import io.github.notenoughupdates.moulconfig.platform.ModernRenderContext
import me.shedaniel.math.Color
import net.minecraft.client.gui.DrawContext
import net.minecraft.util.Identifier
import moe.nea.firmament.Firmament

class BarComponent(
    val progress: GetSetter<Double>, val total: GetSetter<Double>,
    val fillColor: Color,
    val emptyColor: Color,
) : GuiComponent() {
    override fun getWidth(): Int {
        return 80
    }

    override fun getHeight(): Int {
        return 8
    }

    data class Texture(
        val identifier: Identifier,
        val u1: Float, val v1: Float,
        val u2: Float, val v2: Float,
    ) {
        fun draw(context: DrawContext, x: Int, y: Int, width: Int, height: Int, color: Color) {
            context.drawTexturedQuad(
                identifier,
                x, y, x + width, x + height, 0,
                u1, u2, v1, v2,
                color.red / 255F,
                color.green / 255F,
                color.blue / 255F,
                color.alpha / 255F,
            )
        }
    }

    companion object {
        val resource = Firmament.identifier("textures/gui/bar.png")
        val left = Texture(resource, 0 / 64F, 0 / 64F, 4 / 64F, 8 / 64F)
        val middle = Texture(resource, 4 / 64F, 0 / 64F, 8 / 64F, 8 / 64F)
        val right = Texture(resource, 8 / 64F, 0 / 64F, 12 / 64F, 8 / 64F)
        val segmentOverlay = Texture(resource, 12 / 64F, 0 / 64F, 15 / 64F, 8 / 64F)
    }

    private fun drawSection(
        context: DrawContext,
        texture: Texture,
        x: Int,
        y: Int,
        width: Int,
        sectionStart: Double,
        sectionEnd: Double
    ) {
        if (sectionEnd < progress.get() && width == 4) {
            texture.draw(context, x, y, 4, 8, fillColor)
            return
        }
        if (sectionStart > progress.get() && width == 4) {
            texture.draw(context, x, y, 4, 8, emptyColor)
            return
        }
        val increasePerPixel = (sectionEnd - sectionStart) / width
        var valueAtPixel = sectionStart
        for (i in (0 until width)) {
            val newTex =
                Texture(texture.identifier, texture.u1 + i / 64F, texture.v1, texture.u1 + (i + 1) / 64F, texture.v2)
            newTex.draw(
                context, x + i, y, 1, 8,
                if (valueAtPixel < progress.get()) fillColor else emptyColor
            )
            valueAtPixel += increasePerPixel
        }
    }

    override fun render(context: GuiImmediateContext) {
        val renderContext = (context.renderContext as ModernRenderContext).drawContext
        var i = 0
        val x = 0
        val y = 0
        while (i < context.width - 4) {
            drawSection(
                renderContext,
                if (i == 0) left else middle,
                x + i, y,
                (context.width - (i + 4)).coerceAtMost(4),
                i * total.get() / context.width, (i + 4) * total.get() / context.width
            )
            i += 4
        }
        drawSection(
            renderContext,
            right,
            x + context.width - 4,
            y,
            4,
            (context.width - 4) * total.get() / context.width,
            total.get()
        )
        RenderSystem.setShaderColor(1F, 1F, 1F, 1F)

    }

}

fun Identifier.toMoulConfig(): MyResourceLocation {
    return MyResourceLocation(this.namespace, this.path)
}

fun RenderContext.color(color: Color) {
    color(color.red, color.green, color.blue, color.alpha)
}

fun RenderContext.color(red: Int, green: Int, blue: Int, alpha: Int) {
    color(red / 255f, green / 255f, blue / 255f, alpha / 255f)
}