TextArea - XY at Insertion Point

Textarea has InsertionPointAtXY which returns the integer value of where the insertion point is closest to the supplied X,Y values

How to do the opposite???

Given an character postion (ie. Selstart for the most part)… get the X,Y pixel location of that character position…

+/- a few pixels is fine

I remember a thread about that very topic, a while ago. I don’t remember the specifics, but it could very well have been answered through some declares.

You could also scan the text and get coordinates for each character, and pick the closest one.

You had written something a while back

https://forum.xojo.com/29922-highlight-text-in-a-textarea/0

I was hoping for something a bit faster… .but I will use a varaition of this for now

You could speed up the method by doing a binary search separately on the coordinates: first the y coordinate, then the x coordinate.

Yeah I thought that too… .but InserttionPointAtXY returns “Nearest”… so anything past the actual point doesn’t work out

so I start with Y=0 and step down in increments of Textheight… then across by 1 pixel

``````Dim p As New picture(10,10)
Dim g As graphics=p.Graphics
Dim th As Integer
g.TextFont=Me.TextFont
g.TextSize=Me.TextSize
th=g.TextHeight // ASSUMPTION : TextArea is only ONE Font/Size!
For y As Integer = 0 To Me.Height+th Step th
If Me.charPosAtXY (0, Y) = Me.selstart Then
y=y-1
For x As Integer=0 To Me.width
If Me.charPosAtXY (x, Y) = Me.selstart Then
xp=x
yp=y
Exit For y
End If
Next x
End If
Next y``````

This is what I meant:

``````Public Sub XYatCharPos(ta as textarea, cp As Integer, byRef x As Integer, byref y As Integer)
'Return the x and y coordinates of the character at character position cp
'in text field ta.

dim targetLine As Integer = ta.LineNumAtCharPos(cp+1)
dim targetY As Integer = ta.CharPosAtLineNum(targetLine)
dim targetX As Integer = cp-targetY
dim xMax As Integer = ta.Width
dim yMax As Integer = ta.Height
dim yTest As Integer
dim Lbound As Integer = 0
dim Hbound As Integer = yMax
while Hbound>Lbound
yTest = (Lbound+Hbound)\\2
if ta.CharPosAtXY(0,yTest)<targetY then
Lbound=yTest+1
Else
Hbound=yTest
end if
wend
yTest=yTest+1
y=yTest
Lbound = 0
Hbound = xMax
dim xTest As Integer
while Hbound>Lbound
xTest = (Lbound+Hbound)\\2
if ta.CharPosAtXY(xTest,yTest)<cp then
Lbound=xTest+1
Else
Hbound=xTest
end if
wend
x=xTest
End Sub``````

After some brief testing, it appears to work, but I didn’t take text field scrolling into account.