4343 getBlinkPhase, resetBlinking
4444 getCursor, setCursor, moveCursor, getCursorSelectionSide, getAnchorSelectionSide
4545 getCursorLayout
46- getInfoAtCoords
46+ getInfoAtCoords, getInfoAtCursor, getInfoAtCharacter
4747 getScroll, getScrollX, getScrollY, setScroll, setScrollX, setScrollY, scroll, scrollToCursor
4848 getScrollHandles, getScrollHandleHorizontal, getScrollHandleVertical
4949 getScrollLimits
@@ -1445,10 +1445,10 @@ end
14451445--
14461446-- Info table fields:
14471447-- cursorPosition -- integer Cursor position.
1448- -- lineIndex -- integer Visible line index.
1449- -- linePosition -- integer Visible line start position.
14501448-- characterPosition -- integer Character position. (Is set even if hasText is false.)
14511449-- hasText -- boolean Whether there's text directly at the coordinates.
1450+ -- lineIndex -- integer Visible line index.
1451+ -- linePosition -- integer Visible line start position.
14521452--
14531453-- Note: The coordinates must be relative to the field's position on the screen.
14541454--
@@ -1459,10 +1459,10 @@ function InputField.getInfoAtCoords(field, x, y, info)
14591459
14601460 if field .text == " " then
14611461 info .cursorPosition = 0
1462- info .lineIndex = 1
1463- info .linePosition = 1
14641462 info .characterPosition = 1
14651463 info .hasText = false
1464+ info .lineIndex = 1
1465+ info .linePosition = 1
14661466
14671467 else
14681468 local curPos , visualLineI , visualLineIUnclamped = getCursorPositionAtCoordinates (field , x + field .scrollX , y + field .scrollY )
@@ -1483,15 +1483,108 @@ function InputField.getInfoAtCoords(field, x, y, info)
14831483 local xInText = unalignOnLine (field , line , x + field .scrollX )
14841484
14851485 info .cursorPosition = curPos
1486- info .lineIndex = lineI
1487- info .linePosition = linePos1
14881486 info .characterPosition = math.min (linePos1 + charPosOnLine - 1 , utf8.len (field .text ))
14891487 info .hasText = field .wrappedText [visualLineIUnclamped ] ~= nil and xInText >= 0 and xInText < field .font :getWidth (line )
1488+ info .lineIndex = lineI
1489+ info .linePosition = linePos1
14901490 end
14911491
14921492 return info
14931493end
14941494
1495+ --
1496+ -- info = field:getInfoAtCursor( cursorPosition [, info={} ] )
1497+ --
1498+ -- Info table fields:
1499+ -- x -- integer X position.
1500+ -- y -- integer Y/top position.
1501+ -- height -- integer Line height.
1502+ -- lineIndex -- integer Visible line index.
1503+ -- linePosition -- integer Visible line start position.
1504+ --
1505+ function InputField .getInfoAtCursor (field , pos , info )
1506+ updateWrap (field )
1507+
1508+ info = info or {}
1509+
1510+ if field .text == " " then
1511+ info .x = alignOnLine (field , " " , 0 )
1512+ info .y = 0
1513+ info .height = field .font :getHeight ()
1514+ info .lineIndex = 1
1515+ info .linePosition = 1
1516+
1517+ else
1518+ pos = clamp (pos , 0 , utf8.len (field .text ))
1519+
1520+ local line , curPosOnLine , lineI , linePos1 , linePos2 = getLineInfoAtPosition (field , pos )
1521+
1522+ local savedCursorPosition = field .cursorPosition
1523+ field .cursorPosition = pos
1524+ local x , y , h = field :getCursorLayout ()
1525+ field .cursorPosition = savedCursorPosition
1526+
1527+ info .x = x
1528+ info .y = y
1529+ info .height = h
1530+ info .lineIndex = lineI
1531+ info .linePosition = linePos1
1532+ end
1533+
1534+ return info
1535+ end
1536+
1537+ --
1538+ -- info = field:getInfoAtCharacter( characterPosition [, info={} ] )
1539+ --
1540+ -- Info table fields:
1541+ -- character -- string The character (unobfuscated if field type is "password").
1542+ -- x -- integer Character x/left position.
1543+ -- y -- integer Character y/top position.
1544+ -- width -- integer Character width.
1545+ -- height -- integer Character/line height.
1546+ -- lineIndex -- integer Visible line index.
1547+ -- linePosition -- integer Visible line start position.
1548+ --
1549+ -- Returns nil if characterPosition is invalid or points at a newline.
1550+ --
1551+ function InputField .getInfoAtCharacter (field , pos , info )
1552+ updateWrap (field )
1553+
1554+ local text = field .text
1555+
1556+ if
1557+ text == " " or pos < 1 or pos > utf8.len (text ) -- Error: Out-of-range!
1558+ or utf8.codepoint (text , utf8.offset (text , pos )) == 10 -- Don't return info about newlines.
1559+ then
1560+ return nil
1561+ end
1562+
1563+ local line , curPosOnLine , lineI , linePos1 , linePos2 = getLineInfoAtPosition (field , pos - 1 )
1564+
1565+ local i1 = utf8.offset (line , curPosOnLine + 1 )
1566+ local i2 = utf8GetEndOffset (line , curPosOnLine + 1 )
1567+ local visibleChar = line :sub (i1 , i2 )
1568+
1569+ local preText = line :sub (1 , i1 - 1 ) -- @Speed @Memory
1570+ local x = alignOnLine (field , line , field .font :getWidth (preText ))
1571+
1572+ local fontH = field .font :getHeight ()
1573+ local lineDist = math.ceil (fontH * field .font :getLineHeight ())
1574+ local y = (lineI - 1 ) * lineDist
1575+
1576+ info = info or {}
1577+ info .character = (field .type == " password" ) and text :sub (utf8.offset (text , pos ), utf8GetEndOffset (text , pos )) or visibleChar
1578+ info .x = x
1579+ info .y = y
1580+ info .width = field .font :getWidth (visibleChar )
1581+ info .height = fontH
1582+ info .lineIndex = lineI
1583+ info .linePosition = linePos1
1584+
1585+ return info
1586+ end
1587+
14951588
14961589
14971590---- ------------------------------------------------------------
0 commit comments