diff --git a/lib/common/widgets/text_field/controller.dart b/lib/common/widgets/text_field/controller.dart index 379c7ace..47139101 100644 --- a/lib/common/widgets/text_field/controller.dart +++ b/lib/common/widgets/text_field/controller.dart @@ -865,6 +865,26 @@ class RichTextEditingController extends TextEditingController { return position; } + int tapOffsetSimple(int offset) { + for (var e in items) { + final range = e.range; + if (offset >= range.end) { + continue; + } + if (offset <= range.start) { + break; + } + if (e.isRich) { + if (offset * 2 > range.start + range.end) { + return range.end; + } else { + return range.start; + } + } + } + return offset; + } + int tapOffset( int offset, { required TextPainter textPainter, diff --git a/lib/common/widgets/text_field/cupertino/cupertino_text_field.dart b/lib/common/widgets/text_field/cupertino/cupertino_text_field.dart index 705df17e..d73184e0 100644 --- a/lib/common/widgets/text_field/cupertino/cupertino_text_field.dart +++ b/lib/common/widgets/text_field/cupertino/cupertino_text_field.dart @@ -117,6 +117,7 @@ class _CupertinoTextFieldSelectionGestureDetectorBuilder extends TextSelectionGestureDetectorBuilder { _CupertinoTextFieldSelectionGestureDetectorBuilder({ required _CupertinoRichTextFieldState state, + required super.controller, }) : _state = state, super(delegate: state); @@ -1254,6 +1255,7 @@ class _CupertinoRichTextFieldState extends State _selectionGestureDetectorBuilder = _CupertinoTextFieldSelectionGestureDetectorBuilder( state: this, + controller: widget.controller, ); // if (widget.controller == null) { // _createLocalController(); diff --git a/lib/common/widgets/text_field/editable.dart b/lib/common/widgets/text_field/editable.dart index 4e3af69e..42c736d2 100644 --- a/lib/common/widgets/text_field/editable.dart +++ b/lib/common/widgets/text_field/editable.dart @@ -2227,6 +2227,15 @@ class RenderEditable extends RenderBox lastTapDownPosition: from, ); extentOffset = baseOffset; + } else { + // select + final isNormalized = baseOffset < extentOffset; + final newOffset = controller.longPressOffset( + isNormalized ? baseOffset : extentOffset, + isNormalized ? extentOffset : baseOffset, + ); + baseOffset = isNormalized ? newOffset.startOffset : newOffset.endOffset; + extentOffset = isNormalized ? newOffset.endOffset : newOffset.startOffset; } final TextSelection newSelection = TextSelection( diff --git a/lib/common/widgets/text_field/text_field.dart b/lib/common/widgets/text_field/text_field.dart index c128d28f..0dfc8916 100644 --- a/lib/common/widgets/text_field/text_field.dart +++ b/lib/common/widgets/text_field/text_field.dart @@ -84,9 +84,11 @@ typedef InputCounterWidgetBuilder = class _TextFieldSelectionGestureDetectorBuilder extends TextSelectionGestureDetectorBuilder { - _TextFieldSelectionGestureDetectorBuilder({required RichTextFieldState state}) - : _state = state, - super(delegate: state); + _TextFieldSelectionGestureDetectorBuilder({ + required RichTextFieldState state, + required super.controller, + }) : _state = state, + super(delegate: state); final RichTextFieldState _state; @@ -1373,7 +1375,10 @@ class RichTextFieldState extends State void initState() { super.initState(); _selectionGestureDetectorBuilder = - _TextFieldSelectionGestureDetectorBuilder(state: this); + _TextFieldSelectionGestureDetectorBuilder( + state: this, + controller: widget.controller, + ); // if (widget.controller == null) { // _createLocalController(); // } diff --git a/lib/common/widgets/text_field/text_selection.dart b/lib/common/widgets/text_field/text_selection.dart index b81a19bc..0213bc32 100644 --- a/lib/common/widgets/text_field/text_selection.dart +++ b/lib/common/widgets/text_field/text_selection.dart @@ -49,7 +49,10 @@ abstract class TextSelectionGestureDetectorBuilderDelegate { /// Cupertino-specific gesture logic of an [EditableText]. class TextSelectionGestureDetectorBuilder { /// Creates a [TextSelectionGestureDetectorBuilder]. - TextSelectionGestureDetectorBuilder({required this.delegate}); + TextSelectionGestureDetectorBuilder({ + required this.delegate, + required this.controller, + }); /// The delegate for this [TextSelectionGestureDetectorBuilder]. /// @@ -62,6 +65,8 @@ class TextSelectionGestureDetectorBuilder { @protected final TextSelectionGestureDetectorBuilderDelegate delegate; + final RichTextEditingController controller; + // Shows the magnifier on supported platforms at the given offset, currently // only Android and iOS. void _showMagnifierIfSupportedByPlatform(Offset positionToShow) { @@ -177,7 +182,7 @@ class TextSelectionGestureDetectorBuilder { ); final TextSelection selection = renderEditable.selection!; final TextSelection nextSelection = selection.copyWith( - extentOffset: tappedPosition.offset, + extentOffset: controller.tapOffsetSimple(tappedPosition.offset), ); editableText.userUpdateTextEditingValue(