[chore]: change gesture

pull/2126/head
xuyang 8 months ago
parent 245e349d04
commit 20262740cf
  1. 281
      lib/src/editor/raw_editor/raw_editor_state.dart
  2. 5
      lib/src/editor/widgets/delegate.dart

@ -9,15 +9,8 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart' show RenderAbstractViewport; import 'package:flutter/rendering.dart' show RenderAbstractViewport;
import 'package:flutter/scheduler.dart' show SchedulerBinding; import 'package:flutter/scheduler.dart' show SchedulerBinding;
import 'package:flutter/services.dart' import 'package:flutter/services.dart'
show show Clipboard, HardwareKeyboard, KeyDownEvent, LogicalKeyboardKey, SystemChannels, TextInputControl;
Clipboard, import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart' show KeyboardVisibilityController;
HardwareKeyboard,
KeyDownEvent,
LogicalKeyboardKey,
SystemChannels,
TextInputControl;
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'
show KeyboardVisibilityController;
import '../../common/structs/horizontal_spacing.dart'; import '../../common/structs/horizontal_spacing.dart';
import '../../common/structs/offset_value.dart'; import '../../common/structs/offset_value.dart';
@ -107,11 +100,8 @@ class QuillRawEditorState extends EditorState
@override @override
void insertContent(KeyboardInsertedContent content) { void insertContent(KeyboardInsertedContent content) {
assert(widget.configurations.contentInsertionConfiguration?.allowedMimeTypes assert(widget.configurations.contentInsertionConfiguration?.allowedMimeTypes.contains(content.mimeType) ?? false);
.contains(content.mimeType) ?? widget.configurations.contentInsertionConfiguration?.onContentInserted.call(content);
false);
widget.configurations.contentInsertionConfiguration?.onContentInserted
.call(content);
} }
/// Copy current selection to [Clipboard]. /// Copy current selection to [Clipboard].
@ -127,8 +117,7 @@ class QuillRawEditorState extends EditorState
userUpdateTextEditingValue( userUpdateTextEditingValue(
TextEditingValue( TextEditingValue(
text: textEditingValue.text, text: textEditingValue.text,
selection: selection: TextSelection.collapsed(offset: textEditingValue.selection.end),
TextSelection.collapsed(offset: textEditingValue.selection.end),
), ),
SelectionChangedCause.toolbar, SelectionChangedCause.toolbar,
); );
@ -202,8 +191,7 @@ class QuillRawEditorState extends EditorState
void selectAll(SelectionChangedCause cause) { void selectAll(SelectionChangedCause cause) {
userUpdateTextEditingValue( userUpdateTextEditingValue(
textEditingValue.copyWith( textEditingValue.copyWith(
selection: TextSelection( selection: TextSelection(baseOffset: 0, extentOffset: textEditingValue.text.length),
baseOffset: 0, extentOffset: textEditingValue.text.length),
), ),
cause, cause,
); );
@ -218,27 +206,14 @@ class QuillRawEditorState extends EditorState
/// Copied from [EditableTextState]. /// Copied from [EditableTextState].
List<ContextMenuButtonItem> get contextMenuButtonItems { List<ContextMenuButtonItem> get contextMenuButtonItems {
return EditableText.getEditableButtonItems( return EditableText.getEditableButtonItems(
clipboardStatus: clipboardStatus: (_clipboardStatus != null) ? _clipboardStatus!.value : null,
(_clipboardStatus != null) ? _clipboardStatus!.value : null, onCopy: copyEnabled ? () => copySelection(SelectionChangedCause.toolbar) : null,
onCopy: copyEnabled onCut: cutEnabled ? () => cutSelection(SelectionChangedCause.toolbar) : null,
? () => copySelection(SelectionChangedCause.toolbar) onPaste: pasteEnabled ? () => pasteText(SelectionChangedCause.toolbar) : null,
: null, onSelectAll: selectAllEnabled ? () => selectAll(SelectionChangedCause.toolbar) : null,
onCut: onLookUp: lookUpEnabled ? () => lookUpSelection(SelectionChangedCause.toolbar) : null,
cutEnabled ? () => cutSelection(SelectionChangedCause.toolbar) : null, onSearchWeb: searchWebEnabled ? () => searchWebForSelection(SelectionChangedCause.toolbar) : null,
onPaste: onShare: shareEnabled ? () => shareSelection(SelectionChangedCause.toolbar) : null,
pasteEnabled ? () => pasteText(SelectionChangedCause.toolbar) : null,
onSelectAll: selectAllEnabled
? () => selectAll(SelectionChangedCause.toolbar)
: null,
onLookUp: lookUpEnabled
? () => lookUpSelection(SelectionChangedCause.toolbar)
: null,
onSearchWeb: searchWebEnabled
? () => searchWebForSelection(SelectionChangedCause.toolbar)
: null,
onShare: shareEnabled
? () => shareSelection(SelectionChangedCause.toolbar)
: null,
onLiveTextInput: liveTextInputEnabled ? () {} : null, onLiveTextInput: liveTextInputEnabled ? () {} : null,
); );
} }
@ -332,10 +307,8 @@ class QuillRawEditorState extends EditorState
); );
} }
final startCharacterRect = final startCharacterRect = renderEditor.getLocalRectForCaret(selection.base);
renderEditor.getLocalRectForCaret(selection.base); final endCharacterRect = renderEditor.getLocalRectForCaret(selection.extent);
final endCharacterRect =
renderEditor.getLocalRectForCaret(selection.extent);
return QuillEditorGlyphHeights( return QuillEditorGlyphHeights(
startCharacterRect.height, startCharacterRect.height,
endCharacterRect.height, endCharacterRect.height,
@ -382,12 +355,9 @@ class QuillRawEditorState extends EditorState
Widget _scribbleFocusable(Widget child) { Widget _scribbleFocusable(Widget child) {
return ScribbleFocusable( return ScribbleFocusable(
editorKey: _editorKey, editorKey: _editorKey,
enabled: widget.configurations.enableScribble && enabled: widget.configurations.enableScribble && !widget.configurations.readOnly,
!widget.configurations.readOnly, renderBoxForBounds: () =>
renderBoxForBounds: () => context context.findAncestorStateOfType<QuillEditorState>()?.context.findRenderObject() as RenderBox?,
.findAncestorStateOfType<QuillEditorState>()
?.context
.findRenderObject() as RenderBox?,
onScribbleFocus: (offset) { onScribbleFocus: (offset) {
widget.configurations.focusNode.requestFocus(); widget.configurations.focusNode.requestFocus();
widget.configurations.onScribbleActivated?.call(); widget.configurations.onScribbleActivated?.call();
@ -433,8 +403,7 @@ class QuillRawEditorState extends EditorState
/// the scroll view with [BaselineProxy] which mimics the editor's /// the scroll view with [BaselineProxy] which mimics the editor's
/// baseline. /// baseline.
// This implies that the first line has no styles applied to it. // This implies that the first line has no styles applied to it.
final baselinePadding = final baselinePadding = EdgeInsets.only(top: _styles!.paragraph!.verticalSpacing.top);
EdgeInsets.only(top: _styles!.paragraph!.verticalSpacing.top);
child = BaselineProxy( child = BaselineProxy(
textStyle: _styles!.paragraph!.style, textStyle: _styles!.paragraph!.style,
padding: baselinePadding, padding: baselinePadding,
@ -464,8 +433,7 @@ class QuillRawEditorState extends EditorState
padding: widget.configurations.padding, padding: widget.configurations.padding,
maxContentWidth: widget.configurations.maxContentWidth, maxContentWidth: widget.configurations.maxContentWidth,
cursorController: _cursorCont, cursorController: _cursorCont,
floatingCursorDisabled: floatingCursorDisabled: widget.configurations.floatingCursorDisabled,
widget.configurations.floatingCursorDisabled,
children: _buildChildren(doc, context), children: _buildChildren(doc, context),
), ),
), ),
@ -479,9 +447,8 @@ class QuillRawEditorState extends EditorState
link: _toolbarLayerLink, link: _toolbarLayerLink,
child: Semantics( child: Semantics(
child: MouseRegion( child: MouseRegion(
cursor: widget.configurations.readOnly cursor:
? widget.configurations.readOnlyMouseCursor widget.configurations.readOnly ? widget.configurations.readOnlyMouseCursor : SystemMouseCursors.text,
: SystemMouseCursors.text,
child: QuillRawEditorMultiChildRenderObject( child: QuillRawEditorMultiChildRenderObject(
key: _editorKey, key: _editorKey,
document: doc, document: doc,
@ -497,8 +464,7 @@ class QuillRawEditorState extends EditorState
scrollBottomInset: widget.configurations.scrollBottomInset, scrollBottomInset: widget.configurations.scrollBottomInset,
padding: widget.configurations.padding, padding: widget.configurations.padding,
maxContentWidth: widget.configurations.maxContentWidth, maxContentWidth: widget.configurations.maxContentWidth,
floatingCursorDisabled: floatingCursorDisabled: widget.configurations.floatingCursorDisabled,
widget.configurations.floatingCursorDisabled,
children: _buildChildren(doc, context), children: _buildChildren(doc, context),
), ),
), ),
@ -708,15 +674,12 @@ class QuillRawEditorState extends EditorState
LogicalKeyboardKey.pageUp, LogicalKeyboardKey.pageUp,
control: !isDesktopMacOS, control: !isDesktopMacOS,
meta: isDesktopMacOS, meta: isDesktopMacOS,
): const ScrollIntent( ): const ScrollIntent(direction: AxisDirection.up, type: ScrollIncrementType.page),
direction: AxisDirection.up, type: ScrollIncrementType.page),
SingleActivator( SingleActivator(
LogicalKeyboardKey.pageDown, LogicalKeyboardKey.pageDown,
control: !isDesktopMacOS, control: !isDesktopMacOS,
meta: isDesktopMacOS, meta: isDesktopMacOS,
): const ScrollIntent( ): const ScrollIntent(direction: AxisDirection.down, type: ScrollIncrementType.page),
direction: AxisDirection.down,
type: ScrollIncrementType.page),
}, },
), ),
child: Actions( child: Actions(
@ -770,8 +733,7 @@ class QuillRawEditorState extends EditorState
} }
KeyEventResult _handleSpaceKey(KeyEvent event) { KeyEventResult _handleSpaceKey(KeyEvent event) {
final child = final child = controller.document.queryChild(controller.selection.baseOffset);
controller.document.queryChild(controller.selection.baseOffset);
if (child.node == null) { if (child.node == null) {
return KeyEventResult.ignored; return KeyEventResult.ignored;
} }
@ -788,8 +750,7 @@ class QuillRawEditorState extends EditorState
const olKeyPhrase = '1.'; const olKeyPhrase = '1.';
const ulKeyPhrase = '-'; const ulKeyPhrase = '-';
final enableMdConversion = final enableMdConversion = widget.configurations.enableMarkdownStyleConversion;
widget.configurations.enableMarkdownStyleConversion;
if (text.value == olKeyPhrase && enableMdConversion) { if (text.value == olKeyPhrase && enableMdConversion) {
_updateSelectionForKeyPhrase(olKeyPhrase, Attribute.ol); _updateSelectionForKeyPhrase(olKeyPhrase, Attribute.ol);
@ -803,8 +764,7 @@ class QuillRawEditorState extends EditorState
} }
KeyEventResult _handleTabKey(KeyEvent event) { KeyEventResult _handleTabKey(KeyEvent event) {
final child = final child = controller.document.queryChild(controller.selection.baseOffset);
controller.document.queryChild(controller.selection.baseOffset);
KeyEventResult insertTabCharacter() { KeyEventResult insertTabCharacter() {
if (widget.configurations.readOnly) { if (widget.configurations.readOnly) {
@ -866,23 +826,20 @@ class QuillRawEditorState extends EditorState
void _moveCursor(int chars) { void _moveCursor(int chars) {
final selection = controller.selection; final selection = controller.selection;
controller.updateSelection( controller.updateSelection(
controller.selection.copyWith( controller.selection
baseOffset: selection.baseOffset + chars, .copyWith(baseOffset: selection.baseOffset + chars, extentOffset: selection.baseOffset + chars),
extentOffset: selection.baseOffset + chars),
ChangeSource.local); ChangeSource.local);
} }
void _updateSelectionForKeyPhrase(String phrase, Attribute attribute) { void _updateSelectionForKeyPhrase(String phrase, Attribute attribute) {
controller.replaceText(controller.selection.baseOffset - phrase.length, controller.replaceText(controller.selection.baseOffset - phrase.length, phrase.length, '\n', null);
phrase.length, '\n', null);
_moveCursor(-phrase.length); _moveCursor(-phrase.length);
controller controller
..formatSelection(attribute) ..formatSelection(attribute)
// Remove the added newline. // Remove the added newline.
..replaceText(controller.selection.baseOffset + 1, 1, '', null); ..replaceText(controller.selection.baseOffset + 1, 1, '', null);
// //
final style = final style = controller.document.collectStyle(controller.selection.baseOffset, 0);
controller.document.collectStyle(controller.selection.baseOffset, 0);
if (style.isNotEmpty) { if (style.isNotEmpty) {
for (final attr in style.values) { for (final attr in style.values) {
controller.formatSelection(attr); controller.formatSelection(attr);
@ -930,10 +887,8 @@ class QuillRawEditorState extends EditorState
/// Updates the checkbox positioned at [offset] in document /// Updates the checkbox positioned at [offset] in document
/// by changing its attribute according to [value]. /// by changing its attribute according to [value].
void _handleCheckboxTap(int offset, bool value) { void _handleCheckboxTap(int offset, bool value) {
final requestKeyboardFocusOnCheckListChanged = final requestKeyboardFocusOnCheckListChanged = widget.configurations.requestKeyboardFocusOnCheckListChanged;
widget.configurations.requestKeyboardFocusOnCheckListChanged; if (!(widget.configurations.checkBoxReadOnly ?? widget.configurations.readOnly)) {
if (!(widget.configurations.checkBoxReadOnly ??
widget.configurations.readOnly)) {
_disableScrollControllerAnimateOnce = true; _disableScrollControllerAnimateOnce = true;
final currentSelection = controller.selection.copyWith(); final currentSelection = controller.selection.copyWith();
final attribute = value ? Attribute.checked : Attribute.unchecked; final attribute = value ? Attribute.checked : Attribute.unchecked;
@ -946,10 +901,7 @@ class QuillRawEditorState extends EditorState
// Checkbox tapping causes controller.selection to go to offset 0 // Checkbox tapping causes controller.selection to go to offset 0
// Stop toggling those two toolbar buttons // Stop toggling those two toolbar buttons
..toolbarButtonToggler = { ..toolbarButtonToggler = {Attribute.list.key: attribute, Attribute.header.key: Attribute.header};
Attribute.list.key: attribute,
Attribute.header.key: Attribute.header
};
// Go back from offset 0 to current selection // Go back from offset 0 to current selection
SchedulerBinding.instance.addPostFrameCallback((_) { SchedulerBinding.instance.addPostFrameCallback((_) {
@ -985,14 +937,12 @@ class QuillRawEditorState extends EditorState
// and watch if the system language is a RTL language and avoid putting // and watch if the system language is a RTL language and avoid putting
// to the edge of the left side any checkbox or list point/number if is a // to the edge of the left side any checkbox or list point/number if is a
// RTL language // RTL language
if (nodeTextDirection == TextDirection.ltr && if (nodeTextDirection == TextDirection.ltr && _textDirection == TextDirection.rtl) {
_textDirection == TextDirection.rtl) {
nodeTextDirection = TextDirection.rtl; nodeTextDirection = TextDirection.rtl;
} }
if (node is Line) { if (node is Line) {
final editableTextLine = _getEditableTextLineFromNode(node, context); final editableTextLine = _getEditableTextLineFromNode(node, context);
result.add(Directionality( result.add(Directionality(textDirection: nodeTextDirection, child: editableTextLine));
textDirection: nodeTextDirection, child: editableTextLine));
} else if (node is Block) { } else if (node is Block) {
final editableTextBlock = EditableTextBlock( final editableTextBlock = EditableTextBlock(
block: node, block: node,
@ -1004,12 +954,9 @@ class QuillRawEditorState extends EditorState
textSelection: controller.selection, textSelection: controller.selection,
color: widget.configurations.selectionColor, color: widget.configurations.selectionColor,
styles: _styles, styles: _styles,
enableInteractiveSelection: enableInteractiveSelection: widget.configurations.enableInteractiveSelection,
widget.configurations.enableInteractiveSelection,
hasFocus: _hasFocus, hasFocus: _hasFocus,
contentPadding: attrs.containsKey(Attribute.codeBlock.key) contentPadding: attrs.containsKey(Attribute.codeBlock.key) ? const EdgeInsets.all(16) : null,
? const EdgeInsets.all(16)
: null,
embedBuilder: widget.configurations.embedBuilder, embedBuilder: widget.configurations.embedBuilder,
linkActionPicker: _linkActionPicker, linkActionPicker: _linkActionPicker,
onLaunchUrl: widget.configurations.onLaunchUrl, onLaunchUrl: widget.configurations.onLaunchUrl,
@ -1039,8 +986,7 @@ class QuillRawEditorState extends EditorState
return result; return result;
} }
EditableTextLine _getEditableTextLineFromNode( EditableTextLine _getEditableTextLineFromNode(Line node, BuildContext context) {
Line node, BuildContext context) {
final textLine = TextLine( final textLine = TextLine(
line: node, line: node,
textDirection: _textDirection, textDirection: _textDirection,
@ -1136,8 +1082,7 @@ class QuillRawEditorState extends EditorState
return defaultStyles!.paragraph!.verticalSpacing; return defaultStyles!.paragraph!.verticalSpacing;
} }
HorizontalSpacing _getHorizontalSpacingForBlock( HorizontalSpacing _getHorizontalSpacingForBlock(Block node, DefaultStyles? defaultStyles) {
Block node, DefaultStyles? defaultStyles) {
final attrs = node.style.attributes; final attrs = node.style.attributes;
if (attrs.containsKey(Attribute.blockQuote.key)) { if (attrs.containsKey(Attribute.blockQuote.key)) {
return defaultStyles!.quote!.horizontalSpacing; return defaultStyles!.quote!.horizontalSpacing;
@ -1153,8 +1098,7 @@ class QuillRawEditorState extends EditorState
return HorizontalSpacing.zero; return HorizontalSpacing.zero;
} }
VerticalSpacing _getVerticalSpacingForBlock( VerticalSpacing _getVerticalSpacingForBlock(Block node, DefaultStyles? defaultStyles) {
Block node, DefaultStyles? defaultStyles) {
final attrs = node.style.attributes; final attrs = node.style.attributes;
if (attrs.containsKey(Attribute.blockQuote.key)) { if (attrs.containsKey(Attribute.blockQuote.key)) {
return defaultStyles!.quote!.verticalSpacing; return defaultStyles!.quote!.verticalSpacing;
@ -1209,8 +1153,7 @@ class QuillRawEditorState extends EditorState
} else { } else {
_keyboardVisibilityController = KeyboardVisibilityController(); _keyboardVisibilityController = KeyboardVisibilityController();
_keyboardVisible = _keyboardVisibilityController!.isVisible; _keyboardVisible = _keyboardVisibilityController!.isVisible;
_keyboardVisibilitySubscription = _keyboardVisibilitySubscription = _keyboardVisibilityController?.onChange.listen((visible) {
_keyboardVisibilityController?.onChange.listen((visible) {
_keyboardVisible = visible; _keyboardVisible = visible;
if (visible) { if (visible) {
_onChangeTextEditingValue(!_hasFocus); _onChangeTextEditingValue(!_hasFocus);
@ -1252,9 +1195,7 @@ class QuillRawEditorState extends EditorState
super.didChangeDependencies(); super.didChangeDependencies();
final parentStyles = QuillStyles.getStyles(context, true); final parentStyles = QuillStyles.getStyles(context, true);
final defaultStyles = DefaultStyles.getInstance(context); final defaultStyles = DefaultStyles.getInstance(context);
_styles = (parentStyles != null) _styles = (parentStyles != null) ? defaultStyles.merge(parentStyles) : defaultStyles;
? defaultStyles.merge(parentStyles)
: defaultStyles;
if (widget.configurations.customStyles != null) { if (widget.configurations.customStyles != null) {
_styles = _styles!.merge(widget.configurations.customStyles!); _styles = _styles!.merge(widget.configurations.customStyles!);
@ -1317,8 +1258,7 @@ class QuillRawEditorState extends EditorState
} }
bool _shouldShowSelectionHandles() { bool _shouldShowSelectionHandles() {
return widget.configurations.showSelectionHandles && return widget.configurations.showSelectionHandles && !controller.selection.isCollapsed;
!controller.selection.isCollapsed;
} }
@override @override
@ -1419,10 +1359,7 @@ class QuillRawEditorState extends EditorState
void _updateOrDisposeSelectionOverlayIfNeeded() { void _updateOrDisposeSelectionOverlayIfNeeded() {
if (_selectionOverlay != null) { if (_selectionOverlay != null) {
if (!_hasFocus || textEditingValue.selection.isCollapsed) { if (_hasFocus) {
_selectionOverlay?.dispose();
_selectionOverlay = null;
} else if (_hasFocus) {
_selectionOverlay!.update(textEditingValue); _selectionOverlay!.update(textEditingValue);
} else { } else {
_selectionOverlay!.dispose(); _selectionOverlay!.dispose();
@ -1448,18 +1385,16 @@ class QuillRawEditorState extends EditorState
clipboardStatus: _clipboardStatus, clipboardStatus: _clipboardStatus,
contextMenuBuilder: widget.configurations.contextMenuBuilder == null contextMenuBuilder: widget.configurations.contextMenuBuilder == null
? null ? null
: (context) => : (context) => widget.configurations.contextMenuBuilder!(context, this),
widget.configurations.contextMenuBuilder!(context, this), magnifierConfiguration:
magnifierConfiguration: widget.configurations.magnifierConfiguration ?? widget.configurations.magnifierConfiguration ?? TextMagnifier.adaptiveMagnifierConfiguration,
TextMagnifier.adaptiveMagnifierConfiguration,
); );
} }
void _handleFocusChanged() { void _handleFocusChanged() {
if (dirty) { if (dirty) {
requestKeyboard(); requestKeyboard();
SchedulerBinding.instance SchedulerBinding.instance.addPostFrameCallback((_) => _handleFocusChanged());
.addPostFrameCallback((_) => _handleFocusChanged());
return; return;
} }
openOrCloseConnection(); openOrCloseConnection();
@ -1483,8 +1418,7 @@ class QuillRawEditorState extends EditorState
Future<LinkMenuAction> _linkActionPicker(Node linkNode) async { Future<LinkMenuAction> _linkActionPicker(Node linkNode) async {
final link = linkNode.style.attributes[Attribute.link.key]!.value!; final link = linkNode.style.attributes[Attribute.link.key]!.value!;
return widget.configurations return widget.configurations.linkActionPickerDelegate(context, link, linkNode);
.linkActionPickerDelegate(context, link, linkNode);
} }
bool _showCaretOnScreenScheduled = false; bool _showCaretOnScreenScheduled = false;
@ -1511,8 +1445,7 @@ class QuillRawEditorState extends EditorState
} }
final viewport = RenderAbstractViewport.of(renderEditor); final viewport = RenderAbstractViewport.of(renderEditor);
final editorOffset = final editorOffset = renderEditor.localToGlobal(const Offset(0, 0), ancestor: viewport);
renderEditor.localToGlobal(const Offset(0, 0), ancestor: viewport);
final offsetInViewport = _scrollController.offset + editorOffset.dy; final offsetInViewport = _scrollController.offset + editorOffset.dy;
final offset = renderEditor.getOffsetToRevealCursor( final offset = renderEditor.getOffsetToRevealCursor(
@ -1540,8 +1473,7 @@ class QuillRawEditorState extends EditorState
/// ///
/// This property is typically used to notify the renderer of input gestures. /// This property is typically used to notify the renderer of input gestures.
@override @override
RenderEditor get renderEditor => RenderEditor get renderEditor => _editorKey.currentContext!.findRenderObject() as RenderEditor;
_editorKey.currentContext!.findRenderObject() as RenderEditor;
/// Express interest in interacting with the keyboard. /// Express interest in interacting with the keyboard.
/// ///
@ -1616,8 +1548,7 @@ class QuillRawEditorState extends EditorState
void _replaceText(ReplaceTextIntent intent) { void _replaceText(ReplaceTextIntent intent) {
userUpdateTextEditingValue( userUpdateTextEditingValue(
intent.currentTextEditingValue intent.currentTextEditingValue.replaced(intent.replacementRange, intent.replacementText),
.replaced(intent.replacementRange, intent.replacementText),
intent.cause, intent.cause,
); );
} }
@ -1626,22 +1557,18 @@ class QuillRawEditorState extends EditorState
bool get wantKeepAlive => widget.configurations.focusNode.hasFocus; bool get wantKeepAlive => widget.configurations.focusNode.hasFocus;
@override @override
AnimationController get floatingCursorResetController => AnimationController get floatingCursorResetController => _floatingCursorResetController;
_floatingCursorResetController;
late AnimationController _floatingCursorResetController; late AnimationController _floatingCursorResetController;
// --------------------------- Text Editing Actions -------------------------- // --------------------------- Text Editing Actions --------------------------
QuillEditorTextBoundary _characterBoundary( QuillEditorTextBoundary _characterBoundary(DirectionalTextEditingIntent intent) {
DirectionalTextEditingIntent intent) {
final atomicTextBoundary = QuillEditorCharacterBoundary(textEditingValue); final atomicTextBoundary = QuillEditorCharacterBoundary(textEditingValue);
return QuillEditorCollapsedSelectionBoundary( return QuillEditorCollapsedSelectionBoundary(atomicTextBoundary, intent.forward);
atomicTextBoundary, intent.forward);
} }
QuillEditorTextBoundary _nextWordBoundary( QuillEditorTextBoundary _nextWordBoundary(DirectionalTextEditingIntent intent) {
DirectionalTextEditingIntent intent) {
final QuillEditorTextBoundary atomicTextBoundary; final QuillEditorTextBoundary atomicTextBoundary;
final QuillEditorTextBoundary boundary; final QuillEditorTextBoundary boundary;
@ -1650,8 +1577,7 @@ class QuillRawEditorState extends EditorState
atomicTextBoundary = QuillEditorCharacterBoundary(textEditingValue); atomicTextBoundary = QuillEditorCharacterBoundary(textEditingValue);
// This isn't enough. Newline characters. // This isn't enough. Newline characters.
boundary = QuillEditorExpandedTextBoundary( boundary = QuillEditorExpandedTextBoundary(
QuillEditorWhitespaceBoundary(textEditingValue), QuillEditorWhitespaceBoundary(textEditingValue), QuillEditorWordBoundary(renderEditor, textEditingValue));
QuillEditorWordBoundary(renderEditor, textEditingValue));
final mixedBoundary = intent.forward final mixedBoundary = intent.forward
? QuillEditorMixedBoundary(atomicTextBoundary, boundary) ? QuillEditorMixedBoundary(atomicTextBoundary, boundary)
@ -1676,26 +1602,21 @@ class QuillRawEditorState extends EditorState
// since the document boundary is unique and the linebreak boundary is // since the document boundary is unique and the linebreak boundary is
// already caret-location based. // already caret-location based.
return intent.forward return intent.forward
? QuillEditorMixedBoundary( ? QuillEditorMixedBoundary(QuillEditorCollapsedSelectionBoundary(atomicTextBoundary, true), boundary)
QuillEditorCollapsedSelectionBoundary(atomicTextBoundary, true),
boundary)
: QuillEditorMixedBoundary( : QuillEditorMixedBoundary(
boundary, boundary,
QuillEditorCollapsedSelectionBoundary(atomicTextBoundary, false), QuillEditorCollapsedSelectionBoundary(atomicTextBoundary, false),
); );
} }
QuillEditorTextBoundary _documentBoundary( QuillEditorTextBoundary _documentBoundary(DirectionalTextEditingIntent intent) =>
DirectionalTextEditingIntent intent) =>
QuillEditorDocumentBoundary(textEditingValue); QuillEditorDocumentBoundary(textEditingValue);
Action<T> _makeOverridable<T extends Intent>(Action<T> defaultAction) { Action<T> _makeOverridable<T extends Intent>(Action<T> defaultAction) {
return Action<T>.overridable( return Action<T>.overridable(context: context, defaultAction: defaultAction);
context: context, defaultAction: defaultAction);
} }
late final Action<ReplaceTextIntent> _replaceTextAction = late final Action<ReplaceTextIntent> _replaceTextAction = CallbackAction<ReplaceTextIntent>(onInvoke: _replaceText);
CallbackAction<ReplaceTextIntent>(onInvoke: _replaceText);
void _updateSelection(UpdateSelectionIntent intent) { void _updateSelection(UpdateSelectionIntent intent) {
userUpdateTextEditingValue( userUpdateTextEditingValue(
@ -1707,27 +1628,20 @@ class QuillRawEditorState extends EditorState
late final Action<UpdateSelectionIntent> _updateSelectionAction = late final Action<UpdateSelectionIntent> _updateSelectionAction =
CallbackAction<UpdateSelectionIntent>(onInvoke: _updateSelection); CallbackAction<UpdateSelectionIntent>(onInvoke: _updateSelection);
late final QuillEditorUpdateTextSelectionToAdjacentLineAction< late final QuillEditorUpdateTextSelectionToAdjacentLineAction<ExtendSelectionVerticallyToAdjacentLineIntent>
ExtendSelectionVerticallyToAdjacentLineIntent> _adjacentLineAction = _adjacentLineAction =
QuillEditorUpdateTextSelectionToAdjacentLineAction< QuillEditorUpdateTextSelectionToAdjacentLineAction<ExtendSelectionVerticallyToAdjacentLineIntent>(this);
ExtendSelectionVerticallyToAdjacentLineIntent>(this);
late final _adjacentPageAction = late final _adjacentPageAction =
QuillEditorUpdateTextSelectionToAdjacentPageAction< QuillEditorUpdateTextSelectionToAdjacentPageAction<ExtendSelectionVerticallyToAdjacentPageIntent>(this);
ExtendSelectionVerticallyToAdjacentPageIntent>(this);
late final QuillEditorToggleTextStyleAction _formatSelectionAction = late final QuillEditorToggleTextStyleAction _formatSelectionAction = QuillEditorToggleTextStyleAction(this);
QuillEditorToggleTextStyleAction(this);
late final QuillEditorIndentSelectionAction _indentSelectionAction = late final QuillEditorIndentSelectionAction _indentSelectionAction = QuillEditorIndentSelectionAction(this);
QuillEditorIndentSelectionAction(this);
late final QuillEditorOpenSearchAction _openSearchAction = late final QuillEditorOpenSearchAction _openSearchAction = QuillEditorOpenSearchAction(this);
QuillEditorOpenSearchAction(this); late final QuillEditorApplyHeaderAction _applyHeaderAction = QuillEditorApplyHeaderAction(this);
late final QuillEditorApplyHeaderAction _applyHeaderAction = late final QuillEditorApplyCheckListAction _applyCheckListAction = QuillEditorApplyCheckListAction(this);
QuillEditorApplyHeaderAction(this);
late final QuillEditorApplyCheckListAction _applyCheckListAction =
QuillEditorApplyCheckListAction(this);
late final Map<Type, Action<Intent>> _actions = <Type, Action<Intent>>{ late final Map<Type, Action<Intent>> _actions = <Type, Action<Intent>>{
DoNothingAndStopPropagationTextIntent: DoNothingAction(consumesKey: false), DoNothingAndStopPropagationTextIntent: DoNothingAction(consumesKey: false),
@ -1736,48 +1650,35 @@ class QuillRawEditorState extends EditorState
DirectionalFocusIntent: DirectionalFocusAction.forTextField(), DirectionalFocusIntent: DirectionalFocusAction.forTextField(),
// Delete // Delete
DeleteCharacterIntent: _makeOverridable( DeleteCharacterIntent:
QuillEditorDeleteTextAction<DeleteCharacterIntent>( _makeOverridable(QuillEditorDeleteTextAction<DeleteCharacterIntent>(this, _characterBoundary)),
this, _characterBoundary)), DeleteToNextWordBoundaryIntent:
DeleteToNextWordBoundaryIntent: _makeOverridable( _makeOverridable(QuillEditorDeleteTextAction<DeleteToNextWordBoundaryIntent>(this, _nextWordBoundary)),
QuillEditorDeleteTextAction<DeleteToNextWordBoundaryIntent>( DeleteToLineBreakIntent: _makeOverridable(QuillEditorDeleteTextAction<DeleteToLineBreakIntent>(this, _linebreak)),
this, _nextWordBoundary)),
DeleteToLineBreakIntent: _makeOverridable(
QuillEditorDeleteTextAction<DeleteToLineBreakIntent>(this, _linebreak)),
// Extend/Move Selection // Extend/Move Selection
ExtendSelectionByCharacterIntent: _makeOverridable( ExtendSelectionByCharacterIntent:
QuillEditorUpdateTextSelectionAction<ExtendSelectionByCharacterIntent>( _makeOverridable(QuillEditorUpdateTextSelectionAction<ExtendSelectionByCharacterIntent>(
this, this,
false, false,
_characterBoundary, _characterBoundary,
)), )),
ExtendSelectionToNextWordBoundaryIntent: _makeOverridable( ExtendSelectionToNextWordBoundaryIntent: _makeOverridable(
QuillEditorUpdateTextSelectionAction< QuillEditorUpdateTextSelectionAction<ExtendSelectionToNextWordBoundaryIntent>(this, true, _nextWordBoundary)),
ExtendSelectionToNextWordBoundaryIntent>(
this, true, _nextWordBoundary)),
ExtendSelectionToLineBreakIntent: _makeOverridable( ExtendSelectionToLineBreakIntent: _makeOverridable(
QuillEditorUpdateTextSelectionAction<ExtendSelectionToLineBreakIntent>( QuillEditorUpdateTextSelectionAction<ExtendSelectionToLineBreakIntent>(this, true, _linebreak)),
this, true, _linebreak)), ExtendSelectionVerticallyToAdjacentLineIntent: _makeOverridable(_adjacentLineAction),
ExtendSelectionVerticallyToAdjacentLineIntent:
_makeOverridable(_adjacentLineAction),
ExtendSelectionToDocumentBoundaryIntent: _makeOverridable( ExtendSelectionToDocumentBoundaryIntent: _makeOverridable(
QuillEditorUpdateTextSelectionAction< QuillEditorUpdateTextSelectionAction<ExtendSelectionToDocumentBoundaryIntent>(this, true, _documentBoundary)),
ExtendSelectionToDocumentBoundaryIntent>( ExtendSelectionToNextWordBoundaryOrCaretLocationIntent:
this, true, _documentBoundary)), _makeOverridable(QuillEditorExtendSelectionOrCaretPositionAction(this, _nextWordBoundary)),
ExtendSelectionToNextWordBoundaryOrCaretLocationIntent: _makeOverridable(
QuillEditorExtendSelectionOrCaretPositionAction(
this, _nextWordBoundary)),
// Copy Paste // Copy Paste
SelectAllTextIntent: _makeOverridable(QuillEditorSelectAllAction(this)), SelectAllTextIntent: _makeOverridable(QuillEditorSelectAllAction(this)),
CopySelectionTextIntent: CopySelectionTextIntent: _makeOverridable(QuillEditorCopySelectionAction(this)),
_makeOverridable(QuillEditorCopySelectionAction(this)), PasteTextIntent: _makeOverridable(CallbackAction<PasteTextIntent>(onInvoke: (intent) => pasteText(intent.cause))),
PasteTextIntent: _makeOverridable(CallbackAction<PasteTextIntent>(
onInvoke: (intent) => pasteText(intent.cause))),
HideSelectionToolbarIntent: HideSelectionToolbarIntent: _makeOverridable(QuillEditorHideSelectionToolbarAction(this)),
_makeOverridable(QuillEditorHideSelectionToolbarAction(this)),
UndoTextIntent: _makeOverridable(QuillEditorUndoKeyboardAction(this)), UndoTextIntent: _makeOverridable(QuillEditorUndoKeyboardAction(this)),
RedoTextIntent: _makeOverridable(QuillEditorRedoKeyboardAction(this)), RedoTextIntent: _makeOverridable(QuillEditorRedoKeyboardAction(this)),
@ -1851,10 +1752,8 @@ class QuillRawEditorState extends EditorState
if (_hasFocus == false) return; if (_hasFocus == false) return;
if (_selectionOverlay == null) return; if (_selectionOverlay == null) return;
final position = renderEditor.getPositionForOffset(positionToShow); final position = renderEditor.getPositionForOffset(positionToShow);
_selectionOverlay?.showMagnifier(position, positionToShow, renderEditor);
if (_selectionOverlay!.magnifierIsVisible) { if (_selectionOverlay!.magnifierIsVisible) {
_selectionOverlay! _selectionOverlay!.updateMagnifier(position, positionToShow, renderEditor);
.updateMagnifier(position, positionToShow, renderEditor);
} else { } else {
_selectionOverlay!.showMagnifier(position, positionToShow, renderEditor); _selectionOverlay!.showMagnifier(position, positionToShow, renderEditor);
} }

@ -8,7 +8,7 @@ import 'package:flutter/services.dart';
import '../../common/utils/platform.dart'; import '../../common/utils/platform.dart';
import '../../document/attribute.dart'; import '../../document/attribute.dart';
import '../../document/nodes/leaf.dart'; import '../../document/nodes/leaf.dart';
import '../../widgets/editor/editor.dart'; import '../editor.dart';
import '../raw_editor/raw_editor.dart'; import '../raw_editor/raw_editor.dart';
import 'text/text_selection.dart'; import 'text/text_selection.dart';
@ -254,7 +254,8 @@ class EditorTextSelectionGestureDetectorBuilder {
@protected @protected
void onTapDown(TapDragDownDetails details) { void onTapDown(TapDragDownDetails details) {
if (!delegate.selectionEnabled) return; if (!delegate.selectionEnabled) return;
renderEditor!.handleTapDown(details); renderEditor!
.handleTapDown(TapDownDetails(globalPosition: details.globalPosition));
final kind = details.kind; final kind = details.kind;
shouldShowSelectionToolbar = kind == null || shouldShowSelectionToolbar = kind == null ||
kind == PointerDeviceKind.touch || kind == PointerDeviceKind.touch ||

Loading…
Cancel
Save