@@ -47,6 +47,8 @@ const linkPrefixes = [
4747];
4848
4949abstract class EditorState extends State <RawEditor > {
50+ ScrollController get scrollController;
51+
5052 TextEditingValue getTextEditingValue ();
5153
5254 void setTextEditingValue (TextEditingValue value);
@@ -62,32 +64,75 @@ abstract class EditorState extends State<RawEditor> {
6264 void requestKeyboard ();
6365}
6466
67+ /// Base interface for editable render objects.
6568abstract class RenderAbstractEditor {
6669 TextSelection selectWordAtPosition (TextPosition position);
6770
6871 TextSelection selectLineAtPosition (TextPosition position);
6972
73+ /// Returns preferred line height at specified `position` in text.
7074 double preferredLineHeight (TextPosition position);
7175
76+ /// Returns [Rect] for caret in local coordinates
77+ ///
78+ /// Useful to enforce visibility of full caret at given position
79+ Rect getLocalRectForCaret (TextPosition position);
80+
81+ /// Returns the local coordinates of the endpoints of the given selection.
82+ ///
83+ /// If the selection is collapsed (and therefore occupies a single point), the
84+ /// returned list is of length one. Otherwise, the selection is not collapsed
85+ /// and the returned list is of length two. In this case, however, the two
86+ /// points might actually be co-located (e.g., because of a bidirectional
87+ /// selection that contains some text but whose ends meet in the middle).
7288 TextPosition getPositionForOffset (Offset offset);
7389
7490 List <TextSelectionPoint > getEndpointsForSelection (
7591 TextSelection textSelection);
7692
93+ /// If [ignorePointer] is false (the default) then this method is called by
94+ /// the internal gesture recognizer's [TapGestureRecognizer.onTapDown]
95+ /// callback.
96+ ///
97+ /// When [ignorePointer] is true, an ancestor widget must respond to tap
98+ /// down events by calling this method.
7799 void handleTapDown (TapDownDetails details);
78100
101+ /// Selects the set words of a paragraph in a given range of global positions.
102+ ///
103+ /// The first and last endpoints of the selection will always be at the
104+ /// beginning and end of a word respectively.
105+ ///
106+ /// {@macro flutter.rendering.editable.select}
79107 void selectWordsInRange (
80108 Offset from,
81109 Offset to,
82110 SelectionChangedCause cause,
83111 );
84112
113+ /// Move the selection to the beginning or end of a word.
114+ ///
115+ /// {@macro flutter.rendering.editable.select}
85116 void selectWordEdge (SelectionChangedCause cause);
86117
118+ /// Select text between the global positions [from] and [to] .
87119 void selectPositionAt (Offset from, Offset to, SelectionChangedCause cause);
88120
121+ /// Select a word around the location of the last tap down.
122+ ///
123+ /// {@macro flutter.rendering.editable.select}
89124 void selectWord (SelectionChangedCause cause);
90125
126+ /// Move selection to the location of the last tap down.
127+ ///
128+ /// {@template flutter.rendering.editable.select}
129+ /// This method is mainly used to translate user inputs in global positions
130+ /// into a [TextSelection] . When used in conjunction with a [EditableText] ,
131+ /// the selection change is fed back into [TextEditingController.selection] .
132+ ///
133+ /// If you have a [TextEditingController] , it's generally easier to
134+ /// programmatically manipulate its `value` or `selection` directly.
135+ /// {@endtemplate}
91136 void selectPosition (SelectionChangedCause cause);
92137}
93138
@@ -988,7 +1033,8 @@ class RenderEditor extends RenderEditableContainerBox
9881033
9891034 final caretTop = endpoint.point.dy -
9901035 child.preferredLineHeight (TextPosition (
991- offset: selection.extentOffset - child.getContainer ().offset)) -
1036+ offset:
1037+ selection.extentOffset - child.getContainer ().documentOffset)) -
9921038 kMargin +
9931039 offsetInViewport +
9941040 scrollBottomInset;
@@ -1005,6 +1051,17 @@ class RenderEditor extends RenderEditableContainerBox
10051051 }
10061052 return math.max (dy, 0 );
10071053 }
1054+
1055+ @override
1056+ Rect getLocalRectForCaret (TextPosition position) {
1057+ final targetChild = childAtPosition (position);
1058+ final localPosition = targetChild.globalToLocalPosition (position);
1059+
1060+ final childLocalRect = targetChild.getLocalRectForCaret (localPosition);
1061+
1062+ final boxParentData = targetChild.parentData as BoxParentData ;
1063+ return childLocalRect.shift (Offset (0 , boxParentData.offset.dy));
1064+ }
10081065}
10091066
10101067class EditableContainerParentData
0 commit comments