aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/gui/config/KeyBindingStateManager.kt
blob: 500f0fa2db0cf8572d17509e11fbb20411bbac73 (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
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 io.github.notenoughupdates.moulconfig.platform.MoulConfigPlatform
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.GenericInputButton
import moe.nea.firmament.keybindings.InputModifiers
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: GenericInputButton? = null
	var label: Text = Text.literal("")

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

	fun keyboardEvent(keyCode: GenericInputButton, pressed: Boolean): Boolean {
		return if (pressed) onKeyPressed(keyCode, InputModifiers.getCurrentModifiers())
		else onKeyReleased(keyCode, InputModifiers.getCurrentModifiers())
	}

	fun onKeyPressed(
		ch: GenericInputButton,
		modifiers: InputModifiers
	): Boolean { // TODO !!!!!: genericify this method to allow for other inputs
		if (!editing) {
			return false
		}
		if (ch == GenericInputButton.escape()) {
			editing = false
			lastPressed = null
			setValue(SavedKeyBinding.unbound())
			updateLabel()
			blur()
			return true
		}
		if (ch.isModifier()) {
			lastPressed = ch
		} else {
			setValue(SavedKeyBinding(ch, modifiers))
			editing = false
			blur()
			lastPressed = null
		}
		updateLabel()
		return true
	}

	fun onLostFocus() {
		editing = false
		lastPressed = null
		updateLabel()
	}

	fun onKeyReleased(ch: GenericInputButton, modifiers: InputModifiers): Boolean {
		if (!editing)
			return false
		if (ch == lastPressed) { // TODO: check modifiers dont duplicate (CTRL+CTRL)
			setValue(SavedKeyBinding(ch, modifiers))
			editing = false
			blur()
			lastPressed = null
		}
		updateLabel()
		return true
	}

	fun updateLabel() {
		var stroke = value().format()
		if (editing) {
			stroke = Text.empty()
			val modifiers = InputModifiers.getCurrentModifiers()
			if (!modifiers.isEmpty()) {
				stroke.append(modifiers.format())
				stroke.append(" + ")
			}
			stroke.append("???")
			stroke.styled { it.withColor(Formatting.YELLOW) }
		}
		label = stroke
	}

	fun createButton(): FirmButtonComponent {
		return object : FirmButtonComponent(
			TextComponent(
				IMinecraft.INSTANCE.defaultFontRenderer,
				{ MoulConfigPlatform.wrap(this@KeyBindingStateManager.label) },
				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(GenericInputButton.ofKeyAndScan(event.keycode, event.scancode), 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()
			}
		}
	}
}