selection wiping
This commit is contained in:
parent
dac83d7e63
commit
16e371ec01
@ -34,6 +34,7 @@ open class TextInputPanel<out S : Screen>(
|
||||
private data class TextSelection(val start: Int, val end: Int) {
|
||||
val isInversed get() = start > end
|
||||
val isNotEmpty get() = start != end
|
||||
val isValid get() = start != end
|
||||
|
||||
val actualStart get() = if (isInversed) this.end else this.start
|
||||
val actualEnd get() = if (isInversed) this.start else this.end
|
||||
@ -67,6 +68,14 @@ open class TextInputPanel<out S : Screen>(
|
||||
}
|
||||
}
|
||||
|
||||
private fun putSelection(index: Int, selection: TextSelection) {
|
||||
if (selection.isValid) {
|
||||
selections[index] = selection
|
||||
} else {
|
||||
selections.remove(index)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class Snapshot {
|
||||
private val lines = ArrayList(this@TextInputPanel.lines) // ultra fast copy
|
||||
private val cursorLine = this@TextInputPanel.cursorLine
|
||||
@ -296,19 +305,19 @@ open class TextInputPanel<out S : Screen>(
|
||||
val (start, end) = selection
|
||||
|
||||
if (character < start) {
|
||||
selections[line] = TextSelection(start + moveBy, end + moveBy)
|
||||
putSelection(line, TextSelection(start + moveBy, end + moveBy))
|
||||
} else if (character > end && character + moveBy < end) {
|
||||
if (character + moveBy < start) {
|
||||
// selections.remove(line)
|
||||
selections[line] = TextSelection(0, 0)
|
||||
} else {
|
||||
selections[line] = TextSelection(start, character + moveBy)
|
||||
putSelection(line, TextSelection(start, character + moveBy))
|
||||
}
|
||||
} else if (character in start .. end) {
|
||||
if (moveBy > 0 || character + moveBy <= start) {
|
||||
selections[line] = TextSelection(start, end + moveBy)
|
||||
putSelection(line, TextSelection(start, end + moveBy))
|
||||
} else {
|
||||
selections[line] = TextSelection(character + moveBy, end + moveBy)
|
||||
putSelection(line, TextSelection(character + moveBy, end + moveBy))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -319,29 +328,41 @@ open class TextInputPanel<out S : Screen>(
|
||||
return
|
||||
|
||||
pushbackSnapshotIfNoTimer()
|
||||
val set = selections.int2ObjectEntrySet()
|
||||
|
||||
val inversed = ArrayList(selections.int2ObjectEntrySet())
|
||||
while (set.isNotEmpty()) {
|
||||
val (lineNumber, selection) = set.last()
|
||||
selections.remove(lineNumber)
|
||||
val line = this[lineNumber] ?: continue
|
||||
if (!selection.isValid) continue // ???
|
||||
|
||||
var downTo = inversed.size.ushr(1)
|
||||
if (inversed.size and 1 == 1) downTo++
|
||||
|
||||
for (i in inversed.size - 1 downTo downTo) {
|
||||
val i2 = inversed.size - i
|
||||
val a = inversed[i]
|
||||
val b = inversed[i2]
|
||||
inversed[i] = b
|
||||
inversed[i2] = a
|
||||
}
|
||||
|
||||
for ((lineNumber, selection) in inversed) {
|
||||
if (selection.start != selection.end) {
|
||||
if (selection.start == 0 && selection.end == this[lineNumber]!!.length) {
|
||||
if (selection.coversEntireLine(line)) {
|
||||
removeLine(lineNumber)
|
||||
} else if (selection.coversEntireString(line)) {
|
||||
this[lineNumber] = ""
|
||||
} else if (selection.coversNewline(line)) {
|
||||
val before = line.substring(0, selection.actualStart.coerceIn(0, line.length))
|
||||
val next = this[lineNumber + 1]
|
||||
|
||||
if (next == null) {
|
||||
this[lineNumber] = before
|
||||
} else {
|
||||
this[lineNumber] = before + next
|
||||
removeLine(lineNumber + 1)
|
||||
}
|
||||
} else {
|
||||
val before = line.substring(0, selection.actualStart.coerceIn(0, line.length))
|
||||
val after = line.substring(selection.actualEnd.coerceIn(0, line.length))
|
||||
this[lineNumber] = before + after
|
||||
}
|
||||
|
||||
if (lineNumber < cursorLine) {
|
||||
cursorLine = lineNumber
|
||||
cursorCharacter = selection.actualStart
|
||||
} else if (lineNumber == cursorLine && cursorCharacter > selection.actualStart) {
|
||||
cursorCharacter = selection.actualStart
|
||||
}
|
||||
}
|
||||
|
||||
// selections.clear()
|
||||
}
|
||||
|
||||
protected open fun textChanged(oldText: String, newText: String) {}
|
||||
@ -453,22 +474,22 @@ open class TextInputPanel<out S : Screen>(
|
||||
val result = advanceCursorLeft(greedy)
|
||||
|
||||
if (!result.linesChanged)
|
||||
selections[result.oldLine] = TextSelection(
|
||||
putSelection(result.oldLine, TextSelection(
|
||||
existing?.start ?: result.oldCharacter,
|
||||
result.newCharacter)
|
||||
result.newCharacter))
|
||||
else {
|
||||
this[result.newLine]?.let {
|
||||
val existingNewline = selections[result.newLine]
|
||||
|
||||
if (existingNewline == null) {
|
||||
selections[result.newLine] = TextSelection(
|
||||
putSelection(result.newLine, TextSelection(
|
||||
Int.MAX_VALUE,
|
||||
it.length)
|
||||
it.length))
|
||||
} else {
|
||||
if (!existingNewline.isInversed) {
|
||||
selections[result.newLine] = TextSelection(
|
||||
putSelection(result.newLine, TextSelection(
|
||||
existingNewline.start,
|
||||
result.newCharacter)
|
||||
result.newCharacter))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -485,9 +506,9 @@ open class TextInputPanel<out S : Screen>(
|
||||
val existing = selections[cursorLine]
|
||||
val result = advanceCursorRight(greedy)
|
||||
|
||||
selections[result.oldLine] = TextSelection(
|
||||
putSelection(result.oldLine, TextSelection(
|
||||
existing?.start ?: result.oldCharacter,
|
||||
if (result.couldHaveChangedLine) Int.MAX_VALUE else result.newCharacter)
|
||||
if (result.couldHaveChangedLine) Int.MAX_VALUE else result.newCharacter))
|
||||
}
|
||||
|
||||
override fun keyPressedInternal(key: Int, scancode: Int, mods: Int): Boolean {
|
||||
@ -644,7 +665,10 @@ open class TextInputPanel<out S : Screen>(
|
||||
}
|
||||
|
||||
if (key == InputConstants.KEY_BACKSPACE) {
|
||||
wipeSelection()
|
||||
if (selections.isNotEmpty()) {
|
||||
wipeSelection()
|
||||
return true
|
||||
}
|
||||
|
||||
val line = this[cursorLine]
|
||||
|
||||
@ -692,7 +716,10 @@ open class TextInputPanel<out S : Screen>(
|
||||
}
|
||||
|
||||
if (key == InputConstants.KEY_DELETE) {
|
||||
wipeSelection()
|
||||
if (selections.isNotEmpty()) {
|
||||
wipeSelection()
|
||||
return true
|
||||
}
|
||||
|
||||
if (cursorLine !in 0 until lines.size) {
|
||||
cursorLine = lines.size - 1
|
||||
@ -799,7 +826,7 @@ open class TextInputPanel<out S : Screen>(
|
||||
color = textColor
|
||||
)
|
||||
|
||||
if (selection != null && (selection.isNotEmpty || selection.coversEntireLine(line))) {
|
||||
if (selection != null && selection.isValid && (selection.isNotEmpty || selection.coversEntireLine(line))) {
|
||||
val (before, selected) = selection.sub(line)
|
||||
|
||||
var x = 0f
|
||||
|
Loading…
Reference in New Issue
Block a user