From 273340a1f6610abf0c760ace45261629392f3cf8 Mon Sep 17 00:00:00 2001 From: Xun Gong Date: Mon, 19 Apr 2021 17:49:22 -0700 Subject: [PATCH] Pass getTextPosition instead of passing the tap text position to be more flexible; optional ignoreFocus on replaceText --- lib/widgets/controller.dart | 8 +++++++- lib/widgets/editor.dart | 34 ++++++++++++++-------------------- lib/widgets/raw_editor.dart | 29 +++++++++++++++++------------ 3 files changed, 38 insertions(+), 33 deletions(-) diff --git a/lib/widgets/controller.dart b/lib/widgets/controller.dart index 3bd66b6f..a17fe92d 100644 --- a/lib/widgets/controller.dart +++ b/lib/widgets/controller.dart @@ -23,6 +23,7 @@ class QuillController extends ChangeNotifier { final Document document; TextSelection selection; Style toggledStyle = Style(); + bool ignoreFocusOnTextChange = false; // item1: Document state before [change]. // @@ -76,7 +77,7 @@ class QuillController extends ChangeNotifier { bool get hasRedo => document.hasRedo; void replaceText( - int index, int len, Object? data, TextSelection? textSelection) { + int index, int len, Object? data, TextSelection? textSelection, {bool ignoreFocus = false}) { assert(data is String || data is Embeddable); Delta? delta; @@ -124,7 +125,12 @@ class QuillController extends ChangeNotifier { ); } } + + if (ignoreFocus) { + ignoreFocusOnTextChange = true; + } notifyListeners(); + ignoreFocusOnTextChange = false; } void formatText(int index, int len, Attribute? attribute) { diff --git a/lib/widgets/editor.dart b/lib/widgets/editor.dart index 5be0dd24..42fd769c 100644 --- a/lib/widgets/editor.dart +++ b/lib/widgets/editor.dart @@ -176,20 +176,19 @@ class QuillEditor extends StatefulWidget { final ScrollPhysics? scrollPhysics; final ValueChanged? onLaunchUrl; // Returns whether gesture is handled - final bool Function(TapDownDetails details, TextPosition textPosition)? - onTapDown; + final bool Function(TapDownDetails details, TextPosition Function(Offset offset))? onTapDown; + // Returns whether gesture is handled - final bool Function(TapUpDetails details, TextPosition textPosition)? onTapUp; + final bool Function(TapUpDetails details, TextPosition Function(Offset offset))? onTapUp; + // Returns whether gesture is handled - final bool Function(LongPressStartDetails details, TextPosition textPosition)? - onSingleLongTapStart; + final bool Function(LongPressStartDetails details, TextPosition Function(Offset offset))? onSingleLongTapStart; + // Returns whether gesture is handled - final bool Function( - LongPressMoveUpdateDetails details, TextPosition textPosition)? - onSingleLongTapMoveUpdate; + final bool Function(LongPressMoveUpdateDetails details, TextPosition Function(Offset offset))? onSingleLongTapMoveUpdate; // Returns whether gesture is handled - final bool Function(LongPressEndDetails details, TextPosition textPosition)? - onSingleLongTapEnd; + final bool Function(LongPressEndDetails details, TextPosition Function(Offset offset))? onSingleLongTapEnd; + final EmbedBuilder embedBuilder; @override @@ -340,8 +339,7 @@ class _QuillEditorSelectionGestureDetectorBuilder if (_state.widget.onSingleLongTapMoveUpdate != null) { final renderEditor = getRenderEditor(); if (renderEditor != null) { - if (_state.widget.onSingleLongTapMoveUpdate!(details, - renderEditor.getPositionForOffset(details.globalPosition))) { + if (_state.widget.onSingleLongTapMoveUpdate!(details, renderEditor.getPositionForOffset)) { return; } } @@ -470,8 +468,7 @@ class _QuillEditorSelectionGestureDetectorBuilder if (_state.widget.onTapDown != null) { final renderEditor = getRenderEditor(); if (renderEditor != null) { - if (_state.widget.onTapDown!(details, - renderEditor.getPositionForOffset(details.globalPosition))) { + if (_state.widget.onTapDown!(details, renderEditor.getPositionForOffset)) { return; } } @@ -484,8 +481,7 @@ class _QuillEditorSelectionGestureDetectorBuilder if (_state.widget.onTapUp != null) { final renderEditor = getRenderEditor(); if (renderEditor != null) { - if (_state.widget.onTapUp!(details, - renderEditor.getPositionForOffset(details.globalPosition))) { + if (_state.widget.onTapUp!(details, renderEditor.getPositionForOffset)) { return; } } @@ -527,8 +523,7 @@ class _QuillEditorSelectionGestureDetectorBuilder if (_state.widget.onSingleLongTapStart != null) { final renderEditor = getRenderEditor(); if (renderEditor != null) { - if (_state.widget.onSingleLongTapStart!(details, - renderEditor.getPositionForOffset(details.globalPosition))) { + if (_state.widget.onSingleLongTapStart!(details, renderEditor.getPositionForOffset)) { return; } } @@ -562,8 +557,7 @@ class _QuillEditorSelectionGestureDetectorBuilder if (_state.widget.onSingleLongTapEnd != null) { final renderEditor = getRenderEditor(); if (renderEditor != null) { - if (_state.widget.onSingleLongTapEnd!(details, - renderEditor.getPositionForOffset(details.globalPosition))) { + if (_state.widget.onSingleLongTapEnd!(details, renderEditor.getPositionForOffset)) { return; } } diff --git a/lib/widgets/raw_editor.dart b/lib/widgets/raw_editor.dart index 1627ebc3..7114e670 100644 --- a/lib/widgets/raw_editor.dart +++ b/lib/widgets/raw_editor.dart @@ -675,7 +675,9 @@ class RawEditorState extends EditorState _clipboardStatus?.addListener(_onChangedClipboardStatus); - widget.controller.addListener(_didChangeTextEditingValue); + widget.controller.addListener(() { + _didChangeTextEditingValue(widget.controller.ignoreFocusOnTextChange); + }); _scrollController = widget.scrollController; _scrollController!.addListener(_updateSelectionOverlayForScroll); @@ -883,15 +885,17 @@ class RawEditorState extends EditorState _selectionOverlay?.markNeedsBuild(); } - void _didChangeTextEditingValue() { + void _didChangeTextEditingValue([bool ignoreFocus = false]) { if (kIsWeb) { - _onChangeTextEditingValue(); - requestKeyboard(); + _onChangeTextEditingValue(ignoreFocus); + if (!ignoreFocus) { + requestKeyboard(); + } return; } - if (_keyboardVisible) { - _onChangeTextEditingValue(); + if (ignoreFocus || _keyboardVisible) { + _onChangeTextEditingValue(ignoreFocus); } else { requestKeyboard(); if (mounted) { @@ -903,19 +907,20 @@ class RawEditorState extends EditorState } } - void _onChangeTextEditingValue() { - _showCaretOnScreen(); + void _onChangeTextEditingValue([bool ignoreCaret = false]) { updateRemoteValueIfNeeded(); - _cursorCont.startOrStopCursorTimerIfNeeded( - _hasFocus, widget.controller.selection); + if (ignoreCaret) { + return; + } + _showCaretOnScreen(); + _cursorCont.startOrStopCursorTimerIfNeeded(_hasFocus, widget.controller.selection); if (hasConnection) { _cursorCont ..stopCursorTimer(resetCharTicks: false) ..startCursorTimer(); } - SchedulerBinding.instance!.addPostFrameCallback( - (_) => _updateOrDisposeSelectionOverlayIfNeeded()); + SchedulerBinding.instance!.addPostFrameCallback((_) => _updateOrDisposeSelectionOverlayIfNeeded()); if (mounted) { setState(() { // Use widget.controller.value in build()