aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/gui/config/KeyBindingStateManager.kt
blob: 1528ac4843e3fbca06c87d920a666e2d5e351d5f (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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package moe.nea.firmament.gui.config

import io.github.notenoughupdates.moulconfig.common.IMinecraft
import io.github.notenoughupdates.moulconfig.common.MyResourceLocation
import io.github.notenoughupdates.moulconfig.deps.libninepatch.NinePatch
import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext
import io.github.notenoughupdates.moulconfig.gui.KeyboardEvent
import io.github.notenoughupdates.moulconfig.gui.component.TextComponent
import org.lwjgl.glfw.GLFW
import net.minecraft.text.Text
import net.minecraft.util.Formatting
import moe.nea.firmament.gui.FirmButtonComponent
import moe.nea.firmament.keybindings.SavedKeyBinding

class KeyBindingStateManager(
	val value: () -> SavedKeyBinding,
	val setValue: (key: SavedKeyBinding) -> Unit,
	val blur: () -> Unit,
	val requestFocus: () -> Unit,
) {
	var editing = false
	var lastPressed = 0
	var lastPressedNonModifier = 0
	var label: Text = Text.literal("")

	fun onClick() {
		if (editing) {
			editing = false
			blur()
		} else {
			editing = true
			requestFocus()
		}
		updateLabel()
	}

	fun keyboardEvent(keyCode: Int, pressed: Boolean): Boolean {
		return if (pressed) onKeyPressed(keyCode, SavedKeyBinding.getModInt())
		else onKeyReleased(keyCode, SavedKeyBinding.getModInt())
	}

	fun onKeyPressed(ch: Int, modifiers: Int): Boolean {
		if (!editing) {
			return false
		}
		if (ch == GLFW.GLFW_KEY_ESCAPE) {
			lastPressedNonModifier = 0
			editing = false
			lastPressed = 0
			setValue(SavedKeyBinding(GLFW.GLFW_KEY_UNKNOWN))
			updateLabel()
			blur()
			return true
		}
		if (ch == GLFW.GLFW_KEY_LEFT_SHIFT || ch == GLFW.GLFW_KEY_RIGHT_SHIFT
			|| ch == GLFW.GLFW_KEY_LEFT_ALT || ch == GLFW.GLFW_KEY_RIGHT_ALT
			|| ch == GLFW.GLFW_KEY_LEFT_CONTROL || ch == GLFW.GLFW_KEY_RIGHT_CONTROL
		) {
			lastPressed = ch
		} else {
			setValue(
				SavedKeyBinding(
					ch, modifiers
				)
			)
			editing = false
			blur()
			lastPressed = 0
			lastPressedNonModifier = 0
		}
		updateLabel()
		return true
	}

	fun onLostFocus() {
		lastPressedNonModifier = 0
		editing = false
		lastPressed = 0
		updateLabel()
	}

	fun onKeyReleased(ch: Int, modifiers: Int): Boolean {
		if (!editing)
			return false
		if (lastPressedNonModifier == ch || (lastPressedNonModifier == 0 && ch == lastPressed)) {
			setValue(SavedKeyBinding(ch, modifiers))
			editing = false
			blur()
			lastPressed = 0
			lastPressedNonModifier = 0
		}
		updateLabel()
		return true
	}

	fun updateLabel() {
		var stroke = value().format()
		if (editing) {
			stroke = Text.literal("")
			val (shift, ctrl, alt) = SavedKeyBinding.getMods(SavedKeyBinding.getModInt())
			if (shift) {
				stroke.append("SHIFT + ")
			}
			if (alt) {
				stroke.append("ALT + ")
			}
			if (ctrl) {
				stroke.append("CTRL + ")
			}
			stroke.append("???")
			stroke.styled { it.withColor(Formatting.YELLOW) }
		}
		label = stroke
	}

	fun createButton(): FirmButtonComponent {
		return object : FirmButtonComponent(
			TextComponent(
				IMinecraft.instance.defaultFontRenderer,
				{ this@KeyBindingStateManager.label.string },
				130,
				TextComponent.TextAlignment.LEFT,
				false,
				false
			), action = {
				this@KeyBindingStateManager.onClick()
			}) {
			override fun keyboardEvent(event: KeyboardEvent, context: GuiImmediateContext): Boolean {
				if (event is KeyboardEvent.KeyPressed) {
					return this@KeyBindingStateManager.keyboardEvent(event.keycode, event.pressed)
				}
				return super.keyboardEvent(event, context)
			}

			override fun getBackground(context: GuiImmediateContext): NinePatch<MyResourceLocation> {
				if (this@KeyBindingStateManager.editing) return activeBg
				return super.getBackground(context)
			}


			override fun onLostFocus() {
				this@KeyBindingStateManager.onLostFocus()
			}
		}
	}
}