diff --git a/packages/flutter/lib/src/widgets/editable_text.dart b/packages/flutter/lib/src/widgets/editable_text.dart index a367b67648b..8ef77a7fa88 100644 --- a/packages/flutter/lib/src/widgets/editable_text.dart +++ b/packages/flutter/lib/src/widgets/editable_text.dart @@ -1623,7 +1623,7 @@ class EditableTextState extends State with AutomaticKeepAliveClien // cursor. TextPosition _lastTextPosition; - // The offset of the floating cursor as determined from the first update call. + // The offset of the floating cursor as determined from the start call. Offset _pointOffsetOrigin; // The most recent position of the floating cursor. @@ -1642,22 +1642,24 @@ class EditableTextState extends State with AutomaticKeepAliveClien _floatingCursorResetController.stop(); _onFloatingCursorResetTick(); } + // We want to send in points that are centered around a (0,0) origin, so + // we cache the position. + _pointOffsetOrigin = point.offset; + final TextPosition currentTextPosition = TextPosition(offset: renderEditable.selection.baseOffset); _startCaretRect = renderEditable.getLocalRectForCaret(currentTextPosition); - renderEditable.setFloatingCursor(point.state, _startCaretRect.center - _floatingCursorOffset, currentTextPosition); + + _lastBoundedOffset = _startCaretRect.center - _floatingCursorOffset; + _lastTextPosition = currentTextPosition; + renderEditable.setFloatingCursor(point.state, _lastBoundedOffset, _lastTextPosition); break; case FloatingCursorDragState.Update: - // We want to send in points that are centered around a (0,0) origin, so we cache the - // position on the first update call. - if (_pointOffsetOrigin != null) { - final Offset centeredPoint = point.offset - _pointOffsetOrigin; - final Offset rawCursorOffset = _startCaretRect.center + centeredPoint - _floatingCursorOffset; - _lastBoundedOffset = renderEditable.calculateBoundedFloatingCursorOffset(rawCursorOffset); - _lastTextPosition = renderEditable.getPositionForPoint(renderEditable.localToGlobal(_lastBoundedOffset + _floatingCursorOffset)); - renderEditable.setFloatingCursor(point.state, _lastBoundedOffset, _lastTextPosition); - } else { - _pointOffsetOrigin = point.offset; - } + final Offset centeredPoint = point.offset - _pointOffsetOrigin; + final Offset rawCursorOffset = _startCaretRect.center + centeredPoint - _floatingCursorOffset; + + _lastBoundedOffset = renderEditable.calculateBoundedFloatingCursorOffset(rawCursorOffset); + _lastTextPosition = renderEditable.getPositionForPoint(renderEditable.localToGlobal(_lastBoundedOffset + _floatingCursorOffset)); + renderEditable.setFloatingCursor(point.state, _lastBoundedOffset, _lastTextPosition); break; case FloatingCursorDragState.End: // We skip animation if no update has happened. diff --git a/packages/flutter/test/widgets/editable_text_cursor_test.dart b/packages/flutter/test/widgets/editable_text_cursor_test.dart index 77c7def4c08..5b8c1422161 100644 --- a/packages/flutter/test/widgets/editable_text_cursor_test.dart +++ b/packages/flutter/test/widgets/editable_text_cursor_test.dart @@ -398,13 +398,9 @@ void main() { expect(controller.selection.baseOffset, 29); final EditableTextState editableTextState = tester.firstState(find.byType(EditableText)); - editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Start)); - - expect(controller.selection.baseOffset, 29); // Sets the origin. - editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Update, - offset: const Offset(20, 20))); + editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Start, offset: const Offset(20, 20))); expect(controller.selection.baseOffset, 29); @@ -427,10 +423,9 @@ void main() { expect(controller.selection.baseOffset, 8); // Go in the other direction. - editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Start)); + // Sets the origin. - editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Update, - offset: const Offset(20, 20))); + editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Start, offset: const Offset(20, 20))); editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Update, offset: const Offset(-5000, 20))); @@ -482,13 +477,9 @@ void main() { expect(controller.selection.baseOffset, 29); final EditableTextState editableTextState = tester.firstState(find.byType(EditableText)); - editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Start)); - - expect(controller.selection.baseOffset, 29); // Sets the origin. - editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Update, - offset: const Offset(20, 20))); + editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Start, offset: const Offset(20, 20))); expect(controller.selection.baseOffset, 29); @@ -583,13 +574,9 @@ void main() { expect(controller.selection.baseOffset, 29); final EditableTextState editableTextState = tester.firstState(find.byType(EditableText)); - editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Start)); - - expect(controller.selection.baseOffset, 29); // Sets the origin. - editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Update, - offset: const Offset(20, 20))); + editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Start, offset: const Offset(20, 20))); expect(controller.selection.baseOffset, 29); @@ -603,13 +590,11 @@ void main() { editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.End)); // Immediately start a new floating cursor, in the same way as happens when // the user tries to select text in trackpad mode. - editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Start)); + editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Start, offset: const Offset(20, 20))); await tester.pumpAndSettle(); // Set and move the second cursor like a selection. Previously, the second // Update here caused a crash. - editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Update, - offset: const Offset(20, 20))); editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Update, offset: const Offset(-250, 20))); editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.End)); @@ -676,13 +661,7 @@ void main() { final EditableTextState editableTextState = tester.firstState(find.byType(EditableText)); editableTextState.updateFloatingCursor( - RawFloatingCursorPoint(state: FloatingCursorDragState.Start), - ); - editableTextState.updateFloatingCursor( - RawFloatingCursorPoint( - state: FloatingCursorDragState.Update, - offset: const Offset(20, 20), - ), + RawFloatingCursorPoint(state: FloatingCursorDragState.Start, offset: const Offset(20, 20)), ); await tester.pump();