diff --git a/src/main/java/de/bixilon/minosoft/config/key/KeyActions.kt b/src/main/java/de/bixilon/minosoft/config/key/KeyActions.kt index 09050f5f0..74989bbd0 100644 --- a/src/main/java/de/bixilon/minosoft/config/key/KeyActions.kt +++ b/src/main/java/de/bixilon/minosoft/config/key/KeyActions.kt @@ -27,7 +27,7 @@ enum class KeyAction { RELEASE, /** - * Key must be pressed or released + * Key is pressed or released */ CHANGE, @@ -38,20 +38,20 @@ enum class KeyAction { */ MODIFIER, - /** - * ToDo: Key must be pressed twice - */ - DOUBLE_CLICK, - /** * Pressing the key makes it sticky, you have to press it again to make it not pressed anymore */ STICKY, /** - * Exactly the same as STICKY, but inverted. Initial pressed + * Exactly the same as STICKY, but inverted. Initial pressed. */ STICKY_INVERTED, + + /** + * Key must be pressed twice in a certain time. Behaves like sticky (press twice again to disable) + */ + DOUBLE_PRESS, ; companion object { diff --git a/src/main/java/de/bixilon/minosoft/gui/input/key/RenderWindowInputHandler.kt b/src/main/java/de/bixilon/minosoft/gui/input/key/RenderWindowInputHandler.kt index 84cfa74a0..6345ef90f 100644 --- a/src/main/java/de/bixilon/minosoft/gui/input/key/RenderWindowInputHandler.kt +++ b/src/main/java/de/bixilon/minosoft/gui/input/key/RenderWindowInputHandler.kt @@ -19,6 +19,7 @@ import de.bixilon.minosoft.config.key.KeyAction import de.bixilon.minosoft.config.key.KeyCodes import de.bixilon.minosoft.data.mappings.ResourceLocation import de.bixilon.minosoft.gui.input.camera.Camera +import de.bixilon.minosoft.gui.rendering.RenderConstants import de.bixilon.minosoft.gui.rendering.RenderWindow import de.bixilon.minosoft.gui.rendering.hud.elements.input.KeyConsumer import de.bixilon.minosoft.protocol.network.connection.PlayConnection @@ -33,7 +34,8 @@ class RenderWindowInputHandler( private val keyBindingCallbacks: MutableMap = mutableMapOf() private val keysDown: MutableList = mutableListOf() - private val keyCombinationsDown: MutableList = mutableListOf() + private val keyBindingsDown: MutableList = mutableListOf() + private val keysLastDownTime: MutableMap = mutableMapOf() private var skipNextCharPress = false @@ -75,10 +77,11 @@ class RenderWindowInputHandler( return } else -> { - Log.game("Unknown glfw action $action") + Log.warn("Unknown glfw action $action") return } } + val currentTime = System.currentTimeMillis() if (keyDown) { keysDown += keyCode @@ -92,7 +95,7 @@ class RenderWindowInputHandler( if (currentKeyConsumer != null && !pair.keyBinding.ignoreConsumer) { continue } - var combinationDown = keyDown + var thisKeyBindingDown = keyDown var checksRun = 0 var thisIsChange = true @@ -131,7 +134,7 @@ class RenderWindowInputHandler( } fun checkSticky(keys: MutableSet, invert: Boolean) { - var alreadyActive = keyCombinationsDown.contains(resourceLocation) + var alreadyActive = keyBindingsDown.contains(resourceLocation) if (invert) { alreadyActive = !alreadyActive } @@ -144,7 +147,7 @@ class RenderWindowInputHandler( thisIsChange = false return } - combinationDown = !alreadyActive + thisKeyBindingDown = !alreadyActive } pair.keyBinding.action[KeyAction.STICKY]?.let { @@ -155,21 +158,42 @@ class RenderWindowInputHandler( checkSticky(it, true) } + pair.keyBinding.action[KeyAction.DOUBLE_PRESS]?.let { + if (!it.contains(keyCode)) { + thisIsChange = false + return + } + val lastDownTime = keysLastDownTime[keyCode] + if (lastDownTime == null) { + thisIsChange = false + return + } + if (currentTime - lastDownTime > RenderConstants.DOUBLE_PRESS_KEY_MAX_DELAY) { + thisIsChange = false + return + } + thisKeyBindingDown = !isKeyBindingDown(resourceLocation) + } + if (!thisIsChange || checksRun == 0) { continue } // Log.debug("Changing $resourceLocation because of $keyCode -> $combinationDown") for (callback in pair.callback) { - callback.invoke(combinationDown) + callback.invoke(thisKeyBindingDown) } - if (combinationDown) { - keyCombinationsDown += resourceLocation + if (thisKeyBindingDown) { + keyBindingsDown += resourceLocation } else { - keyCombinationsDown -= resourceLocation + keyBindingsDown -= resourceLocation } } + if (keyDown) { + keysLastDownTime[keyCode] = currentTime + } + if (previousKeyConsumer != currentKeyConsumer) { skipNextCharPress = true } @@ -216,7 +240,7 @@ class RenderWindowInputHandler( } fun isKeyBindingDown(resourceLocation: ResourceLocation): Boolean { - return keyCombinationsDown.contains(resourceLocation) + return keyBindingsDown.contains(resourceLocation) } fun unregisterKeyBinding(it: ResourceLocation) { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt index 21d45e82e..8eadc3cb9 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt @@ -70,4 +70,6 @@ object RenderConstants { val PIXEL_UV_PIXEL_ADD = Vec2(0, 0.1f) const val CAMPFIRE_ITEMS = 4 + + const val DOUBLE_PRESS_KEY_MAX_DELAY = 200 }