fix: посимвольное выделение + magnifier на позиции handle + haptic на каждый символ
Было: word snap при drag handle → нельзя выделить часть слова Стало: посимвольно при drag (word snap только при первом long press) Magnifier: показывается на позиции handle (текущий символ), а не на позиции пальца. По Y — центр строки текста. Haptic: TEXT_HANDLE_MOVE на каждый символ (не на каждое слово). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -124,8 +124,7 @@ class TextSelectionHelper {
|
||||
fun updateSelectionStart(charOffset: Int) {
|
||||
if (!isActive) return
|
||||
val text = layoutInfo?.text ?: return
|
||||
var newStart = charOffset.coerceIn(0, text.length)
|
||||
while (newStart > 0 && Character.isLetterOrDigit(text[newStart - 1])) newStart--
|
||||
val newStart = charOffset.coerceIn(0, text.length)
|
||||
if (newStart >= selectionEnd) return
|
||||
val changed = newStart != selectionStart
|
||||
selectionStart = newStart
|
||||
@@ -135,8 +134,7 @@ class TextSelectionHelper {
|
||||
fun updateSelectionEnd(charOffset: Int) {
|
||||
if (!isActive) return
|
||||
val text = layoutInfo?.text ?: return
|
||||
var newEnd = charOffset.coerceIn(0, text.length)
|
||||
while (newEnd < text.length && Character.isLetterOrDigit(text[newEnd])) newEnd++
|
||||
val newEnd = charOffset.coerceIn(0, text.length)
|
||||
if (newEnd <= selectionStart) return
|
||||
val changed = newEnd != selectionEnd
|
||||
selectionEnd = newEnd
|
||||
@@ -201,7 +199,7 @@ class TextSelectionHelper {
|
||||
.setSize(240, 64)
|
||||
.setCornerRadius(12f)
|
||||
.setElevation(4f)
|
||||
.setDefaultSourceToMagnifierOffset(0, -80)
|
||||
.setDefaultSourceToMagnifierOffset(0, -96)
|
||||
.build()
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
@@ -209,11 +207,21 @@ class TextSelectionHelper {
|
||||
}
|
||||
}
|
||||
val info = layoutInfo ?: return
|
||||
// Convert overlay-local → view-local (magnifierView coords)
|
||||
|
||||
// Magnifier should show at the HANDLE position (current char), not finger
|
||||
// Use handle X for horizontal, and line center for vertical
|
||||
val handleX = if (movingHandleStart) startHandleX else endHandleX
|
||||
val handleY = if (movingHandleStart) startHandleY else endHandleY
|
||||
val activeOffset = if (movingHandleStart) selectionStart else selectionEnd
|
||||
val layout = info.layout
|
||||
val line = layout.getLineForOffset(activeOffset.coerceIn(0, info.text.length))
|
||||
val lineCenter = (layout.getLineTop(line) + layout.getLineBottom(line)) / 2f
|
||||
|
||||
// Convert to view-local coordinates
|
||||
val viewLoc = IntArray(2)
|
||||
view.getLocationInWindow(viewLoc)
|
||||
val sourceX = (overlayLocalX + overlayWindowX - viewLoc[0]).coerceIn(0f, view.width.toFloat())
|
||||
val sourceY = (overlayLocalY + overlayWindowY - viewLoc[1]).coerceIn(0f, view.height.toFloat())
|
||||
val sourceX = (handleX + overlayWindowX - viewLoc[0]).coerceIn(0f, view.width.toFloat())
|
||||
val sourceY = (lineCenter + info.windowY - viewLoc[1]).coerceIn(0f, view.height.toFloat())
|
||||
magnifier?.show(sourceX, sourceY)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user