Skip to content

Commit 86c9386

Browse files
committed
Windows, Buttons and tests
1 parent e768dce commit 86c9386

File tree

16 files changed

+523
-141
lines changed

16 files changed

+523
-141
lines changed

common/src/main/kotlin/com/lambda/graphics/animation/Animation.kt

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,27 @@ class Animation(initialValue: Double, val update: (Double) -> Double) {
2424
}
2525

2626
companion object {
27-
fun AnimationTicker.exp(min: Double, max: Double, speed: Double, flag: () -> Boolean) =
27+
fun AnimationTicker.exp(min: () -> Double, max: () -> Double, speed: Double, flag: () -> Boolean) =
28+
exp(min, max, { speed }, flag)
29+
30+
fun AnimationTicker.exp(min: Double, max: Double, speed: () -> Double, flag: () -> Boolean) =
2831
exp({ min }, { max }, speed, flag)
2932

30-
fun AnimationTicker.exp(min: () -> Double, max: () -> Double, speed: Double, flag: () -> Boolean) =
31-
Animation(min()) {
32-
val target = if (flag()) max() else min()
33-
if (abs(target - it) < CLAMP) target
34-
else lerp(it, target, speed)
35-
}.apply(::register)
33+
fun AnimationTicker.exp(min: Double, max: Double, speed: Double, flag: () -> Boolean) =
34+
exp({ min }, { max }, { speed }, flag)
3635

37-
fun AnimationTicker.linear(min: Double, max: Double, step: Double, flag: () -> Boolean) =
38-
Animation(min) {
36+
@Suppress("NAME_SHADOWING")
37+
fun AnimationTicker.exp(min: () -> Double, max: () -> Double, speed: () -> Double, flag: () -> Boolean) =
38+
Animation(min()) {
39+
val min = min(); val max = max()
3940
val target = if (flag()) max else min
40-
target.coerceIn(it - step, it + step)
41-
}.apply(::register)
4241

43-
fun AnimationTicker.linear(min: () -> Double, max: () -> Double, step: Double, flag: () -> Boolean) =
44-
Animation(min()) {
45-
val target = if (flag()) max() else min()
46-
target.coerceIn(it - step, it + step)
42+
if (abs(target - it) < CLAMP * abs(max - min)) target
43+
else lerp(it, target, speed())
4744
}.apply(::register)
4845

4946
// Exponent animation will never reach target value
50-
private const val CLAMP = 0.01
47+
private const val CLAMP = 0.001
5148
}
5249
}
5350

common/src/main/kotlin/com/lambda/graphics/renderer/gui/rect/RectEntry.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ class RectEntry(
4444

4545
val round = min(roundRadius, maxRadius)
4646

47-
val p1 = pos1 - 0.5
48-
val p2 = pos2 + 0.5
47+
val p1 = pos1 - 0.75
48+
val p2 = pos2 + 0.75
4949

5050
grow(4)
5151

common/src/main/kotlin/com/lambda/gui/LambdaGui.kt

Lines changed: 0 additions & 52 deletions
This file was deleted.
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.lambda.gui.api
2+
3+
import com.lambda.Lambda.mc
4+
import com.lambda.event.EventFlow
5+
import com.lambda.event.events.RenderEvent
6+
import com.lambda.event.events.TickEvent
7+
import com.lambda.event.listener.SafeListener.Companion.listener
8+
import com.lambda.gui.api.component.core.IComponent
9+
import com.lambda.util.KeyCode
10+
import com.lambda.util.Mouse
11+
import com.lambda.util.Nameable
12+
import com.lambda.util.math.Vec2d
13+
import com.mojang.blaze3d.systems.RenderSystem.recordRenderCall
14+
import net.minecraft.client.gui.DrawContext
15+
import net.minecraft.client.gui.screen.Screen
16+
import net.minecraft.text.Text
17+
18+
interface LambdaGui : IComponent, Nameable {
19+
fun onCloseRequest(): Boolean = true
20+
21+
/**
22+
* Shows this gui screen
23+
*
24+
* No safe context required (TODO: let user open clickgui via main menu)
25+
*/
26+
fun show() = recordRenderCall {
27+
mc.setScreen(object : Screen(Text.of(name)) {
28+
private var screenSize = Vec2d.ZERO
29+
30+
private val renderListener = listener<RenderEvent.GUI.Scaled> { event ->
31+
screenSize = event.screenSize
32+
onRender()
33+
}
34+
35+
private val tickListener = listener<TickEvent.Pre> {
36+
onTick()
37+
}
38+
39+
override fun onDisplayed() {
40+
onShow()
41+
}
42+
43+
override fun render(context: DrawContext?, mouseX: Int, mouseY: Int, delta: Float) {
44+
// Let's remove background tint
45+
}
46+
47+
override fun removed() {
48+
onHide()
49+
50+
with(EventFlow.syncListeners) {
51+
unsubscribe(renderListener)
52+
unsubscribe(tickListener)
53+
}
54+
}
55+
56+
override fun keyPressed(keyCode: Int, scanCode: Int, modifiers: Int): Boolean {
57+
onKey(KeyCode(keyCode))
58+
59+
if (keyCode == KeyCode.Escape.key && onCloseRequest()) {
60+
this.close()
61+
}
62+
63+
return true
64+
}
65+
66+
override fun charTyped(chr: Char, modifiers: Int): Boolean {
67+
onChar(chr)
68+
return true
69+
}
70+
71+
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
72+
onMouseClick(Mouse.Button(button), Mouse.Action.Click, rescaleMouse(mouseX, mouseY))
73+
return true
74+
}
75+
76+
override fun mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean {
77+
onMouseClick(Mouse.Button(button), Mouse.Action.Release, rescaleMouse(mouseX, mouseY))
78+
return true
79+
}
80+
81+
override fun mouseMoved(mouseX: Double, mouseY: Double) {
82+
onMouseMove(rescaleMouse(mouseX, mouseY))
83+
}
84+
85+
override fun shouldPause() = false
86+
87+
private fun rescaleMouse(mouseX: Double, mouseY: Double): Vec2d {
88+
val mcMouse = Vec2d(mouseX, mouseY)
89+
val mcWindow = Vec2d(mc.window.scaledWidth, mc.window.scaledHeight)
90+
91+
val uv = mcMouse / mcWindow
92+
return uv * screenSize
93+
}
94+
})
95+
}
96+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.lambda.gui.api.component
2+
3+
import com.lambda.gui.api.component.core.IRectComponent
4+
import com.lambda.util.Mouse
5+
import com.lambda.util.math.Vec2d
6+
7+
abstract class InteractiveComponent : IRectComponent {
8+
protected var hovered = false
9+
protected var pressed = false; set(value) {
10+
if (field == value) return
11+
field = value
12+
13+
if (value) onPress()
14+
else onRelease()
15+
}
16+
17+
protected var activeMouseButton: Mouse.Button? = null
18+
19+
protected open fun onPress() {}
20+
protected open fun onRelease() {}
21+
22+
override fun onShow() {
23+
hovered = false
24+
pressed = false
25+
}
26+
27+
override fun onMouseMove(mouse: Vec2d) {
28+
hovered = rect.contains(mouse)
29+
}
30+
31+
override fun onMouseClick(button: Mouse.Button, action: Mouse.Action, mouse: Vec2d) {
32+
activeMouseButton = button.takeUnless { it.isMainButton && action == Mouse.Action.Click }
33+
pressed = hovered && button.isMainButton && action == Mouse.Action.Click
34+
}
35+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package com.lambda.gui.api.component
2+
3+
import com.lambda.graphics.animation.Animation.Companion.exp
4+
import com.lambda.graphics.animation.AnimationTicker
5+
import com.lambda.graphics.gl.Scissor.scissor
6+
import com.lambda.graphics.renderer.gui.font.IFontEntry
7+
import com.lambda.gui.api.component.core.IListComponent
8+
import com.lambda.gui.api.component.core.IRectComponent
9+
import com.lambda.gui.api.layer.RenderLayer
10+
import com.lambda.module.modules.client.ClickGui
11+
import com.lambda.util.KeyCode
12+
import com.lambda.util.Mouse
13+
import com.lambda.util.math.MathUtils.toInt
14+
import com.lambda.util.math.Rect
15+
import com.lambda.util.math.Vec2d
16+
17+
abstract class WindowComponent <T : IRectComponent> : InteractiveComponent(), IListComponent<T> {
18+
abstract val title: String
19+
20+
abstract var width: Double
21+
abstract var height: Double
22+
23+
var position = Vec2d.ZERO
24+
25+
private var isOpen = false
26+
private var dragOffset: Vec2d? = null
27+
private val padding get() = ClickGui.padding
28+
29+
final override val rect get() = Rect.basedOn(position, width, renderHeight + titleBarHeight)
30+
val contentRect get() = rect.shrink(padding).moveFirst(Vec2d(0.0, titleBarHeight - padding))
31+
32+
private val titleBar get() = Rect.basedOn(rect.leftTop, rect.size.x, titleBarHeight)
33+
private val titleBarHeight get() = titleFont.height + 2 + padding * 2
34+
private val titleFont: IFontEntry
35+
36+
private val layer = RenderLayer()
37+
private val animation = AnimationTicker()
38+
39+
override val children = mutableListOf<T>()
40+
val subLayer = RenderLayer()
41+
42+
private val renderHeight by animation.exp({ 0.0 }, { height + padding * 2 * isOpen.toInt() }, 0.5, ::isOpen)
43+
44+
init {
45+
// Background
46+
layer.rect.build {
47+
position = rect
48+
roundRadius = ClickGui.windowRadius
49+
color(ClickGui.backgroundColor)
50+
}
51+
52+
// Title
53+
titleFont = layer.font.build {
54+
text = title
55+
position = titleBar.center - widthVec * 0.5
56+
}
57+
}
58+
59+
override fun onShow() {
60+
super<InteractiveComponent>.onShow()
61+
super<IListComponent>.onShow()
62+
63+
dragOffset = null
64+
}
65+
66+
override fun onHide() {
67+
super<IListComponent>.onHide()
68+
}
69+
70+
override fun onTick() {
71+
animation.tick()
72+
super<IListComponent>.onTick()
73+
}
74+
75+
override fun onRender() {
76+
layer.render()
77+
78+
scissor(contentRect) {
79+
subLayer.render()
80+
super<IListComponent>.onRender()
81+
}
82+
}
83+
84+
override fun onMouseMove(mouse: Vec2d) {
85+
super<InteractiveComponent>.onMouseMove(mouse)
86+
super<IListComponent>.onMouseMove(mouse)
87+
88+
dragOffset?.let {
89+
position = mouse - it
90+
}
91+
}
92+
93+
override fun onKey(key: KeyCode) {
94+
super<IListComponent>.onKey(key)
95+
}
96+
97+
override fun onChar(char: Char) {
98+
super<IListComponent>.onChar(char)
99+
}
100+
101+
override fun onMouseClick(button: Mouse.Button, action: Mouse.Action, mouse: Vec2d) {
102+
super<InteractiveComponent>.onMouseClick(button, action, mouse)
103+
104+
dragOffset = null
105+
106+
if (mouse in titleBar && action == Mouse.Action.Click) {
107+
when(button) {
108+
Mouse.Button.Left -> dragOffset = mouse - position
109+
Mouse.Button.Right -> isOpen = !isOpen
110+
}
111+
}
112+
113+
super<IListComponent>.onMouseClick(button, action, mouse)
114+
}
115+
116+
override fun isChildAccessible(child: T) =
117+
child.rect in contentRect
118+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.lambda.gui.api.component.core
2+
3+
import com.lambda.util.KeyCode
4+
import com.lambda.util.Mouse
5+
import com.lambda.util.math.Vec2d
6+
7+
interface IComponent {
8+
fun onShow() {}
9+
10+
fun onHide() {}
11+
12+
fun onTick() {}
13+
14+
fun onRender() {}
15+
16+
fun onKey(key: KeyCode) {}
17+
18+
fun onChar(char: Char) {}
19+
20+
fun onMouseClick(button: Mouse.Button, action: Mouse.Action, mouse: Vec2d) {}
21+
22+
fun onMouseMove(mouse: Vec2d) {}
23+
}

0 commit comments

Comments
 (0)