aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/features/inventory/buttons/InventoryButtons.kt
blob: f49e6ab4401d3a365474978c3acd9ea92506e830 (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
package moe.nea.firmament.features.inventory.buttons

import me.shedaniel.math.Rectangle
import kotlinx.serialization.Serializable
import kotlinx.serialization.serializer
import kotlin.time.Duration.Companion.seconds
import net.minecraft.client.gui.screen.ingame.HandledScreen
import net.minecraft.client.gui.screen.ingame.InventoryScreen
import net.minecraft.text.Text
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.HandledScreenClickEvent
import moe.nea.firmament.events.HandledScreenForegroundEvent
import moe.nea.firmament.events.HandledScreenPushREIEvent
import moe.nea.firmament.util.data.ManagedConfig
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.ScreenUtil
import moe.nea.firmament.util.TimeMark
import moe.nea.firmament.util.data.DataHolder
import moe.nea.firmament.util.accessors.getRectangle
import moe.nea.firmament.util.data.Config
import moe.nea.firmament.util.gold

object InventoryButtons {

	@Config
    object TConfig : ManagedConfig("inventory-buttons-config", Category.INVENTORY) {
        val _openEditor by button("open-editor") {
            openEditor()
        }
		val hoverText by toggle("hover-text") { true }
		val onlyInv by toggle("only-inv") { false }
    }

    object DConfig : DataHolder<Data>(serializer(), "inventory-buttons", ::Data)

    @Serializable
    data class Data(
        var buttons: MutableList<InventoryButton> = mutableListOf()
    )

	fun getValidButtons(screen: HandledScreen<*>): Sequence<InventoryButton> {
		return DConfig.data.buttons.asSequence().filter { button ->
			button.isValid() && (!TConfig.onlyInv || screen is InventoryScreen)
		}
	}


    @Subscribe
    fun onRectangles(it: HandledScreenPushREIEvent) {
        val bounds = it.screen.getRectangle()
        for (button in getValidButtons(it.screen)) {
            val buttonBounds = button.getBounds(bounds)
            it.block(buttonBounds)
        }
    }

    @Subscribe
    fun onClickScreen(it: HandledScreenClickEvent) {
        val bounds = it.screen.getRectangle()
        for (button in getValidButtons(it.screen)) {
            val buttonBounds = button.getBounds(bounds)
            if (buttonBounds.contains(it.mouseX, it.mouseY)) {
                MC.sendCommand(button.command!! /* non null invariant covered by getValidButtons */)
                break
            }
        }
    }

	var lastHoveredComponent: InventoryButton? = null
	var lastMouseMove = TimeMark.farPast()

    @Subscribe
    fun onRenderForeground(it: HandledScreenForegroundEvent) {
		val bounds = it.screen.getRectangle()

		var hoveredComponent: InventoryButton? = null
		for (button in getValidButtons(it.screen)) {
            val buttonBounds = button.getBounds(bounds)
            it.context.matrices.pushMatrix()
            it.context.matrices.translate(buttonBounds.minX.toFloat(), buttonBounds.minY.toFloat())
            button.render(it.context)
            it.context.matrices.popMatrix()

			if (buttonBounds.contains(it.mouseX, it.mouseY) && TConfig.hoverText && hoveredComponent == null) {
				hoveredComponent = button
				if (lastMouseMove.passedTime() > 0.6.seconds && lastHoveredComponent === button) {
					it.context.drawTooltip(
						MC.font,
						listOf(Text.literal(button.command).gold()),
						buttonBounds.minX - 15,
						buttonBounds.maxY + 20,
					)
				}
			}
        }
		if (hoveredComponent !== lastHoveredComponent)
			lastMouseMove = TimeMark.now()
		lastHoveredComponent = hoveredComponent
        lastRectangle = bounds
    }

    var lastRectangle: Rectangle? = null
    fun openEditor() {
        ScreenUtil.setScreenLater(
            InventoryButtonEditor(
                lastRectangle ?: Rectangle(
                    MC.window.scaledWidth / 2 - 88,
                    MC.window.scaledHeight / 2 - 83,
                    176, 166,
                )
            )
        )
    }
}