From c5c8083b450764ba8f9b4283323d0546fa7f55b7 Mon Sep 17 00:00:00 2001 From: Ellet Date: Wed, 6 Dec 2023 11:05:28 +0300 Subject: [PATCH] 4+ --- .../models/config/editor/configurations.dart | 1 - lib/src/widgets/editor/editor.dart | 27 -- lib/src/widgets/others/delegate.dart | 1 + lib/src/widgets/raw_editor/raw_editor.dart | 38 ++- .../raw_editor_context_menu_items.dart | 160 ---------- .../widgets/raw_editor/raw_editor_state.dart | 7 +- ...editor_state_selection_delegate_mixin.dart | 2 +- ..._editor_state_text_input_client_mixin.dart | 1 + lib/src/widgets/toolbar/base_toolbar.dart | 1 - .../buttons/select_alignment_old_buttons.dart | 283 ------------------ .../buttons/select_header_style_button.dart | 6 +- 11 files changed, 48 insertions(+), 479 deletions(-) delete mode 100644 lib/src/widgets/raw_editor/raw_editor_context_menu_items.dart delete mode 100644 lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart diff --git a/lib/src/models/config/editor/configurations.dart b/lib/src/models/config/editor/configurations.dart index 55151b1b..c41787b4 100644 --- a/lib/src/models/config/editor/configurations.dart +++ b/lib/src/models/config/editor/configurations.dart @@ -6,7 +6,6 @@ import 'package:flutter/material.dart' import 'package:flutter/widgets.dart'; import 'package:meta/meta.dart' show experimental; -import '../../../widgets/editor/editor.dart'; import '../../../widgets/editor/editor_builder.dart'; import '../../../widgets/others/controller.dart'; import '../../../widgets/others/default_styles.dart'; diff --git a/lib/src/widgets/editor/editor.dart b/lib/src/widgets/editor/editor.dart index ab07a9ea..3964cd64 100644 --- a/lib/src/widgets/editor/editor.dart +++ b/lib/src/widgets/editor/editor.dart @@ -14,7 +14,6 @@ import '../../models/config/raw_editor/configurations.dart'; import '../../models/documents/document.dart'; import '../../models/documents/nodes/container.dart' as container_node; import '../../models/documents/nodes/leaf.dart'; -import '../../models/structs/offset_value.dart'; import '../../utils/platform.dart'; import '../others/box.dart'; import '../others/cursor.dart'; @@ -26,32 +25,6 @@ import '../raw_editor/raw_editor.dart'; import '../utils/provider.dart'; import 'editor_builder.dart'; -/// Base interface for the editor state which defines contract used by -/// various mixins. -abstract class EditorState extends State - implements TextSelectionDelegate { - ScrollController get scrollController; - - RenderEditor get renderEditor; - - EditorTextSelectionOverlay? get selectionOverlay; - - List get pasteStyleAndEmbed; - - String get pastePlainText; - - /// Controls the floating cursor animation when it is released. - /// The floating cursor is animated to merge with the regular cursor. - AnimationController get floatingCursorResetController; - - /// Returns true if the editor has been marked as needing to be rebuilt. - bool get dirty; - - bool showToolbar(); - - void requestKeyboard(); -} - /// Base interface for editable render objects. abstract class RenderAbstractEditor implements TextLayoutMetrics { TextSelection selectWordAtPosition(TextPosition position); diff --git a/lib/src/widgets/others/delegate.dart b/lib/src/widgets/others/delegate.dart index dff3709a..b34874d0 100644 --- a/lib/src/widgets/others/delegate.dart +++ b/lib/src/widgets/others/delegate.dart @@ -7,6 +7,7 @@ import '../../models/documents/attribute.dart'; import '../../models/documents/nodes/leaf.dart'; import '../../utils/platform.dart'; import '../editor/editor.dart'; +import '../raw_editor/raw_editor.dart'; import 'embeds.dart'; import 'text_selection.dart'; diff --git a/lib/src/widgets/raw_editor/raw_editor.dart b/lib/src/widgets/raw_editor/raw_editor.dart index c0ecf52d..4e11d707 100644 --- a/lib/src/widgets/raw_editor/raw_editor.dart +++ b/lib/src/widgets/raw_editor/raw_editor.dart @@ -1,8 +1,18 @@ import 'package:flutter/widgets.dart' - show BuildContext, State, StatefulWidget, Widget; + show + AnimationController, + BuildContext, + ScrollController, + State, + StatefulWidget, + TextSelectionDelegate, + Widget; import 'package:meta/meta.dart' show immutable; import '../../models/config/raw_editor/configurations.dart'; +import '../../models/structs/offset_value.dart'; +import '../editor/editor.dart'; +import '../others/text_selection.dart'; import 'raw_editor_state.dart'; class QuillRawEditor extends StatefulWidget { @@ -49,3 +59,29 @@ class QuillEditorGlyphHeights { final double startGlyphHeight; final double endGlyphHeight; } + +/// Base interface for the editor state which defines contract used by +/// various mixins. +abstract class EditorState extends State + implements TextSelectionDelegate { + ScrollController get scrollController; + + RenderEditor get renderEditor; + + EditorTextSelectionOverlay? get selectionOverlay; + + List get pasteStyleAndEmbed; + + String get pastePlainText; + + /// Controls the floating cursor animation when it is released. + /// The floating cursor is animated to merge with the regular cursor. + AnimationController get floatingCursorResetController; + + /// Returns true if the editor has been marked as needing to be rebuilt. + bool get dirty; + + bool showToolbar(); + + void requestKeyboard(); +} diff --git a/lib/src/widgets/raw_editor/raw_editor_context_menu_items.dart b/lib/src/widgets/raw_editor/raw_editor_context_menu_items.dart deleted file mode 100644 index 39541e6c..00000000 --- a/lib/src/widgets/raw_editor/raw_editor_context_menu_items.dart +++ /dev/null @@ -1,160 +0,0 @@ -// import 'package:flutter/widgets.dart' show TextSelectionDelegate; - -// class QuillEditorTextSelectionDelegate implements TextSelectionDelegate { -// /// Copy current selection to [Clipboard]. -// @override -// void copySelection(SelectionChangedCause cause) { -// controller.copiedImageUrl = null; -// _pastePlainText = controller.getPlainText(); -// _pasteStyleAndEmbed = controller.getAllIndividualSelectionStylesAndEmbed(); - -// final selection = textEditingValue.selection; -// final text = textEditingValue.text; -// if (selection.isCollapsed) { -// return; -// } -// Clipboard.setData(ClipboardData(text: selection.textInside(text))); - -// if (cause == SelectionChangedCause.toolbar) { -// bringIntoView(textEditingValue.selection.extent); - -// // Collapse the selection and hide the toolbar and handles. -// userUpdateTextEditingValue( -// TextEditingValue( -// text: textEditingValue.text, -// selection: -// TextSelection.collapsed(offset: textEditingValue.selection.end), -// ), -// SelectionChangedCause.toolbar, -// ); -// } -// } - -// /// Cut current selection to [Clipboard]. -// @override -// void cutSelection(SelectionChangedCause cause) { -// controller.copiedImageUrl = null; -// _pastePlainText = controller.getPlainText(); -// _pasteStyleAndEmbed = controller.getAllIndividualSelectionStylesAndEmbed(); - -// if (widget.configurations.readOnly) { -// return; -// } -// final selection = textEditingValue.selection; -// final text = textEditingValue.text; -// if (selection.isCollapsed) { -// return; -// } -// Clipboard.setData(ClipboardData(text: selection.textInside(text))); -// _replaceText(ReplaceTextIntent(textEditingValue, '', selection, cause)); - -// if (cause == SelectionChangedCause.toolbar) { -// bringIntoView(textEditingValue.selection.extent); -// hideToolbar(); -// } -// } - -// /// Paste text from [Clipboard]. -// @override -// Future pasteText(SelectionChangedCause cause) async { -// if (widget.configurations.readOnly) { -// return; -// } - -// if (controller.copiedImageUrl != null) { -// final index = textEditingValue.selection.baseOffset; -// final length = textEditingValue.selection.extentOffset - index; -// final copied = controller.copiedImageUrl!; -// controller.replaceText( -// index, -// length, -// BlockEmbed.image(copied.url), -// null, -// ); -// if (copied.styleString.isNotEmpty) { -// controller.formatText( -// getEmbedNode(controller, index + 1).offset, -// 1, -// StyleAttribute(copied.styleString), -// ); -// } -// controller.copiedImageUrl = null; -// await Clipboard.setData( -// const ClipboardData(text: ''), -// ); -// return; -// } - -// final selection = textEditingValue.selection; -// if (!selection.isValid) { -// return; -// } -// // Snapshot the input before using `await`. -// // See https://github.com/flutter/flutter/issues/11427 -// final text = await Clipboard.getData(Clipboard.kTextPlain); -// if (text != null) { -// _replaceText( -// ReplaceTextIntent( -// textEditingValue, -// text.text!, -// selection, -// cause, -// ), -// ); - -// bringIntoView(textEditingValue.selection.extent); - -// // Collapse the selection and hide the toolbar and handles. -// userUpdateTextEditingValue( -// TextEditingValue( -// text: textEditingValue.text, -// selection: TextSelection.collapsed( -// offset: textEditingValue.selection.end, -// ), -// ), -// cause, -// ); - -// return; -// } - -// final onImagePaste = widget.configurations.onImagePaste; -// if (onImagePaste != null) { -// final reader = await ClipboardReader.readClipboard(); -// if (!reader.canProvide(Formats.png)) { -// return; -// } -// reader.getFile(Formats.png, (value) async { -// final image = value; - -// final imageUrl = await onImagePaste(await image.readAll()); -// if (imageUrl == null) { -// return; -// } - -// controller.replaceText( -// textEditingValue.selection.end, -// 0, -// BlockEmbed.image(imageUrl), -// null, -// ); -// }); -// } -// } - -// /// Select the entire text value. -// @override -// void selectAll(SelectionChangedCause cause) { -// userUpdateTextEditingValue( -// textEditingValue.copyWith( -// selection: TextSelection( -// baseOffset: 0, extentOffset: textEditingValue.text.length), -// ), -// cause, -// ); - -// if (cause == SelectionChangedCause.toolbar) { -// bringIntoView(textEditingValue.selection.extent); -// } -// } -// } diff --git a/lib/src/widgets/raw_editor/raw_editor_state.dart b/lib/src/widgets/raw_editor/raw_editor_state.dart index 702f312c..897658cc 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state.dart @@ -116,10 +116,6 @@ class QuillRawEditorState extends EditorState .call(content); } - /// Returns the [ContextMenuButtonItem]s representing the buttons in this - /// platform's default selection menu for [QuillRawEditor]. - /// - /// Copied from [EditableTextState]. // List get contextMenuButtonItems { // return EditableText.getEditableButtonItems( // clipboardStatus: _clipboardStatus.value, @@ -297,6 +293,9 @@ class QuillRawEditorState extends EditorState } } + /// Returns the [ContextMenuButtonItem]s representing the buttons in this + /// platform's default selection menu for [QuillRawEditor]. + /// Copied from [EditableTextState]. List get contextMenuButtonItems { return EditableText.getEditableButtonItems( clipboardStatus: _clipboardStatus.value, diff --git a/lib/src/widgets/raw_editor/raw_editor_state_selection_delegate_mixin.dart b/lib/src/widgets/raw_editor/raw_editor_state_selection_delegate_mixin.dart index 53f0cd6f..2b5bfa10 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state_selection_delegate_mixin.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state_selection_delegate_mixin.dart @@ -8,7 +8,7 @@ import '../../models/documents/nodes/embeddable.dart'; import '../../models/documents/nodes/leaf.dart'; import '../../models/documents/style.dart'; import '../../utils/delta.dart'; -import '../editor/editor.dart'; +import 'raw_editor.dart'; mixin RawEditorStateSelectionDelegateMixin on EditorState implements TextSelectionDelegate { diff --git a/lib/src/widgets/raw_editor/raw_editor_state_text_input_client_mixin.dart b/lib/src/widgets/raw_editor/raw_editor_state_text_input_client_mixin.dart index d41180ca..2c6a08da 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state_text_input_client_mixin.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state_text_input_client_mixin.dart @@ -10,6 +10,7 @@ import 'package:flutter/services.dart'; import '../../models/documents/document.dart'; import '../../utils/delta.dart'; import '../editor/editor.dart'; +import 'raw_editor.dart'; mixin RawEditorStateTextInputClientMixin on EditorState implements TextInputClient { diff --git a/lib/src/widgets/toolbar/base_toolbar.dart b/lib/src/widgets/toolbar/base_toolbar.dart index c2211305..33e0f127 100644 --- a/lib/src/widgets/toolbar/base_toolbar.dart +++ b/lib/src/widgets/toolbar/base_toolbar.dart @@ -20,7 +20,6 @@ export 'buttons/link_style2_button.dart'; export 'buttons/link_style_button.dart'; export 'buttons/quill_icon_button.dart'; export 'buttons/search/search_button.dart'; -export 'buttons/select_alignment_old_buttons.dart'; export 'buttons/select_header_style_buttons.dart'; export 'buttons/toggle_check_list_button.dart'; export 'buttons/toggle_style_button.dart'; diff --git a/lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart b/lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart deleted file mode 100644 index ed591389..00000000 --- a/lib/src/widgets/toolbar/buttons/select_alignment_old_buttons.dart +++ /dev/null @@ -1,283 +0,0 @@ -// import 'package:flutter/foundation.dart'; -// import 'package:flutter/material.dart'; - -// import '../../../extensions/quill_provider.dart'; -// import '../../../l10n/extensions/localizations.dart'; -// import '../../../models/documents/attribute.dart'; -// import '../../../models/documents/style.dart'; -// import '../../../models/themes/quill_icon_theme.dart'; -// import '../../../utils/widgets.dart'; -// import '../../others/controller.dart'; -// import '../base_toolbar.dart'; - -// @Deprecated('This button has been deprecated, use') -// class QuillToolbarSelectAlignmentOldButtons extends StatefulWidget { -// const QuillToolbarSelectAlignmentOldButtons({ -// required this.controller, -// this.options, -// this.showLeftAlignment, -// this.showCenterAlignment, -// this.showRightAlignment, -// this.showJustifyAlignment, -// this.padding, -// super.key, -// }); - -// final QuillController controller; -// final QuillToolbarSelectAlignmentButtonOptions options; - -// final bool? showLeftAlignment; -// final bool? showCenterAlignment; -// final bool? showRightAlignment; -// final bool? showJustifyAlignment; -// final EdgeInsetsGeometry? padding; - -// @override -// QuillToolbarSelectAlignmentOldButtonsState createState() => -// QuillToolbarSelectAlignmentOldButtonsState(); -// } - -// class QuillToolbarSelectAlignmentOldButtonsState -// extends State { -// Attribute? _value; - -// Style get _selectionStyle => controller.getSelectionStyle(); - -// @override -// void initState() { -// super.initState(); -// setState(() { -// _value = _selectionStyle.attributes[Attribute.align.key] ?? -// Attribute.leftAlignment; -// }); -// controller.addListener(_didChangeEditingValue); -// } - -// QuillToolbarSelectAlignmentButtonOptions get options { -// return widget.options; -// } - -// QuillController get controller { -// return widget.controller; -// } - -// double get _iconSize { -// final baseFontSize = baseButtonExtraOptions.globalIconSize; -// final iconSize = options.iconSize; -// return iconSize ?? baseFontSize; -// } - -// double get _iconButtonFactor { -// final baseIconFactor = baseButtonExtraOptions.globalIconButtonFactor; -// final iconButtonFactor = options.iconButtonFactor; -// return iconButtonFactor ?? baseIconFactor; -// } - -// VoidCallback? get _afterButtonPressed { -// return options.afterButtonPressed ?? -// baseButtonExtraOptions.afterButtonPressed; -// } - -// QuillIconTheme? get _iconTheme { -// return options.iconTheme ?? baseButtonExtraOptions.iconTheme; -// } - -// QuillToolbarBaseButtonOptions get baseButtonExtraOptions { -// return context.requireQuillToolbarBaseButtonOptions; -// } - -// QuillSelectAlignmentValues get _iconsData { -// final iconsData = options.iconsData; -// if (iconsData != null) { -// return iconsData; -// } -// final baseIconData = baseButtonExtraOptions.iconData; -// if (baseIconData != null) { -// return QuillSelectAlignmentValues( -// leftAlignment: baseIconData, -// centerAlignment: baseIconData, -// rightAlignment: baseIconData, -// justifyAlignment: baseIconData, -// ); -// } -// return const QuillSelectAlignmentValues( -// leftAlignment: Icons.format_align_left, -// centerAlignment: Icons.format_align_center, -// rightAlignment: Icons.format_align_right, -// justifyAlignment: Icons.format_align_justify, -// ); -// } - -// QuillSelectAlignmentValues get _tooltips { -// final tooltips = options.tooltips; -// if (tooltips != null) { -// return tooltips; -// } -// final baseToolTip = baseButtonExtraOptions.tooltip; -// if (baseToolTip != null) { -// return QuillSelectAlignmentValues( -// leftAlignment: baseToolTip, -// centerAlignment: baseToolTip, -// rightAlignment: baseToolTip, -// justifyAlignment: baseToolTip, -// ); -// } -// return QuillSelectAlignmentValues( -// leftAlignment: context.loc.alignLeft, -// centerAlignment: context.loc.alignCenter, -// rightAlignment: context.loc.alignRight, -// justifyAlignment: context.loc.justifyWinWidth, -// ); -// } - -// void _didChangeEditingValue() { -// setState(() { -// _value = _selectionStyle.attributes[Attribute.align.key] ?? -// Attribute.leftAlignment; -// }); -// } - -// @override -// void didUpdateWidget( -// covariant QuillToolbarSelectAlignmentOldButtons oldWidget) { -// super.didUpdateWidget(oldWidget); -// if (oldWidget.controller != controller) { -// oldWidget.controller.removeListener(_didChangeEditingValue); -// controller.addListener(_didChangeEditingValue); -// _value = _selectionStyle.attributes[Attribute.align.key] ?? -// Attribute.leftAlignment; -// } -// } - -// @override -// void dispose() { -// controller.removeListener(_didChangeEditingValue); -// super.dispose(); -// } - -// @override -// Widget build(BuildContext context) { -// final valueToText = { -// if (widget.showLeftAlignment!) -// Attribute.leftAlignment: Attribute.leftAlignment.value!, -// if (widget.showCenterAlignment!) -// Attribute.centerAlignment: Attribute.centerAlignment.value!, -// if (widget.showRightAlignment!) -// Attribute.rightAlignment: Attribute.rightAlignment.value!, -// if (widget.showJustifyAlignment!) -// Attribute.justifyAlignment: Attribute.justifyAlignment.value!, -// }; - -// final valueAttribute = [ -// if (widget.showLeftAlignment!) Attribute.leftAlignment, -// if (widget.showCenterAlignment!) Attribute.centerAlignment, -// if (widget.showRightAlignment!) Attribute.rightAlignment, -// if (widget.showJustifyAlignment!) Attribute.justifyAlignment -// ]; -// final valueString = [ -// if (widget.showLeftAlignment!) Attribute.leftAlignment.value!, -// if (widget.showCenterAlignment!) Attribute.centerAlignment.value!, -// if (widget.showRightAlignment!) Attribute.rightAlignment.value!, -// if (widget.showJustifyAlignment!) Attribute.justifyAlignment.value!, -// ]; -// // final _valueToButtons = { -// // if (widget.showLeftAlignment!) -// // Attribute.leftAlignment: ToolbarButtons.leftAlignment, -// // if (widget.showCenterAlignment!) -// // Attribute.centerAlignment: ToolbarButtons.centerAlignment, -// // if (widget.showRightAlignment!) -// // Attribute.rightAlignment: ToolbarButtons.rightAlignment, -// // if (widget.showJustifyAlignment!) -// // Attribute.justifyAlignment: ToolbarButtons.justifyAlignment, -// // }; - -// final buttonCount = ((widget.showLeftAlignment!) ? 1 : 0) + -// ((widget.showCenterAlignment!) ? 1 : 0) + -// ((widget.showRightAlignment!) ? 1 : 0) + -// ((widget.showJustifyAlignment!) ? 1 : 0); - -// final childBuilder = -// options.childBuilder ?? baseButtonExtraOptions.childBuilder; - -// void sharedOnPressed(int index) { -// valueAttribute[index] == Attribute.leftAlignment -// ? controller.formatSelection( -// Attribute.clone(Attribute.align, null), -// ) -// : controller.formatSelection(valueAttribute[index]); -// _afterButtonPressed?.call(); -// } - -// return Row( -// mainAxisSize: MainAxisSize.min, -// children: List.generate(buttonCount, (index) { -// if (childBuilder != null) { -// return childBuilder( -// QuillToolbarSelectAlignmentButtonOptions( -// afterButtonPressed: _afterButtonPressed, -// iconSize: _iconSize, -// iconButtonFactor: _iconButtonFactor, -// iconTheme: _iconTheme, -// tooltips: _tooltips, -// iconsData: _iconsData, -// ), -// QuillToolbarSelectAlignmentButtonExtraOptions( -// context: context, -// controller: controller, -// onPressed: () => sharedOnPressed(index), -// ), -// ); -// } -// final theme = Theme.of(context); -// return Padding( -// padding: widget.padding ?? -// const EdgeInsets.symmetric(horizontal: !kIsWeb ? 1.0 : 5.0), -// child: ConstrainedBox( -// constraints: BoxConstraints.tightFor( -// width: _iconSize * _iconButtonFactor, -// height: _iconSize * _iconButtonFactor, -// ), -// child: UtilityWidgets.maybeTooltip( -// message: valueString[index] == Attribute.leftAlignment.value -// ? _tooltips.leftAlignment -// : valueString[index] == Attribute.centerAlignment.value -// ? _tooltips.centerAlignment -// : valueString[index] == Attribute.rightAlignment.value -// ? _tooltips.rightAlignment -// : _tooltips.justifyAlignment, -// child: RawMaterialButton( -// hoverElevation: 0, -// highlightElevation: 0, -// elevation: 0, -// visualDensity: VisualDensity.compact, -// shape: RoundedRectangleBorder( -// borderRadius: -// BorderRadius.circular(_iconTheme?.borderRadius ?? 2)), -// fillColor: valueToText[_value] == valueString[index] -// ? (_iconTheme?.iconSelectedFillColor ?? theme.primaryColor) -// : (_iconTheme?.iconUnselectedFillColor ?? -// theme.canvasColor), -// onPressed: () => sharedOnPressed(index), -// child: Icon( -// valueString[index] == Attribute.leftAlignment.value -// ? _iconsData.leftAlignment -// : valueString[index] == Attribute.centerAlignment.value -// ? _iconsData.centerAlignment -// : valueString[index] == Attribute.rightAlignment.value -// ? _iconsData.rightAlignment -// : _iconsData.justifyAlignment, -// size: _iconSize, -// color: valueToText[_value] == valueString[index] -// ? (_iconTheme?.iconSelectedColor ?? -// theme.primaryIconTheme.color) -// : (_iconTheme?.iconUnselectedColor ?? -// theme.iconTheme.color), -// ), -// ), -// ), -// ), -// ); -// }), -// ); -// } -// } diff --git a/lib/src/widgets/toolbar/buttons/select_header_style_button.dart b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart index 32140602..59f66d8d 100644 --- a/lib/src/widgets/toolbar/buttons/select_header_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/select_header_style_button.dart @@ -37,8 +37,12 @@ class _QuillToolbarSelectHeaderStyleButtonState } void _didChangeEditingValue() { + final newSelectedItem = _getOptionsItemByAttribute(_getHeaderValue()); + if (newSelectedItem == _selectedItem) { + return; + } setState(() { - _selectedItem = _getOptionsItemByAttribute(_getHeaderValue()); + _selectedItem = newSelectedItem; }); }