Add better key binding support
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 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
|
||||
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.util.MC
|
||||
import moe.nea.firmament.util.ScreenUtil.setScreenLater
|
||||
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user