window: cursor shapes, hud: change cursor shapes, text: fix offset detection

This commit is contained in:
Bixilon 2022-02-18 22:09:29 +01:00
parent f9536f7f32
commit 54edcfd4b1
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
6 changed files with 91 additions and 10 deletions

View File

@ -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
}

View File

@ -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)
}

View File

@ -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

View File

@ -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)

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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,
;
}

View File

@ -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<Int, KeyCodes>