-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathUITextInput.kt
150 lines (122 loc) · 4.98 KB
/
UITextInput.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
package gg.essential.elementa.components.input
import gg.essential.elementa.constraints.WidthConstraint
import gg.essential.elementa.dsl.*
import gg.essential.universal.UMatrixStack
import java.awt.Color
open class UITextInput @JvmOverloads constructor(
placeholder: String = "",
shadow: Boolean = true,
selectionBackgroundColor: Color = Color.WHITE,
selectionForegroundColor: Color = Color(64, 139, 229),
allowInactiveSelection: Boolean = false,
inactiveSelectionBackgroundColor: Color = Color(176, 176, 176),
inactiveSelectionForegroundColor: Color = Color.WHITE,
cursorColor: Color = Color.WHITE
) : AbstractTextInput(
placeholder,
shadow,
selectionBackgroundColor,
selectionForegroundColor,
allowInactiveSelection,
inactiveSelectionBackgroundColor,
inactiveSelectionForegroundColor,
cursorColor = Color.WHITE
) {
protected var minWidth: WidthConstraint? = null
protected var maxWidth: WidthConstraint? = null
protected val placeholderWidth = placeholder.width()
fun setMinWidth(constraint: WidthConstraint) = apply {
minWidth = constraint
}
fun setMaxWidth(constraint: WidthConstraint) = apply {
maxWidth = constraint
}
override fun getText() = textualLines.first().text
protected open fun getTextForRender(): String = getText()
protected open fun setCursorPos() {
cursorComponent.unhide()
val (cursorPosX, _) = cursor.toScreenPos()
cursorComponent.setX((cursorPosX).pixels())
}
override fun textToLines(text: String): List<String> {
return listOf(text.replace('\n', ' '))
}
override fun scrollIntoView(pos: LinePosition) {
val column = pos.column
val lineText = getTextForRender()
if (column < 0 || column > lineText.length)
return
val widthBeforePosition = lineText.substring(0, column).width(getTextScale())
when {
getTextForRender().width(getTextScale()) < getWidth() -> {
horizontalScrollingOffset = 0f
}
horizontalScrollingOffset > widthBeforePosition -> {
horizontalScrollingOffset = widthBeforePosition
}
widthBeforePosition - horizontalScrollingOffset > getWidth() -> {
horizontalScrollingOffset = widthBeforePosition - getWidth()
}
}
}
override fun screenPosToVisualPos(x: Float, y: Float): LinePosition {
val targetXPos = x + horizontalScrollingOffset
var currentX = 0f
val line = getTextForRender()
for (i in line.indices) {
val charWidth = line[i].width(getTextScale())
if (currentX + (charWidth / 2) >= targetXPos) return LinePosition(0, i, isVisual = true)
currentX += charWidth
}
return LinePosition(0, line.length, isVisual = true)
}
override fun recalculateDimensions() {
if (minWidth != null && maxWidth != null) {
val width = if (!hasText() && !this.active) {
placeholderWidth
} else {
getTextForRender().width(getTextScale()) + 1 /* cursor */
}
setWidth(width.pixels().coerceIn(minWidth!!, maxWidth!!))
}
}
override fun splitTextForWrapping(text: String, maxLineWidth: Float): List<String> {
return listOf(text)
}
override fun onEnterPressed() {
activateAction(getText())
}
override fun draw(matrixStack: UMatrixStack) {
beforeDrawCompat(matrixStack)
if (!active && !hasText()) {
getFontProvider().drawString(matrixStack, placeholder, getColor(), getLeft(), getTop(), 10f, getTextScale(), shadow)
return super.draw(matrixStack)
}
val lineText = getTextForRender()
if (hasSelection()) {
var currentX = getLeft()
cursorComponent.hide(instantly = true)
if (!selectionStart().isAtLineStart) {
val preSelectionText = lineText.substring(0, selectionStart().column)
drawUnselectedTextCompat(matrixStack, preSelectionText, currentX, row = 0)
currentX += preSelectionText.width(getTextScale())
}
val selectedText = lineText.substring(selectionStart().column, selectionEnd().column)
val selectedTextWidth = selectedText.width(getTextScale())
drawSelectedTextCompat(matrixStack, selectedText, currentX, currentX + selectedTextWidth, row = 0)
currentX += selectedTextWidth
if (!selectionEnd().isAtLineEnd) {
drawUnselectedTextCompat(matrixStack, lineText.substring(selectionEnd().column), currentX, row = 0)
}
} else {
if (active) {
cursorComponent.setY(basicYConstraint {
getTop()
})
setCursorPos()
}
drawUnselectedTextCompat(matrixStack, lineText, getLeft(), 0)
}
super.draw(matrixStack)
}
}