From 6a74e2b6dde19aae3c09142ffc8e5b42cea58776 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Mon, 26 Apr 2021 20:50:29 +0200 Subject: [PATCH] rendering: Improve TextField --- .../config/game/controls/KeyBindingsNames.kt | 5 +-- .../gui/input/key/RenderWindowInputHandler.kt | 9 +++++ .../minosoft/gui/rendering/hud/HUDRenderer.kt | 4 +++ .../hud/elements/input/KeyConsumer.kt | 2 +- .../hud/elements/input/MouseConsumer.kt | 1 - .../rendering/hud/elements/input/TextField.kt | 35 ++++++++++++++----- ...bleTextField.kt => TextFieldProperties.kt} | 33 +++++------------ .../hud/nodes/chat/ChatBoxHUDElement.kt | 21 +++++------ .../protocol/protocol/PacketSender.java | 2 +- 9 files changed, 63 insertions(+), 49 deletions(-) rename src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/{SubmittableTextField.kt => TextFieldProperties.kt} (58%) diff --git a/src/main/java/de/bixilon/minosoft/config/config/game/controls/KeyBindingsNames.kt b/src/main/java/de/bixilon/minosoft/config/config/game/controls/KeyBindingsNames.kt index 245c4010e..4e7fda6cd 100644 --- a/src/main/java/de/bixilon/minosoft/config/config/game/controls/KeyBindingsNames.kt +++ b/src/main/java/de/bixilon/minosoft/config/config/game/controls/KeyBindingsNames.kt @@ -44,7 +44,7 @@ object KeyBindingsNames { val OPEN_CHAT = ResourceLocation("minosoft:open_chat") - val CLOSE_CHAT = ResourceLocation("minosoft:close_chat") + val CLOSE = ResourceLocation("minosoft:close") val SELECT_HOTBAR_SLOTS = arrayOf( @@ -194,10 +194,11 @@ object KeyBindingsNames { KeyAction.PRESS to mutableSetOf(KeyCodes.KEY_T) ), ), - CLOSE_CHAT to KeyBinding( + CLOSE to KeyBinding( mutableMapOf( KeyAction.PRESS to mutableSetOf(KeyCodes.KEY_ESCAPE) ), + ignoreConsumer = true ), ) } 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 fb4bbb5a6..0e0e1d8d2 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 @@ -257,4 +257,13 @@ class RenderWindowInputHandler( fun unregisterKeyBinding(it: ResourceLocation) { keyBindingCallbacks.remove(it) } + + fun isKeyDown(vararg keys: KeyCodes): Boolean { + for (key in keys) { + if (keysDown.contains(key)) { + return true + } + } + return false + } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDRenderer.kt index 3015194e5..e3e64b7ba 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDRenderer.kt @@ -72,6 +72,10 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow for ((_, element) in hudElements.values) { element.init() } + + renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.CLOSE) { + + } } private fun registerDefaultElements() { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/KeyConsumer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/KeyConsumer.kt index 9608dde9d..2656a9d6d 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/KeyConsumer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/KeyConsumer.kt @@ -17,7 +17,7 @@ import de.bixilon.minosoft.config.key.KeyCodes interface KeyConsumer { - val focused: Boolean + fun close() fun charInput(char: Char) {} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/MouseConsumer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/MouseConsumer.kt index 0bb3b8602..11f75765f 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/MouseConsumer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/MouseConsumer.kt @@ -16,7 +16,6 @@ package de.bixilon.minosoft.gui.rendering.hud.elements.input import glm_.vec2.Vec2i interface MouseConsumer { - val focused: Boolean fun mouseMove(position: Vec2i) {} } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/TextField.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/TextField.kt index 1df345d74..4fc3064d8 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/TextField.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/TextField.kt @@ -24,11 +24,9 @@ import glm_.vec2.Vec2i open class TextField( renderWindow: RenderWindow, - defaultText: String = "", - var maxLength: Int = 256, + val properties: TextFieldProperties, ) : AbsoluteLayout(renderWindow), KeyConsumer, MouseConsumer { - override var focused: Boolean = true - private var textBuilder: StringBuilder = StringBuilder(defaultText) + private var textBuilder: StringBuilder = StringBuilder(properties.defaultText) val textElement = LabelNode(renderWindow, sizing = sizing, text = ChatComponent.valueOf(raw = text), background = false) private var position = text.length @@ -57,7 +55,7 @@ open class TextField( override fun keyInput(keyCodes: KeyCodes) { when (keyCodes) { KeyCodes.KEY_BACKSPACE -> { - if (textBuilder.isEmpty()) { + if (textBuilder.isEmpty() || position == 0) { return } textBuilder.deleteCharAt(--position) @@ -69,10 +67,19 @@ open class TextField( textBuilder.deleteCharAt(position) } KeyCodes.KEY_ENTER -> { - if (position > maxLength) { + if (renderWindow.inputHandler.isKeyDown(KeyCodes.KEY_LEFT_CONTROL, KeyCodes.KEY_RIGHT_CONTROL, KeyCodes.KEY_LEFT_SHIFT, KeyCodes.KEY_RIGHT_SHIFT)) { + // new line + if (position > properties.maxLength) { + return + } + textBuilder.insert(position++, '\n') return } - textBuilder.insert(position++, '\n') + properties.onSubmit(text) + if (properties.submitCloses) { + properties.onClose() + } + text = properties.defaultText } KeyCodes.KEY_LEFT -> { position = MMath.clamp(position - 1, 0, text.length) @@ -92,18 +99,28 @@ open class TextField( } override fun tick(tick: Long) { - if ((tick / 8) % 2L == 0L && position == text.length) { + if ((tick / FIELD_CURSOR_BLINK_INTERVAL) % 2L == 0L && position == text.length) { textElement.sText = "$textBuilder" + "_" } else { textElement.sText = textBuilder.toString() } } + override fun close() { + properties.onClose() + } + override fun charInput(char: Char) { - if (position >= maxLength) { + if (position >= properties.maxLength) { return } + val previous = textBuilder.toString() textBuilder.insert(position++, char.toString()) + properties.onInput(previous, textBuilder.toString()) update() } + + companion object { + const val FIELD_CURSOR_BLINK_INTERVAL = 8 + } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/SubmittableTextField.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/TextFieldProperties.kt similarity index 58% rename from src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/SubmittableTextField.kt rename to src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/TextFieldProperties.kt index 7b7a99010..b2b7ac59c 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/SubmittableTextField.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/input/TextFieldProperties.kt @@ -13,28 +13,11 @@ package de.bixilon.minosoft.gui.rendering.hud.elements.input -import de.bixilon.minosoft.config.key.KeyCodes -import de.bixilon.minosoft.gui.rendering.RenderWindow - -class SubmittableTextField( - renderWindow: RenderWindow, - defaultText: String = "", - maxLength: Int = 256, - private val onSubmit: (text: String) -> Unit, -) : TextField(renderWindow, defaultText, maxLength) { - - fun submit() { - onSubmit.invoke(text) - text = "" - } - - - override fun keyInput(keyCodes: KeyCodes) { - if (keyCodes == KeyCodes.KEY_ENTER) { - // submit - submit() - return - } - super.keyInput(keyCodes) - } -} +data class TextFieldProperties( + var defaultText: String = "", + var maxLength: Int = 256, + var onSubmit: (text: String) -> Unit = {}, + var onClose: () -> Unit = {}, + var onInput: (previousText: String, nextText: String) -> Unit = { _, _ -> }, + var submitCloses: Boolean = false, +) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/chat/ChatBoxHUDElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/chat/ChatBoxHUDElement.kt index 2adc46408..59aa7c767 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/chat/ChatBoxHUDElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/chat/ChatBoxHUDElement.kt @@ -18,7 +18,8 @@ import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames import de.bixilon.minosoft.gui.rendering.RenderConstants import de.bixilon.minosoft.gui.rendering.font.Font import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer -import de.bixilon.minosoft.gui.rendering.hud.elements.input.SubmittableTextField +import de.bixilon.minosoft.gui.rendering.hud.elements.input.TextField +import de.bixilon.minosoft.gui.rendering.hud.elements.input.TextFieldProperties import de.bixilon.minosoft.gui.rendering.hud.nodes.HUDElement import de.bixilon.minosoft.gui.rendering.hud.nodes.primitive.ImageNode import de.bixilon.minosoft.gui.rendering.hud.nodes.properties.NodeSizing @@ -28,14 +29,18 @@ import de.bixilon.minosoft.util.MMath import glm_.vec2.Vec2i class ChatBoxHUDElement(hudRenderer: HUDRenderer) : HUDElement(hudRenderer), ScreenResizeCallback { - private lateinit var inputField: SubmittableTextField + private lateinit var inputField: TextField private var inputFieldBackground = ImageNode(hudRenderer.renderWindow, sizing = NodeSizing(margin = Spacing(left = 1, right = 1)), textureLike = hudRenderer.renderWindow.WHITE_TEXTURE, z = 0, tintColor = RenderConstants.TEXT_BACKGROUND_COLOR) override fun init() { - inputField = SubmittableTextField(renderWindow = hudRenderer.renderWindow, maxLength = 256, onSubmit = { - hudRenderer.renderWindow.connection.sender.sendChatMessage(it) - closeChat() - }) + inputField = TextField( + renderWindow = hudRenderer.renderWindow, + properties = TextFieldProperties( + maxLength = 256, + submitCloses = true, + onSubmit = { hudRenderer.renderWindow.connection.sender.sendChatMessage(it) }, + onClose = { closeChat() }, + )) layout.addChild(Vec2i(0, 0), inputField) inputField.apply() @@ -43,9 +48,6 @@ class ChatBoxHUDElement(hudRenderer: HUDRenderer) : HUDElement(hudRenderer), Scr hudRenderer.renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.OPEN_CHAT) { openChat() } - hudRenderer.renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.CLOSE_CHAT) { - closeChat() - } } override fun onScreenResize(screenDimensions: Vec2i) { @@ -63,7 +65,6 @@ class ChatBoxHUDElement(hudRenderer: HUDRenderer) : HUDElement(hudRenderer), Scr fun closeChat() { layout.removeChild(inputFieldBackground) - inputField.clearText() hudRenderer.renderWindow.inputHandler.currentKeyConsumer = null } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketSender.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketSender.java index ae2ac9915..fff97f054 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketSender.java +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketSender.java @@ -59,7 +59,7 @@ public class PacketSender { if (this.connection.fireEvent(event)) { return; } - Log.log(LogMessageType.CHAT_OUT, "Sending chat message: %s", message); + Log.log(LogMessageType.CHAT_OUT, message); this.connection.sendPacket(new ChatMessageC2SP(event.getMessage())); }