@@ -1222,6 +1222,71 @@ class RenderEditor extends RenderEditableContainerBox
1222
1222
);
1223
1223
}
1224
1224
1225
+ /// Returns the y-offset of the editor at which [selection] is visible.
1226
+ ///
1227
+ /// The offset is the distance from the top of the editor and is the minimum
1228
+ /// from the current scroll position until [selection] becomes visible.
1229
+ /// Returns null if [selection] is already visible.
1230
+ ///
1231
+ /// Finds the closest scroll offset that fully reveals the editing cursor.
1232
+ ///
1233
+ /// The `scrollOffset` parameter represents current scroll offset in the
1234
+ /// parent viewport.
1235
+ ///
1236
+ /// The `offsetInViewport` parameter represents the editor's vertical offset
1237
+ /// in the parent viewport. This value should normally be 0.0 if this editor
1238
+ /// is the only child of the viewport or if it's the topmost child. Otherwise
1239
+ /// it should be a positive value equal to total height of all siblings of
1240
+ /// this editor from above it.
1241
+ ///
1242
+ /// Returns `null` if the cursor is currently visible.
1243
+ double ? getOffsetToRevealCursor (
1244
+ double viewportHeight, double scrollOffset, double offsetInViewport) {
1245
+ // Endpoints coordinates represents lower left or lower right corner of
1246
+ // the selection. If we want to scroll up to reveal the caret we need to
1247
+ // adjust the dy value by the height of the line. We also add a small margin
1248
+ // so that the caret is not too close to the edge of the viewport.
1249
+ final endpoints = getEndpointsForSelection (selection);
1250
+
1251
+ // when we drag the right handle, we should get the last point
1252
+ TextSelectionPoint endpoint;
1253
+ if (selection.isCollapsed) {
1254
+ endpoint = endpoints.first;
1255
+ } else {
1256
+ if (selection is DragTextSelection ) {
1257
+ endpoint = (selection as DragTextSelection ).first
1258
+ ? endpoints.first
1259
+ : endpoints.last;
1260
+ } else {
1261
+ endpoint = endpoints.first;
1262
+ }
1263
+ }
1264
+
1265
+ // Collapsed selection => caret
1266
+ final child = childAtPosition (selection.extent);
1267
+ const kMargin = 8.0 ;
1268
+
1269
+ final caretTop = endpoint.point.dy -
1270
+ child.preferredLineHeight (TextPosition (
1271
+ offset: selection.extentOffset - child.container.documentOffset)) -
1272
+ kMargin +
1273
+ offsetInViewport +
1274
+ scrollBottomInset;
1275
+ final caretBottom =
1276
+ endpoint.point.dy + kMargin + offsetInViewport + scrollBottomInset;
1277
+ double ? dy;
1278
+ if (caretTop < scrollOffset) {
1279
+ dy = caretTop;
1280
+ } else if (caretBottom > scrollOffset + viewportHeight) {
1281
+ dy = caretBottom - viewportHeight;
1282
+ }
1283
+ if (dy == null ) {
1284
+ return null ;
1285
+ }
1286
+ // Clamping to 0.0 so that the content does not jump unnecessarily.
1287
+ return math.max (dy, 0 );
1288
+ }
1289
+
1225
1290
@override
1226
1291
Rect getLocalRectForCaret (TextPosition position) {
1227
1292
final targetChild = childAtPosition (position);
@@ -1233,10 +1298,6 @@ class RenderEditor extends RenderEditableContainerBox
1233
1298
return childLocalRect.shift (Offset (0 , boxParentData.offset.dy));
1234
1299
}
1235
1300
1236
- TextPosition get caretTextPosition => _floatingCursorRect == null
1237
- ? selection.extent
1238
- : _floatingCursorTextPosition;
1239
-
1240
1301
// Start floating cursor
1241
1302
1242
1303
FloatingCursorPainter get _floatingCursorPainter => FloatingCursorPainter (
0 commit comments