aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt
blob: 73bba56861c5d4d7f0d2491768655659ef565d08 (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
package at.hannibal2.skyhanni.utils.renderables

import at.hannibal2.skyhanni.utils.NEUItems.renderOnScreen
import io.github.moulberry.notenoughupdates.util.Utils
import net.minecraft.client.Minecraft
import net.minecraft.item.ItemStack
import org.lwjgl.input.Mouse
import kotlin.math.max

interface Renderable {
    val width: Int
    fun isHovered(posX: Int, posY: Int) =
        Utils.getMouseX() in (posX..posX + width)
                && Utils.getMouseY() in (posY..posY + 10) // TODO: adjust for variable height?

    /**
     * N.B.: the offset is absolute, not relative to the position and should not be used for rendering
     * (the GL matrix stack should already be pre transformed)
     */
    fun render(posX: Int, posY: Int)

    companion object {
        fun fromAny(any: Any?, itemScale: Double = 1.0): Renderable? {
            return when (any) {
                null -> placeholder(12)
                is Renderable -> any
                is String -> string(any)
                is ItemStack -> itemStack(any, itemScale)
                else -> null
            }
        }

        fun link(text: String, onClick: () -> Unit): Renderable {
            return clickable(hoverable(string("§n$text"), string(text)), onClick)
        }

        fun clickable(render: Renderable, onClick: () -> Unit, button: Int = 0): Renderable {
            return object : Renderable {
                override val width: Int
                    get() = render.width

                var wasDown = false

                override fun render(posX: Int, posY: Int) {
                    val isDown = Mouse.isButtonDown(button)
                    if (isDown > wasDown && isHovered(posX, posY)) {
                        onClick()
                    }
                    wasDown = isDown
                    render.render(posX, posY)
                }

            }
        }

        fun hoverable(hovered: Renderable, unhovered: Renderable): Renderable {
            return object : Renderable {
                override val width: Int
                    get() = max(hovered.width, unhovered.width)

                override fun render(posX: Int, posY: Int) {
                    if (isHovered(posX, posY))
                        hovered.render(posX, posY)
                    else
                        unhovered.render(posX, posY)
                }
            }
        }

        fun itemStack(any: ItemStack, scale: Double = 1.0): Renderable {
            return object : Renderable {
                override val width: Int
                    get() = 12

                override fun render(posX: Int, posY: Int) {
                    any.renderOnScreen(0F, 0F, scaleMultiplier = scale)
                }
            }
        }

        fun string(string: String): Renderable {
            return object : Renderable {
                override val width: Int
                    get() = Minecraft.getMinecraft().fontRendererObj.getStringWidth(string)

                override fun render(posX: Int, posY: Int) {
                    Minecraft.getMinecraft().fontRendererObj.drawStringWithShadow("§f$string", 1f, 1f, 0)
                }
            }
        }

        fun placeholder(width: Int): Renderable {
            return object : Renderable {
                override val width: Int = width

                override fun render(posX: Int, posY: Int) {
                }
            }
        }
    }
}