Skip to content

Commit e93d9ca

Browse files
committed
Window resizing
1 parent af6a2c9 commit e93d9ca

File tree

6 files changed

+108
-24
lines changed

6 files changed

+108
-24
lines changed

common/src/main/kotlin/com/lambda/gui/api/component/core/DockingRect.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ package com.lambda.gui.api.component.core
33
import com.lambda.module.modules.client.ClickGui
44
import com.lambda.newgui.component.HAlign
55
import com.lambda.newgui.component.VAlign
6-
import com.lambda.util.math.MathUtils.coerceIn
76
import com.lambda.util.math.MathUtils.roundToStep
87
import com.lambda.util.math.Rect
98
import com.lambda.util.math.Vec2d
9+
import com.lambda.util.math.coerceIn
1010

1111
abstract class DockingRect {
1212
abstract var relativePos: Vec2d

common/src/main/kotlin/com/lambda/module/modules/client/NewCGui.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ object NewCGui : Module(
1313
defaultTags = setOf(ModuleTag.CLIENT)
1414
) {
1515
val titleBarHeight by setting("Title Bar Height", 4.0, 0.0..10.0, 0.1)
16-
val padding by setting("Padding", 2.0, 0.0..6.0, 0.1)
16+
val padding by setting("Padding", 2.0, 1.0..6.0, 0.1)
1717
val listStep by setting("List Step", 2.0, 0.0..6.0, 0.1)
1818

1919
private val clickGuiLayout =

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ package com.lambda.newgui.component.core
22

33
import com.lambda.newgui.component.VAlign
44
import com.lambda.newgui.component.layout.Layout
5-
import com.lambda.util.math.MathUtils.lerp
65
import com.lambda.util.math.Vec2d
6+
import com.lambda.util.math.lerp
77
import java.awt.Color
88

99
class TextField(
@@ -31,17 +31,17 @@ class TextField(
3131
val h = font.getHeight(scale)
3232

3333
val x = lerp(
34+
horizontalAlignment.multiplier,
3435
rect.left,
3536
rect.right - w,
36-
horizontalAlignment.multiplier
3737
) - offset * horizontalAlignment.offset
3838

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

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

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import com.lambda.newgui.component.VAlign
1010
import com.lambda.newgui.component.core.UIBuilder
1111
import com.lambda.util.KeyCode
1212
import com.lambda.util.Mouse
13-
import com.lambda.util.math.MathUtils.coerceIn
1413
import com.lambda.util.math.Rect
1514
import com.lambda.util.math.Vec2d
15+
import com.lambda.util.math.coerceIn
1616

1717
/**
1818
* Represents a component for creating complex ui structures.
@@ -102,7 +102,7 @@ open class Layout(
102102

103103
// Structure
104104
val children = mutableListOf<Layout>()
105-
private var selectedChild: Layout? = null
105+
protected var selectedChild: Layout? = null
106106

107107
// Inputs
108108
protected var mousePosition = Vec2d.ZERO
@@ -297,15 +297,15 @@ open class Layout(
297297

298298
companion object {
299299
/**
300-
* Creates an empty [Layout]
300+
* Creates an empty [Layout].
301301
*
302-
* @param useBatching Whether to use parent's renderer
302+
* @param useBatching Whether to use parent's renderer.
303303
*
304-
* @param batchChildren Whether allow children to use the renderer of this layout
304+
* @param batchChildren Whether allow children to use the renderer of this layout.
305305
*
306-
* @param block Actions to perform within this component
306+
* @param block Actions to perform within this component.
307307
*
308-
* Check [Layout] description for more info about batching
308+
* Check [Layout] description for more info about batching.
309309
*/
310310
@UIBuilder
311311
fun Layout.layout(
@@ -314,5 +314,20 @@ open class Layout(
314314
block: Layout.() -> Unit = {},
315315
) = Layout(this, useBatching, batchChildren)
316316
.apply(children::add).apply(block)
317+
318+
/**
319+
* Creates new [AnimationTicker].
320+
*
321+
* Use it to create and manage animations.
322+
*
323+
* It's ok to have multiple tickers per component if you need to tick different animations at different timings.
324+
*
325+
* @param register Whether to tick this [AnimationTicker].
326+
* Otherwise, you will have to tick it manually
327+
*/
328+
@UIBuilder
329+
fun Layout.animationTicker(register: Boolean = true) = AnimationTicker().apply {
330+
if (register) onTick(this::tick)
331+
}
317332
}
318333
}

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

Lines changed: 79 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import com.lambda.newgui.component.layout.Layout
66
import com.lambda.newgui.component.core.UIBuilder
77
import com.lambda.newgui.component.window.TitleBar.Companion.titleBar
88
import com.lambda.newgui.component.window.WindowContent.Companion.windowContent
9+
import com.lambda.util.Mouse
910
import com.lambda.util.math.Rect
1011
import com.lambda.util.math.Vec2d
12+
import com.lambda.util.math.coerceIn
1113
import java.awt.Color
1214

1315
/**
@@ -18,25 +20,46 @@ import java.awt.Color
1820
open class Window(
1921
owner: Layout,
2022
initialTitle: String,
23+
initialPosition: Vec2d,
24+
initialSize: Vec2d,
2125
draggable: Boolean,
22-
scrollable: Boolean
26+
scrollable: Boolean,
27+
private val minimizable: Boolean,
28+
private val resizable: Boolean
2329
) : Layout(owner, false, true) {
2430
val titleBar = titleBar(initialTitle, draggable)
2531
val content = windowContent(scrollable)
2632

33+
private val animation = animationTicker()
34+
35+
// Minimizing
36+
var minimized = true
37+
38+
// Resizing
39+
private var resizeX: Double? = null
40+
private var resizeY: Double? = null
41+
2742
init {
43+
position = initialPosition
44+
size = initialSize
45+
2846
// Clamp the window only within the screen bounds
2947
properties.clampPosition = owner.owner == null
3048

3149
onShow {
32-
content.properties.scissorChildren = true
50+
with(content) {
51+
properties.scissorChildren = true
3352

34-
content.rectUpdate {
35-
Rect(
36-
titleBar.rect.leftBottom + NewCGui.padding,
37-
this@Window.rect.rightBottom - NewCGui.padding
38-
)
53+
rectUpdate {
54+
Rect(
55+
titleBar.rect.leftBottom + NewCGui.padding,
56+
this@Window.rect.rightBottom - NewCGui.padding
57+
)
58+
}
3959
}
60+
61+
resizeX = null
62+
resizeY = null
4063
}
4164

4265
onRender {
@@ -55,6 +78,42 @@ open class Window(
5578
true
5679
)
5780
}
81+
82+
onMouseClick { button: Mouse.Button, action: Mouse.Action ->
83+
resizeX = null
84+
resizeY = null
85+
86+
if (!resizable) return@onMouseClick
87+
if (selectedChild != null) return@onMouseClick
88+
if (button != Mouse.Button.Left || action != Mouse.Action.Click) return@onMouseClick
89+
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+
100+
if (resizeXHovered) resizeX = mousePosition.x - size.x
101+
if (resizeYHovered) resizeY = mousePosition.y - size.y
102+
}
103+
104+
onMouseMove {
105+
if (resizeX == null && resizeY == null) return@onMouseMove
106+
107+
val x = resizeX?.let { rx ->
108+
mousePosition.x - rx
109+
} ?: size.x
110+
111+
val y = resizeY?.let { ry ->
112+
mousePosition.y - ry
113+
} ?: size.y
114+
115+
size = Vec2d(x, y).coerceIn(10.0, 1000.0, titleBar.size.y, 1000.0)
116+
}
58117
}
59118

60119
companion object {
@@ -72,6 +131,10 @@ open class Window(
72131
* @param scrollable Whether to allow user to scroll the elements
73132
* Note: applies to elements with [VAlign.TOP] only
74133
*
134+
* @param minimizable Whether to allow user to minimize the window
135+
*
136+
* @param resizable Whether to allow user to resize the window
137+
*
75138
* @param block Actions to perform within content space of the window
76139
*/
77140
@UIBuilder
@@ -81,11 +144,17 @@ open class Window(
81144
title: String = "Untitled",
82145
draggable: Boolean = true,
83146
scrollable: Boolean = true,
147+
minimizable: Boolean = true,
148+
resizable: Boolean = true,
84149
block: WindowContent.() -> Unit = {}
85-
) = Window(this, title, draggable, scrollable).apply(children::add).apply {
86-
this.position = position
87-
this.size = size
150+
) = Window(
151+
this, title,
152+
position, size,
153+
draggable, scrollable, minimizable, resizable
154+
).apply(children::add).apply {
88155
block(this.content)
89156
}
157+
158+
private const val RESIZE_RANGE = 5.0
90159
}
91160
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class WindowContent(
1313
owner: Window,
1414
scrollable: Boolean
1515
) : Layout(owner, false, true) {
16-
private val animation = AnimationTicker()
16+
private val animation = animationTicker(false)
1717

1818
private var dwheel = 0.0
1919
private var scrollOffset = 0.0

0 commit comments

Comments
 (0)