Skip to content

Commit cc38ff9

Browse files
committed
InputBar
1 parent 3d0a549 commit cc38ff9

File tree

16 files changed

+241
-81
lines changed

16 files changed

+241
-81
lines changed

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ package com.lambda.gui.api.component
33
import com.lambda.gui.api.GuiEvent
44
import com.lambda.gui.api.component.core.IComponent
55
import com.lambda.util.Mouse
6-
import com.lambda.util.math.Rect
76

87
abstract class InteractiveComponent : IComponent {
98
protected var hovered = false
10-
protected var pressed = false
9+
protected var activeButton: Mouse.Button? = null
1110

1211
protected open fun onPress(e: GuiEvent.MouseClick) {}
1312
protected open fun onRelease(e: GuiEvent.MouseClick) {}
@@ -16,7 +15,7 @@ abstract class InteractiveComponent : IComponent {
1615
when (e) {
1716
is GuiEvent.Show -> {
1817
hovered = false
19-
pressed = false
18+
activeButton = null
2019
}
2120

2221
is GuiEvent.MouseMove -> {
@@ -26,8 +25,9 @@ abstract class InteractiveComponent : IComponent {
2625
is GuiEvent.MouseClick -> {
2726
hovered = rect.contains(e.mouse)
2827

29-
val prevPressed = pressed
30-
pressed = hovered && e.button.isMainButton && e.action == Mouse.Action.Click
28+
val prevPressed = activeButton != null
29+
activeButton = if (hovered && e.button.isMainButton && e.action == Mouse.Action.Click) e.button else null
30+
val pressed = activeButton != null
3131

3232
if (prevPressed == pressed) return
3333
if (pressed) onPress(e)

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ import java.awt.Color
2121
import kotlin.math.abs
2222

2323
abstract class WindowComponent <T : ChildComponent> (
24-
final override val owner: AbstractClickGui
25-
) : ChildComponent(owner) {
24+
val gui: AbstractClickGui
25+
) : ChildComponent(gui.windows) {
2626
abstract val title: String
2727

2828
abstract var width: Double
@@ -47,8 +47,7 @@ abstract class WindowComponent <T : ChildComponent> (
4747
private val renderer = layer.entry()
4848
private val contentLayer = RenderLayer()
4949

50-
private val animation = owner.animation
51-
private val gui = owner
50+
private val animation = gui.animation
5251

5352
private val showAnimation by animation.exp(0.0, 1.0, 0.6, ::isOpen)
5453
override val childShowAnimation get() = lerp(0.0, showAnimation, gui.childShowAnimation)
@@ -57,7 +56,7 @@ abstract class WindowComponent <T : ChildComponent> (
5756
private var renderHeightAnimation by animation.exp({ 0.0 }, ::actualHeight, 0.6, ::isOpen)
5857
private val renderHeight get() = lerp(0.0, renderHeightAnimation, childShowAnimation)
5958

60-
val contentComponents = ChildLayer.Drawable<T>(gui, this, contentLayer, ::contentRect)
59+
open val contentComponents = ChildLayer.Drawable<T, WindowComponent<T>>(gui, this, contentLayer, ::contentRect)
6160

6261
/*val titleBarComponents = ChildLayer<ButtonComponent> { child ->
6362
child.rect in titleBar && accessible
@@ -149,7 +148,7 @@ abstract class WindowComponent <T : ChildComponent> (
149148

150149
fun focus() {
151150
// move window into foreground
152-
owner.apply {
151+
gui.apply {
153152
scheduleAction {
154153
windows.children.apply {
155154
this@WindowComponent
@@ -161,7 +160,7 @@ abstract class WindowComponent <T : ChildComponent> (
161160
}
162161

163162
fun destroy() {
164-
owner.apply {
163+
gui.apply {
165164
scheduleAction {
166165
windows.removeChild(this@WindowComponent)
167166
}

common/src/main/kotlin/com/lambda/gui/api/component/button/ButtonComponent.kt

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,42 +16,46 @@ import com.lambda.util.math.Vec2d
1616
import java.awt.Color
1717

1818
abstract class ButtonComponent(
19-
final override val owner: ChildLayer.Drawable<*>
19+
owner: ChildLayer.Drawable<*, *>
2020
) : ChildComponent(owner) {
2121
abstract val position: Vec2d
2222
abstract val size: Vec2d
2323

2424
abstract val text: String
25+
protected open val textColor get() = lerp(Color.WHITE, GuiSettings.mainColor, activeAnimation).multAlpha(showAnimation)
2526
protected abstract var activeAnimation: Double
2627

2728
private val actualSize get() = Vec2d(if (size.x == FILL_PARENT) owner.rect.size.x else size.x, size.y)
2829
final override val rect get() = Rect.basedOn(position, actualSize) + owner.rect.leftTop
2930

30-
protected val renderer = owner.renderer.entry()
31+
val renderer = owner.renderer.entry()
3132
protected val animation = owner.gui.animation
3233

3334
private var hoverRectAnimation by animation.exp({ 0.0 }, { 1.0 }, { if (renderHovered) 0.6 else 0.07 }, ::renderHovered)
34-
private var hoverFontAnimation by animation.exp(0.0, 1.0, 0.5, ::renderHovered)
35-
private var pressAnimation by animation.exp(0.0, 1.0, 0.5, ::pressed)
35+
protected var hoverFontAnimation by animation.exp(0.0, 1.0, 0.5, ::renderHovered)
36+
protected var pressAnimation by animation.exp(0.0, 1.0, 0.5) { activeButton != null }
3637
protected val interactAnimation get() = lerp(hoverRectAnimation, 1.5, pressAnimation) * 0.4
3738
override val childShowAnimation: Double get() = owner.childShowAnimation
3839
protected open val showAnimation get() = owner.childShowAnimation
3940

4041
private var lastHoveredTime = 0L
4142
private val renderHovered get() = hovered || System.currentTimeMillis() - lastHoveredTime < 110
4243

44+
// Removes button shrinking if there's no space between buttons
45+
protected val shrink get() = lerp(0.0, interactAnimation, ClickGui.buttonStep)
46+
4347
init {
4448
// Active color
4549
renderer.filled {
46-
position = rect.shrink(interactAnimation)
50+
position = rect.shrink(shrink)
4751
shade = GuiSettings.shade
4852
color(GuiSettings.mainColor.multAlpha(activeAnimation * 0.3 * showAnimation))
4953
}
5054

5155
// Hover glint
5256
renderer.filled {
5357
val hoverRect = Rect.basedOn(rect.leftTop, rect.size.x * hoverRectAnimation, rect.size.y)
54-
position = hoverRect.shrink(interactAnimation)
58+
position = hoverRect.shrink(shrink)
5559
shade = GuiSettings.shade
5660

5761
val alpha = interactAnimation * 0.2 * showAnimation
@@ -63,10 +67,10 @@ abstract class ButtonComponent(
6367
text = this@ButtonComponent.text
6468
scale = 1.0 - pressAnimation * 0.08
6569

66-
color = lerp(Color.WHITE, GuiSettings.mainColor, activeAnimation).multAlpha(showAnimation)
70+
color = textColor
6771

6872
val x = ClickGui.windowPadding + interactAnimation + hoverFontAnimation
69-
position = rect.leftTop + Vec2d(x, rect.size.y * 0.5)
73+
position = Vec2d(rect.left + x, rect.center.y)
7074
}
7175
}
7276

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package com.lambda.gui.api.component.button
2+
3+
import com.lambda.graphics.animation.Animation.Companion.exp
4+
import com.lambda.gui.api.GuiEvent
5+
import com.lambda.gui.api.component.core.list.ChildComponent
6+
import com.lambda.gui.api.component.core.list.ChildLayer
7+
import com.lambda.gui.api.layer.LayerEntry
8+
import com.lambda.module.modules.client.ClickGui
9+
import com.lambda.util.KeyCode
10+
import com.lambda.util.math.ColorUtils.setAlpha
11+
import com.lambda.util.math.MathUtils.lerp
12+
import com.lambda.util.math.Rect
13+
import com.lambda.util.math.Vec2d
14+
import java.awt.Color
15+
import kotlin.math.abs
16+
17+
abstract class InputBarOverlay (renderer: LayerEntry, owner: ChildLayer.Drawable<InputBarOverlay, *>) : ChildComponent(owner) {
18+
override val rect: Rect get() = owner.rect
19+
override var isActive = false
20+
21+
abstract val pressAnimation: Double
22+
abstract val interactAnimation: Double
23+
abstract val hoverFontAnimation: Double
24+
abstract val showAnimation: Double
25+
26+
val activeAnimation by owner.gui.animation.exp(0.0, 1.0, 0.7, ::isActive)
27+
private var typeAnimation by owner.gui.animation.exp({ 0.0 }, 0.2)
28+
29+
private var targetOffset = 0.0
30+
private var offset by owner.gui.animation.exp(::targetOffset, 0.4)
31+
32+
abstract fun getInitText(): String
33+
abstract fun setValue(string: String)
34+
35+
open fun isCharAllowed(char: Char): Boolean = true
36+
37+
private val field = renderer.font {
38+
scale = lerp(0.5, 1.0, activeAnimation) - pressAnimation * 0.08
39+
color = Color.WHITE.setAlpha(lerp(0.0, activeAnimation, showAnimation))
40+
41+
val x = ClickGui.windowPadding + interactAnimation + hoverFontAnimation
42+
position = Vec2d(rect.left + x, rect.center.y)
43+
targetOffset = stringWidth
44+
}
45+
46+
init {
47+
renderer.filled {
48+
val shrink = lerp(rect.size.y * 0.5, 2 + abs(typeAnimation), activeAnimation)
49+
val x = field.position.x + offset + 2
50+
51+
position = Rect(
52+
Vec2d(0.0, rect.top + shrink),
53+
Vec2d(1.0, rect.bottom - shrink)
54+
) + Vec2d(lerp(rect.right, x, activeAnimation), 0.0)
55+
56+
color(field.color.setAlpha(0.8))
57+
}
58+
}
59+
60+
override fun onEvent(e: GuiEvent) {
61+
super.onEvent(e)
62+
63+
when (e) {
64+
is GuiEvent.Show -> {
65+
isActive = false
66+
}
67+
68+
is GuiEvent.CharTyped -> {
69+
if (!isActive || !isCharAllowed(e.char)) return
70+
field.text += e.char
71+
typeAnimation = 1.0
72+
}
73+
74+
is GuiEvent.KeyPress -> {
75+
if (!isActive) return
76+
77+
when (e.key) {
78+
KeyCode.Enter -> {
79+
setValue(field.text)
80+
toggle()
81+
}
82+
83+
KeyCode.Backspace -> {
84+
field.text = field.text.dropLast(1)
85+
typeAnimation = -1.0
86+
}
87+
}
88+
}
89+
}
90+
}
91+
92+
fun toggle() {
93+
isActive = !isActive
94+
95+
if (isActive) {
96+
field.text = getInitText()
97+
targetOffset = field.stringWidth
98+
}
99+
}
100+
}

common/src/main/kotlin/com/lambda/gui/api/component/button/ListButton.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@ import com.lambda.module.modules.client.ClickGui
77
import com.lambda.util.math.MathUtils.lerp
88
import com.lambda.util.math.Vec2d
99

10-
abstract class ListButton(owner: ChildLayer.Drawable<*>) : ButtonComponent(owner) {
10+
abstract class ListButton(owner: ChildLayer.Drawable<*, *>) : ButtonComponent(owner) {
1111
override val position get() = Vec2d(0.0, lerp(0.0, renderHeightOffset, owner.childShowAnimation))
1212
override val size get() = Vec2d(FILL_PARENT, ClickGui.buttonHeight)
1313

1414
open val listStep get() = ClickGui.buttonStep
1515

1616
var heightOffset = 0.0
17-
1817
protected var renderHeightAnimation by animation.exp(::heightOffset, 0.8)
1918
protected open val renderHeightOffset get() = renderHeightAnimation
2019

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ package com.lambda.gui.api.component.core.list
22

33
import com.lambda.gui.api.GuiEvent
44
import com.lambda.gui.api.component.InteractiveComponent
5-
import com.lambda.gui.api.component.core.IComponent
65

7-
abstract class ChildComponent(open val owner: IComponent) : InteractiveComponent() {
6+
abstract class ChildComponent(open val owner: ChildLayer<*, *>) : InteractiveComponent() {
87
open var accessible = false
98

109
override fun onEvent(e: GuiEvent) {

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ import com.lambda.gui.api.layer.RenderLayer
77
import com.lambda.util.Mouse
88
import com.lambda.util.math.Rect
99

10-
open class ChildLayer <T : ChildComponent> (
10+
open class ChildLayer <T : ChildComponent, R : IComponent> (
1111
val gui: LambdaGui,
12-
val owner: IComponent,
12+
val ownerComponent: R,
1313
private val childRect: () -> Rect,
1414
private val childAccessible: (T) -> Boolean = { true }
1515
) : IComponent {
16-
override val isActive get() = owner.isActive
17-
override val childShowAnimation get() = owner.childShowAnimation
16+
override val isActive get() = ownerComponent.isActive
17+
override val childShowAnimation get() = ownerComponent.childShowAnimation
1818
override val rect get() = childRect()
1919
val children = mutableListOf<T>()
2020

@@ -32,8 +32,8 @@ open class ChildLayer <T : ChildComponent> (
3232
children.forEach { child ->
3333
when (e) {
3434
is GuiEvent.Tick -> {
35-
val ownerAccessible = (owner as? ChildComponent)?.accessible ?: true
36-
child.accessible = childAccessible(child) && child.rect in rect && ownerAccessible && owner.isActive
35+
val ownerAccessible = (ownerComponent as? ChildComponent)?.accessible ?: true
36+
child.accessible = childAccessible(child) && child.rect in rect && ownerAccessible && ownerComponent.isActive
3737
}
3838

3939
is GuiEvent.KeyPress, is GuiEvent.CharTyped -> {
@@ -52,11 +52,11 @@ open class ChildLayer <T : ChildComponent> (
5252
}
5353
}
5454

55-
class Drawable <T : ChildComponent> (
55+
class Drawable <T : ChildComponent, R : IComponent> (
5656
gui: LambdaGui,
57-
owner: IComponent,
57+
owner: R,
5858
val renderer: RenderLayer,
5959
contentRect: () -> Rect,
6060
childAccessible: (T) -> Boolean = { true }
61-
) : ChildLayer<T>(gui, owner, contentRect, childAccessible)
61+
) : ChildLayer<T, R>(gui, owner, contentRect, childAccessible)
6262
}

common/src/main/kotlin/com/lambda/gui/impl/clickgui/AbstractClickGui.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ abstract class AbstractClickGui(name: String = "ClickGui") : LambdaGui(name, Cli
1818
if (closing) ClickGui.closeSpeed else ClickGui.openSpeed
1919
}) { !closing }; private set
2020

21-
val windows = ChildLayer<WindowComponent<*>>(this, this, ::rect) { child ->
21+
val windows = ChildLayer<WindowComponent<*>, AbstractClickGui>(this, this, ::rect) { child ->
2222
child == activeWindow && !closing
2323
}
2424

common/src/main/kotlin/com/lambda/gui/impl/clickgui/buttons/ModuleButton.kt

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ import com.lambda.core.SoundManager.playSoundRandomly
77
import com.lambda.graphics.animation.Animation.Companion.exp
88
import com.lambda.graphics.gl.Scissor.scissor
99
import com.lambda.gui.api.GuiEvent
10+
import com.lambda.gui.api.component.WindowComponent
1011
import com.lambda.gui.api.component.button.ListButton
1112
import com.lambda.gui.api.component.core.list.ChildLayer
1213
import com.lambda.gui.api.layer.RenderLayer
1314
import com.lambda.gui.impl.clickgui.buttons.setting.BooleanButton
1415
import com.lambda.gui.impl.clickgui.buttons.setting.NumberSlider
15-
import com.lambda.gui.impl.clickgui.windows.ModuleWindow
1616
import com.lambda.module.Module
1717
import com.lambda.module.modules.client.GuiSettings
1818
import com.lambda.util.Mouse
@@ -26,7 +26,10 @@ import com.lambda.util.math.transform
2626
import java.awt.Color
2727
import kotlin.math.abs
2828

29-
class ModuleButton(val module: Module, owner: ChildLayer.Drawable<*>) : ListButton(owner) {
29+
class ModuleButton(
30+
val module: Module,
31+
override val owner: ChildLayer.Drawable<ModuleButton, WindowComponent<ModuleButton>>
32+
) : ListButton(owner) {
3033
override val text get() = module.name
3134
private val enabled get() = module.isEnabled
3235

@@ -38,8 +41,8 @@ class ModuleButton(val module: Module, owner: ChildLayer.Drawable<*>) : ListButt
3841
private var isOpen = false
3942
override val isActive get() = isOpen
4043

41-
private val childShowAnimation0 by animation.exp(0.0, 1.0, 0.7, ::isOpen)
42-
override val childShowAnimation get() = lerp(0.0, childShowAnimation0, owner.childShowAnimation)
44+
private val openAnimation by animation.exp(0.0, 1.0, 0.7, ::isOpen)
45+
override val childShowAnimation get() = lerp(0.0, openAnimation, owner.childShowAnimation)
4346

4447
private var settingsHeight = 0.0
4548
private var renderHeight by animation.exp(::settingsHeight, 0.6)
@@ -48,7 +51,7 @@ class ModuleButton(val module: Module, owner: ChildLayer.Drawable<*>) : ListButt
4851
.moveSecond(Vec2d(0.0, renderHeight))
4952

5053
private val settingsRenderer = RenderLayer()
51-
private val settingsLayer = ChildLayer.Drawable<SettingButton<*, *>>(owner.gui, this, settingsRenderer, ::settingsRect) {
54+
val settingsLayer = ChildLayer.Drawable<SettingButton<*, *>, ModuleButton>(owner.gui, this, settingsRenderer, ::settingsRect) {
5255
it.visible && abs(settingsHeight - renderHeight) <3
5356
}
5457

@@ -86,9 +89,8 @@ class ModuleButton(val module: Module, owner: ChildLayer.Drawable<*>) : ListButt
8689

8790
// Bottom shadow
8891
renderer.filled {
89-
val show = (owner.owner as? ModuleWindow)?.let {
90-
this@ModuleButton != it.contentComponents.children.lastOrNull()
91-
} ?: false
92+
val last = this@ModuleButton.owner.ownerComponent.contentComponents.children.lastOrNull()
93+
val show = this@ModuleButton != last
9294

9395
position = Rect(settingsRect.leftBottom - Vec2d(0.0, 5.0), settingsRect.rightBottom)
9496
val progress = transform(renderHeight, 0.0, 10.0, 0.0, 1.0).coerceIn(0.0, 1.0) * show.toInt()

0 commit comments

Comments
 (0)