-
Notifications
You must be signed in to change notification settings - Fork 4
/
ElementValue.kt
160 lines (142 loc) · 5.4 KB
/
ElementValue.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package com.spoiligaming.generator.gui.element
import com.spoiligaming.generator.gui.ColorPalette
import com.spoiligaming.generator.gui.ResourceHandler
import javafx.application.Platform
import javafx.beans.property.Property
import javafx.beans.property.SimpleIntegerProperty
import javafx.beans.property.SimpleLongProperty
import javafx.geometry.Insets
import javafx.geometry.Pos
import javafx.scene.Cursor
import javafx.scene.control.Button
import javafx.scene.control.TextField
import javafx.scene.input.ContextMenuEvent
import javafx.scene.input.KeyCode
import javafx.scene.input.MouseButton
import javafx.scene.layout.HBox
import java.text.DecimalFormat
object ElementValue {
fun <T : Number> addUnitValue(
initialValue: T,
labelText: String,
tooltipText: String? = null,
valueUpdater: (T) -> Unit,
padding: Insets = Insets(10.0, 0.0, 0.0, 10.0),
): HBox {
val property = initialValue.toSimpleProperty()
return HBox().apply {
alignment = Pos.TOP_LEFT
spacing = 5.0
this.padding = padding
children.addAll(
createTextField(property, valueUpdater),
createButton("-", 30.0, 25.0) { updateValue(property, -1, valueUpdater as (Number) -> Unit) },
createButton("+", 30.0, 25.0) { updateValue(property, 1, valueUpdater as (Number) -> Unit) },
CommonElement.createLabel(labelText),
)
tooltipText?.let {
children.add(CommonElement.createTooltip(it))
}
Platform.runLater { requestFocus() }
}
}
private fun <T : Number> createTextField(
property: Any,
valueUpdater: (T) -> Unit,
) = TextField().apply {
setMaxSize(70.0, 25.0)
setMinSize(70.0, 25.0)
if (property is SimpleLongProperty || property is SimpleIntegerProperty) {
textProperty().bindBidirectional(property as Property<out Number>, DecimalFormat("#"))
}
style =
"-fx-background-color: ${ColorPalette.controlColor}; -fx-text-fill: ${ColorPalette.textColor}; -fx-font-family: '${ResourceHandler.comfortaaSemiBold.family}'; -fx-font-size: 14; -fx-background-radius: 12; -fx-highlight-fill: ${ColorPalette.accentColor};"
alignment = Pos.CENTER
var oldValue: String? = null
textProperty().addListener { _, oldVal, newVal ->
if (newVal.matches("\\d*".toRegex())) {
if (oldValue == null) {
oldValue = oldVal
}
} else {
text = oldValue
}
}
setOnKeyPressed { event ->
if (event.code == KeyCode.ENTER) {
Platform.runLater {
if (text.isEmpty()) {
text = oldValue
}
scene?.focusOwner?.requestFocus()
}
}
}
setOnMouseClicked { event ->
if (event.button == MouseButton.PRIMARY) {
Platform.runLater {
if (text.isEmpty()) {
text = oldValue
}
scene?.focusOwner?.requestFocus()
}
}
}
focusedProperty().addListener { _, _, isFocused ->
if (!isFocused) {
oldValue = null
if (text.isNotEmpty()) {
when (property) {
is SimpleIntegerProperty -> valueUpdater(text.toInt() as T)
is SimpleLongProperty -> valueUpdater(text.toLong() as T)
}
}
}
}
addEventFilter(ContextMenuEvent.CONTEXT_MENU_REQUESTED) { it.consume() }
}
private fun createButton(
text: String,
maxWidth: Double,
maxHeight: Double,
onClick: () -> Unit,
) = Button(text).apply {
alignment = Pos.CENTER
style =
"-fx-background-color: ${ColorPalette.controlColor}; -fx-text-fill: ${ColorPalette.textColor}; -fx-font-family: '${ResourceHandler.comfortaaSemiBold.family}'; -fx-font-size: 15; -fx-background-radius: 12;"
setMaxSize(maxWidth, maxHeight)
setMinSize(maxWidth, maxHeight)
setOnMouseEntered { cursor = Cursor.HAND }
setOnMouseExited { cursor = Cursor.DEFAULT }
setOnAction { onClick() }
}
private fun updateValue(
property: Any,
increment: Long,
valueUpdater: (Number) -> Unit,
) {
when (property) {
is SimpleIntegerProperty -> {
val newValue = property.get().toLong() + increment
if (newValue >= 0) {
property.set(newValue.toInt())
valueUpdater(newValue.toInt())
}
}
is SimpleLongProperty -> {
val newValue = property.get() + increment
if (newValue >= 0) {
property.set(newValue)
valueUpdater(newValue)
}
}
else -> throw IllegalArgumentException("Unsupported property type")
}
}
private fun <T : Number> T.toSimpleProperty(): Any =
when (this) {
is Long -> SimpleLongProperty(this)
is Int -> SimpleIntegerProperty(this)
else -> throw IllegalArgumentException("Unsupported type")
}
}