aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/keybindings
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/keybindings')
-rw-r--r--src/main/kotlin/keybindings/FirmamentKeyBindings.kt26
-rw-r--r--src/main/kotlin/keybindings/IKeyBinding.kt29
-rw-r--r--src/main/kotlin/keybindings/SavedKeyBinding.kt106
3 files changed, 161 insertions, 0 deletions
diff --git a/src/main/kotlin/keybindings/FirmamentKeyBindings.kt b/src/main/kotlin/keybindings/FirmamentKeyBindings.kt
new file mode 100644
index 0000000..e2bed8d
--- /dev/null
+++ b/src/main/kotlin/keybindings/FirmamentKeyBindings.kt
@@ -0,0 +1,26 @@
+
+
+package moe.nea.firmament.keybindings
+
+import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper
+import net.minecraft.client.option.KeyBinding
+import net.minecraft.client.util.InputUtil
+import moe.nea.firmament.gui.config.KeyBindingHandler
+import moe.nea.firmament.gui.config.ManagedOption
+
+object FirmamentKeyBindings {
+ fun registerKeyBinding(name: String, config: ManagedOption<SavedKeyBinding>) {
+ val vanillaKeyBinding = KeyBindingHelper.registerKeyBinding(
+ KeyBinding(
+ name,
+ InputUtil.Type.KEYSYM,
+ -1,
+ "firmament.key.category"
+ )
+ )
+ keyBindings[vanillaKeyBinding] = config
+ }
+
+ val keyBindings = mutableMapOf<KeyBinding, ManagedOption<SavedKeyBinding>>()
+
+}
diff --git a/src/main/kotlin/keybindings/IKeyBinding.kt b/src/main/kotlin/keybindings/IKeyBinding.kt
new file mode 100644
index 0000000..1975361
--- /dev/null
+++ b/src/main/kotlin/keybindings/IKeyBinding.kt
@@ -0,0 +1,29 @@
+
+
+package moe.nea.firmament.keybindings
+
+import net.minecraft.client.option.KeyBinding
+
+interface IKeyBinding {
+ fun matches(keyCode: Int, scanCode: Int, modifiers: Int): Boolean
+
+ fun withModifiers(wantedModifiers: Int): IKeyBinding {
+ val old = this
+ return object : IKeyBinding {
+ override fun matches(keyCode: Int, scanCode: Int, modifiers: Int): Boolean {
+ return old.matches(keyCode, scanCode, modifiers) && (modifiers and wantedModifiers) == wantedModifiers
+ }
+ }
+ }
+
+ companion object {
+ fun minecraft(keyBinding: KeyBinding) = object : IKeyBinding {
+ override fun matches(keyCode: Int, scanCode: Int, modifiers: Int) =
+ keyBinding.matchesKey(keyCode, scanCode)
+ }
+
+ fun ofKeyCode(wantedKeyCode: Int) = object : IKeyBinding {
+ override fun matches(keyCode: Int, scanCode: Int, modifiers: Int): Boolean = keyCode == wantedKeyCode
+ }
+ }
+}
diff --git a/src/main/kotlin/keybindings/SavedKeyBinding.kt b/src/main/kotlin/keybindings/SavedKeyBinding.kt
new file mode 100644
index 0000000..8607fd0
--- /dev/null
+++ b/src/main/kotlin/keybindings/SavedKeyBinding.kt
@@ -0,0 +1,106 @@
+
+
+package moe.nea.firmament.keybindings
+
+import org.lwjgl.glfw.GLFW
+import kotlinx.serialization.Serializable
+import net.minecraft.client.MinecraftClient
+import net.minecraft.client.util.InputUtil
+import net.minecraft.text.Text
+import moe.nea.firmament.util.MC
+
+@Serializable
+data class SavedKeyBinding(
+ val keyCode: Int,
+ val shift: Boolean = false,
+ val ctrl: Boolean = false,
+ val alt: Boolean = false,
+) : IKeyBinding {
+ val isBound: Boolean get() = keyCode != GLFW.GLFW_KEY_UNKNOWN
+
+ constructor(keyCode: Int, mods: Triple<Boolean, Boolean, Boolean>) : this(
+ keyCode,
+ mods.first && keyCode != GLFW.GLFW_KEY_LEFT_SHIFT && keyCode != GLFW.GLFW_KEY_RIGHT_SHIFT,
+ mods.second && keyCode != GLFW.GLFW_KEY_LEFT_CONTROL && keyCode != GLFW.GLFW_KEY_RIGHT_CONTROL,
+ mods.third && keyCode != GLFW.GLFW_KEY_LEFT_ALT && keyCode != GLFW.GLFW_KEY_RIGHT_ALT,
+ )
+
+ constructor(keyCode: Int, mods: Int) : this(keyCode, getMods(mods))
+
+ companion object {
+ fun getMods(modifiers: Int): Triple<Boolean, Boolean, Boolean> {
+ return Triple(
+ modifiers and GLFW.GLFW_MOD_SHIFT != 0,
+ modifiers and GLFW.GLFW_MOD_CONTROL != 0,
+ modifiers and GLFW.GLFW_MOD_ALT != 0
+ )
+ }
+
+ fun getModInt(): Int {
+ val h = MC.window.handle
+ val ctrl = if (MinecraftClient.IS_SYSTEM_MAC) {
+ InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_SUPER)
+ || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_SUPER)
+ } else InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_CONTROL)
+ || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_CONTROL)
+ val shift = isShiftDown()
+ val alt = InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_ALT)
+ || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_ALT)
+ var mods = 0
+ if (ctrl) mods = mods or GLFW.GLFW_MOD_CONTROL
+ if (shift) mods = mods or GLFW.GLFW_MOD_SHIFT
+ if (alt) mods = mods or GLFW.GLFW_MOD_ALT
+ return mods
+ }
+
+ private val h get() = MC.window.handle
+ fun isShiftDown() = InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_SHIFT)
+ || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_SHIFT)
+
+ }
+
+ fun isPressed(atLeast: Boolean = false): Boolean {
+ if (!isBound) return false
+ val h = MC.window.handle
+ if (!InputUtil.isKeyPressed(h, keyCode)) return false
+
+ val ctrl = if (MinecraftClient.IS_SYSTEM_MAC) {
+ InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_SUPER)
+ || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_SUPER)
+ } else InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_CONTROL)
+ || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_CONTROL)
+ val shift = isShiftDown()
+ val alt = InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_ALT)
+ || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_ALT)
+ if (atLeast)
+ return (ctrl >= this.ctrl) &&
+ (alt >= this.alt) &&
+ (shift >= this.shift)
+
+ return (ctrl == this.ctrl) &&
+ (alt == this.alt) &&
+ (shift == this.shift)
+ }
+
+ override fun matches(keyCode: Int, scanCode: Int, modifiers: Int): Boolean {
+ if (this.keyCode == GLFW.GLFW_KEY_UNKNOWN) return false
+ return keyCode == this.keyCode && getMods(modifiers) == Triple(shift, ctrl, alt)
+ }
+
+ fun format(): Text {
+ val stroke = Text.literal("")
+ if (ctrl) {
+ stroke.append("CTRL + ")
+ }
+ if (alt) {
+ stroke.append("ALT + ")
+ }
+ if (shift) {
+ stroke.append("SHIFT + ") // TODO: translations?
+ }
+
+ stroke.append(InputUtil.Type.KEYSYM.createFromCode(keyCode).localizedText)
+ return stroke
+ }
+
+}