From 518b7e67fea0bfe6ed22f3adc18884a3dfaaafc6 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 26 Jan 2023 16:06:20 +0700 Subject: [PATCH] Selecting text with mouse --- .../client/screen/panels/TextInputPanel.kt | 157 ++++++++++++------ 1 file changed, 105 insertions(+), 52 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/TextInputPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/TextInputPanel.kt index 66ee71717..d78276a78 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/TextInputPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/TextInputPanel.kt @@ -515,6 +515,64 @@ open class TextInputPanel( if (result.couldHaveChangedLine) Int.MAX_VALUE else result.newCharacter)) } + private fun simulateSelectionUp(): Boolean { + if (cursorLine <= 0) + return false + + val cursorCharacter = cursorCharacter + val cursorLine = cursorLine + + while (this.cursorCharacter >= 0 && this.cursorLine == cursorLine) { + simulateSelectLeft(false) + } + + val line = this[this.cursorLine]!! + + if (cursorCharacter < line.length) { + this.cursorCharacter = line.length + + while (this.cursorCharacter > cursorCharacter) { + simulateSelectLeft(false) + } + } + + this.cursorCharacter = cursorCharacter + return true + } + + private fun simulateSelectionDown(): Boolean { + if (cursorLine >= lines.size - 1) + return false + + val cursorCharacter = cursorCharacter + val cursorLine = cursorLine + + while (this.cursorCharacter >= cursorCharacter && this.cursorLine == cursorLine) { + simulateSelectRight(true) + } + + val line = this[this.cursorLine]!! + + if (cursorCharacter < line.length) { + this.cursorCharacter = 0 + + while (this.cursorCharacter < cursorCharacter) { + simulateSelectRight(false) + } + } else { + val store = this.cursorLine + + for (i in 0 .. line.length) { + simulateSelectRight(false) + } + + this.cursorLine = store + } + + this.cursorCharacter = cursorCharacter + return true + } + override fun keyPressedInternal(key: Int, scancode: Int, mods: Int): Boolean { if (key == InputConstants.KEY_ESCAPE) { killFocus() @@ -598,26 +656,7 @@ open class TextInputPanel( return true } else if (key == InputConstants.KEY_UP) { if (minecraft.window.isShiftDown) { - if (cursorLine > 0) { - val cursorCharacter = cursorCharacter - val cursorLine = cursorLine - - while (this.cursorCharacter >= 0 && this.cursorLine == cursorLine) { - simulateSelectLeft(false) - } - - val line = this[this.cursorLine]!! - - if (cursorCharacter < line.length) { - this.cursorCharacter = line.length - - while (this.cursorCharacter > cursorCharacter) { - simulateSelectLeft(false) - } - } - - this.cursorCharacter = cursorCharacter - } + simulateSelectionUp() } else { if (cursorLine > 0) { cursorLine-- @@ -629,34 +668,7 @@ open class TextInputPanel( return true } else if (key == InputConstants.KEY_DOWN) { if (minecraft.window.isShiftDown) { - if (cursorLine < lines.size - 1) { - val cursorCharacter = cursorCharacter - val cursorLine = cursorLine - - while (this.cursorCharacter >= cursorCharacter && this.cursorLine == cursorLine) { - simulateSelectRight(true) - } - - val line = this[this.cursorLine]!! - - if (cursorCharacter < line.length) { - this.cursorCharacter = 0 - - while (this.cursorCharacter < cursorCharacter) { - simulateSelectRight(false) - } - } else { - val store = this.cursorLine - - for (i in 0 .. line.length) { - simulateSelectRight(false) - } - - this.cursorLine = store - } - - this.cursorCharacter = cursorCharacter - } + simulateSelectionDown() } else { if (cursorLine < lines.size - 1) { cursorLine++ @@ -930,14 +942,21 @@ open class TextInputPanel( BUFFER.endBatch() } + var isSelecting = false + protected set + override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean { selections.clear() requestFocus() - val (lx, ly) = screenToLocal(x, y) - val pos = localToText(lx, ly) - cursorLine = pos.y - cursorCharacter = pos.x + if (button == InputConstants.MOUSE_BUTTON_LEFT) { + val (lx, ly) = screenToLocal(x, y) + val pos = localToText(lx, ly) + cursorLine = pos.y + cursorCharacter = pos.x + + isSelecting = true + } return true } @@ -996,6 +1015,40 @@ open class TextInputPanel( return Vector2i(sLine.length, line) } + override fun mouseReleasedInner(x: Double, y: Double, button: Int): Boolean { + if (button == InputConstants.MOUSE_BUTTON_LEFT) + isSelecting = false + + return true + } + + override fun mouseDraggedInner(x: Double, y: Double, button: Int, xDelta: Double, yDelta: Double): Boolean { + if (button != InputConstants.MOUSE_BUTTON_LEFT || !isSelecting) + return true + + val (lx, ly) = screenToLocal(x, y) + val pos = localToText(lx, ly) + val cursorLine = pos.y + val cursorCharacter = pos.x + + while (cursorLine > this.cursorLine && simulateSelectionDown()) {} + while (cursorLine < this.cursorLine && simulateSelectionUp()) {} + + var lastCursorCharacter = this.cursorCharacter + 1 + + while (cursorCharacter < this.cursorCharacter && lastCursorCharacter != this.cursorCharacter) { + lastCursorCharacter = this.cursorCharacter + simulateSelectLeft(false) + } + + while (cursorCharacter > this.cursorCharacter && lastCursorCharacter != this.cursorCharacter) { + lastCursorCharacter = this.cursorCharacter + simulateSelectRight(false) + } + + return true + } + private enum class CharType { SPACES { override fun contains(input: Char): Boolean {