From f4266ac32676abd3397a06a7ef70b4c75af88347 Mon Sep 17 00:00:00 2001 From: Ahmed Hnewa <73608287+freshtechtips@users.noreply.github.com> Date: Sun, 22 Oct 2023 18:12:17 +0300 Subject: [PATCH] Bug fixes && Refactor more buttons --- CHANGELOG.md | 5 + .../models/config/toolbar/buttons/base.dart | 56 ++++- .../config/toolbar/buttons/font_family.dart | 69 ++++- .../config/toolbar/buttons/font_size.dart | 94 +++++-- .../config/toolbar/buttons/history.dart | 16 +- .../config/toolbar/buttons/toggle_style.dart | 27 +- .../models/config/toolbar/configurations.dart | 48 +++- lib/src/models/documents/attribute.dart | 16 +- .../utils/extensions/quill_controller.dart | 2 +- lib/src/utils/widgets.dart | 18 +- .../widgets/toolbar/buttons/font_family.dart | 82 +++--- lib/src/widgets/toolbar/buttons/history.dart | 4 +- .../toolbar/buttons/quill_font_size.dart | 237 +++++++++++------- .../widgets/toolbar/buttons/toggle_style.dart | 216 +++++++++++++--- lib/src/widgets/toolbar/toolbar.dart | 236 +++++++++-------- pubspec.yaml | 2 +- 16 files changed, 821 insertions(+), 307 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00fb9778..fd5a486b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## [7.7.0] + +- **Breaking change**: We have mirgrated more buttons in the toolbar configurations, you can do change them in the `QuillProvider` +- Important bug fixes + ## [7.6.1] - Bug fixes diff --git a/lib/src/models/config/toolbar/buttons/base.dart b/lib/src/models/config/toolbar/buttons/base.dart index d683b5a0..931b6fa3 100644 --- a/lib/src/models/config/toolbar/buttons/base.dart +++ b/lib/src/models/config/toolbar/buttons/base.dart @@ -1,11 +1,35 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart' show VoidCallback, immutable; -import 'package:flutter/widgets.dart' show IconData, Widget; +import 'package:flutter/widgets.dart' show BuildContext, IconData, Widget; import '../../../../../flutter_quill.dart' show QuillController, QuillProvider; import '../../../themes/quill_icon_theme.dart' show QuillIconTheme; import '../../quill_configurations.dart' show kDefaultIconSize; +@immutable +class QuillToolbarBaseButtonExtraOptions extends Equatable { + const QuillToolbarBaseButtonExtraOptions({ + required this.controller, + required this.context, + required this.onPressed, + }); + + /// if you need the not null controller for some usage in the [childBuilder] + /// then please use this instead of the one in the [options] + final QuillController controller; + + /// if the child builder you must use this when the widget tapped or pressed + /// in order to do what it expected to do + final VoidCallback? onPressed; + + final BuildContext context; + @override + List get props => [ + controller, + ]; +} + /// The [T] is the options for the button, usually should refresnce itself /// it's used in [childBuilder] so the developer can custmize this when using it /// The [I] is extra options for the button, usually for it's state @@ -41,10 +65,13 @@ class QuillToolbarBaseButtonOptions extends Equatable { final QuillIconTheme? iconTheme; /// If you want to dispaly a differnet widget based using a builder - final Widget Function(T options, I extraOptions)? childBuilder; + final QuillToolbarButtonOptionsChildBuilder childBuilder; /// By default it will be from the one in [QuillProvider] /// To override it you must pass not null controller + /// if you wish to use the controller in the [childBuilder], please use the + /// one from the extraOptions since it will be not null and will be the one + /// which will be used from the quill toolbar final QuillController? controller; @override @@ -57,4 +84,29 @@ class QuillToolbarBaseButtonOptions extends Equatable { childBuilder, controller, ]; + + // QuillToolbarBaseButtonOptions copyWith({ + // IconData? iconData, + // double? globalIconSize, + // VoidCallback? afterButtonPressed, + // String? tooltip, + // QuillIconTheme? iconTheme, + // Widget Function(T options, I extraOptions)? childBuilder, + // QuillController? controller, + // }) { + // return QuillToolbarBaseButtonOptions( + // iconData: iconData ?? this.iconData, + // globalIconSize: globalIconSize ?? this.globalIconSize, + // afterButtonPressed: afterButtonPressed ?? this.afterButtonPressed, + // tooltip: tooltip ?? this.tooltip, + // iconTheme: iconTheme ?? this.iconTheme, + // childBuilder: childBuilder ?? this.childBuilder, + // controller: controller ?? this.controller, + // ); + // } } + +typedef QuillToolbarButtonOptionsChildBuilder = Widget Function( + T options, + I extraOptions, +)?; diff --git a/lib/src/models/config/toolbar/buttons/font_family.dart b/lib/src/models/config/toolbar/buttons/font_family.dart index 92bb5395..6b79685f 100644 --- a/lib/src/models/config/toolbar/buttons/font_family.dart +++ b/lib/src/models/config/toolbar/buttons/font_family.dart @@ -3,19 +3,25 @@ import 'package:flutter/material.dart' show Colors, PopupMenuEntry; import 'package:flutter/widgets.dart' show Color, - ValueChanged, + EdgeInsets, EdgeInsetsGeometry, + IconData, + TextOverflow, TextStyle, - EdgeInsets, - TextOverflow; + ValueChanged, + VoidCallback; import '../../../../../flutter_quill.dart'; @immutable -class QuillToolbarFontFamilyButtonExtraOptions { +class QuillToolbarFontFamilyButtonExtraOptions + extends QuillToolbarBaseButtonExtraOptions { const QuillToolbarFontFamilyButtonExtraOptions({ required this.defaultDisplayText, required this.currentValue, + required super.controller, + required super.context, + required super.onPressed, }); final String defaultDisplayText; final String currentValue; @@ -76,4 +82,59 @@ class QuillToolbarFontFamilyButtonOptions extends QuillToolbarBaseButtonOptions< /// By default will use [globalIconSize] final double? iconSize; + + QuillToolbarFontFamilyButtonOptions copyWith({ + Color? fillColor, + double? hoverElevation, + double? highlightElevation, + List>? items, + Map? rawItemsMap, + ValueChanged? onSelected, + Attribute? attribute, + EdgeInsetsGeometry? padding, + TextStyle? style, + double? width, + String? initialValue, + TextOverflow? labelOverflow, + bool? renderFontFamilies, + bool? overrideTooltipByFontFamily, + double? itemHeight, + EdgeInsets? itemPadding, + Color? defaultItemColor, + double? iconSize, + // Add properties to override inherited properties + QuillController? controller, + IconData? iconData, + VoidCallback? afterButtonPressed, + String? tooltip, + QuillIconTheme? iconTheme, + }) { + return QuillToolbarFontFamilyButtonOptions( + attribute: attribute ?? this.attribute, + rawItemsMap: rawItemsMap ?? this.rawItemsMap, + controller: controller ?? this.controller, + iconData: iconData ?? this.iconData, + afterButtonPressed: afterButtonPressed ?? this.afterButtonPressed, + tooltip: tooltip ?? this.tooltip, + iconTheme: iconTheme ?? this.iconTheme, + onSelected: onSelected ?? this.onSelected, + padding: padding ?? this.padding, + style: style ?? this.style, + width: width ?? this.width, + initialValue: initialValue ?? this.initialValue, + labelOverflow: labelOverflow ?? this.labelOverflow, + renderFontFamilies: renderFontFamilies ?? this.renderFontFamilies, + overrideTooltipByFontFamily: + overrideTooltipByFontFamily ?? this.overrideTooltipByFontFamily, + itemHeight: itemHeight ?? this.itemHeight, + itemPadding: itemPadding ?? this.itemPadding, + defaultItemColor: defaultItemColor ?? this.defaultItemColor, + iconSize: iconSize ?? this.iconSize, + fillColor: fillColor ?? this.fillColor, + hoverElevation: hoverElevation ?? this.hoverElevation, + highlightElevation: highlightElevation ?? this.highlightElevation, + // ignore: deprecated_member_use_from_same_package + items: items ?? this.items, + ); + } } diff --git a/lib/src/models/config/toolbar/buttons/font_size.dart b/lib/src/models/config/toolbar/buttons/font_size.dart index 693e55fb..e9d4d5e7 100644 --- a/lib/src/models/config/toolbar/buttons/font_size.dart +++ b/lib/src/models/config/toolbar/buttons/font_size.dart @@ -1,22 +1,33 @@ +import 'dart:ui'; + import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/material.dart' show Colors, PopupMenuEntry, ValueChanged; import 'package:flutter/widgets.dart' - show - Color, - EdgeInsetsGeometry, - TextStyle, - VoidCallback, - TextOverflow, - EdgeInsets; + show Color, EdgeInsets, EdgeInsetsGeometry, TextOverflow, TextStyle; import '../../../../widgets/controller.dart'; import '../../../documents/attribute.dart'; import '../../../themes/quill_icon_theme.dart'; import '../../quill_configurations.dart'; +class QuillToolbarFontSizeButtonExtraOptions + extends QuillToolbarBaseButtonExtraOptions { + const QuillToolbarFontSizeButtonExtraOptions({ + required super.controller, + required this.currentValue, + required this.defaultDisplayText, + required super.context, + required super.onPressed, + }); + + final String currentValue; + final String defaultDisplayText; +} + @immutable -class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions { +class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions< + QuillToolbarFontSizeButtonOptions, QuillToolbarFontSizeButtonExtraOptions> { const QuillToolbarFontSizeButtonOptions({ this.iconSize, this.fillColor, @@ -25,11 +36,11 @@ class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions { this.items, this.rawItemsMap, this.onSelected, - this.iconTheme, + super.iconTheme, this.attribute = Attribute.size, - this.controller, - this.afterButtonPressed, - this.tooltip, + super.controller, + super.afterButtonPressed, + super.tooltip, this.padding, this.style, this.width, @@ -38,6 +49,7 @@ class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions { this.itemHeight, this.itemPadding, this.defaultItemColor = Colors.red, + super.childBuilder, }); final double? iconSize; @@ -46,17 +58,12 @@ class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions { final double highlightElevation; @Deprecated('It is not required because of `rawItemsMap`') final List>? items; + + /// By default it will be [fontSizesValues] from [QuillToolbarConfigurations] + /// You can override this if you want final Map? rawItemsMap; final ValueChanged? onSelected; - @override - final QuillIconTheme? iconTheme; final Attribute attribute; - @override - final QuillController? controller; - @override - final VoidCallback? afterButtonPressed; - @override - final String? tooltip; final EdgeInsetsGeometry? padding; final TextStyle? style; final double? width; @@ -65,4 +72,51 @@ class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions { final double? itemHeight; final EdgeInsets? itemPadding; final Color? defaultItemColor; + + QuillToolbarFontSizeButtonOptions copyWith({ + double? iconSize, + Color? fillColor, + double? hoverElevation, + double? highlightElevation, + List>? items, + Map? rawItemsMap, + ValueChanged? onSelected, + Attribute? attribute, + EdgeInsetsGeometry? padding, + TextStyle? style, + double? width, + String? initialValue, + TextOverflow? labelOverflow, + double? itemHeight, + EdgeInsets? itemPadding, + Color? defaultItemColor, + VoidCallback? afterButtonPressed, + String? tooltip, + QuillIconTheme? iconTheme, + QuillController? controller, + }) { + return QuillToolbarFontSizeButtonOptions( + iconSize: iconSize ?? this.iconSize, + fillColor: fillColor ?? this.fillColor, + hoverElevation: hoverElevation ?? this.hoverElevation, + highlightElevation: highlightElevation ?? this.highlightElevation, + // ignore: deprecated_member_use_from_same_package + items: items ?? this.items, + rawItemsMap: rawItemsMap ?? this.rawItemsMap, + onSelected: onSelected ?? this.onSelected, + attribute: attribute ?? this.attribute, + padding: padding ?? this.padding, + style: style ?? this.style, + width: width ?? this.width, + initialValue: initialValue ?? this.initialValue, + labelOverflow: labelOverflow ?? this.labelOverflow, + itemHeight: itemHeight ?? this.itemHeight, + itemPadding: itemPadding ?? this.itemPadding, + defaultItemColor: defaultItemColor ?? this.defaultItemColor, + tooltip: tooltip ?? super.tooltip, + iconTheme: iconTheme ?? super.iconTheme, + afterButtonPressed: afterButtonPressed ?? super.afterButtonPressed, + controller: controller ?? super.controller, + ); + } } diff --git a/lib/src/models/config/toolbar/buttons/history.dart b/lib/src/models/config/toolbar/buttons/history.dart index 06076fcd..eeceeda5 100644 --- a/lib/src/models/config/toolbar/buttons/history.dart +++ b/lib/src/models/config/toolbar/buttons/history.dart @@ -1,24 +1,24 @@ -import 'package:flutter/foundation.dart' show VoidCallback, immutable; +import 'package:flutter/foundation.dart' show immutable; import '../../../../../flutter_quill.dart'; @immutable -class HistoryButtonExtraOptions { - const HistoryButtonExtraOptions({ - required this.onPressed, +class QuillToolbarHistoryButtonExtraOptions + extends QuillToolbarBaseButtonExtraOptions { + const QuillToolbarHistoryButtonExtraOptions({ required this.canPressed, + required super.controller, + required super.context, + required super.onPressed, }); - /// When the button pressed - final VoidCallback onPressed; - /// If it can redo or undo final bool canPressed; } @immutable class QuillToolbarHistoryButtonOptions extends QuillToolbarBaseButtonOptions< - QuillToolbarHistoryButtonOptions, HistoryButtonExtraOptions> { + QuillToolbarHistoryButtonOptions, QuillToolbarHistoryButtonExtraOptions> { const QuillToolbarHistoryButtonOptions({ required this.isUndo, super.iconData, diff --git a/lib/src/models/config/toolbar/buttons/toggle_style.dart b/lib/src/models/config/toolbar/buttons/toggle_style.dart index 4f68693a..68df179c 100644 --- a/lib/src/models/config/toolbar/buttons/toggle_style.dart +++ b/lib/src/models/config/toolbar/buttons/toggle_style.dart @@ -1,15 +1,32 @@ import 'package:flutter/foundation.dart' show immutable; -import 'package:flutter/widgets.dart' show IconData; +import 'package:flutter/widgets.dart' show Color; import 'base.dart'; +class QuillToolbarToggleStyleButtonExtraOptions + extends QuillToolbarBaseButtonExtraOptions { + const QuillToolbarToggleStyleButtonExtraOptions({ + required super.controller, + required super.context, + required super.onPressed, + }); +} + @immutable class QuillToolbarToggleStyleButtonOptions - extends QuillToolbarBaseButtonOptions { + extends QuillToolbarBaseButtonOptions { const QuillToolbarToggleStyleButtonOptions({ - required this.iconData, + super.iconData, + this.iconSize, + this.fillColor, + super.tooltip, + super.afterButtonPressed, + super.iconTheme, + super.childBuilder, + super.controller, }); - @override - final IconData iconData; + final double? iconSize; + final Color? fillColor; } diff --git a/lib/src/models/config/toolbar/configurations.dart b/lib/src/models/config/toolbar/configurations.dart index b28b437d..3a814143 100644 --- a/lib/src/models/config/toolbar/configurations.dart +++ b/lib/src/models/config/toolbar/configurations.dart @@ -3,8 +3,9 @@ import 'package:flutter/foundation.dart' show immutable; import 'buttons/base.dart'; import 'buttons/font_family.dart'; -// import 'buttons/font_size.dart'; +import 'buttons/font_size.dart'; import 'buttons/history.dart'; +import 'buttons/toggle_style.dart'; export './buttons/base.dart'; export './buttons/font_family.dart'; @@ -31,6 +32,7 @@ class QuillToolbarConfigurations extends Equatable { this.buttonOptions = const QuillToolbarButtonOptions(), this.multiRowsDisplay = true, this.fontFamilyValues, + this.fontSizesValues, /// By default it will calculated based on the [baseOptions] iconSize /// You can change it but the the change only apply if @@ -55,7 +57,7 @@ class QuillToolbarConfigurations extends Equatable { final QuillToolbarButtonOptions buttonOptions; final bool multiRowsDisplay; - /// By default will be final + /// By default it will be /// ``` /// { /// 'Sans Serif': 'sans-serif', @@ -71,11 +73,23 @@ class QuillToolbarConfigurations extends Equatable { /// ``` final Map? fontFamilyValues; + /// By default it will be + /// ``` + /// { + /// 'Small'.i18n: 'small', + /// 'Large'.i18n: 'large', + /// 'Huge'.i18n: 'huge', + /// 'Clear'.i18n: '0' + /// } + /// ``` + final Map? fontSizesValues; + @override List get props => [ buttonOptions, multiRowsDisplay, fontFamilyValues, + fontSizesValues, toolbarSize, ]; } @@ -92,7 +106,20 @@ class QuillToolbarButtonOptions extends Equatable { isUndo: false, ), this.fontFamily = const QuillToolbarFontFamilyButtonOptions(), - // this.fontSize = const QuillToolbarFontSizeButtonOptions(), + this.fontSize = const QuillToolbarFontSizeButtonOptions(), + this.bold = const QuillToolbarToggleStyleButtonOptions(), + this.subscript = const QuillToolbarToggleStyleButtonOptions(), + this.superscript = const QuillToolbarToggleStyleButtonOptions(), + this.italic = const QuillToolbarToggleStyleButtonOptions(), + this.small = const QuillToolbarToggleStyleButtonOptions(), + this.underLine = const QuillToolbarToggleStyleButtonOptions(), + this.strikeThrough = const QuillToolbarToggleStyleButtonOptions(), + this.inlineCode = const QuillToolbarToggleStyleButtonOptions(), + this.direction = const QuillToolbarToggleStyleButtonOptions(), + this.listNumbers = const QuillToolbarToggleStyleButtonOptions(), + this.listBullets = const QuillToolbarToggleStyleButtonOptions(), + this.codeBlock = const QuillToolbarToggleStyleButtonOptions(), + this.quote = const QuillToolbarToggleStyleButtonOptions(), }); /// The base configurations for all the buttons which will apply to all @@ -102,7 +129,20 @@ class QuillToolbarButtonOptions extends Equatable { final QuillToolbarHistoryButtonOptions undoHistory; final QuillToolbarHistoryButtonOptions redoHistory; final QuillToolbarFontFamilyButtonOptions fontFamily; - // final QuillToolbarFontSizeButtonOptions fontSize; + final QuillToolbarFontSizeButtonOptions fontSize; + final QuillToolbarToggleStyleButtonOptions bold; + final QuillToolbarToggleStyleButtonOptions subscript; + final QuillToolbarToggleStyleButtonOptions superscript; + final QuillToolbarToggleStyleButtonOptions italic; + final QuillToolbarToggleStyleButtonOptions small; + final QuillToolbarToggleStyleButtonOptions underLine; + final QuillToolbarToggleStyleButtonOptions strikeThrough; + final QuillToolbarToggleStyleButtonOptions inlineCode; + final QuillToolbarToggleStyleButtonOptions direction; + final QuillToolbarToggleStyleButtonOptions listNumbers; + final QuillToolbarToggleStyleButtonOptions listBullets; + final QuillToolbarToggleStyleButtonOptions codeBlock; + final QuillToolbarToggleStyleButtonOptions quote; @override List get props => [ diff --git a/lib/src/models/documents/attribute.dart b/lib/src/models/documents/attribute.dart index d0dd2cfc..91e6c89e 100644 --- a/lib/src/models/documents/attribute.dart +++ b/lib/src/models/documents/attribute.dart @@ -1,5 +1,6 @@ import 'dart:collection'; +import 'package:equatable/equatable.dart'; import 'package:quiver/core.dart'; enum AttributeScope { @@ -9,8 +10,12 @@ enum AttributeScope { IGNORE, // attributes that can be ignored } -class Attribute { - const Attribute(this.key, this.scope, this.value); +class Attribute extends Equatable { + const Attribute( + this.key, + this.scope, + this.value, + ); /// Unique key of this attribute. final String key; @@ -102,7 +107,7 @@ class Attribute { static final ScriptAttribute script = ScriptAttribute(null); - // TODO: You might want to mark those as key (mobileWidthKey) + // TODO: You might want to mark those as key (like mobileWidthKey) // because it was not very clear to a developer that is new to this project static const String mobileWidth = 'mobileWidth'; @@ -253,6 +258,7 @@ class Attribute { return Attribute(origin.key, origin.scope, value); } + // This might not needed anymore because of equatable @override bool operator ==(Object other) { if (identical(this, other)) return true; @@ -263,6 +269,7 @@ class Attribute { value == typedOther.value; } + // This might not needed anymore because of equatable @override int get hashCode => hash3(key, scope, value); @@ -270,6 +277,9 @@ class Attribute { String toString() { return 'Attribute{key: $key, scope: $scope, value: $value}'; } + + @override + List get props => [key, scope, value]; } class BoldAttribute extends Attribute { diff --git a/lib/src/utils/extensions/quill_controller.dart b/lib/src/utils/extensions/quill_controller.dart index 0495daa2..6fa3c73b 100644 --- a/lib/src/utils/extensions/quill_controller.dart +++ b/lib/src/utils/extensions/quill_controller.dart @@ -3,7 +3,7 @@ import 'package:flutter/widgets.dart' show BuildContext; import '../../../flutter_quill.dart' show QuillController, QuillProvider; import 'build_context.dart'; -extension QuillControllerExt on QuillController? { +extension QuillControllerNullableExt on QuillController? { /// Simple logic to use the current passed controller if not null /// if null then we will have to use the default one from [QuillProvider] /// using the [context] diff --git a/lib/src/utils/widgets.dart b/lib/src/utils/widgets.dart index c27777f0..f7126616 100644 --- a/lib/src/utils/widgets.dart +++ b/lib/src/utils/widgets.dart @@ -6,16 +6,20 @@ typedef WidgetWrapper = Widget Function(Widget child); abstract class UtilityWidgets { /// Conditionally wraps the [child] with [Tooltip] widget if [message] /// is not null and not empty. - static Widget maybeTooltip({required Widget child, String? message}) => - (message ?? '').isNotEmpty - ? Tooltip(message: message!, child: child) + static Widget maybeTooltip({ + required Widget child, + String? message, + }) => + (message?.isNotEmpty ?? false) + ? Tooltip(message: message, child: child) : child; /// Conditionally wraps the [child] with [wrapper] widget if [enabled] /// is true. - static Widget maybeWidget( - {required WidgetWrapper wrapper, - required Widget child, - bool enabled = false}) => + static Widget maybeWidget({ + required WidgetWrapper wrapper, + required Widget child, + bool enabled = false, + }) => enabled ? wrapper(child) : child; } diff --git a/lib/src/widgets/toolbar/buttons/font_family.dart b/lib/src/widgets/toolbar/buttons/font_family.dart index e2328868..5ec16f6d 100644 --- a/lib/src/widgets/toolbar/buttons/font_family.dart +++ b/lib/src/widgets/toolbar/buttons/font_family.dart @@ -4,14 +4,15 @@ import '../../../../extensions.dart'; import '../../../models/config/toolbar/buttons/font_family.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; +import '../../../models/themes/quill_icon_theme.dart'; import '../../../translations/toolbar.i18n.dart'; import '../../../utils/extensions/build_context.dart'; -import '../../../utils/extensions/quill_controller.dart'; import '../../controller.dart'; class QuillToolbarFontFamilyButton extends StatefulWidget { QuillToolbarFontFamilyButton({ required this.options, + required this.controller, super.key, }) : assert(options.rawItemsMap?.isNotEmpty ?? (true)), assert( @@ -20,6 +21,10 @@ class QuillToolbarFontFamilyButton extends StatefulWidget { final QuillToolbarFontFamilyButtonOptions options; + /// 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(); @@ -33,16 +38,12 @@ class _QuillToolbarFontFamilyButtonState return widget.options; } - /// Since t's not safe to call anything related to the context in dispose + /// Since it's not safe to call anything related to the context in dispose /// then we will save a reference to the [controller] /// and update it in [didChangeDependencies] /// and use it in dispose method late QuillController _controller; - QuillController get controller { - return options.controller.notNull(context); - } - Style get _selectionStyle => controller.getSelectionStyle(); @override @@ -82,7 +83,7 @@ class _QuillToolbarFontFamilyButtonState @override void didUpdateWidget(covariant QuillToolbarFontFamilyButton oldWidget) { super.didUpdateWidget(oldWidget); - if (controller == controller) { + if (oldWidget.controller == controller) { return; } controller @@ -102,6 +103,7 @@ class _QuillToolbarFontFamilyButtonState Map get rawItemsMap { final rawItemsMap = options.rawItemsMap ?? + context.requireQuillToolbarConfigurations.fontFamilyValues ?? { 'Sans Serif': 'sans-serif', 'Serif': 'serif', @@ -125,15 +127,36 @@ class _QuillToolbarFontFamilyButtonState return null; } + QuillController get controller { + return options.controller ?? widget.controller; + } + double get iconSize { + final baseFontSize = + context.requireQuillToolbarBaseButtonOptions.globalIconSize; final iconSize = options.iconSize; - return iconSize ?? 40; - // final baseFontSize = - // context.requireQuillToolbarBaseButtonOptions.globalIconSize; - // if (baseFontSize != iconSize) { - // return 40; - // } - // return iconSize ?? baseFontSize; + return iconSize ?? baseFontSize; + } + + VoidCallback? get afterButtonPressed { + return options.afterButtonPressed ?? + context.requireQuillToolbarBaseButtonOptions.afterButtonPressed; + } + + QuillIconTheme? get iconTheme { + return options.iconTheme ?? + context.requireQuillToolbarBaseButtonOptions.iconTheme; + } + + String get tooltip { + return options.tooltip ?? + context.requireQuillToolbarBaseButtonOptions.tooltip ?? + 'Font family'.i18n; + } + + void _onPressed() { + _showMenu(); + options.afterButtonPressed?.call(); } @override @@ -144,10 +167,19 @@ class _QuillToolbarFontFamilyButtonState options.childBuilder ?? baseButtonConfigurations.childBuilder; if (childBuilder != null) { return childBuilder( - options, + options.copyWith( + iconSize: iconSize, + rawItemsMap: rawItemsMap, + iconTheme: iconTheme, + tooltip: tooltip, + afterButtonPressed: afterButtonPressed, + ), QuillToolbarFontFamilyButtonExtraOptions( currentValue: _currentValue, defaultDisplayText: _defaultDisplayText, + controller: controller, + context: context, + onPressed: _onPressed, ), ); } @@ -157,10 +189,9 @@ class _QuillToolbarFontFamilyButtonState width: options.width, ), child: UtilityWidgets.maybeWidget( - enabled: (options.tooltip ?? '').isNotEmpty || - options.overrideTooltipByFontFamily, + enabled: tooltip.isNotEmpty || options.overrideTooltipByFontFamily, wrapper: (child) { - var effectiveTooltip = options.tooltip ?? ''; + var effectiveTooltip = tooltip; if (options.overrideTooltipByFontFamily) { effectiveTooltip = effectiveTooltip.isNotEmpty ? '$effectiveTooltip: $_currentValue' @@ -171,17 +202,13 @@ class _QuillToolbarFontFamilyButtonState child: RawMaterialButton( visualDensity: VisualDensity.compact, shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(options.iconTheme?.borderRadius ?? 2), + borderRadius: BorderRadius.circular(iconTheme?.borderRadius ?? 2), ), fillColor: options.fillColor, elevation: 0, hoverElevation: options.hoverElevation, highlightElevation: options.hoverElevation, - onPressed: () { - _showMenu(); - options.afterButtonPressed?.call(); - }, + onPressed: _onPressed, child: _buildContent(context), ), ), @@ -266,8 +293,8 @@ class _QuillToolbarFontFamilyButtonState style: options.style ?? TextStyle( fontSize: iconSize / 1.15, - color: options.iconTheme?.iconUnselectedColor ?? - theme.iconTheme.color, + color: + iconTheme?.iconUnselectedColor ?? theme.iconTheme.color, ), ), ), @@ -275,8 +302,7 @@ class _QuillToolbarFontFamilyButtonState Icon( Icons.arrow_drop_down, size: iconSize / 1.15, - color: - options.iconTheme?.iconUnselectedColor ?? theme.iconTheme.color, + color: iconTheme?.iconUnselectedColor ?? theme.iconTheme.color, ) ], ), diff --git a/lib/src/widgets/toolbar/buttons/history.dart b/lib/src/widgets/toolbar/buttons/history.dart index 603d10d8..6d9da528 100644 --- a/lib/src/widgets/toolbar/buttons/history.dart +++ b/lib/src/widgets/toolbar/buttons/history.dart @@ -86,12 +86,14 @@ class _QuillToolbarHistoryButtonState extends State { iconTheme: iconTheme, tooltip: tooltip, ), - HistoryButtonExtraOptions( + QuillToolbarHistoryButtonExtraOptions( onPressed: () { _updateHistory(); afterButtonPressed?.call(); }, canPressed: _canPressed, + controller: controller, + context: context, ), ); } diff --git a/lib/src/widgets/toolbar/buttons/quill_font_size.dart b/lib/src/widgets/toolbar/buttons/quill_font_size.dart index 5230005b..d4622d55 100644 --- a/lib/src/widgets/toolbar/buttons/quill_font_size.dart +++ b/lib/src/widgets/toolbar/buttons/quill_font_size.dart @@ -1,61 +1,25 @@ import 'package:flutter/material.dart'; -import '../../../models/documents/attribute.dart'; -import '../../../models/documents/style.dart'; -import '../../../models/themes/quill_icon_theme.dart'; +import '../../../../extensions.dart'; +import '../../../../flutter_quill.dart'; import '../../../translations/toolbar.i18n.dart'; +import '../../../utils/extensions/build_context.dart'; import '../../../utils/font.dart'; -import '../../../utils/widgets.dart'; -import '../../controller.dart'; class QuillToolbarFontSizeButton extends StatefulWidget { - const QuillToolbarFontSizeButton({ - required this.rawItemsMap, - required this.attribute, + QuillToolbarFontSizeButton({ + required this.options, required this.controller, - this.onSelected, - @Deprecated('It is not required because of `rawItemsMap`') this.items, - this.iconSize = 40, - this.fillColor, - this.hoverElevation = 1, - this.highlightElevation = 1, - this.iconTheme, - this.afterButtonPressed, - this.tooltip, - this.padding, - this.style, - this.width, - this.initialValue, - this.labelOverflow = TextOverflow.visible, - this.itemHeight, - this.itemPadding, - this.defaultItemColor = Colors.red, - Key? key, - }) : assert(rawItemsMap.length > 0), - assert(initialValue == null || initialValue.length > 0), - super(key: key); - - final double iconSize; - final Color? fillColor; - final double hoverElevation; - final double highlightElevation; - @Deprecated('It is not required because of `rawItemsMap`') - final List>? items; - final Map rawItemsMap; - final ValueChanged? onSelected; - final QuillIconTheme? iconTheme; - final Attribute attribute; + super.key, + }) : assert(options.rawItemsMap?.isNotEmpty ?? true), + assert(options.initialValue == null || + (options.initialValue?.isNotEmpty ?? true)); + + final QuillToolbarFontSizeButtonOptions options; + + /// 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; - final VoidCallback? afterButtonPressed; - final String? tooltip; - final EdgeInsetsGeometry? padding; - final TextStyle? style; - final double? width; - final String? initialValue; - final TextOverflow labelOverflow; - final double? itemHeight; - final EdgeInsets? itemPadding; - final Color? defaultItemColor; @override _QuillToolbarFontSizeButtonState createState() => @@ -64,34 +28,79 @@ class QuillToolbarFontSizeButton extends StatefulWidget { class _QuillToolbarFontSizeButtonState extends State { - late String _defaultDisplayText; - late String _currentValue; - Style get _selectionStyle => widget.controller.getSelectionStyle(); + String _currentValue = ''; + + QuillToolbarFontSizeButtonOptions get options { + return widget.options; + } + + /// Since it's not safe to call anything related to the context in dispose + /// then we will save a reference to the [controller] + /// and update it in [didChangeDependencies] + /// and use it in dispose method + late QuillController _controller; + + Map get rawItemsMap { + final fontSizes = options.rawItemsMap ?? + context.requireQuillToolbarConfigurations.fontSizesValues ?? + { + 'Small'.i18n: 'small', + 'Large'.i18n: 'large', + 'Huge'.i18n: 'huge', + 'Clear'.i18n: '0' + }; + return fontSizes; + } + + String get _defaultDisplayText { + return options.initialValue ?? 'Size'.i18n; + } + + Style get _selectionStyle => controller.getSelectionStyle(); @override void initState() { super.initState(); - _currentValue = _defaultDisplayText = widget.initialValue ?? 'Size'.i18n; - widget.controller.addListener(_didChangeEditingValue); + + _initState(); + } + + Future _initState() async { + if (isFlutterTest()) { + return; + } + await Future.delayed(Duration.zero); + setState(() { + _currentValue = _defaultDisplayText; + }); + controller.addListener(_didChangeEditingValue); + } + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + _controller = controller; } @override void dispose() { - widget.controller.removeListener(_didChangeEditingValue); + _controller.removeListener(_didChangeEditingValue); super.dispose(); } @override void didUpdateWidget(covariant QuillToolbarFontSizeButton oldWidget) { super.didUpdateWidget(oldWidget); - if (oldWidget.controller != widget.controller) { - oldWidget.controller.removeListener(_didChangeEditingValue); - widget.controller.addListener(_didChangeEditingValue); + if (widget.controller == controller) { + return; } + controller + ..removeListener(_didChangeEditingValue) + ..addListener(_didChangeEditingValue); } void _didChangeEditingValue() { - final attribute = _selectionStyle.attributes[widget.attribute.key]; + final attribute = _selectionStyle.attributes[options.attribute.key]; if (attribute == null) { setState(() => _currentValue = _defaultDisplayText); return; @@ -101,7 +110,7 @@ class _QuillToolbarFontSizeButtonState } String? _getKeyName(dynamic value) { - for (final entry in widget.rawItemsMap.entries) { + for (final entry in rawItemsMap.entries) { if (getFontSize(entry.value) == getFontSize(value)) { return entry.key; } @@ -109,29 +118,79 @@ class _QuillToolbarFontSizeButtonState return null; } + QuillController get controller { + return options.controller ?? widget.controller; + } + + double get iconSize { + final baseFontSize = + context.requireQuillToolbarBaseButtonOptions.globalIconSize; + final iconSize = options.iconSize; + return iconSize ?? baseFontSize; + } + + VoidCallback? get afterButtonPressed { + return options.afterButtonPressed ?? + context.requireQuillToolbarBaseButtonOptions.afterButtonPressed; + } + + QuillIconTheme? get iconTheme { + return options.iconTheme ?? + context.requireQuillToolbarBaseButtonOptions.iconTheme; + } + + String get tooltip { + return options.tooltip ?? + context.requireQuillToolbarBaseButtonOptions.tooltip ?? + 'Font size'.i18n; + } + + void _onPressed() { + _showMenu(); + afterButtonPressed?.call(); + } + @override Widget build(BuildContext context) { + final baseButtonConfigurations = + context.requireQuillToolbarBaseButtonOptions; + final childBuilder = + options.childBuilder ?? baseButtonConfigurations.childBuilder; + if (childBuilder != null) { + return childBuilder( + options.copyWith( + tooltip: tooltip, + iconSize: iconSize, + iconTheme: iconTheme, + afterButtonPressed: afterButtonPressed, + controller: controller, + ), + QuillToolbarFontSizeButtonExtraOptions( + controller: controller, + currentValue: _currentValue, + defaultDisplayText: _defaultDisplayText, + context: context, + onPressed: _onPressed, + ), + ); + } return ConstrainedBox( constraints: BoxConstraints.tightFor( - height: widget.iconSize * 1.81, - width: widget.width, + height: iconSize * 1.81, + width: options.width, ), child: UtilityWidgets.maybeTooltip( - message: widget.tooltip, + message: tooltip, child: RawMaterialButton( visualDensity: VisualDensity.compact, shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(widget.iconTheme?.borderRadius ?? 2), + borderRadius: BorderRadius.circular(iconTheme?.borderRadius ?? 2), ), - fillColor: widget.fillColor, + fillColor: options.fillColor, elevation: 0, - hoverElevation: widget.hoverElevation, - highlightElevation: widget.hoverElevation, - onPressed: () { - _showMenu(); - widget.afterButtonPressed?.call(); - }, + hoverElevation: options.hoverElevation, + highlightElevation: options.hoverElevation, + onPressed: _onPressed, child: _buildContent(context), ), ), @@ -154,17 +213,16 @@ class _QuillToolbarFontSizeButtonState context: context, elevation: 4, items: [ - for (final MapEntry fontSize - in widget.rawItemsMap.entries) + for (final MapEntry fontSize in rawItemsMap.entries) PopupMenuItem( key: ValueKey(fontSize.key), value: fontSize.value, - height: widget.itemHeight ?? kMinInteractiveDimension, - padding: widget.itemPadding, + height: options.itemHeight ?? kMinInteractiveDimension, + padding: options.itemPadding, child: Text( fontSize.key.toString(), style: TextStyle( - color: fontSize.value == '0' ? widget.defaultItemColor : null, + color: fontSize.value == '0' ? options.defaultItemColor : null, ), ), ), @@ -181,18 +239,18 @@ class _QuillToolbarFontSizeButtonState setState(() { _currentValue = keyName ?? _defaultDisplayText; if (keyName != null) { - widget.controller.formatSelection(Attribute.fromKeyValue( + controller.formatSelection(Attribute.fromKeyValue( 'size', newValue == '0' ? null : getFontSize(newValue))); - widget.onSelected?.call(newValue); + options.onSelected?.call(newValue); } }); } Widget _buildContent(BuildContext context) { final theme = Theme.of(context); - final hasFinalWidth = widget.width != null; + final hasFinalWidth = options.width != null; return Padding( - padding: widget.padding ?? const EdgeInsets.fromLTRB(10, 0, 0, 0), + padding: options.padding ?? const EdgeInsets.fromLTRB(10, 0, 0, 0), child: Row( mainAxisSize: !hasFinalWidth ? MainAxisSize.min : MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -202,21 +260,20 @@ class _QuillToolbarFontSizeButtonState wrapper: (child) => Expanded(child: child), child: Text( _currentValue, - overflow: widget.labelOverflow, - style: widget.style ?? + overflow: options.labelOverflow, + style: options.style ?? TextStyle( - fontSize: widget.iconSize / 1.15, - color: widget.iconTheme?.iconUnselectedColor ?? - theme.iconTheme.color, + fontSize: iconSize / 1.15, + color: + iconTheme?.iconUnselectedColor ?? theme.iconTheme.color, ), ), ), const SizedBox(width: 3), Icon( Icons.arrow_drop_down, - size: widget.iconSize / 1.15, - color: - widget.iconTheme?.iconUnselectedColor ?? theme.iconTheme.color, + size: iconSize / 1.15, + color: iconTheme?.iconUnselectedColor ?? theme.iconTheme.color, ) ], ), diff --git a/lib/src/widgets/toolbar/buttons/toggle_style.dart b/lib/src/widgets/toolbar/buttons/toggle_style.dart index e85ac6d1..110cba31 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_style.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_style.dart @@ -1,8 +1,10 @@ import 'package:flutter/material.dart'; +import '../../../../translations.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; +import '../../../utils/extensions/build_context.dart'; import '../../../utils/widgets.dart'; import '../../controller.dart'; import '../toolbar.dart'; @@ -21,65 +23,207 @@ typedef ToggleStyleButtonBuilder = Widget Function( class ToggleStyleButton extends StatefulWidget { const ToggleStyleButton({ - required this.attribute, - required this.icon, + required this.options, required this.controller, - this.iconSize = kDefaultIconSize, - this.fillColor, - this.childBuilder = defaultToggleStyleButtonBuilder, - this.iconTheme, - this.afterButtonPressed, - this.tooltip, - Key? key, - }) : super(key: key); + required this.attribute, + // required this.icon, + // required this.controller, + // this.iconSize = kDefaultIconSize, + // this.fillColor, + // this.childBuilder = defaultToggleStyleButtonBuilder, + // this.iconTheme, + // this.afterButtonPressed, + // this.tooltip, + super.key, + }); final Attribute attribute; - final IconData icon; - final double iconSize; + // final IconData icon; + // final double iconSize; - final Color? fillColor; + // final Color? fillColor; - final QuillController controller; + // final QuillController controller; - final ToggleStyleButtonBuilder childBuilder; + // final ToggleStyleButtonBuilder childBuilder; - ///Specify an icon theme for the icons in the toolbar - final QuillIconTheme? iconTheme; + // ///Specify an icon theme for the icons in the toolbar + // final QuillIconTheme? iconTheme; - final VoidCallback? afterButtonPressed; - final String? tooltip; + // final VoidCallback? afterButtonPressed; + // final String? tooltip; + final QuillToolbarToggleStyleButtonOptions options; + + /// 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 _ToggleStyleButtonState createState() => _ToggleStyleButtonState(); } class _ToggleStyleButtonState extends State { + /// Since it's not safe to call anything related to the context in dispose + /// then we will save a reference to the [controller] + /// and update it in [didChangeDependencies] + /// and use it in dispose method + late QuillController _controller; + bool? _isToggled; - Style get _selectionStyle => widget.controller.getSelectionStyle(); + Style get _selectionStyle => controller.getSelectionStyle(); + + QuillToolbarToggleStyleButtonOptions get options { + return widget.options; + } @override void initState() { super.initState(); _isToggled = _getIsToggled(_selectionStyle.attributes); - widget.controller.addListener(_didChangeEditingValue); + controller.addListener(_didChangeEditingValue); + } + + QuillController get controller { + return options.controller ?? widget.controller; + } + + double get iconSize { + final baseFontSize = + context.requireQuillToolbarBaseButtonOptions.globalIconSize; + final iconSize = options.iconSize; + return iconSize ?? baseFontSize; + } + + VoidCallback? get afterButtonPressed { + return options.afterButtonPressed ?? + context.requireQuillToolbarBaseButtonOptions.afterButtonPressed; + } + + QuillIconTheme? get iconTheme { + return options.iconTheme ?? + context.requireQuillToolbarBaseButtonOptions.iconTheme; + } + + String? get _defaultTooltip { + switch (widget.attribute.key) { + case 'bold': + return 'Bold'.i18n; + case 'script': + if (widget.attribute.value == ScriptAttributes.sub.value) { + return 'Subscript'.i18n; + } + return 'Superscript'.i18n; + case 'italic': + return 'Italic'.i18n; + case 'small': + return 'Small'.i18n; + case 'underline': + return 'Underline'.i18n; + case 'strike': + return 'Strike through'.i18n; + case 'code': + return 'Inline code'.i18n; + case 'rtl': + return 'Text direction'.i18n; + case 'list': + if (widget.attribute.value == 'bullet') { + return 'Bullet list'.i18n; + } + return 'Numbered list'.i18n; + case 'code-block': + return 'Code block'.i18n; + case 'blockquote': + return 'Quote'.i18n; + default: + throw ArgumentError( + 'Could not find the default tooltip for ' + '${widget.attribute.toString()}', + ); + } + } + + String? get tooltip { + return options.tooltip ?? + context.requireQuillToolbarBaseButtonOptions.tooltip ?? + _defaultTooltip; + } + + IconData get _defaultIconData { + switch (widget.attribute.key) { + case 'bold': + return Icons.format_bold; + case 'script': + if (widget.attribute.value == ScriptAttributes.sub.value) { + return Icons.subscript; + } + return Icons.superscript; + case 'italic': + return Icons.format_italic; + case 'small': + return Icons.format_size; + case 'underline': + return Icons.format_underline; + case 'strike': + return Icons.format_strikethrough; + case 'code': + return Icons.code; + case 'rtl': + return Icons.format_textdirection_r_to_l; + case 'list': + if (widget.attribute.value == 'bullet') { + return Icons.format_list_bulleted; + } + return Icons.format_list_numbered; + case 'code-block': + return Icons.code; + case 'blockquote': + return Icons.format_quote; + default: + throw ArgumentError( + 'Could not find the icon for ${widget.attribute.toString()}', + ); + } + } + + IconData get iconData { + return options.iconData ?? + context.requireQuillToolbarBaseButtonOptions.iconData ?? + _defaultIconData; + } + + void _onPressed() { + _toggleAttribute(); + options.afterButtonPressed?.call(); } @override Widget build(BuildContext context) { + final childBuilder = options.childBuilder ?? + context.requireQuillToolbarBaseButtonOptions.childBuilder; + if (childBuilder != null) { + return childBuilder( + options, + QuillToolbarToggleStyleButtonExtraOptions( + context: context, + controller: controller, + onPressed: _onPressed, + ), + ); + } return UtilityWidgets.maybeTooltip( - message: widget.tooltip, - child: widget.childBuilder( + message: tooltip, + child: defaultToggleStyleButtonBuilder( context, widget.attribute, - widget.icon, - widget.fillColor, + iconData, + options.fillColor, _isToggled, _toggleAttribute, - widget.afterButtonPressed, - widget.iconSize, - widget.iconTheme, + options.afterButtonPressed, + iconSize, + iconTheme, ), ); } @@ -87,16 +231,22 @@ class _ToggleStyleButtonState extends State { @override void didUpdateWidget(covariant ToggleStyleButton oldWidget) { super.didUpdateWidget(oldWidget); - if (oldWidget.controller != widget.controller) { + if (oldWidget.controller != controller) { oldWidget.controller.removeListener(_didChangeEditingValue); widget.controller.addListener(_didChangeEditingValue); _isToggled = _getIsToggled(_selectionStyle.attributes); } } + @override + void didChangeDependencies() { + super.didChangeDependencies(); + _controller = controller; + } + @override void dispose() { - widget.controller.removeListener(_didChangeEditingValue); + _controller.removeListener(_didChangeEditingValue); super.dispose(); } @@ -117,9 +267,9 @@ class _ToggleStyleButtonState extends State { } void _toggleAttribute() { - widget.controller.formatSelection(_isToggled! - ? Attribute.clone(widget.attribute, null) - : widget.attribute); + controller.formatSelection( + _isToggled! ? Attribute.clone(widget.attribute, null) : widget.attribute, + ); } } diff --git a/lib/src/widgets/toolbar/toolbar.dart b/lib/src/widgets/toolbar/toolbar.dart index c269813a..ddb921b8 100644 --- a/lib/src/widgets/toolbar/toolbar.dart +++ b/lib/src/widgets/toolbar/toolbar.dart @@ -48,7 +48,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { factory QuillToolbar.basic({ Axis axis = Axis.horizontal, - // double toolbarIconSize = kDefaultIconSize, double toolbarSectionSpacing = kToolbarSectionSpacing, WrapAlignment toolbarIconAlignment = WrapAlignment.center, WrapCrossAlignment toolbarIconCrossAlignment = WrapCrossAlignment.center, @@ -88,9 +87,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { /// The decoration to use for the toolbar. Decoration? decoration, - ///Map of font sizes in string - Map? fontSizeValues, - /// Toolbar items to display for controls of embed blocks List? embedButtons, @@ -161,20 +157,9 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { showLink || showSearchButton ]; - //default font size values - final fontSizes = fontSizeValues ?? - { - 'Small'.i18n: 'small', - 'Large'.i18n: 'large', - 'Huge'.i18n: 'huge', - 'Clear'.i18n: '0' - }; - //default button tooltips final buttonTooltips = tooltips ?? { - // ToolbarButtons.undo: 'Undo'.i18n, - // ToolbarButtons.redo: 'Redo'.i18n, ToolbarButtons.fontFamily: 'Font family'.i18n, ToolbarButtons.fontSize: 'Font size'.i18n, ToolbarButtons.bold: 'Bold'.i18n, @@ -235,96 +220,127 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { if (showFontFamily) QuillToolbarFontFamilyButton( options: toolbarConfigurations.buttonOptions.fontFamily, + controller: + toolbarConfigurations.buttonOptions.fontFamily.controller ?? + context.requireQuillController, ), if (showFontSize) QuillToolbarFontSizeButton( - iconTheme: iconTheme, - iconSize: toolbarIconSize, - tooltip: buttonTooltips[ToolbarButtons.fontSize], - attribute: Attribute.size, - controller: controller, - rawItemsMap: fontSizes, - afterButtonPressed: afterButtonPressed, + options: toolbarConfigurations.buttonOptions.fontSize, + controller: + toolbarConfigurations.buttonOptions.fontFamily.controller ?? + context.requireQuillController, ), if (showBoldButton) ToggleStyleButton( attribute: Attribute.bold, - icon: Icons.format_bold, - iconSize: toolbarIconSize, - tooltip: buttonTooltips[ToolbarButtons.bold], - controller: controller, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, + options: toolbarConfigurations.buttonOptions.bold, + controller: toolbarConfigurations.buttonOptions.bold.controller ?? + context.requireQuillController, + // icon: Icons.format_bold, + // iconSize: toolbarIconSize, + // tooltip: buttonTooltips[ToolbarButtons.bold], + // controller: controller, + // iconTheme: iconTheme, + // afterButtonPressed: afterButtonPressed, ), if (showSubscript) ToggleStyleButton( attribute: Attribute.subscript, - icon: Icons.subscript, - iconSize: toolbarIconSize, - tooltip: buttonTooltips[ToolbarButtons.subscript], - controller: controller, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, + options: toolbarConfigurations.buttonOptions.subscript, + controller: + toolbarConfigurations.buttonOptions.subscript.controller ?? + context.requireQuillController, + // icon: Icons.subscript, + // iconSize: toolbarIconSize, + // tooltip: buttonTooltips[ToolbarButtons.subscript], + // controller: controller, + // iconTheme: iconTheme, + // afterButtonPressed: afterButtonPressed, ), if (showSuperscript) ToggleStyleButton( attribute: Attribute.superscript, - icon: Icons.superscript, - iconSize: toolbarIconSize, - tooltip: buttonTooltips[ToolbarButtons.superscript], - controller: controller, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, + options: toolbarConfigurations.buttonOptions.superscript, + controller: + toolbarConfigurations.buttonOptions.superscript.controller ?? + context.requireQuillController, + // icon: Icons.superscript, + // iconSize: toolbarIconSize, + // tooltip: buttonTooltips[ToolbarButtons.superscript], + // controller: controller, + // iconTheme: iconTheme, + // afterButtonPressed: afterButtonPressed, ), if (showItalicButton) ToggleStyleButton( attribute: Attribute.italic, - icon: Icons.format_italic, - iconSize: toolbarIconSize, - tooltip: buttonTooltips[ToolbarButtons.italic], - controller: controller, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, + options: toolbarConfigurations.buttonOptions.italic, + controller: + toolbarConfigurations.buttonOptions.italic.controller ?? + context.requireQuillController, + // icon: Icons.format_italic, + // iconSize: toolbarIconSize, + // tooltip: buttonTooltips[ToolbarButtons.italic], + // controller: controller, + // iconTheme: iconTheme, + // afterButtonPressed: afterButtonPressed, ), if (showSmallButton) ToggleStyleButton( attribute: Attribute.small, - icon: Icons.format_size, - iconSize: toolbarIconSize, - tooltip: buttonTooltips[ToolbarButtons.small], - controller: controller, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, + options: toolbarConfigurations.buttonOptions.small, + controller: + toolbarConfigurations.buttonOptions.small.controller ?? + context.requireQuillController, + // icon: Icons.format_size, + // iconSize: toolbarIconSize, + // tooltip: buttonTooltips[ToolbarButtons.small], + // controller: controller, + // iconTheme: iconTheme, + // afterButtonPressed: afterButtonPressed, ), if (showUnderLineButton) ToggleStyleButton( attribute: Attribute.underline, - icon: Icons.format_underline, - iconSize: toolbarIconSize, - tooltip: buttonTooltips[ToolbarButtons.underline], - controller: controller, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, + options: toolbarConfigurations.buttonOptions.underLine, + controller: + toolbarConfigurations.buttonOptions.underLine.controller ?? + context.requireQuillController, + // icon: Icons.format_underline, + // iconSize: toolbarIconSize, + // tooltip: buttonTooltips[ToolbarButtons.underline], + // controller: controller, + // iconTheme: iconTheme, + // afterButtonPressed: afterButtonPressed, ), if (showStrikeThrough) ToggleStyleButton( attribute: Attribute.strikeThrough, - icon: Icons.format_strikethrough, - iconSize: toolbarIconSize, - tooltip: buttonTooltips[ToolbarButtons.strikeThrough], - controller: controller, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, + options: toolbarConfigurations.buttonOptions.strikeThrough, + controller: toolbarConfigurations + .buttonOptions.strikeThrough.controller ?? + context.requireQuillController, + // icon: Icons.format_strikethrough, + // iconSize: toolbarIconSize, + // tooltip: buttonTooltips[ToolbarButtons.strikeThrough], + // controller: controller, + // iconTheme: iconTheme, + // afterButtonPressed: afterButtonPressed, ), if (showInlineCode) ToggleStyleButton( attribute: Attribute.inlineCode, - icon: Icons.code, - iconSize: toolbarIconSize, - tooltip: buttonTooltips[ToolbarButtons.inlineCode], - controller: controller, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, + options: toolbarConfigurations.buttonOptions.inlineCode, + controller: + toolbarConfigurations.buttonOptions.inlineCode.controller ?? + context.requireQuillController, + // icon: Icons.code, + // iconSize: toolbarIconSize, + // tooltip: buttonTooltips[ToolbarButtons.inlineCode], + // controller: controller, + // iconTheme: iconTheme, + // afterButtonPressed: afterButtonPressed, ), if (showColorButton) ColorButton( @@ -395,12 +411,16 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { if (showDirection) ToggleStyleButton( attribute: Attribute.rtl, - tooltip: buttonTooltips[ToolbarButtons.direction], - controller: controller, - icon: Icons.format_textdirection_r_to_l, - iconSize: toolbarIconSize, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, + options: toolbarConfigurations.buttonOptions.direction, + controller: + toolbarConfigurations.buttonOptions.direction.controller ?? + context.requireQuillController, + // tooltip: buttonTooltips[ToolbarButtons.direction], + // controller: controller, + // icon: Icons.format_textdirection_r_to_l, + // iconSize: toolbarIconSize, + // iconTheme: iconTheme, + // afterButtonPressed: afterButtonPressed, ), if (showDividers && isButtonGroupShown[1] && @@ -436,22 +456,30 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { if (showListNumbers) ToggleStyleButton( attribute: Attribute.ol, - tooltip: buttonTooltips[ToolbarButtons.listNumbers], - controller: controller, - icon: Icons.format_list_numbered, - iconSize: toolbarIconSize, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, + options: toolbarConfigurations.buttonOptions.listNumbers, + controller: + toolbarConfigurations.buttonOptions.listNumbers.controller ?? + context.requireQuillController, + // tooltip: buttonTooltips[ToolbarButtons.listNumbers], + // controller: controller, + // icon: Icons.format_list_numbered, + // iconSize: toolbarIconSize, + // iconTheme: iconTheme, + // afterButtonPressed: afterButtonPressed, ), if (showListBullets) ToggleStyleButton( attribute: Attribute.ul, - tooltip: buttonTooltips[ToolbarButtons.listBullets], - controller: controller, - icon: Icons.format_list_bulleted, - iconSize: toolbarIconSize, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, + options: toolbarConfigurations.buttonOptions.listBullets, + controller: + toolbarConfigurations.buttonOptions.listBullets.controller ?? + context.requireQuillController, + // tooltip: buttonTooltips[ToolbarButtons.listBullets], + // controller: controller, + // icon: Icons.format_list_bulleted, + // iconSize: toolbarIconSize, + // iconTheme: iconTheme, + // afterButtonPressed: afterButtonPressed, ), if (showListCheck) ToggleCheckListButton( @@ -466,12 +494,16 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { if (showCodeBlock) ToggleStyleButton( attribute: Attribute.codeBlock, - tooltip: buttonTooltips[ToolbarButtons.codeBlock], - controller: controller, - icon: Icons.code, - iconSize: toolbarIconSize, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, + options: toolbarConfigurations.buttonOptions.codeBlock, + controller: + toolbarConfigurations.buttonOptions.codeBlock.controller ?? + context.requireQuillController, + // tooltip: buttonTooltips[ToolbarButtons.codeBlock], + // controller: controller, + // icon: Icons.code, + // iconSize: toolbarIconSize, + // iconTheme: iconTheme, + // afterButtonPressed: afterButtonPressed, ), if (showDividers && isButtonGroupShown[3] && @@ -480,13 +512,17 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { color: sectionDividerColor, space: sectionDividerSpace), if (showQuote) ToggleStyleButton( + options: toolbarConfigurations.buttonOptions.quote, + controller: + toolbarConfigurations.buttonOptions.quote.controller ?? + context.requireQuillController, attribute: Attribute.blockQuote, - tooltip: buttonTooltips[ToolbarButtons.quote], - controller: controller, - icon: Icons.format_quote, - iconSize: toolbarIconSize, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, + // tooltip: buttonTooltips[ToolbarButtons.quote], + // controller: controller, + // icon: Icons.format_quote, + // iconSize: toolbarIconSize, + // iconTheme: iconTheme, + // afterButtonPressed: afterButtonPressed, ), if (showIndent) IndentButton( diff --git a/pubspec.yaml b/pubspec.yaml index f1b1a4d5..64b4af37 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: 7.6.1 +version: 7.7.0 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill platforms: