acceptsCharacter, support text padding in text input
This commit is contained in:
parent
03927bfc72
commit
f76fe4add6
@ -22,6 +22,7 @@ import ru.dbotthepony.mc.otm.client.render.TextAlign
|
|||||||
import ru.dbotthepony.mc.otm.client.render.drawAligned
|
import ru.dbotthepony.mc.otm.client.render.drawAligned
|
||||||
import ru.dbotthepony.mc.otm.client.render.drawRect
|
import ru.dbotthepony.mc.otm.client.render.drawRect
|
||||||
import ru.dbotthepony.mc.otm.client.render.tesselator
|
import ru.dbotthepony.mc.otm.client.render.tesselator
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.DockProperty
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||||
import ru.dbotthepony.mc.otm.core.addAll
|
import ru.dbotthepony.mc.otm.core.addAll
|
||||||
import ru.dbotthepony.mc.otm.core.math.RGBAColor
|
import ru.dbotthepony.mc.otm.core.math.RGBAColor
|
||||||
@ -144,6 +145,11 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
open var backgroundColor = RGBAColor.BLACK
|
open var backgroundColor = RGBAColor.BLACK
|
||||||
open var isActive = true
|
open var isActive = true
|
||||||
|
|
||||||
|
init {
|
||||||
|
scissor = true
|
||||||
|
dockPadding = DockProperty(2f, 2f, 2f, 2f)
|
||||||
|
}
|
||||||
|
|
||||||
private var oldText = ArrayList<String>()
|
private var oldText = ArrayList<String>()
|
||||||
private var textCache: String? = null
|
private var textCache: String? = null
|
||||||
private val lines = ArrayList<String>()
|
private val lines = ArrayList<String>()
|
||||||
@ -968,12 +974,21 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open fun acceptsCharacter(codepoint: Char, mods: Int = 0): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
override fun charTypedInternal(codepoint: Char, mods: Int): Boolean {
|
override fun charTypedInternal(codepoint: Char, mods: Int): Boolean {
|
||||||
if (!isActive) {
|
if (!isActive) {
|
||||||
killFocus()
|
killFocus()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!acceptsCharacter(codepoint, mods)) {
|
||||||
|
playGuiClickSound()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
wipeSelection()
|
wipeSelection()
|
||||||
|
|
||||||
if (!multiLine)
|
if (!multiLine)
|
||||||
@ -1003,9 +1018,10 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
||||||
|
if (!backgroundColor.isFullyTransparent)
|
||||||
drawRect(stack, 0f, 0f, width, height, backgroundColor)
|
drawRect(stack, 0f, 0f, width, height, backgroundColor)
|
||||||
|
|
||||||
var y = 0f
|
var y = dockPadding.top
|
||||||
|
|
||||||
for ((i, line) in lines.withIndex()) {
|
for ((i, line) in lines.withIndex()) {
|
||||||
val selection = selections[i]
|
val selection = selections[i]
|
||||||
@ -1015,7 +1031,7 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
buffer = BUFFER,
|
buffer = BUFFER,
|
||||||
text = line,
|
text = line,
|
||||||
align = TextAlign.TOP_LEFT,
|
align = TextAlign.TOP_LEFT,
|
||||||
x = 0f,
|
x = dockPadding.left,
|
||||||
y = y,
|
y = y,
|
||||||
color = textColor
|
color = textColor
|
||||||
)
|
)
|
||||||
@ -1023,10 +1039,10 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
if (selection != null && selection.isValid) {
|
if (selection != null && selection.isValid) {
|
||||||
val (before, selected) = selection.sub(line)
|
val (before, selected) = selection.sub(line)
|
||||||
|
|
||||||
var x = 0f
|
var x = dockPadding.left
|
||||||
|
|
||||||
if (before.isNotEmpty()) {
|
if (before.isNotEmpty()) {
|
||||||
x = font.width(before).toFloat()
|
x += font.width(before).toFloat()
|
||||||
}
|
}
|
||||||
|
|
||||||
val width = if (selection.coversNewline(line) && i != lines.size - 1) this.width - x else font.width(selected).toFloat()
|
val width = if (selection.coversNewline(line) && i != lines.size - 1) this.width - x else font.width(selected).toFloat()
|
||||||
@ -1057,6 +1073,9 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
y += font.lineHeight + 2f
|
y += font.lineHeight + 2f
|
||||||
|
|
||||||
|
if (y > height - dockPadding.bottom)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFocused && milliTime % 1000L > 500L) {
|
if (isFocused && milliTime % 1000L > 500L) {
|
||||||
@ -1068,8 +1087,8 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
buffer = BUFFER,
|
buffer = BUFFER,
|
||||||
text = "_",
|
text = "_",
|
||||||
align = TextAlign.TOP_LEFT,
|
align = TextAlign.TOP_LEFT,
|
||||||
x = if (activeLine == null) 0f else font.width(activeLine).toFloat(),
|
x = dockPadding.left + (if (activeLine == null) 0f else font.width(activeLine).toFloat()),
|
||||||
y = cursorLine * (font.lineHeight + 2f),
|
y = dockPadding.top + cursorLine * (font.lineHeight + 2f),
|
||||||
color = cursorColor
|
color = cursorColor
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@ -1078,8 +1097,8 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
buffer = BUFFER,
|
buffer = BUFFER,
|
||||||
text = "|",
|
text = "|",
|
||||||
align = TextAlign.TOP_LEFT,
|
align = TextAlign.TOP_LEFT,
|
||||||
x = font.width(activeLine.substring(0, cursorCharacter)).toFloat() - 1f,
|
x = dockPadding.left + font.width(activeLine.substring(0, cursorCharacter)).toFloat() - 1f,
|
||||||
y = cursorLine * (font.lineHeight + 2f),
|
y = dockPadding.top + cursorLine * (font.lineHeight + 2f),
|
||||||
color = cursorColor
|
color = cursorColor
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -1092,7 +1111,7 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
text = cursorLine.toString(),
|
text = cursorLine.toString(),
|
||||||
align = TextAlign.TOP_RIGHT,
|
align = TextAlign.TOP_RIGHT,
|
||||||
x = width,
|
x = width,
|
||||||
y = 0f,
|
y = dockPadding.top,
|
||||||
color = cursorColor
|
color = cursorColor
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1101,8 +1120,8 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
buffer = BUFFER,
|
buffer = BUFFER,
|
||||||
text = cursorCharacter.toString(),
|
text = cursorCharacter.toString(),
|
||||||
align = TextAlign.TOP_RIGHT,
|
align = TextAlign.TOP_RIGHT,
|
||||||
x = width,
|
x = width - dockPadding.right,
|
||||||
y = font.lineHeight + 2f,
|
y = dockPadding.top + font.lineHeight + 2f,
|
||||||
color = cursorColor
|
color = cursorColor
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1111,8 +1130,8 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
buffer = BUFFER,
|
buffer = BUFFER,
|
||||||
text = lines.size.toString(),
|
text = lines.size.toString(),
|
||||||
align = TextAlign.TOP_RIGHT,
|
align = TextAlign.TOP_RIGHT,
|
||||||
x = width,
|
x = width - dockPadding.right,
|
||||||
y = font.lineHeight * 2 + 4f,
|
y = dockPadding.top + font.lineHeight * 2 + 4f,
|
||||||
color = cursorColor
|
color = cursorColor
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -1142,10 +1161,20 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("name_shadowing")
|
||||||
fun localToText(x: Float, y: Float): Vector2i {
|
fun localToText(x: Float, y: Float): Vector2i {
|
||||||
if (lines.isEmpty())
|
if (lines.isEmpty())
|
||||||
return Vector2i(0, 0)
|
return Vector2i(0, 0)
|
||||||
|
|
||||||
|
var x = x - dockPadding.left
|
||||||
|
var y = y - dockPadding.top
|
||||||
|
|
||||||
|
if (y > height - dockPadding.bottom)
|
||||||
|
y = height - dockPadding.bottom
|
||||||
|
|
||||||
|
if (x > width - dockPadding.right)
|
||||||
|
x = width - dockPadding.right
|
||||||
|
|
||||||
val line = (y / (font.lineHeight + 2f)).toInt().coerceIn(0, lines.size - 1)
|
val line = (y / (font.lineHeight + 2f)).toInt().coerceIn(0, lines.size - 1)
|
||||||
val sLine = this[line] ?: return Vector2i(0, line)
|
val sLine = this[line] ?: return Vector2i(0, line)
|
||||||
|
|
||||||
@ -1154,29 +1183,6 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
else if (x >= font.width(sLine))
|
else if (x >= font.width(sLine))
|
||||||
return Vector2i(sLine.length, line)
|
return Vector2i(sLine.length, line)
|
||||||
|
|
||||||
// binary search attempt
|
|
||||||
// simply: sucks
|
|
||||||
/*@Suppress("name_shadowing")
|
|
||||||
var x = x
|
|
||||||
var start = 0
|
|
||||||
var end = sLine.length - 1
|
|
||||||
|
|
||||||
while (start < end - 1) {
|
|
||||||
val split = (end - start) / 2
|
|
||||||
val before = font.width(sLine.substring(start, start + split))
|
|
||||||
|
|
||||||
if (x < before) {
|
|
||||||
end = start + split
|
|
||||||
} else if (x > before) {
|
|
||||||
x -= before
|
|
||||||
start += split
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Vector2i(start, line)*/
|
|
||||||
|
|
||||||
val cache = Char2IntOpenHashMap()
|
val cache = Char2IntOpenHashMap()
|
||||||
var accumulatedWidth = 0f
|
var accumulatedWidth = 0f
|
||||||
|
|
||||||
|
@ -76,33 +76,38 @@ data class RGBAColor(val red: Float, val green: Float, val blue: Float, val alph
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val isFullyTransparent get() = alpha <= 0f
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val BLACK = RGBAColor(0f, 0f, 0f, 1f)
|
@JvmField val TRANSPARENT_BLACK = RGBAColor(0f, 0f, 0f, 0f)
|
||||||
val WHITE = RGBAColor(1f, 1f, 1f, 1f)
|
@JvmField val TRANSPARENT_WHITE = RGBAColor(1f, 1f, 1f, 0f)
|
||||||
val RED = RGBAColor(1f, 0f, 0f)
|
|
||||||
val GREEN = RGBAColor(0f, 1f, 0f, 1f)
|
|
||||||
val LIGHT_GREEN = RGBAColor(136, 255, 124)
|
|
||||||
val SLATE_GRAY = RGBAColor(64, 64, 64)
|
|
||||||
val GRAY = RGBAColor(0x2C2C2CFFL)
|
|
||||||
|
|
||||||
val DARK_BLUE = rgb(ChatFormatting.DARK_BLUE.color!!)
|
@JvmField val BLACK = RGBAColor(0f, 0f, 0f, 1f)
|
||||||
val DARK_GREEN = rgb(ChatFormatting.DARK_GREEN.color!!)
|
@JvmField val WHITE = RGBAColor(1f, 1f, 1f, 1f)
|
||||||
val DARK_AQUA = rgb(ChatFormatting.DARK_AQUA.color!!)
|
@JvmField val RED = RGBAColor(1f, 0f, 0f)
|
||||||
val DARK_RED = rgb(ChatFormatting.DARK_RED.color!!)
|
@JvmField val GREEN = RGBAColor(0f, 1f, 0f, 1f)
|
||||||
val DARK_PURPLE = rgb(ChatFormatting.DARK_PURPLE.color!!)
|
@JvmField val LIGHT_GREEN = RGBAColor(136, 255, 124)
|
||||||
val GOLD = rgb(ChatFormatting.GOLD.color!!)
|
@JvmField val SLATE_GRAY = RGBAColor(64, 64, 64)
|
||||||
val DARK_GRAY = rgb(ChatFormatting.DARK_GRAY.color!!)
|
@JvmField val GRAY = RGBAColor(0x2C2C2CFFL)
|
||||||
val BLUE = rgb(ChatFormatting.BLUE.color!!)
|
|
||||||
val AQUA = rgb(ChatFormatting.AQUA.color!!)
|
|
||||||
val LIGHT_PURPLE = rgb(ChatFormatting.LIGHT_PURPLE.color!!)
|
|
||||||
val YELLOW = rgb(ChatFormatting.YELLOW.color!!)
|
|
||||||
|
|
||||||
val LOW_POWER = RGBAColor(173, 41, 41)
|
@JvmField val DARK_BLUE = rgb(ChatFormatting.DARK_BLUE.color!!)
|
||||||
val FULL_POWER = RGBAColor(255, 242, 40)
|
@JvmField val DARK_GREEN = rgb(ChatFormatting.DARK_GREEN.color!!)
|
||||||
val LOW_MATTER = RGBAColor(0, 24, 148)
|
@JvmField val DARK_AQUA = rgb(ChatFormatting.DARK_AQUA.color!!)
|
||||||
val FULL_MATTER = RGBAColor(72, 90, 255)
|
@JvmField val DARK_RED = rgb(ChatFormatting.DARK_RED.color!!)
|
||||||
val LOW_PATTERNS = RGBAColor(44, 104, 57)
|
@JvmField val DARK_PURPLE = rgb(ChatFormatting.DARK_PURPLE.color!!)
|
||||||
val FULL_PATTERNS = RGBAColor(65, 255, 87)
|
@JvmField val GOLD = rgb(ChatFormatting.GOLD.color!!)
|
||||||
|
@JvmField val DARK_GRAY = rgb(ChatFormatting.DARK_GRAY.color!!)
|
||||||
|
@JvmField val BLUE = rgb(ChatFormatting.BLUE.color!!)
|
||||||
|
@JvmField val AQUA = rgb(ChatFormatting.AQUA.color!!)
|
||||||
|
@JvmField val LIGHT_PURPLE = rgb(ChatFormatting.LIGHT_PURPLE.color!!)
|
||||||
|
@JvmField val YELLOW = rgb(ChatFormatting.YELLOW.color!!)
|
||||||
|
|
||||||
|
@JvmField val LOW_POWER = RGBAColor(173, 41, 41)
|
||||||
|
@JvmField val FULL_POWER = RGBAColor(255, 242, 40)
|
||||||
|
@JvmField val LOW_MATTER = RGBAColor(0, 24, 148)
|
||||||
|
@JvmField val FULL_MATTER = RGBAColor(72, 90, 255)
|
||||||
|
@JvmField val LOW_PATTERNS = RGBAColor(44, 104, 57)
|
||||||
|
@JvmField val FULL_PATTERNS = RGBAColor(65, 255, 87)
|
||||||
|
|
||||||
fun inv(color: Int): RGBAColor {
|
fun inv(color: Int): RGBAColor {
|
||||||
val r = (color and -0x1000000 ushr 24) / 255f
|
val r = (color and -0x1000000 ushr 24) / 255f
|
||||||
|
Loading…
Reference in New Issue
Block a user