diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/input/button/ButtonElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/input/button/ButtonElement.kt index 74aaf45c1..57ae62dc6 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/input/button/ButtonElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/input/button/ButtonElement.kt @@ -26,6 +26,7 @@ import de.bixilon.minosoft.gui.rendering.gui.input.mouse.MouseActions import de.bixilon.minosoft.gui.rendering.gui.input.mouse.MouseButtons import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions +import de.bixilon.minosoft.gui.rendering.system.window.CursorShapes import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes import de.bixilon.minosoft.util.KUtil.toResourceLocation import glm_.vec2.Vec2i @@ -147,12 +148,14 @@ open class ButtonElement( override fun onMouseEnter(position: Vec2i, absolute: Vec2i): Boolean { hovered = true + renderWindow.window.cursorShape = CursorShapes.HAND return true } override fun onMouseLeave(): Boolean { hovered = false + renderWindow.window.resetCursor() return true } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/text/TextElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/text/TextElement.kt index c9f8928bb..9ceed1ff5 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/text/TextElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/text/TextElement.kt @@ -33,6 +33,7 @@ import de.bixilon.minosoft.gui.rendering.gui.input.mouse.MouseButtons import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMesh import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions +import de.bixilon.minosoft.gui.rendering.system.window.CursorShapes import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY import de.bixilon.minosoft.gui.rendering.util.vec.vec4.Vec4iUtil.offset import glm_.vec2.Vec2i @@ -185,6 +186,9 @@ open class TextElement( val pair = getTextComponentAt(position) ?: return false activeElement = pair.first pair.first.hoverEvent?.onMouseEnter(guiRenderer, pair.second, absolute) + if (pair.first.clickEvent != null) { + renderWindow.window.cursorShape = CursorShapes.HAND + } return true } @@ -194,14 +198,23 @@ open class TextElement( if (activeElement != pair?.first) { val activeElement = activeElement this.activeElement = pair?.first + if (pair?.first?.clickEvent == null) { + renderWindow.window.resetCursor() + } else { + renderWindow.window.cursorShape = CursorShapes.HAND + } return (activeElement?.hoverEvent?.onMouseLeave(guiRenderer) ?: false) || (pair?.first?.hoverEvent?.onMouseEnter(guiRenderer, pair.second, absolute) ?: false) } return pair?.first?.hoverEvent?.onMouseMove(guiRenderer, pair.second, absolute) ?: false } override fun onMouseLeave(): Boolean { - activeElement?.hoverEvent?.onMouseLeave(guiRenderer) ?: return false - activeElement = null + val activeElement = activeElement ?: return false + this.activeElement = null + if (activeElement.clickEvent != null) { + renderWindow.window.resetCursor() + } + activeElement.hoverEvent?.onMouseLeave(guiRenderer) ?: return false return true } @@ -215,17 +228,23 @@ open class TextElement( val line = renderInfo.lines.getOrNull(offset.y / charHeight) ?: return null offset.y = offset.y % charHeight - val textElement = TextElement(guiRenderer, line.text, fontAlignment, false, backgroundColor, noBorder, parent, scale) - textElement._prefMaxSize = Vec2i(offset.x, charHeight) - textElement.forceSilentApply() + val cutText = TextElement(guiRenderer, line.text, fontAlignment, false, backgroundColor, noBorder, parent, scale) + cutText._prefMaxSize = Vec2i(offset.x, charHeight) + cutText.forceSilentApply() + + + val line0 = cutText.renderInfo.lines.getOrNull(0) ?: return null + val message = line0.text.message + var charToCheck = message.length + if (line0.width < offset.x && charToCheck < line.text.message.length) { + // last char got cut off + charToCheck++ + } + val text = line.text.getTextAt(charToCheck) + offset.x -= line0.width // ToDo: Not 100% correct offset.x += fontAlignment.getOffset(size.x, line.width) - - val line0 = textElement.renderInfo.lines.getOrNull(0) ?: return null - val text = line.text.getTextAt(line0.text.message.length) - offset.x -= line0.width // ToDo: Not 100% correct - return Pair(text, offset) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/elements/input/TextInputElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/elements/input/TextInputElement.kt index 69604021a..fb6ff9cf5 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/elements/input/TextInputElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/elements/input/TextInputElement.kt @@ -28,6 +28,7 @@ import de.bixilon.minosoft.gui.rendering.gui.input.mouse.MouseActions import de.bixilon.minosoft.gui.rendering.gui.input.mouse.MouseButtons import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions +import de.bixilon.minosoft.gui.rendering.system.window.CursorShapes import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY import glm_.vec2.Vec2i @@ -261,6 +262,16 @@ class TextInputElement( return true } + override fun onMouseEnter(position: Vec2i, absolute: Vec2i): Boolean { + renderWindow.window.cursorShape = CursorShapes.IBEAM + return true + } + + override fun onMouseLeave(): Boolean { + renderWindow.window.resetCursor() + return true + } + override fun onMouseAction(position: Vec2i, button: MouseButtons, action: MouseActions): Boolean { if (action != MouseActions.PRESS) { return true diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/BaseWindow.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/BaseWindow.kt index 018960f7a..c88ab5875 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/BaseWindow.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/BaseWindow.kt @@ -38,6 +38,7 @@ interface BaseWindow { var swapInterval: Int var cursorMode: CursorModes + var cursorShape: CursorShapes var clipboardText: String @@ -80,6 +81,10 @@ interface BaseWindow { setIcon(Vec2i(decoder.width, decoder.height), data) } + fun resetCursor() { + cursorShape = CursorShapes.ARROW + } + companion object { val DEFAULT_WINDOW_SIZE: Vec2i get() = Vec2i(900, 500) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/CursorShapes.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/CursorShapes.kt new file mode 100644 index 000000000..c91509c0a --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/CursorShapes.kt @@ -0,0 +1,24 @@ +/* + * 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.system.window + +enum class CursorShapes { + ARROW, + IBEAM, + CROSSHAIR, + HAND, + HORIZONTAL_RESIZE, + VERTICAL_RESIZE, + ; +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/GLFWWindow.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/GLFWWindow.kt index 15f427d8f..e1ccd71cd 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/GLFWWindow.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/GLFWWindow.kt @@ -60,6 +60,14 @@ class GLFWWindow( field = value skipNextMouseEvent = true } + override var cursorShape: CursorShapes = CursorShapes.ARROW + set(value) { + if (field == value) { + return + } + glfwSetCursor(window, glfwCreateStandardCursor(value.glfw)) + field = value + } private var _size = Vec2i(DEFAULT_WINDOW_SIZE) @@ -487,6 +495,17 @@ class GLFWWindow( false -> GLFW_FALSE } } + val CursorShapes.glfw: Int + get() { + return when (this) { + CursorShapes.ARROW -> GLFW_ARROW_CURSOR + CursorShapes.IBEAM -> GLFW_IBEAM_CURSOR + CursorShapes.CROSSHAIR -> GLFW_CROSSHAIR_CURSOR + CursorShapes.HAND -> GLFW_HAND_CURSOR + CursorShapes.HORIZONTAL_RESIZE -> GLFW_HRESIZE_CURSOR + CursorShapes.VERTICAL_RESIZE -> GLFW_VRESIZE_CURSOR + } + } init { val keyCodes: Map