Pass getTextPosition instead of passing the tap text position to be more flexible; optional ignoreFocus on replaceText

pull/157/head
Xun Gong 4 years ago
parent 63c2ef9d0e
commit 273340a1f6
  1. 8
      lib/widgets/controller.dart
  2. 34
      lib/widgets/editor.dart
  3. 27
      lib/widgets/raw_editor.dart

@ -23,6 +23,7 @@ class QuillController extends ChangeNotifier {
final Document document; final Document document;
TextSelection selection; TextSelection selection;
Style toggledStyle = Style(); Style toggledStyle = Style();
bool ignoreFocusOnTextChange = false;
// item1: Document state before [change]. // item1: Document state before [change].
// //
@ -76,7 +77,7 @@ class QuillController extends ChangeNotifier {
bool get hasRedo => document.hasRedo; bool get hasRedo => document.hasRedo;
void replaceText( 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); assert(data is String || data is Embeddable);
Delta? delta; Delta? delta;
@ -124,7 +125,12 @@ class QuillController extends ChangeNotifier {
); );
} }
} }
if (ignoreFocus) {
ignoreFocusOnTextChange = true;
}
notifyListeners(); notifyListeners();
ignoreFocusOnTextChange = false;
} }
void formatText(int index, int len, Attribute? attribute) { void formatText(int index, int len, Attribute? attribute) {

@ -176,20 +176,19 @@ class QuillEditor extends StatefulWidget {
final ScrollPhysics? scrollPhysics; final ScrollPhysics? scrollPhysics;
final ValueChanged<String>? onLaunchUrl; final ValueChanged<String>? onLaunchUrl;
// Returns whether gesture is handled // Returns whether gesture is handled
final bool Function(TapDownDetails details, TextPosition textPosition)? final bool Function(TapDownDetails details, TextPosition Function(Offset offset))? onTapDown;
onTapDown;
// Returns whether gesture is handled // 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 // Returns whether gesture is handled
final bool Function(LongPressStartDetails details, TextPosition textPosition)? final bool Function(LongPressStartDetails details, TextPosition Function(Offset offset))? onSingleLongTapStart;
onSingleLongTapStart;
// Returns whether gesture is handled // Returns whether gesture is handled
final bool Function( final bool Function(LongPressMoveUpdateDetails details, TextPosition Function(Offset offset))? onSingleLongTapMoveUpdate;
LongPressMoveUpdateDetails details, TextPosition textPosition)?
onSingleLongTapMoveUpdate;
// Returns whether gesture is handled // Returns whether gesture is handled
final bool Function(LongPressEndDetails details, TextPosition textPosition)? final bool Function(LongPressEndDetails details, TextPosition Function(Offset offset))? onSingleLongTapEnd;
onSingleLongTapEnd;
final EmbedBuilder embedBuilder; final EmbedBuilder embedBuilder;
@override @override
@ -340,8 +339,7 @@ class _QuillEditorSelectionGestureDetectorBuilder
if (_state.widget.onSingleLongTapMoveUpdate != null) { if (_state.widget.onSingleLongTapMoveUpdate != null) {
final renderEditor = getRenderEditor(); final renderEditor = getRenderEditor();
if (renderEditor != null) { if (renderEditor != null) {
if (_state.widget.onSingleLongTapMoveUpdate!(details, if (_state.widget.onSingleLongTapMoveUpdate!(details, renderEditor.getPositionForOffset)) {
renderEditor.getPositionForOffset(details.globalPosition))) {
return; return;
} }
} }
@ -470,8 +468,7 @@ class _QuillEditorSelectionGestureDetectorBuilder
if (_state.widget.onTapDown != null) { if (_state.widget.onTapDown != null) {
final renderEditor = getRenderEditor(); final renderEditor = getRenderEditor();
if (renderEditor != null) { if (renderEditor != null) {
if (_state.widget.onTapDown!(details, if (_state.widget.onTapDown!(details, renderEditor.getPositionForOffset)) {
renderEditor.getPositionForOffset(details.globalPosition))) {
return; return;
} }
} }
@ -484,8 +481,7 @@ class _QuillEditorSelectionGestureDetectorBuilder
if (_state.widget.onTapUp != null) { if (_state.widget.onTapUp != null) {
final renderEditor = getRenderEditor(); final renderEditor = getRenderEditor();
if (renderEditor != null) { if (renderEditor != null) {
if (_state.widget.onTapUp!(details, if (_state.widget.onTapUp!(details, renderEditor.getPositionForOffset)) {
renderEditor.getPositionForOffset(details.globalPosition))) {
return; return;
} }
} }
@ -527,8 +523,7 @@ class _QuillEditorSelectionGestureDetectorBuilder
if (_state.widget.onSingleLongTapStart != null) { if (_state.widget.onSingleLongTapStart != null) {
final renderEditor = getRenderEditor(); final renderEditor = getRenderEditor();
if (renderEditor != null) { if (renderEditor != null) {
if (_state.widget.onSingleLongTapStart!(details, if (_state.widget.onSingleLongTapStart!(details, renderEditor.getPositionForOffset)) {
renderEditor.getPositionForOffset(details.globalPosition))) {
return; return;
} }
} }
@ -562,8 +557,7 @@ class _QuillEditorSelectionGestureDetectorBuilder
if (_state.widget.onSingleLongTapEnd != null) { if (_state.widget.onSingleLongTapEnd != null) {
final renderEditor = getRenderEditor(); final renderEditor = getRenderEditor();
if (renderEditor != null) { if (renderEditor != null) {
if (_state.widget.onSingleLongTapEnd!(details, if (_state.widget.onSingleLongTapEnd!(details, renderEditor.getPositionForOffset)) {
renderEditor.getPositionForOffset(details.globalPosition))) {
return; return;
} }
} }

@ -675,7 +675,9 @@ class RawEditorState extends EditorState
_clipboardStatus?.addListener(_onChangedClipboardStatus); _clipboardStatus?.addListener(_onChangedClipboardStatus);
widget.controller.addListener(_didChangeTextEditingValue); widget.controller.addListener(() {
_didChangeTextEditingValue(widget.controller.ignoreFocusOnTextChange);
});
_scrollController = widget.scrollController; _scrollController = widget.scrollController;
_scrollController!.addListener(_updateSelectionOverlayForScroll); _scrollController!.addListener(_updateSelectionOverlayForScroll);
@ -883,15 +885,17 @@ class RawEditorState extends EditorState
_selectionOverlay?.markNeedsBuild(); _selectionOverlay?.markNeedsBuild();
} }
void _didChangeTextEditingValue() { void _didChangeTextEditingValue([bool ignoreFocus = false]) {
if (kIsWeb) { if (kIsWeb) {
_onChangeTextEditingValue(); _onChangeTextEditingValue(ignoreFocus);
if (!ignoreFocus) {
requestKeyboard(); requestKeyboard();
}
return; return;
} }
if (_keyboardVisible) { if (ignoreFocus || _keyboardVisible) {
_onChangeTextEditingValue(); _onChangeTextEditingValue(ignoreFocus);
} else { } else {
requestKeyboard(); requestKeyboard();
if (mounted) { if (mounted) {
@ -903,19 +907,20 @@ class RawEditorState extends EditorState
} }
} }
void _onChangeTextEditingValue() { void _onChangeTextEditingValue([bool ignoreCaret = false]) {
_showCaretOnScreen();
updateRemoteValueIfNeeded(); updateRemoteValueIfNeeded();
_cursorCont.startOrStopCursorTimerIfNeeded( if (ignoreCaret) {
_hasFocus, widget.controller.selection); return;
}
_showCaretOnScreen();
_cursorCont.startOrStopCursorTimerIfNeeded(_hasFocus, widget.controller.selection);
if (hasConnection) { if (hasConnection) {
_cursorCont _cursorCont
..stopCursorTimer(resetCharTicks: false) ..stopCursorTimer(resetCharTicks: false)
..startCursorTimer(); ..startCursorTimer();
} }
SchedulerBinding.instance!.addPostFrameCallback( SchedulerBinding.instance!.addPostFrameCallback((_) => _updateOrDisposeSelectionOverlayIfNeeded());
(_) => _updateOrDisposeSelectionOverlayIfNeeded());
if (mounted) { if (mounted) {
setState(() { setState(() {
// Use widget.controller.value in build() // Use widget.controller.value in build()

Loading…
Cancel
Save