diff options
Diffstat (limited to 'src/main/kotlin/keybindings')
-rw-r--r-- | src/main/kotlin/keybindings/FirmamentKeyBindings.kt | 26 | ||||
-rw-r--r-- | src/main/kotlin/keybindings/IKeyBinding.kt | 29 | ||||
-rw-r--r-- | src/main/kotlin/keybindings/SavedKeyBinding.kt | 106 |
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 + } + +} |