From 9044e2ad493e822b3bc59a5c1f8f03749eb0f36d Mon Sep 17 00:00:00 2001 From: D Brezack Date: Fri, 26 Apr 2024 16:45:11 -0700 Subject: [PATCH 1/4] fix: MD Parsing for multi space (#1828) * Fixing MD Parsing for multi space * Fixing lint --- lib/src/packages/quill_markdown/markdown_to_delta.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/src/packages/quill_markdown/markdown_to_delta.dart b/lib/src/packages/quill_markdown/markdown_to_delta.dart index 76285a15..53194f77 100644 --- a/lib/src/packages/quill_markdown/markdown_to_delta.dart +++ b/lib/src/packages/quill_markdown/markdown_to_delta.dart @@ -117,9 +117,7 @@ class MarkdownToDelta extends Converter _justPreviousBlockExit = false; _listItemIndent = -1; - final lines = const LineSplitter().convert(input); - final mdNodes = markdownDocument.parseLines(lines); - + final mdNodes = markdownDocument.parseInline(input); _topLevelNodes.addAll(mdNodes); for (final node in mdNodes) { From 08d2a2e4f25577871dd29f38f5e1e011d6ef0661 Mon Sep 17 00:00:00 2001 From: AtlasAutocode <165201146+AtlasAutocode@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:45:50 -0600 Subject: [PATCH 2/4] fix: FontFamily and FontSize toolbars track the text selected in the editor. (#1829) * toggle_style_button : calls to options.afterButtonPressed replaced by call to class function afterButtonPressed to allow default call to base button settings quill_icon_button: L26 build for isSelected updated to call afterButtonPressed = same as if not selected QuillController _updateSelection removed param=source because not used; added new param insertNewline when true set tog to style of preceding char (last entered); updated replaceText to call _updateSelection for NL document collectStyle: Selecting the start of a line, user expects the style to be the visible style of the line including inline styles * color_button calls afterButtonPressed insert at start of line uses style for line * Remove comments * Fix formatting issue * Fix FontFamily and Size button actions * Fix FontFamily and Size button actions * Value setting Stateful toolbar buttons derive from base class * Rename base class as QuillToolbarBaseValueButton * Fixes for before_push script * Removed deprecated functions --------- Co-authored-by: Douglas Ward --- .../lib/screens/quill/my_quill_toolbar.dart | 6 +- lib/src/widgets/quill/quill_controller.dart | 35 ----- .../base_button/base_value_button.dart | 98 ++++++++++++++ .../toolbar/buttons/font_family_button.dart | 121 ++++-------------- .../toolbar/buttons/font_size_button.dart | 92 ++++--------- .../buttons/toggle_check_list_button.dart | 96 +++----------- .../toolbar/buttons/toggle_style_button.dart | 96 +++----------- 7 files changed, 184 insertions(+), 360 deletions(-) create mode 100644 lib/src/widgets/toolbar/base_button/base_value_button.dart diff --git a/example/lib/screens/quill/my_quill_toolbar.dart b/example/lib/screens/quill/my_quill_toolbar.dart index 5acfb2de..7e177956 100644 --- a/example/lib/screens/quill/my_quill_toolbar.dart +++ b/example/lib/screens/quill/my_quill_toolbar.dart @@ -225,7 +225,7 @@ class MyQuillToolbar extends StatelessWidget { // headerStyleType: HeaderStyleType.buttons, // buttonOptions: QuillSimpleToolbarButtonOptions( // base: QuillToolbarBaseButtonOptions( - // afterButtonPressed: focusNode.requestFocus, + // afterButtonPressed: focusNode.requestFocus, // // iconSize: 20, // iconTheme: QuillIconTheme( // iconButtonSelectedData: IconButtonData( @@ -239,8 +239,8 @@ class MyQuillToolbar extends StatelessWidget { // ), // ), // ), - // ), - // ), + // ), + //), customButtons: [ QuillToolbarCustomButtonOptions( icon: const Icon(Icons.add_alarm_rounded), diff --git a/lib/src/widgets/quill/quill_controller.dart b/lib/src/widgets/quill/quill_controller.dart index ebbaa7d6..1a2634e4 100644 --- a/lib/src/widgets/quill/quill_controller.dart +++ b/lib/src/widgets/quill/quill_controller.dart @@ -14,7 +14,6 @@ import '../../models/structs/doc_change.dart'; import '../../models/structs/image_url.dart'; import '../../models/structs/offset_value.dart'; import '../../utils/delta.dart'; -import '../toolbar/buttons/toggle_style_button.dart'; typedef ReplaceTextCallback = bool Function(int index, int len, Object? data); typedef DeleteCallback = void Function(int cursorPosition, bool forward); @@ -67,40 +66,6 @@ class QuillController extends ChangeNotifier { notifyListeners(); } - // Thoses are the values that the user selects and not the one - // from the current line - - /// The current font family, null to use the default one - MapEntry? _selectedFontFamily; - - /// The current font family, null to use the default one - MapEntry? get selectedFontFamily => _selectedFontFamily; - - void selectFontFamily(MapEntry? newFontFamily) { - _selectedFontFamily = newFontFamily; - } - - /// The current font size, null to use the default one - MapEntry? _selectedFontSize; - - /// The current font size, null to use the default one - MapEntry? get selectedFontSize => _selectedFontSize; - - void selectFontSize(MapEntry? newFontSize) { - _selectedFontSize = newFontSize; - } - - /// For the [QuillToolbarToggleStyleButton] - final Map _selectedStyles = {}; - - /// For the [QuillToolbarToggleStyleButton] - Map get selectedStyles => _selectedStyles; - - /// For the [QuillToolbarToggleStyleButton] - void selectStyle(Attribute attribute, bool value) { - _selectedStyles[attribute] = value; - } - /// Tells whether to keep or reset the [toggledStyle] /// when user adds a new line. final bool keepStyleOnNewLine; diff --git a/lib/src/widgets/toolbar/base_button/base_value_button.dart b/lib/src/widgets/toolbar/base_button/base_value_button.dart new file mode 100644 index 00000000..3c2b8046 --- /dev/null +++ b/lib/src/widgets/toolbar/base_button/base_value_button.dart @@ -0,0 +1,98 @@ +import 'package:flutter/material.dart'; + +import '../../../../flutter_quill.dart'; + +/// The [T] is the options for the button +/// The [E] is the extra options for the button +abstract class QuillToolbarBaseValueButton< + T extends QuillToolbarBaseButtonOptions, + E extends QuillToolbarBaseButtonExtraOptions> extends StatefulWidget { + const QuillToolbarBaseValueButton( + {required this.controller, required this.options, super.key}); + + final T options; + + final QuillController controller; +} + +/// The [W] is the widget that creates this State +/// The [V] is the type of the currentValue +abstract class QuillToolbarBaseValueButtonState< + W extends QuillToolbarBaseValueButton, + T extends QuillToolbarBaseButtonOptions, + E extends QuillToolbarBaseButtonExtraOptions, + V> extends State { + T get options => widget.options; + + QuillController get controller => widget.controller; + + late V currentValue; + + /// Callback to query the widget's state for the value to be assigned to currentState + V get currentStateValue; + + @override + void initState() { + super.initState(); + controller.addListener(didChangeEditingValue); + } + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + currentValue = currentStateValue; + } + + void didChangeEditingValue() { + setState(() => currentValue = currentStateValue); + } + + @override + void dispose() { + controller.removeListener(didChangeEditingValue); + super.dispose(); + } + + @override + void didUpdateWidget(covariant W oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.controller != controller) { + oldWidget.controller.removeListener(didChangeEditingValue); + controller.addListener(didChangeEditingValue); + currentValue = currentStateValue; + } + } + + String get defaultTooltip; + + String get tooltip { + return options.tooltip ?? + context.quillToolbarBaseButtonOptions?.tooltip ?? + defaultTooltip; + } + + double get iconSize { + final baseFontSize = baseButtonExtraOptions?.iconSize; + final iconSize = options.iconSize; + return iconSize ?? baseFontSize ?? kDefaultIconSize; + } + + double get iconButtonFactor { + final baseIconFactor = baseButtonExtraOptions?.iconButtonFactor; + final iconButtonFactor = options.iconButtonFactor; + return iconButtonFactor ?? baseIconFactor ?? kDefaultIconButtonFactor; + } + + QuillIconTheme? get iconTheme { + return options.iconTheme ?? baseButtonExtraOptions?.iconTheme; + } + + QuillToolbarBaseButtonOptions? get baseButtonExtraOptions { + return context.quillToolbarBaseButtonOptions; + } + + VoidCallback? get afterButtonPressed { + return options.afterButtonPressed ?? + baseButtonExtraOptions?.afterButtonPressed; + } +} diff --git a/lib/src/widgets/toolbar/buttons/font_family_button.dart b/lib/src/widgets/toolbar/buttons/font_family_button.dart index a8ba667b..10cf8712 100644 --- a/lib/src/widgets/toolbar/buttons/font_family_button.dart +++ b/lib/src/widgets/toolbar/buttons/font_family_button.dart @@ -4,55 +4,43 @@ import '../../../../extensions.dart'; import '../../../extensions/quill_configurations_ext.dart'; import '../../../l10n/extensions/localizations.dart'; import '../../../models/documents/attribute.dart'; -import '../../../models/themes/quill_icon_theme.dart'; -import '../../quill/quill_controller.dart'; +import '../base_button/base_value_button.dart'; import '../base_toolbar.dart'; -class QuillToolbarFontFamilyButton extends StatefulWidget { +class QuillToolbarFontFamilyButton extends QuillToolbarBaseValueButton< + QuillToolbarFontFamilyButtonOptions, + QuillToolbarFontFamilyButtonExtraOptions> { QuillToolbarFontFamilyButton({ - required this.controller, + required super.controller, @Deprecated('Please use the default display text from the options') this.defaultDisplayText, - this.options = const QuillToolbarFontFamilyButtonOptions(), + super.options = const QuillToolbarFontFamilyButtonOptions(), super.key, }) : assert(options.rawItemsMap?.isNotEmpty ?? (true)), assert( options.initialValue == null || options.initialValue!.isNotEmpty, ); - final QuillToolbarFontFamilyButtonOptions options; - final String? defaultDisplayText; - /// Since we can't get the state from the instace of the widget for comparing - /// in [didUpdateWidget] then we will have to store reference here - final QuillController controller; - @override QuillToolbarFontFamilyButtonState createState() => QuillToolbarFontFamilyButtonState(); } class QuillToolbarFontFamilyButtonState - extends State { - var _currentValue = ''; - - QuillToolbarFontFamilyButtonOptions get options { - return widget.options; - } - - @override - void initState() { - super.initState(); - _initState(); - } - - void _initState() {} - + extends QuillToolbarBaseValueButtonState< + QuillToolbarFontFamilyButton, + QuillToolbarFontFamilyButtonOptions, + QuillToolbarFontFamilyButtonExtraOptions, + String> { @override - void didChangeDependencies() { - super.didChangeDependencies(); - _currentValue = _defaultDisplayText; + String get currentStateValue { + final attribute = + controller.getSelectionStyle().attributes[options.attribute.key]; + return attribute == null + ? _defaultDisplayText + : (_getKeyName(attribute.value) ?? _defaultDisplayText); } String get _defaultDisplayText { @@ -62,27 +50,6 @@ class QuillToolbarFontFamilyButtonState context.loc.font; } - // @override - // void didUpdateWidget(covariant QuillToolbarFontFamilyButton oldWidget) { - // super.didUpdateWidget(oldWidget); - // if (oldWidget.controller == controller) { - // return; - // } - // controller - // ..removeListener(_didChangeEditingValue) - // ..addListener(_didChangeEditingValue); - // } - - // void _didChangeEditingValue() { - // final attribute = _selectionStyle.attributes[options.attribute.key]; - // if (attribute == null) { - // setState(() => _currentValue = _defaultDisplayText); - // return; - // } - // final keyName = _getKeyName(attribute.value); - // setState(() => _currentValue = keyName ?? _defaultDisplayText); - // } - Map get rawItemsMap { final rawItemsMap = context.quillSimpleToolbarConfigurations?.fontFamilyValues ?? @@ -110,38 +77,8 @@ class QuillToolbarFontFamilyButtonState return null; } - QuillController get controller { - return widget.controller; - } - - double get iconSize { - final baseFontSize = context.quillToolbarBaseButtonOptions?.iconSize; - final iconSize = options.iconSize; - return iconSize ?? baseFontSize ?? kDefaultIconSize; - } - - double get iconButtonFactor { - final baseIconFactor = - context.quillToolbarBaseButtonOptions?.iconButtonFactor; - final iconButtonFactor = widget.options.iconButtonFactor; - return iconButtonFactor ?? baseIconFactor ?? kDefaultIconButtonFactor; - } - - VoidCallback? get afterButtonPressed { - return options.afterButtonPressed ?? - context.quillToolbarBaseButtonOptions?.afterButtonPressed; - } - - QuillIconTheme? get iconTheme { - return options.iconTheme ?? - context.quillToolbarBaseButtonOptions?.iconTheme; - } - - String get tooltip { - return options.tooltip ?? - context.quillToolbarBaseButtonOptions?.tooltip ?? - context.loc.fontFamily; - } + @override + String get defaultTooltip => context.loc.fontFamily; void _onPressed() { if (_menuController.isOpen) { @@ -149,7 +86,7 @@ class QuillToolbarFontFamilyButtonState } else { _menuController.open(); } - options.afterButtonPressed?.call(); + afterButtonPressed?.call(); } final _menuController = MenuController(); @@ -163,7 +100,7 @@ class QuillToolbarFontFamilyButtonState return childBuilder( options, QuillToolbarFontFamilyButtonExtraOptions( - currentValue: _currentValue, + currentValue: currentValue, defaultDisplayText: _defaultDisplayText, controller: controller, context: context, @@ -177,8 +114,8 @@ class QuillToolbarFontFamilyButtonState var effectiveTooltip = tooltip; if (options.overrideTooltipByFontFamily) { effectiveTooltip = effectiveTooltip.isNotEmpty - ? '$effectiveTooltip: $_currentValue' - : '${context.loc.font}: $_currentValue'; + ? '$effectiveTooltip: $currentValue' + : '${context.loc.font}: $currentValue'; } return Tooltip(message: effectiveTooltip, child: child); }, @@ -196,9 +133,9 @@ class QuillToolbarFontFamilyButtonState final keyName = _getKeyName(newValue); setState(() { if (keyName != 'Clear') { - _currentValue = keyName ?? _defaultDisplayText; + currentValue = keyName ?? _defaultDisplayText; } else { - _currentValue = _defaultDisplayText; + currentValue = _defaultDisplayText; } if (keyName != null) { controller.formatSelection( @@ -210,12 +147,6 @@ class QuillToolbarFontFamilyButtonState options.onSelected?.call(newValue); } }); - - if (fontFamily.value == 'Clear') { - controller.selectFontFamily(null); - return; - } - controller.selectFontFamily(fontFamily); }, child: Text( fontFamily.key.toString(), @@ -262,7 +193,7 @@ class QuillToolbarFontFamilyButtonState enabled: hasFinalWidth, wrapper: (child) => Expanded(child: child), child: Text( - widget.controller.selectedFontFamily?.key ?? _currentValue, + currentValue, maxLines: 1, overflow: options.labelOverflow, style: options.style ?? diff --git a/lib/src/widgets/toolbar/buttons/font_size_button.dart b/lib/src/widgets/toolbar/buttons/font_size_button.dart index 17807c47..71a6bfcc 100644 --- a/lib/src/widgets/toolbar/buttons/font_size_button.dart +++ b/lib/src/widgets/toolbar/buttons/font_size_button.dart @@ -5,43 +5,35 @@ import '../../../../extensions.dart'; import '../../../extensions/quill_configurations_ext.dart'; import '../../../l10n/extensions/localizations.dart'; import '../../../models/documents/attribute.dart'; -import '../../../models/themes/quill_icon_theme.dart'; import '../../../utils/font.dart'; -import '../../quill/quill_controller.dart'; +import '../base_button/base_value_button.dart'; import '../base_toolbar.dart'; -class QuillToolbarFontSizeButton extends StatefulWidget { +class QuillToolbarFontSizeButton extends QuillToolbarBaseValueButton< + QuillToolbarFontSizeButtonOptions, QuillToolbarFontSizeButtonExtraOptions> { QuillToolbarFontSizeButton({ - required this.controller, + required super.controller, @Deprecated('Please use the default display text from the options') this.defaultDisplayText, - this.options = const QuillToolbarFontSizeButtonOptions(), + super.options = const QuillToolbarFontSizeButtonOptions(), super.key, }) : assert(options.rawItemsMap?.isNotEmpty ?? true), assert(options.initialValue == null || (options.initialValue?.isNotEmpty ?? true)); - final QuillToolbarFontSizeButtonOptions options; - final String? defaultDisplayText; - /// Since we can't get the state from the instace of the widget for comparing - /// in [didUpdateWidget] then we will have to store reference here - final QuillController controller; - @override QuillToolbarFontSizeButtonState createState() => QuillToolbarFontSizeButtonState(); } -class QuillToolbarFontSizeButtonState - extends State { +class QuillToolbarFontSizeButtonState extends QuillToolbarBaseValueButtonState< + QuillToolbarFontSizeButton, + QuillToolbarFontSizeButtonOptions, + QuillToolbarFontSizeButtonExtraOptions, + String> { final _menuController = MenuController(); - String _currentValue = ''; - - QuillToolbarFontSizeButtonOptions get options { - return widget.options; - } Map get rawItemsMap { final fontSizes = options.rawItemsMap ?? @@ -73,14 +65,12 @@ class QuillToolbarFontSizeButtonState } @override - void didChangeDependencies() { - super.didChangeDependencies(); - _currentValue = _defaultDisplayText; - } - - @override - void dispose() { - super.dispose(); + String get currentStateValue { + final attribute = + controller.getSelectionStyle().attributes[options.attribute.key]; + return attribute == null + ? _defaultDisplayText + : (_getKeyName(attribute.value) ?? _defaultDisplayText); } String? _getKeyName(dynamic value) { @@ -92,38 +82,8 @@ class QuillToolbarFontSizeButtonState return null; } - QuillController get controller { - return widget.controller; - } - - double get iconSize { - final baseFontSize = context.quillToolbarBaseButtonOptions?.iconSize; - final iconSize = options.iconSize; - return iconSize ?? baseFontSize ?? kDefaultIconSize; - } - - double get iconButtonFactor { - final baseIconFactor = - context.quillToolbarBaseButtonOptions?.iconButtonFactor; - final iconButtonFactor = options.iconButtonFactor; - return iconButtonFactor ?? baseIconFactor ?? kDefaultIconButtonFactor; - } - - VoidCallback? get afterButtonPressed { - return options.afterButtonPressed ?? - context.quillToolbarBaseButtonOptions?.afterButtonPressed; - } - - QuillIconTheme? get iconTheme { - return options.iconTheme ?? - context.quillToolbarBaseButtonOptions?.iconTheme; - } - - String get tooltip { - return options.tooltip ?? - context.quillToolbarBaseButtonOptions?.tooltip ?? - context.loc.fontSize; - } + @override + String get defaultTooltip => context.loc.fontSize; void _onDropdownButtonPressed() { if (_menuController.isOpen) { @@ -144,7 +104,7 @@ class QuillToolbarFontSizeButtonState options, QuillToolbarFontSizeButtonExtraOptions( controller: controller, - currentValue: _currentValue, + currentValue: currentValue, defaultDisplayText: _defaultDisplayText, context: context, onPressed: _onDropdownButtonPressed, @@ -162,9 +122,9 @@ class QuillToolbarFontSizeButtonState final keyName = _getKeyName(newValue); setState(() { if (keyName != context.loc.clear) { - _currentValue = keyName ?? _defaultDisplayText; + currentValue = keyName ?? _defaultDisplayText; } else { - _currentValue = _defaultDisplayText; + currentValue = _defaultDisplayText; } if (keyName != null) { controller.formatSelection( @@ -176,12 +136,6 @@ class QuillToolbarFontSizeButtonState options.onSelected?.call(newValue); } }); - - if (fontSize.value == '0') { - controller.selectFontSize(null); - return; - } - controller.selectFontSize(fontSize); }, child: Text( fontSize.key.toString(), @@ -224,9 +178,7 @@ class QuillToolbarFontSizeButtonState enabled: hasFinalWidth, wrapper: (child) => Expanded(child: child), child: Text( - getLabel(widget.controller.selectedFontSize?.key) ?? - getLabel(_currentValue) ?? - '', + getLabel(currentValue) ?? '', overflow: options.labelOverflow, style: options.style ?? TextStyle( diff --git a/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart b/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart index 83679798..00a46db3 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart @@ -1,48 +1,36 @@ import 'package:flutter/material.dart'; -import '../../../extensions/quill_configurations_ext.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 '../../quill/quill_controller.dart'; +import '../base_button/base_value_button.dart'; import '../base_toolbar.dart'; -class QuillToolbarToggleCheckListButton extends StatefulWidget { +class QuillToolbarToggleCheckListButton extends QuillToolbarBaseValueButton< + QuillToolbarToggleCheckListButtonOptions, + QuillToolbarToggleCheckListButtonExtraOptions> { const QuillToolbarToggleCheckListButton({ - required this.controller, - this.options = const QuillToolbarToggleCheckListButtonOptions(), + required super.controller, + super.options = const QuillToolbarToggleCheckListButtonOptions(), super.key, }); - final QuillToolbarToggleCheckListButtonOptions options; - - final QuillController controller; - @override QuillToolbarToggleCheckListButtonState createState() => QuillToolbarToggleCheckListButtonState(); } class QuillToolbarToggleCheckListButtonState - extends State { - bool? _isToggled; - + extends QuillToolbarBaseValueButtonState< + QuillToolbarToggleCheckListButton, + QuillToolbarToggleCheckListButtonOptions, + QuillToolbarToggleCheckListButtonExtraOptions, + bool> { Style get _selectionStyle => controller.getSelectionStyle(); - void _didChangeEditingValue() { - setState(() { - _isToggled = _getIsToggled(controller.getSelectionStyle().attributes); - }); - } - @override - void initState() { - super.initState(); - _isToggled = _getIsToggled(_selectionStyle.attributes); - controller.addListener(_didChangeEditingValue); - } + bool get currentStateValue => _getIsToggled(_selectionStyle.attributes); bool _getIsToggled(Map attrs) { var attribute = controller.toolbarButtonToggler[Attribute.list.key]; @@ -62,53 +50,7 @@ class QuillToolbarToggleCheckListButtonState } @override - void didUpdateWidget(covariant QuillToolbarToggleCheckListButton oldWidget) { - super.didUpdateWidget(oldWidget); - if (oldWidget.controller != controller) { - oldWidget.controller.removeListener(_didChangeEditingValue); - controller.addListener(_didChangeEditingValue); - _isToggled = _getIsToggled(_selectionStyle.attributes); - } - } - - @override - void dispose() { - controller.removeListener(_didChangeEditingValue); - super.dispose(); - } - - QuillToolbarToggleCheckListButtonOptions get options { - return widget.options; - } - - QuillController get controller { - return widget.controller; - } - - double get iconSize { - final baseFontSize = baseButtonExtraOptions?.iconSize; - final iconSize = options.iconSize; - return iconSize ?? baseFontSize ?? kDefaultIconSize; - } - - double get iconButtonFactor { - final baseIconFactor = baseButtonExtraOptions?.iconButtonFactor; - final iconButtonFactor = options.iconButtonFactor; - return iconButtonFactor ?? baseIconFactor ?? kDefaultIconButtonFactor; - } - - VoidCallback? get afterButtonPressed { - return options.afterButtonPressed ?? - baseButtonExtraOptions?.afterButtonPressed; - } - - QuillIconTheme? get iconTheme { - return options.iconTheme ?? baseButtonExtraOptions?.iconTheme; - } - - QuillToolbarBaseButtonOptions? get baseButtonExtraOptions { - return context.quillToolbarBaseButtonOptions; - } + String get defaultTooltip => context.loc.checkedList; IconData get iconData { return options.iconData ?? @@ -116,12 +58,6 @@ class QuillToolbarToggleCheckListButtonState Icons.check_box; } - String get tooltip { - return options.tooltip ?? - baseButtonExtraOptions?.tooltip ?? - context.loc.checkedList; - } - @override Widget build(BuildContext context) { final childBuilder = @@ -136,7 +72,7 @@ class QuillToolbarToggleCheckListButtonState _toggleAttribute(); afterButtonPressed?.call(); }, - isToggled: _isToggled ?? false, + isToggled: currentValue, ), ); } @@ -146,7 +82,7 @@ class QuillToolbarToggleCheckListButtonState context, Attribute.unchecked, iconData, - _isToggled, + currentValue, _toggleAttribute, afterButtonPressed, iconSize, @@ -160,7 +96,7 @@ class QuillToolbarToggleCheckListButtonState controller ..skipRequestKeyboard = !options.isShouldRequestKeyboard ..formatSelection( - _isToggled! + currentValue ? Attribute.clone(Attribute.unchecked, null) : Attribute.unchecked, ); diff --git a/lib/src/widgets/toolbar/buttons/toggle_style_button.dart b/lib/src/widgets/toolbar/buttons/toggle_style_button.dart index 6447bffd..fa065190 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_style_button.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_style_button.dart @@ -6,7 +6,7 @@ import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../../../utils/widgets.dart'; -import '../../quill/quill_controller.dart'; +import '../base_button/base_value_button.dart'; import '../base_toolbar.dart'; typedef ToggleStyleButtonBuilder = Widget Function( @@ -20,68 +20,33 @@ typedef ToggleStyleButtonBuilder = Widget Function( QuillIconTheme? iconTheme, ]); -class QuillToolbarToggleStyleButton extends StatefulWidget { +class QuillToolbarToggleStyleButton extends QuillToolbarBaseValueButton< + QuillToolbarToggleStyleButtonOptions, + QuillToolbarToggleStyleButtonExtraOptions> { const QuillToolbarToggleStyleButton({ - required this.controller, + required super.controller, required this.attribute, - this.options = const QuillToolbarToggleStyleButtonOptions(), + super.options = const QuillToolbarToggleStyleButtonOptions(), super.key, }); final Attribute attribute; - final QuillToolbarToggleStyleButtonOptions options; - - final QuillController controller; - @override QuillToolbarToggleStyleButtonState createState() => QuillToolbarToggleStyleButtonState(); } class QuillToolbarToggleStyleButtonState - extends State { - bool? _isToggled; - + extends QuillToolbarBaseValueButtonState< + QuillToolbarToggleStyleButton, + QuillToolbarToggleStyleButtonOptions, + QuillToolbarToggleStyleButtonExtraOptions, + bool> { Style get _selectionStyle => controller.getSelectionStyle(); - QuillToolbarToggleStyleButtonOptions get options { - return widget.options; - } - @override - void initState() { - super.initState(); - _isToggled = _getIsToggled(_selectionStyle.attributes); - controller.addListener(_didChangeEditingValue); - } - - QuillController get controller { - return widget.controller; - } - - double get iconSize { - final baseFontSize = context.quillToolbarBaseButtonOptions?.iconSize; - final iconSize = options.iconSize; - return iconSize ?? baseFontSize ?? kDefaultIconSize; - } - - double get iconButtonFactor { - final baseIconFactor = - context.quillToolbarBaseButtonOptions?.iconButtonFactor; - final iconButtonFactor = options.iconButtonFactor; - return iconButtonFactor ?? baseIconFactor ?? kDefaultIconButtonFactor; - } - - VoidCallback? get afterButtonPressed { - return options.afterButtonPressed ?? - context.quillToolbarBaseButtonOptions?.afterButtonPressed; - } - - QuillIconTheme? get iconTheme { - return options.iconTheme ?? - context.quillToolbarBaseButtonOptions?.iconTheme; - } + bool get currentStateValue => _getIsToggled(_selectionStyle.attributes); (String, IconData) get _defaultTooltipAndIconData { switch (widget.attribute.key) { @@ -133,11 +98,8 @@ class QuillToolbarToggleStyleButtonState } } - String? get tooltip { - return options.tooltip ?? - context.quillToolbarBaseButtonOptions?.tooltip ?? - _defaultTooltipAndIconData.$1; - } + @override + String get defaultTooltip => _defaultTooltipAndIconData.$1; IconData get iconData { return options.iconData ?? @@ -161,7 +123,7 @@ class QuillToolbarToggleStyleButtonState context: context, controller: controller, onPressed: _onPressed, - isToggled: _isToggled ?? false, + isToggled: currentValue, ), ); } @@ -171,7 +133,7 @@ class QuillToolbarToggleStyleButtonState context, widget.attribute, iconData, - _isToggled, + currentValue, _toggleAttribute, afterButtonPressed, iconSize, @@ -181,26 +143,6 @@ class QuillToolbarToggleStyleButtonState ); } - @override - void didUpdateWidget(covariant QuillToolbarToggleStyleButton oldWidget) { - super.didUpdateWidget(oldWidget); - if (oldWidget.controller != controller) { - oldWidget.controller.removeListener(_didChangeEditingValue); - controller.addListener(_didChangeEditingValue); - _isToggled = _getIsToggled(_selectionStyle.attributes); - } - } - - @override - void dispose() { - controller.removeListener(_didChangeEditingValue); - super.dispose(); - } - - void _didChangeEditingValue() { - setState(() => _isToggled = _getIsToggled(_selectionStyle.attributes)); - } - bool _getIsToggled(Map attrs) { if (widget.attribute.key == Attribute.list.key || widget.attribute.key == Attribute.script.key || @@ -216,12 +158,12 @@ class QuillToolbarToggleStyleButtonState void _toggleAttribute() { controller + ..skipRequestKeyboard = !widget.attribute.isInline ..formatSelection( - (_isToggled ?? false) + currentValue ? Attribute.clone(widget.attribute, null) : widget.attribute, - ) - ..selectStyle(widget.attribute, _isToggled ?? false); + ); } } From 75d3b806fccc8d8f6c72d01e4ffd2c7974b48dd9 Mon Sep 17 00:00:00 2001 From: gklamm Date: Sat, 27 Apr 2024 01:46:01 +0200 Subject: [PATCH 3/4] Add checkBoxReadOnly property (#1836) --- .../models/config/editor/editor_configurations.dart | 12 ++++++++++++ .../config/raw_editor/raw_editor_configurations.dart | 10 ++++++++++ lib/src/widgets/editor/editor.dart | 1 + lib/src/widgets/quill/text_block.dart | 4 +++- lib/src/widgets/raw_editor/raw_editor_state.dart | 4 +++- 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/src/models/config/editor/editor_configurations.dart b/lib/src/models/config/editor/editor_configurations.dart index cb64336a..d3f72b0c 100644 --- a/lib/src/models/config/editor/editor_configurations.dart +++ b/lib/src/models/config/editor/editor_configurations.dart @@ -33,6 +33,7 @@ class QuillEditorConfigurations extends Equatable { this.expands = false, this.placeholder, this.readOnly = false, + this.checkBoxReadOnly, this.disableClipboard = false, this.textSelectionThemeData, this.showCursor, @@ -97,6 +98,15 @@ class QuillEditorConfigurations extends Equatable { /// Defaults to `false`. Must not be `null`. final bool readOnly; + /// Override [readOnly] for checkbox. + /// + /// When this is set to `false`, the checkbox can be checked + /// or unchecked while [readOnly] is set to `true`. + /// When this is set to `null`, the [readOnly] value is used. + /// + /// Defaults to `null`. + final bool? checkBoxReadOnly; + /// Disable Clipboard features /// /// when this is set to `true` clipboard can not be used @@ -369,6 +379,7 @@ class QuillEditorConfigurations extends Equatable { QuillController? controller, String? placeholder, bool? readOnly, + bool? checkBoxReadOnly, bool? disableClipboard, bool? scrollable, double? scrollBottomInset, @@ -421,6 +432,7 @@ class QuillEditorConfigurations extends Equatable { controller: controller ?? this.controller, placeholder: placeholder ?? this.placeholder, readOnly: readOnly ?? this.readOnly, + checkBoxReadOnly: checkBoxReadOnly ?? this.checkBoxReadOnly, disableClipboard: disableClipboard ?? this.disableClipboard, scrollable: scrollable ?? this.scrollable, scrollBottomInset: scrollBottomInset ?? this.scrollBottomInset, diff --git a/lib/src/models/config/raw_editor/raw_editor_configurations.dart b/lib/src/models/config/raw_editor/raw_editor_configurations.dart index 726dda0f..eb1f9def 100644 --- a/lib/src/models/config/raw_editor/raw_editor_configurations.dart +++ b/lib/src/models/config/raw_editor/raw_editor_configurations.dart @@ -50,6 +50,7 @@ class QuillRawEditorConfigurations extends Equatable { this.scrollable = true, this.padding = EdgeInsets.zero, this.readOnly = false, + this.checkBoxReadOnly, this.disableClipboard = false, this.placeholder, this.onLaunchUrl, @@ -104,6 +105,15 @@ class QuillRawEditorConfigurations extends Equatable { /// Defaults to false. Must not be null. final bool readOnly; + /// Override readOnly for checkbox. + /// + /// When this is set to false, the checkbox can be checked + /// or unchecked while readOnly is set to true. + /// When this is set to null, the readOnly value is used. + /// + /// Defaults to null. + final bool? checkBoxReadOnly; + /// Disable Clipboard features /// /// when this is set to true clipboard can not be used diff --git a/lib/src/widgets/editor/editor.dart b/lib/src/widgets/editor/editor.dart index 4c4ea7cb..a68d15ce 100644 --- a/lib/src/widgets/editor/editor.dart +++ b/lib/src/widgets/editor/editor.dart @@ -235,6 +235,7 @@ class QuillEditorState extends State scrollBottomInset: configurations.scrollBottomInset, padding: configurations.padding, readOnly: configurations.readOnly, + checkBoxReadOnly: configurations.checkBoxReadOnly, disableClipboard: configurations.disableClipboard, placeholder: configurations.placeholder, onLaunchUrl: configurations.onLaunchUrl, diff --git a/lib/src/widgets/quill/text_block.dart b/lib/src/widgets/quill/text_block.dart index 8fb89191..c0b6b187 100644 --- a/lib/src/widgets/quill/text_block.dart +++ b/lib/src/widgets/quill/text_block.dart @@ -74,6 +74,7 @@ class EditableTextBlock extends StatelessWidget { required this.clearIndents, required this.onCheckboxTap, required this.readOnly, + this.checkBoxReadOnly, this.onLaunchUrl, this.customStyleBuilder, this.customLinkPrefixes = const [], @@ -100,6 +101,7 @@ class EditableTextBlock extends StatelessWidget { final bool clearIndents; final Function(int, bool) onCheckboxTap; final bool readOnly; + final bool? checkBoxReadOnly; final List customLinkPrefixes; @override @@ -279,7 +281,7 @@ class EditableTextBlock extends StatelessWidget { return QuillEditorCheckboxPoint( size: fontSize, value: attrs[Attribute.list.key] == Attribute.checked, - enabled: !readOnly, + enabled: !(checkBoxReadOnly ?? readOnly), onChanged: (checked) => onCheckboxTap(line.documentOffset, checked), uiBuilder: defaultStyles.lists?.checkboxUIBuilder, ); diff --git a/lib/src/widgets/raw_editor/raw_editor_state.dart b/lib/src/widgets/raw_editor/raw_editor_state.dart index da636414..957e6186 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state.dart @@ -998,7 +998,8 @@ class QuillRawEditorState extends EditorState void _handleCheckboxTap(int offset, bool value) { final requestKeyboardFocusOnCheckListChanged = widget.configurations.requestKeyboardFocusOnCheckListChanged; - if (!widget.configurations.readOnly) { + if (!(widget.configurations.checkBoxReadOnly ?? + widget.configurations.readOnly)) { _disableScrollControllerAnimateOnce = true; final currentSelection = controller.selection.copyWith(); final attribute = value ? Attribute.checked : Attribute.unchecked; @@ -1074,6 +1075,7 @@ class QuillRawEditorState extends EditorState clearIndents: clearIndents, onCheckboxTap: _handleCheckboxTap, readOnly: widget.configurations.readOnly, + checkBoxReadOnly: widget.configurations.checkBoxReadOnly, customStyleBuilder: widget.configurations.customStyleBuilder, customLinkPrefixes: widget.configurations.customLinkPrefixes, ); From b7711bb46d6ad3e4f0d6942335a753b6818e28c0 Mon Sep 17 00:00:00 2001 From: Cheryl Date: Fri, 26 Apr 2024 16:56:57 -0700 Subject: [PATCH 4/4] Upgrade to 9.3.9 --- CHANGELOG.md | 5 +++++ dart_quill_delta/CHANGELOG.md | 5 +++++ dart_quill_delta/pubspec.yaml | 2 +- flutter_quill_extensions/CHANGELOG.md | 5 +++++ flutter_quill_extensions/pubspec.yaml | 2 +- flutter_quill_test/pubspec.yaml | 2 +- pubspec.yaml | 2 +- quill_html_converter/CHANGELOG.md | 5 +++++ quill_html_converter/pubspec.yaml | 2 +- quill_pdf_converter/CHANGELOG.md | 5 +++++ quill_pdf_converter/pubspec.yaml | 2 +- version.dart | 2 +- 12 files changed, 32 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ac1caa1..24ed8a4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +## 9.3.9 +* fix: MD Parsing for multi space +* fix: FontFamily and FontSize toolbars track the text selected in the editor +* feat: Add checkBoxReadOnly property which can override readOnly for checkbox + ## 9.3.8 * fix: removed misleading parameters * fix: added missed translations for ru, es, de diff --git a/dart_quill_delta/CHANGELOG.md b/dart_quill_delta/CHANGELOG.md index 8ac1caa1..24ed8a4e 100644 --- a/dart_quill_delta/CHANGELOG.md +++ b/dart_quill_delta/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +## 9.3.9 +* fix: MD Parsing for multi space +* fix: FontFamily and FontSize toolbars track the text selected in the editor +* feat: Add checkBoxReadOnly property which can override readOnly for checkbox + ## 9.3.8 * fix: removed misleading parameters * fix: added missed translations for ru, es, de diff --git a/dart_quill_delta/pubspec.yaml b/dart_quill_delta/pubspec.yaml index f603e06c..62441a0f 100644 --- a/dart_quill_delta/pubspec.yaml +++ b/dart_quill_delta/pubspec.yaml @@ -1,6 +1,6 @@ name: dart_quill_delta description: A port of quill-js-delta from typescript to dart -version: 9.3.8 +version: 9.3.9 homepage: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ repository: https://github.com/singerdmx/flutter-quill/tree/master/dart_quill_delta/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_extensions/CHANGELOG.md b/flutter_quill_extensions/CHANGELOG.md index 8ac1caa1..24ed8a4e 100644 --- a/flutter_quill_extensions/CHANGELOG.md +++ b/flutter_quill_extensions/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +## 9.3.9 +* fix: MD Parsing for multi space +* fix: FontFamily and FontSize toolbars track the text selected in the editor +* feat: Add checkBoxReadOnly property which can override readOnly for checkbox + ## 9.3.8 * fix: removed misleading parameters * fix: added missed translations for ru, es, de diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index c408d849..f251c6a4 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_extensions description: Embed extensions for flutter_quill including image, video, formula and etc. -version: 9.3.8 +version: 9.3.9 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_extensions/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/flutter_quill_test/pubspec.yaml b/flutter_quill_test/pubspec.yaml index 8da25861..c51881e5 100644 --- a/flutter_quill_test/pubspec.yaml +++ b/flutter_quill_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill_test description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. -version: 9.3.8 +version: 9.3.9 homepage: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/pubspec.yaml b/pubspec.yaml index 41926bcf..5ec1de08 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_quill description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. -version: 9.3.8 +version: 9.3.9 homepage: https://1o24bbs.com/c/bulletjournal/108/ repository: https://github.com/singerdmx/flutter-quill/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/quill_html_converter/CHANGELOG.md b/quill_html_converter/CHANGELOG.md index 8ac1caa1..24ed8a4e 100644 --- a/quill_html_converter/CHANGELOG.md +++ b/quill_html_converter/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +## 9.3.9 +* fix: MD Parsing for multi space +* fix: FontFamily and FontSize toolbars track the text selected in the editor +* feat: Add checkBoxReadOnly property which can override readOnly for checkbox + ## 9.3.8 * fix: removed misleading parameters * fix: added missed translations for ru, es, de diff --git a/quill_html_converter/pubspec.yaml b/quill_html_converter/pubspec.yaml index 04dae1c0..e6e766d0 100644 --- a/quill_html_converter/pubspec.yaml +++ b/quill_html_converter/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_html_converter description: A extension for flutter_quill package to add support for dealing with conversion to/from html -version: 9.3.8 +version: 9.3.9 homepage: https://github.com/singerdmx/flutter-quill/tree/master/quill_html_converter/ repository: https://github.com/singerdmx/flutter-quill/tree/master/quill_html_converter/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/quill_pdf_converter/CHANGELOG.md b/quill_pdf_converter/CHANGELOG.md index 8ac1caa1..24ed8a4e 100644 --- a/quill_pdf_converter/CHANGELOG.md +++ b/quill_pdf_converter/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +## 9.3.9 +* fix: MD Parsing for multi space +* fix: FontFamily and FontSize toolbars track the text selected in the editor +* feat: Add checkBoxReadOnly property which can override readOnly for checkbox + ## 9.3.8 * fix: removed misleading parameters * fix: added missed translations for ru, es, de diff --git a/quill_pdf_converter/pubspec.yaml b/quill_pdf_converter/pubspec.yaml index 870b0ca3..611191f6 100644 --- a/quill_pdf_converter/pubspec.yaml +++ b/quill_pdf_converter/pubspec.yaml @@ -1,6 +1,6 @@ name: quill_pdf_converter description: A extension for flutter_quill package to add support for dealing with conversion to pdf -version: 9.3.8 +version: 9.3.9 homepage: https://github.com/singerdmx/flutter-quill/tree/master/quill_pdf_converter/ repository: https://github.com/singerdmx/flutter-quill/tree/master/quill_pdf_converter/ issue_tracker: https://github.com/singerdmx/flutter-quill/issues/ diff --git a/version.dart b/version.dart index de66619d..c8a06db8 100644 --- a/version.dart +++ b/version.dart @@ -1 +1 @@ -const version = '9.3.8'; +const version = '9.3.9';