diff --git a/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.kt b/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.kt index 104348910..9ea6801ed 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.kt @@ -17,6 +17,8 @@ import com.google.gson.JsonElement import com.google.gson.JsonObject import de.bixilon.minosoft.data.locale.minecraft.Translator import de.bixilon.minosoft.gui.rendering.RenderWindow +import de.bixilon.minosoft.gui.rendering.font.text.TextGetProperties +import de.bixilon.minosoft.gui.rendering.font.text.TextSetProperties import de.bixilon.minosoft.gui.rendering.hud.nodes.primitive.LabelNode import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import glm_.vec2.Vec2i @@ -175,9 +177,9 @@ class BaseComponent : ChatComponent { return nodes } - override fun prepareRender(startPosition: Vec2i, offset: Vec2i, renderWindow: RenderWindow, textElement: LabelNode, z: Int, retMaxSize: Vec2i) { + override fun prepareRender(startPosition: Vec2i, offset: Vec2i, renderWindow: RenderWindow, textElement: LabelNode, z: Int, setProperties: TextSetProperties, getProperties: TextGetProperties) { for (part in parts) { - part.prepareRender(startPosition, offset, renderWindow, textElement, z, retMaxSize) + part.prepareRender(startPosition, offset, renderWindow, textElement, z, setProperties, getProperties) } } diff --git a/src/main/java/de/bixilon/minosoft/data/text/ChatComponent.kt b/src/main/java/de/bixilon/minosoft/data/text/ChatComponent.kt index 675cc3305..050ee5af0 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/ChatComponent.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/ChatComponent.kt @@ -18,6 +18,8 @@ import com.google.gson.JsonParser import com.google.gson.JsonPrimitive import de.bixilon.minosoft.data.locale.minecraft.Translator import de.bixilon.minosoft.gui.rendering.RenderWindow +import de.bixilon.minosoft.gui.rendering.font.text.TextGetProperties +import de.bixilon.minosoft.gui.rendering.font.text.TextSetProperties import de.bixilon.minosoft.gui.rendering.hud.nodes.primitive.LabelNode import glm_.vec2.Vec2i import javafx.collections.FXCollections @@ -60,7 +62,7 @@ interface ChatComponent { /** * Prepares the chat component for rendering (used in opengl) */ - fun prepareRender(startPosition: Vec2i, offset: Vec2i, renderWindow: RenderWindow, textElement: LabelNode, z: Int, retMaxSize: Vec2i) + fun prepareRender(startPosition: Vec2i, offset: Vec2i, renderWindow: RenderWindow, textElement: LabelNode, z: Int, setProperties: TextSetProperties, getProperties: TextGetProperties) companion object { diff --git a/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt b/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt index 970ca1d77..46f23c10f 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt @@ -16,6 +16,8 @@ import de.bixilon.minosoft.Minosoft import de.bixilon.minosoft.gui.rendering.RenderConstants import de.bixilon.minosoft.gui.rendering.RenderWindow import de.bixilon.minosoft.gui.rendering.font.Font +import de.bixilon.minosoft.gui.rendering.font.text.TextGetProperties +import de.bixilon.minosoft.gui.rendering.font.text.TextSetProperties import de.bixilon.minosoft.gui.rendering.hud.nodes.primitive.ImageNode import de.bixilon.minosoft.gui.rendering.hud.nodes.primitive.LabelNode import de.bixilon.minosoft.gui.rendering.hud.nodes.properties.NodeSizing @@ -161,7 +163,7 @@ open class TextComponent( } - override fun prepareRender(startPosition: Vec2i, offset: Vec2i, renderWindow: RenderWindow, textElement: LabelNode, z: Int, retMaxSize: Vec2i) { + override fun prepareRender(startPosition: Vec2i, offset: Vec2i, renderWindow: RenderWindow, textElement: LabelNode, z: Int, setProperties: TextSetProperties, getProperties: TextGetProperties) { val color = this.color ?: ChatColors.WHITE @@ -175,7 +177,7 @@ open class TextComponent( offset.x = 0 val yOffset = Font.CHAR_HEIGHT + RenderConstants.TEXT_LINE_PADDING offset.y += yOffset - retMaxSize.y += yOffset + getProperties.size.y += yOffset continue } val fontChar = renderWindow.font.getChar(char) @@ -186,13 +188,14 @@ open class TextComponent( // ad spacer between chars offset.x += scaledWidth + Font.SPACE_BETWEEN_CHARS - if (offset.x > retMaxSize.x) { - retMaxSize.x += scaledWidth + Font.SPACE_BETWEEN_CHARS + if (offset.x > getProperties.size.x) { + getProperties.size.x += scaledWidth + Font.SPACE_BETWEEN_CHARS } - if (offset.y >= retMaxSize.y) { - if (retMaxSize.y < fontChar.height) { - retMaxSize.y = fontChar.height + if (offset.y >= getProperties.size.y) { + if (getProperties.size.y < fontChar.height) { + getProperties.size.y = fontChar.height } + getProperties.lines = (offset.y + Font.CHAR_HEIGHT) / (Font.CHAR_HEIGHT + RenderConstants.TEXT_LINE_PADDING) } } } 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 547461070..13d4db406 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt @@ -46,6 +46,7 @@ object RenderConstants { val TEXT_BACKGROUND_COLOR = RGBColor(0, 0, 0, 80) const val TEXT_LINE_PADDING = 0 + val WORD_SEPARATORS = arrayOf(' ', '.', ',', '!', '-', '?') const val CHUNK_SECTIONS_PER_MESH = 1 diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/font/text/TextGetProperties.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/font/text/TextGetProperties.kt new file mode 100644 index 000000000..7feb0248e --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/font/text/TextGetProperties.kt @@ -0,0 +1,21 @@ +/* + * Minosoft + * Copyright (C) 2021 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.rendering.font.text + +import glm_.vec2.Vec2i + +class TextGetProperties { + val size: Vec2i = Vec2i(0, 0) + var lines: Int = 0 +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/font/text/TextSetProperties.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/font/text/TextSetProperties.kt new file mode 100644 index 000000000..66431ec86 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/font/text/TextSetProperties.kt @@ -0,0 +1,25 @@ +/* + * Minosoft + * Copyright (C) 2021 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.rendering.font.text + +data class TextSetProperties( + /** + * Wraps after chars. + */ + var hardWrap: Int = Int.MAX_VALUE, + /** + * Wraps after words, or better: RenderConstants.WORD_SEPARATORS. + */ + var softWrap: Int = Int.MAX_VALUE, +) 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 47ff72ce2..1df345d74 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 @@ -29,7 +29,7 @@ open class TextField( ) : AbsoluteLayout(renderWindow), KeyConsumer, MouseConsumer { override var focused: Boolean = true private var textBuilder: StringBuilder = StringBuilder(defaultText) - private val textElement = LabelNode(renderWindow, sizing = sizing, text = ChatComponent.valueOf(raw = text), background = false) + val textElement = LabelNode(renderWindow, sizing = sizing, text = ChatComponent.valueOf(raw = text), background = false) private var position = text.length var text: String 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 1ae192c67..2adc46408 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 @@ -50,7 +50,7 @@ class ChatBoxHUDElement(hudRenderer: HUDRenderer) : HUDElement(hudRenderer), Scr override fun onScreenResize(screenDimensions: Vec2i) { layout.sizing.minSize.x = screenDimensions.x - inputFieldBackground.sizing.forceSize = Vec2i(screenDimensions.x - 2, MMath.clamp(inputField.sizing.currentSize.y, Font.CHAR_HEIGHT, Int.MAX_VALUE)) // 2 pixels for margin + inputFieldBackground.sizing.forceSize = Vec2i(screenDimensions.x - 2, MMath.clamp(inputField.textElement.getProperties.lines, 1, Int.MAX_VALUE) * (Font.CHAR_HEIGHT + RenderConstants.TEXT_LINE_PADDING)) // 2 pixels for margin layout.sizing.maxSize.x = screenDimensions.x layout.sizing.validate() layout.apply() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/primitive/LabelNode.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/primitive/LabelNode.kt index 9ac549416..e9bde1ff9 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/primitive/LabelNode.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/primitive/LabelNode.kt @@ -18,6 +18,8 @@ import de.bixilon.minosoft.data.text.RGBColor import de.bixilon.minosoft.gui.rendering.RenderConstants import de.bixilon.minosoft.gui.rendering.RenderWindow import de.bixilon.minosoft.gui.rendering.font.Font +import de.bixilon.minosoft.gui.rendering.font.text.TextGetProperties +import de.bixilon.minosoft.gui.rendering.font.text.TextSetProperties import de.bixilon.minosoft.gui.rendering.hud.nodes.layout.AbsoluteLayout import de.bixilon.minosoft.gui.rendering.hud.nodes.properties.NodeSizing import glm_.vec2.Vec2i @@ -27,8 +29,11 @@ class LabelNode( sizing: NodeSizing = NodeSizing(minSize = Vec2i(0, Font.CHAR_HEIGHT)), text: ChatComponent = ChatComponent.valueOf(raw = ""), var background: Boolean = true, + val setProperties: TextSetProperties = TextSetProperties(), ) : AbsoluteLayout(renderWindow, sizing) { private var _text: ChatComponent = text + var getProperties = TextGetProperties() + private set var text: ChatComponent get() = _text @@ -50,12 +55,12 @@ class LabelNode( private fun prepare() { clearChildren() - val textSize = Vec2i(0, 0) - text.prepareRender(Vec2i(1, 1), Vec2i(), renderWindow, this, 1, textSize) + getProperties = TextGetProperties() + text.prepareRender(Vec2i(1, 1), Vec2i(), renderWindow, this, 1, setProperties, getProperties) apply() if (background) { - drawBackground(textSize + 1) + drawBackground(getProperties.size + 1) } }