aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea/firmament/gui
diff options
context:
space:
mode:
authornea <nea@nea.moe>2023-08-25 14:18:43 +0200
committernea <nea@nea.moe>2023-08-25 14:18:43 +0200
commit784231941661a3108549a1b5cd499bc5f7de2e46 (patch)
tree1e7c85001aef50af5d0491b2d97ae4fa09bb87d7 /src/main/kotlin/moe/nea/firmament/gui
parenta79452c25406e17b81dd0ed1209f590d01991c68 (diff)
downloadFirmament-784231941661a3108549a1b5cd499bc5f7de2e46.tar.gz
Firmament-784231941661a3108549a1b5cd499bc5f7de2e46.tar.bz2
Firmament-784231941661a3108549a1b5cd499bc5f7de2e46.zip
Add better key binding support
Diffstat (limited to 'src/main/kotlin/moe/nea/firmament/gui')
-rw-r--r--src/main/kotlin/moe/nea/firmament/gui/config/KeyBindingHandler.kt113
-rw-r--r--src/main/kotlin/moe/nea/firmament/gui/config/ManagedConfig.kt35
2 files changed, 139 insertions, 9 deletions
diff --git a/src/main/kotlin/moe/nea/firmament/gui/config/KeyBindingHandler.kt b/src/main/kotlin/moe/nea/firmament/gui/config/KeyBindingHandler.kt
new file mode 100644
index 0000000..5a4e3af
--- /dev/null
+++ b/src/main/kotlin/moe/nea/firmament/gui/config/KeyBindingHandler.kt
@@ -0,0 +1,113 @@
+package moe.nea.firmament.gui.config
+
+import io.github.cottonmc.cotton.gui.widget.WButton
+import io.github.cottonmc.cotton.gui.widget.data.InputResult
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.json.JsonElement
+import kotlinx.serialization.json.decodeFromJsonElement
+import kotlinx.serialization.json.encodeToJsonElement
+import moe.nea.firmament.keybindings.FirmamentKeyBindings
+import moe.nea.firmament.keybindings.SavedKeyBinding
+import net.minecraft.client.util.InputUtil
+import net.minecraft.text.Text
+import net.minecraft.util.Formatting
+import org.lwjgl.glfw.GLFW
+
+class KeyBindingHandler(name: String, managedConfig: ManagedConfig) : ManagedConfig.OptionHandler<SavedKeyBinding> {
+ init {
+ FirmamentKeyBindings.registerKeyBinding(name, managedConfig)
+ }
+
+ override fun toJson(element: SavedKeyBinding): JsonElement? {
+ return Json.encodeToJsonElement(element)
+ }
+
+ override fun fromJson(element: JsonElement): SavedKeyBinding {
+ return Json.decodeFromJsonElement(element)
+ }
+
+ override fun emitGuiElements(opt: ManagedOption<SavedKeyBinding>, guiAppender: GuiAppender) {
+ var editing = false
+ var lastPressed = 0
+ var lastPressedNonModifier = 0
+ var updateButton: (() -> Unit)? = null
+ val button = object : WButton() {
+ override fun onKeyPressed(ch: Int, key: Int, modifiers: Int): InputResult {
+ if (!editing) {
+ return super.onKeyPressed(ch, key, modifiers)
+ }
+ if (ch == GLFW.GLFW_KEY_ESCAPE) {
+ lastPressedNonModifier = 0
+ editing = false
+ lastPressed = 0
+ updateButton!!()
+ return InputResult.PROCESSED
+ }
+ 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 {
+ opt.value = SavedKeyBinding(
+ ch, modifiers
+ )
+ editing = false
+ lastPressed = 0
+ lastPressedNonModifier = 0
+ }
+ updateButton!!()
+ return InputResult.PROCESSED
+ }
+
+ override fun onFocusLost() {
+ super.onFocusLost()
+ lastPressedNonModifier = 0
+ editing = false
+ lastPressed = 0
+ updateButton!!()
+ }
+
+ override fun onKeyReleased(ch: Int, key: Int, modifiers: Int): InputResult {
+ if (!editing)
+ return super.onKeyReleased(ch, key, modifiers)
+ if (lastPressedNonModifier == ch || (lastPressedNonModifier == 0 && ch == lastPressed)) {
+ opt.value = SavedKeyBinding(
+ ch, modifiers
+ )
+ editing = false
+ lastPressed = 0
+ lastPressedNonModifier = 0
+ }
+ updateButton!!()
+ return InputResult.PROCESSED
+ }
+ }
+
+ fun updateLabel() {
+ val stroke = Text.literal("")
+ if (opt.value.shift) {
+ stroke.append("SHIFT + ") // TODO: translations?
+ }
+ if (opt.value.alt) {
+ stroke.append("ALT + ")
+ }
+ if (opt.value.ctrl) {
+ stroke.append("CTRL + ")
+ }
+ stroke.append(InputUtil.Type.KEYSYM.createFromCode(opt.value.keyCode).localizedText)
+ if (editing)
+ stroke.styled { it.withColor(Formatting.YELLOW) }
+ button.setLabel(stroke)
+ }
+ updateButton = ::updateLabel
+ updateButton()
+ button.setOnClick {
+ editing = true
+ button.requestFocus()
+ updateButton()
+ }
+ guiAppender.appendLabeledRow(opt.labelText, button)
+ }
+
+}
diff --git a/src/main/kotlin/moe/nea/firmament/gui/config/ManagedConfig.kt b/src/main/kotlin/moe/nea/firmament/gui/config/ManagedConfig.kt
index 56aca46..8743293 100644
--- a/src/main/kotlin/moe/nea/firmament/gui/config/ManagedConfig.kt
+++ b/src/main/kotlin/moe/nea/firmament/gui/config/ManagedConfig.kt
@@ -14,21 +14,22 @@ import io.github.cottonmc.cotton.gui.widget.WLabel
import io.github.cottonmc.cotton.gui.widget.data.Axis
import io.github.cottonmc.cotton.gui.widget.data.Insets
import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment
-import moe.nea.jarvis.api.Point
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
-import kotlin.io.path.createDirectories
-import kotlin.io.path.readText
-import kotlin.io.path.writeText
-import kotlin.time.Duration
-import net.minecraft.client.gui.screen.Screen
-import net.minecraft.text.Text
import moe.nea.firmament.Firmament
import moe.nea.firmament.gui.WTightScrollPanel
+import moe.nea.firmament.keybindings.SavedKeyBinding
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.ScreenUtil.setScreenLater
+import moe.nea.jarvis.api.Point
+import net.minecraft.client.gui.screen.Screen
+import net.minecraft.text.Text
+import kotlin.io.path.createDirectories
+import kotlin.io.path.readText
+import kotlin.io.path.writeText
+import kotlin.time.Duration
abstract class ManagedConfig(override val name: String) : ManagedConfigElement() {
@@ -106,6 +107,18 @@ abstract class ManagedConfig(override val name: String) : ManagedConfigElement()
}, HudMetaHandler(this, label, width, height))
}
+ protected fun keyBinding(
+ propertyName: String,
+ default: () -> Int,
+ ): ManagedOption<SavedKeyBinding> = keyBindingWithDefaultModifiers(propertyName) { SavedKeyBinding(default()) }
+
+ protected fun keyBindingWithDefaultModifiers(
+ propertyName: String,
+ default: () -> SavedKeyBinding,
+ ): ManagedOption<SavedKeyBinding> {
+ return option(propertyName, default, KeyBindingHandler("firmament.config.${name}.${propertyName}", this))
+ }
+
protected fun integer(
propertyName: String,
min: Int,
@@ -125,7 +138,7 @@ abstract class ManagedConfig(override val name: String) : ManagedConfigElement()
fun reloadGui() {
- latestGuiAppender?.reloadables?.forEach {it() }
+ latestGuiAppender?.reloadables?.forEach { it() }
}
fun getConfigEditor(parent: Screen? = null): CottonClientScreen {
@@ -137,7 +150,11 @@ abstract class ManagedConfig(override val name: String) : ManagedConfigElement()
guiapp.appendFullRow(WBox(Axis.HORIZONTAL).also {
it.add(WButton(Text.literal("←")).also {
it.setOnClick {
- AllConfigsGui.showAllGuis()
+ if (parent != null) {
+ setScreenLater(parent)
+ } else {
+ AllConfigsGui.showAllGuis()
+ }
}
})
it.add(WLabel(Text.translatable("firmament.config.${name}")).also {