Skip to content

Commit 82c931e

Browse files
committed
Cursor system
1 parent e93d9ca commit 82c931e

File tree

4 files changed

+114
-33
lines changed

4 files changed

+114
-33
lines changed

common/src/main/kotlin/com/lambda/newgui/component/core/TextField.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,27 @@ class TextField(
2121

2222
var offset = initialOffset
2323

24+
val textWidth get() = renderer.font.getWidth(text, scale)
25+
val textHeight get() = renderer.font.getHeight(scale)
26+
2427
init {
2528
properties.interactionPassthrough = true
2629
verticalAlignment = VAlign.CENTER
2730
rectUpdate(owner::rect)
2831

2932
onRender {
30-
val w = font.getWidth(text, scale)
31-
val h = font.getHeight(scale)
32-
3333
val x = lerp(
3434
horizontalAlignment.multiplier,
3535
rect.left,
36-
rect.right - w,
36+
rect.right - textWidth,
3737
) - offset * horizontalAlignment.offset
3838

3939
val y = when {
40-
verticalAlignment == VAlign.CENTER || rect.size.y <= h -> rect.center.y
40+
verticalAlignment == VAlign.CENTER || rect.size.y <= textHeight -> rect.center.y
4141
else -> lerp(
4242
verticalAlignment.multiplier,
43-
rect.top + h * 0.5,
44-
rect.bottom - h * 0.5
43+
rect.top + textHeight * 0.5,
44+
rect.bottom - textHeight * 0.5
4545
)
4646
}
4747

common/src/main/kotlin/com/lambda/newgui/component/layout/Layout.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ open class Layout(
106106

107107
// Inputs
108108
protected var mousePosition = Vec2d.ZERO
109-
private val isHovered: Boolean get() = mousePosition in rect && (owner?.isHovered ?: true)
109+
protected val isHovered: Boolean get() = mousePosition in rect && (owner?.isHovered ?: true)
110110

111111
// Graphics
112112
val renderer: RenderLayer = run {
@@ -329,5 +329,17 @@ open class Layout(
329329
fun Layout.animationTicker(register: Boolean = true) = AnimationTicker().apply {
330330
if (register) onTick(this::tick)
331331
}
332+
333+
/**
334+
* Creates new [Mouse.CursorController].
335+
*
336+
* Use it to set the mouse cursor type for various conditions: hovering, resizing, typing etc...
337+
*/
338+
@UIBuilder
339+
@Suppress("UNUSED_EXPRESSION")
340+
fun Layout.cursorController(): Mouse.CursorController {
341+
this // hack ide to let me make that ui-related only
342+
return Mouse.CursorController()
343+
}
332344
}
333345
}

common/src/main/kotlin/com/lambda/newgui/component/window/Window.kt

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,16 @@ open class Window(
3131
val content = windowContent(scrollable)
3232

3333
private val animation = animationTicker()
34+
private val cursorController = cursorController()
3435

3536
// Minimizing
3637
var minimized = true
3738

3839
// Resizing
3940
private var resizeX: Double? = null
4041
private var resizeY: Double? = null
42+
private var resizeXHovered = false
43+
private var resizeYHovered = false
4144

4245
init {
4346
position = initialPosition
@@ -60,6 +63,12 @@ open class Window(
6063

6164
resizeX = null
6265
resizeY = null
66+
resizeXHovered = false
67+
resizeYHovered = false
68+
}
69+
70+
onHide {
71+
cursorController.reset()
6372
}
6473

6574
onRender {
@@ -79,40 +88,61 @@ open class Window(
7988
)
8089
}
8190

91+
onTick {
92+
val rxh = resizeXHovered || resizeX != null
93+
val ryh = resizeYHovered || resizeY != null
94+
95+
val cursor = when {
96+
rxh && ryh -> Mouse.Cursor.ResizeHV
97+
rxh -> Mouse.Cursor.ResizeH
98+
ryh -> Mouse.Cursor.ResizeV
99+
else -> Mouse.Cursor.Arrow
100+
}
101+
102+
cursorController.setCursor(cursor)
103+
}
104+
82105
onMouseClick { button: Mouse.Button, action: Mouse.Action ->
83106
resizeX = null
84107
resizeY = null
85108

86-
if (!resizable) return@onMouseClick
87-
if (selectedChild != null) return@onMouseClick
88109
if (button != Mouse.Button.Left || action != Mouse.Action.Click) return@onMouseClick
89110

90-
val resizeXHovered = mousePosition in Rect(
91-
titleBar.rect.rightTop - Vec2d(RESIZE_RANGE, 0.0),
92-
rect.rightBottom
93-
)
94-
95-
val resizeYHovered = mousePosition in Rect(
96-
rect.leftBottom - Vec2d(0.0, RESIZE_RANGE),
97-
rect.rightBottom
98-
)
99-
100111
if (resizeXHovered) resizeX = mousePosition.x - size.x
101112
if (resizeYHovered) resizeY = mousePosition.y - size.y
102113
}
103114

104115
onMouseMove {
105-
if (resizeX == null && resizeY == null) return@onMouseMove
116+
resizeXHovered = false
117+
resizeYHovered = false
118+
119+
if (!resizable) return@onMouseMove
120+
121+
// Hover state update
122+
if (selectedChild == null && isHovered) {
123+
resizeXHovered = mousePosition in Rect(
124+
titleBar.rect.rightTop - Vec2d(RESIZE_RANGE, 0.0),
125+
rect.rightBottom
126+
)
127+
128+
resizeYHovered = mousePosition in Rect(
129+
rect.leftBottom - Vec2d(0.0, RESIZE_RANGE),
130+
rect.rightBottom
131+
)
132+
}
106133

107-
val x = resizeX?.let { rx ->
108-
mousePosition.x - rx
109-
} ?: size.x
134+
// Resize
135+
if (resizeX != null || resizeY != null) {
136+
val x = resizeX?.let { rx ->
137+
mousePosition.x - rx
138+
} ?: size.x
110139

111-
val y = resizeY?.let { ry ->
112-
mousePosition.y - ry
113-
} ?: size.y
140+
val y = resizeY?.let { ry ->
141+
mousePosition.y - ry
142+
} ?: size.y
114143

115-
size = Vec2d(x, y).coerceIn(10.0, 1000.0, titleBar.size.y, 1000.0)
144+
size = Vec2d(x, y).coerceIn(80.0, 1000.0, titleBar.size.y + RESIZE_RANGE, 1000.0)
145+
}
116146
}
117147
}
118148

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,60 @@
11
package com.lambda.util
22

3-
import org.lwjgl.glfw.GLFW
3+
import com.lambda.Lambda.mc
4+
import com.mojang.blaze3d.systems.RenderSystem
5+
import org.lwjgl.glfw.GLFW.*
46

57
class Mouse {
68
@JvmInline
79
value class Button(val key: Int) {
810
companion object {
9-
val Left = Button(GLFW.GLFW_MOUSE_BUTTON_LEFT)
10-
val Right = Button(GLFW.GLFW_MOUSE_BUTTON_RIGHT)
11-
val Middle = Button(GLFW.GLFW_MOUSE_BUTTON_MIDDLE)
11+
val Left = Button(GLFW_MOUSE_BUTTON_LEFT)
12+
val Right = Button(GLFW_MOUSE_BUTTON_RIGHT)
13+
val Middle = Button(GLFW_MOUSE_BUTTON_MIDDLE)
1214
}
1315

14-
val isMainButton get() = key == GLFW.GLFW_MOUSE_BUTTON_LEFT || key == GLFW.GLFW_MOUSE_BUTTON_RIGHT
16+
val isMainButton get() = key == GLFW_MOUSE_BUTTON_LEFT || key == GLFW_MOUSE_BUTTON_RIGHT
1517
}
1618

1719
enum class Action {
1820
Click,
1921
Release
2022
}
23+
24+
enum class Cursor(private val getCursorPointer: () -> Long) {
25+
Arrow(::arrow),
26+
Pointer(::pointer),
27+
ResizeH(::resizeH), ResizeV(::resizeV), ResizeHV(::resizeHV);
28+
29+
fun set() {
30+
if (lastCursor == this) return
31+
lastCursor = this
32+
33+
RenderSystem.assertOnRenderThread()
34+
glfwSetCursor(mc.window.handle, getCursorPointer())
35+
}
36+
}
37+
38+
class CursorController {
39+
private var lastSetCursor: Cursor? = null
40+
41+
fun setCursor(cursor: Cursor) {
42+
// We're doing this to let other controllers be able to set the cursor when this one doesn't change
43+
if (lastSetCursor == cursor) return
44+
45+
cursor.set()
46+
lastSetCursor = cursor
47+
}
48+
49+
fun reset() = setCursor(Cursor.Arrow)
50+
}
51+
52+
companion object {
53+
private val arrow by lazy { glfwCreateStandardCursor(GLFW_ARROW_CURSOR) }
54+
private val pointer by lazy { glfwCreateStandardCursor(GLFW_POINTING_HAND_CURSOR) }
55+
private val resizeH by lazy { glfwCreateStandardCursor(GLFW_RESIZE_EW_CURSOR) }
56+
private val resizeV by lazy { glfwCreateStandardCursor(GLFW_RESIZE_NS_CURSOR) }
57+
private val resizeHV by lazy { glfwCreateStandardCursor(GLFW_RESIZE_NWSE_CURSOR) }
58+
var lastCursor = Cursor.Arrow
59+
}
2160
}

0 commit comments

Comments
 (0)