Fix cursor positioning for end-of-line clicks
This commit is contained in:
parent
d090447f2d
commit
0b727ff3b2
|
|
@ -456,21 +456,66 @@ func SetCursorFromPoint(x, y float64) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple heuristic: find the closest glyph by distance to (x, y)
|
// 1. Find the best line based on y
|
||||||
bestIdx := 0
|
bestLineY := layout.Y[0]
|
||||||
minDist := float64(1e9)
|
minYDist := 1e9
|
||||||
lineHeight := float64(EditorLineHeight())
|
for _, yVal := range layout.Y {
|
||||||
|
yDist := float64(yVal) - y
|
||||||
|
if yDist < 0 {
|
||||||
|
yDist = -yDist
|
||||||
|
}
|
||||||
|
if yDist < minYDist {
|
||||||
|
minYDist = yDist
|
||||||
|
bestLineY = yVal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for i := 0; i < len(layout.X); i++ {
|
// 2. Identify glyphs on this line and find the rightmost extent
|
||||||
dx := float64(layout.X[i]) - x
|
rightmostX := 0.0
|
||||||
// layout.Y[i] is the baseline. Taps are generally near the middle of the line.
|
rightmostIdx := -1
|
||||||
// Adjust to compare against the approximate vertical center of the line.
|
for i, yVal := range layout.Y {
|
||||||
dy := float64(layout.Y[i] - ui.Dp(lineHeight/2)) - y
|
if yVal == bestLineY {
|
||||||
dist := dx*dx + dy*dy
|
xEnd := float64(layout.X[i] + layout.Advance[i])
|
||||||
|
if xEnd > rightmostX {
|
||||||
|
rightmostX = xEnd
|
||||||
|
rightmostIdx = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Check if tap is to the right of the last character on this line
|
||||||
|
if rightmostIdx != -1 && x > rightmostX {
|
||||||
|
// If rightmostIdx is the last glyph of the entire document
|
||||||
|
if rightmostIdx == len(layout.X)-1 {
|
||||||
|
TheState.Editor.CursorPosition = len(TheState.Editor.Buffer)
|
||||||
|
} else {
|
||||||
|
// Position after the last character on this line
|
||||||
|
TheState.Editor.CursorPosition = layout.ByteOffsets[rightmostIdx+1]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Otherwise, find the closest glyph on this line.
|
||||||
|
bestIdx := -1
|
||||||
|
minDist := float64(1e9)
|
||||||
|
for i, yVal := range layout.Y {
|
||||||
|
if yVal == bestLineY {
|
||||||
|
if bestIdx == -1 {
|
||||||
|
bestIdx = i
|
||||||
|
}
|
||||||
|
// Calculate distance to the glyph center
|
||||||
|
glyphCenterX := float64(layout.X[i] + layout.Advance[i]/2)
|
||||||
|
dist := glyphCenterX - x
|
||||||
|
if dist < 0 {
|
||||||
|
dist = -dist
|
||||||
|
}
|
||||||
if dist < minDist {
|
if dist < minDist {
|
||||||
minDist = dist
|
minDist = dist
|
||||||
bestIdx = i
|
bestIdx = i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if bestIdx != -1 {
|
||||||
TheState.Editor.CursorPosition = layout.ByteOffsets[bestIdx]
|
TheState.Editor.CursorPosition = layout.ByteOffsets[bestIdx]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user