Moving text cursor using mice
This commit is contained in:
parent
962ac1d6b7
commit
b6d5cc4024
@ -6,11 +6,15 @@ import com.mojang.blaze3d.systems.RenderSystem
|
|||||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat
|
import com.mojang.blaze3d.vertex.DefaultVertexFormat
|
||||||
import com.mojang.blaze3d.vertex.PoseStack
|
import com.mojang.blaze3d.vertex.PoseStack
|
||||||
import com.mojang.blaze3d.vertex.VertexFormat
|
import com.mojang.blaze3d.vertex.VertexFormat
|
||||||
|
import it.unimi.dsi.fastutil.chars.Char2IntAVLTreeMap
|
||||||
|
import it.unimi.dsi.fastutil.chars.Char2IntFunction
|
||||||
|
import it.unimi.dsi.fastutil.chars.Char2IntOpenHashMap
|
||||||
import it.unimi.dsi.fastutil.chars.CharOpenHashSet
|
import it.unimi.dsi.fastutil.chars.CharOpenHashSet
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap
|
||||||
import net.minecraft.client.gui.screens.Screen
|
import net.minecraft.client.gui.screens.Screen
|
||||||
import net.minecraft.client.renderer.GameRenderer
|
import net.minecraft.client.renderer.GameRenderer
|
||||||
|
import org.joml.Vector2i
|
||||||
import ru.dbotthepony.mc.otm.client.isCtrlDown
|
import ru.dbotthepony.mc.otm.client.isCtrlDown
|
||||||
import ru.dbotthepony.mc.otm.client.isKeyDown
|
import ru.dbotthepony.mc.otm.client.isKeyDown
|
||||||
import ru.dbotthepony.mc.otm.client.isShiftDown
|
import ru.dbotthepony.mc.otm.client.isShiftDown
|
||||||
@ -929,9 +933,69 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
||||||
selections.clear()
|
selections.clear()
|
||||||
requestFocus()
|
requestFocus()
|
||||||
|
|
||||||
|
val (lx, ly) = screenToLocal(x, y)
|
||||||
|
val pos = localToText(lx, ly)
|
||||||
|
cursorLine = pos.y
|
||||||
|
cursorCharacter = pos.x
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun localToText(x: Float, y: Float): Vector2i {
|
||||||
|
if (lines.isEmpty())
|
||||||
|
return Vector2i(0, 0)
|
||||||
|
|
||||||
|
val line = (y / (font.lineHeight + 2f)).toInt().coerceIn(0, lines.size - 1)
|
||||||
|
val sLine = this[line] ?: return Vector2i(0, line)
|
||||||
|
|
||||||
|
if (x <= 0f)
|
||||||
|
return Vector2i(0, line)
|
||||||
|
else if (x >= font.width(sLine))
|
||||||
|
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()
|
||||||
|
var accumulatedWidth = 0f
|
||||||
|
|
||||||
|
for ((i, char) in sLine.withIndex()) {
|
||||||
|
val width = cache.computeIfAbsent(char, Char2IntFunction { font.width(it.toString()) })
|
||||||
|
|
||||||
|
if (x in accumulatedWidth .. accumulatedWidth + width) {
|
||||||
|
if (x - accumulatedWidth < width / 2)
|
||||||
|
return Vector2i(i, line)
|
||||||
|
else
|
||||||
|
return Vector2i(i + 1, line)
|
||||||
|
} else {
|
||||||
|
accumulatedWidth += width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Vector2i(sLine.length, line)
|
||||||
|
}
|
||||||
|
|
||||||
private enum class CharType {
|
private enum class CharType {
|
||||||
SPACES {
|
SPACES {
|
||||||
override fun contains(input: Char): Boolean {
|
override fun contains(input: Char): Boolean {
|
||||||
|
Loading…
Reference in New Issue
Block a user