More precise filters in textinputpanel
This commit is contained in:
parent
abe82d456c
commit
5784b3346f
@ -27,8 +27,11 @@ import ru.dbotthepony.mc.otm.client.screen.panels.DockProperty
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||
import ru.dbotthepony.mc.otm.core.TextComponent
|
||||
import ru.dbotthepony.mc.otm.core.addAll
|
||||
import ru.dbotthepony.mc.otm.core.collect.mapToInt
|
||||
import ru.dbotthepony.mc.otm.core.collect.reduce
|
||||
import ru.dbotthepony.mc.otm.core.math.RGBAColor
|
||||
import ru.dbotthepony.mc.otm.milliTime
|
||||
import java.util.function.Predicate
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
open class TextInputPanel<out S : Screen>(
|
||||
@ -179,7 +182,7 @@ open class TextInputPanel<out S : Screen>(
|
||||
textCache = null
|
||||
val old = oldText.joinToString("\n")
|
||||
oldText = ArrayList(lines)
|
||||
onTextChanged(old, textCache())
|
||||
onTextChanged(textCache(), old)
|
||||
}
|
||||
}
|
||||
|
||||
@ -650,8 +653,10 @@ open class TextInputPanel<out S : Screen>(
|
||||
return true
|
||||
}
|
||||
|
||||
open fun onEnter() {
|
||||
var onEnter: Runnable? = null
|
||||
|
||||
open fun onEnter() {
|
||||
onEnter?.run()
|
||||
}
|
||||
|
||||
override fun keyPressedInternal(key: Int, scancode: Int, mods: Int): Boolean {
|
||||
@ -899,7 +904,8 @@ open class TextInputPanel<out S : Screen>(
|
||||
pushbackSnapshot()
|
||||
|
||||
if (multiLine) {
|
||||
val insert = minecraft.keyboardHandler.clipboard.replace("\t", " ").filter { acceptsCharacter(it) }.split(NEWLINES).toMutableList()
|
||||
var index = cursorRow + (0 until cursorLine).iterator().mapToInt { this[it]?.length ?: 0 }.reduce(0, Int::plus)
|
||||
val insert = minecraft.keyboardHandler.clipboard.replace("\t", " ").filter { acceptsCharacter(it, 0, index++) }.split(NEWLINES).toMutableList()
|
||||
val actualLastSize = insert.lastOrNull()?.length ?: 0
|
||||
val line = this[cursorLine]
|
||||
|
||||
@ -938,7 +944,8 @@ open class TextInputPanel<out S : Screen>(
|
||||
cursorRow = actualLastSize
|
||||
}
|
||||
} else {
|
||||
val insert = minecraft.keyboardHandler.clipboard.replace("\t", " ").replace(NEWLINES, "").filter { acceptsCharacter(it) }
|
||||
var index = cursorRow + (0 until cursorLine).iterator().mapToInt { this[it]?.length ?: 0 }.reduce(0, Int::plus)
|
||||
val insert = minecraft.keyboardHandler.clipboard.replace("\t", " ").replace(NEWLINES, "").filter { acceptsCharacter(it, 0, index++) }
|
||||
val line = this[cursorLine]
|
||||
|
||||
if (line == null) {
|
||||
@ -1017,8 +1024,38 @@ open class TextInputPanel<out S : Screen>(
|
||||
return true
|
||||
}
|
||||
|
||||
open fun acceptsCharacter(codepoint: Char, mods: Int = 0): Boolean {
|
||||
return true
|
||||
fun interface CharacterFilter : Predicate<Char> {
|
||||
fun acceptsCharacter(codepoint: Char, mods: Int, index: Int): Boolean
|
||||
|
||||
override fun test(t: Char): Boolean {
|
||||
return acceptsCharacter(t, 0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
var characterFilter: CharacterFilter? = null
|
||||
|
||||
fun allowEverything() {
|
||||
characterFilter = null
|
||||
}
|
||||
|
||||
fun allowNumbersAndSign() {
|
||||
characterFilter = CharacterFilter { it, _, i -> if (i == 0) it in SIGNS || it in NUMBERS else it in NUMBERS }
|
||||
}
|
||||
|
||||
fun allowNumbers() {
|
||||
characterFilter = CharacterFilter { it, _, _ -> it in NUMBERS }
|
||||
}
|
||||
|
||||
fun allowHexNumbersAndSign() {
|
||||
characterFilter = CharacterFilter { it, _, i -> if (i == 0) it in SIGNS || it in HEX else it in HEX }
|
||||
}
|
||||
|
||||
fun allowHexNumbers() {
|
||||
characterFilter = CharacterFilter { it, _, _ -> it in HEX }
|
||||
}
|
||||
|
||||
open fun acceptsCharacter(codepoint: Char, mods: Int = 0, index: Int): Boolean {
|
||||
return characterFilter?.acceptsCharacter(codepoint, mods, index) ?: true
|
||||
}
|
||||
|
||||
override fun charTypedInternal(codepoint: Char, mods: Int): Boolean {
|
||||
@ -1027,11 +1064,6 @@ open class TextInputPanel<out S : Screen>(
|
||||
return true
|
||||
}
|
||||
|
||||
if (!acceptsCharacter(codepoint, mods)) {
|
||||
playGuiClickSound()
|
||||
return true
|
||||
}
|
||||
|
||||
wipeSelection()
|
||||
|
||||
if (!multiLine)
|
||||
@ -1045,6 +1077,15 @@ open class TextInputPanel<out S : Screen>(
|
||||
cursorRow = 0
|
||||
}
|
||||
|
||||
var index = 0
|
||||
for (i in 0 until cursorLine) index += this[i]?.length ?: 0
|
||||
index += cursorRow
|
||||
|
||||
if (!acceptsCharacter(codepoint, mods, index)) {
|
||||
playGuiClickSound()
|
||||
return true
|
||||
}
|
||||
|
||||
if (cursorRow >= line.length)
|
||||
line += codepoint
|
||||
else
|
||||
@ -1349,13 +1390,13 @@ open class TextInputPanel<out S : Screen>(
|
||||
return true
|
||||
}
|
||||
|
||||
protected open fun onTextChanged(old: String, new: String) {
|
||||
changeCallback?.invoke(old, new)
|
||||
protected open fun onTextChanged(new: String, old: String) {
|
||||
changeCallback?.invoke(new, old)
|
||||
}
|
||||
|
||||
protected var changeCallback: ((old: String, new: String) -> Unit)? = null
|
||||
protected var changeCallback: ((new: String, old: String) -> Unit)? = null
|
||||
|
||||
fun onTextChange(callback: (old: String, new: String) -> Unit) {
|
||||
fun onTextChange(callback: (new: String, old: String) -> Unit) {
|
||||
changeCallback = callback
|
||||
}
|
||||
|
||||
@ -1420,6 +1461,21 @@ open class TextInputPanel<out S : Screen>(
|
||||
it.add(char)
|
||||
}
|
||||
|
||||
private val NUMBERS = CharOpenHashSet().also {
|
||||
for (char in "0123456789-+")
|
||||
it.add(char)
|
||||
}
|
||||
|
||||
private val SIGNS = CharOpenHashSet().also {
|
||||
for (char in "-+")
|
||||
it.add(char)
|
||||
}
|
||||
|
||||
private val HEX = CharOpenHashSet().also {
|
||||
for (char in "0123456789ABCDEFabcdef")
|
||||
it.add(char)
|
||||
}
|
||||
|
||||
private fun greedyAdvanceLeft(input: String, position: Int): Int {
|
||||
if (position <= 1)
|
||||
return -1
|
||||
|
Loading…
Reference in New Issue
Block a user