Value setting Stateful toolbar buttons derive from base class

pull/1829/head
AtlasAutocode 1 year ago
parent dd03bffa0f
commit 04f086c3f8
  1. 36
      example/lib/screens/quill/my_quill_toolbar.dart
  2. 43
      lib/src/widgets/quill/quill_controller.dart
  3. 83
      lib/src/widgets/toolbar/base_button/stateful_base_button_ex.dart
  4. 110
      lib/src/widgets/toolbar/buttons/font_family_button.dart
  5. 98
      lib/src/widgets/toolbar/buttons/font_size_button.dart
  6. 71
      lib/src/widgets/toolbar/buttons/toggle_check_list_button.dart
  7. 79
      lib/src/widgets/toolbar/buttons/toggle_style_button.dart

@ -223,24 +223,24 @@ class MyQuillToolbar extends StatelessWidget {
'40': '40.0'
},
// headerStyleType: HeaderStyleType.buttons,
buttonOptions: QuillSimpleToolbarButtonOptions(
base: QuillToolbarBaseButtonOptions(
afterButtonPressed: focusNode.requestFocus,
// // iconSize: 20,
// iconTheme: QuillIconTheme(
// iconButtonSelectedData: IconButtonData(
// style: IconButton.styleFrom(
// foregroundColor: Colors.blue,
// ),
// ),
// iconButtonUnselectedData: IconButtonData(
// style: IconButton.styleFrom(
// foregroundColor: Colors.red,
// ),
// ),
// ),
),
),
buttonOptions: QuillSimpleToolbarButtonOptions(
base: QuillToolbarBaseButtonOptions(
afterButtonPressed: focusNode.requestFocus,
// // iconSize: 20,
// iconTheme: QuillIconTheme(
// iconButtonSelectedData: IconButtonData(
// style: IconButton.styleFrom(
// foregroundColor: Colors.blue,
// ),
// ),
// iconButtonUnselectedData: IconButtonData(
// style: IconButton.styleFrom(
// foregroundColor: Colors.red,
// ),
// ),
// ),
),
),
customButtons: [
QuillToolbarCustomButtonOptions(
icon: const Icon(Icons.add_alarm_rounded),

@ -66,6 +66,49 @@ class QuillController extends ChangeNotifier {
notifyListeners();
}
// Those 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
@Deprecated('No longer used')
MapEntry<String, String>? _selectedFontFamily;
/// The current font family, null to use the default one
@Deprecated('No longer used')
MapEntry<String, String>? get selectedFontFamily => _selectedFontFamily;
@Deprecated('No longer used')
void selectFontFamily(MapEntry<String, String>? newFontFamily) {
_selectedFontFamily = newFontFamily;
}
/// The current font size, null to use the default one
@Deprecated('No longer used')
MapEntry<String, String>? _selectedFontSize;
/// The current font size, null to use the default one
@Deprecated('No longer used')
MapEntry<String, String>? get selectedFontSize => _selectedFontSize;
@Deprecated('No longer used')
void selectFontSize(MapEntry<String, String>? newFontSize) {
_selectedFontSize = newFontSize;
}
/// For the [QuillToolbarToggleStyleButton]
@Deprecated('No longer used')
final Map<Attribute, bool?> _selectedStyles = {};
/// For the [QuillToolbarToggleStyleButton]
@Deprecated('No longer used')
Map<Attribute, bool?> get selectedStyles => _selectedStyles;
/// For the [QuillToolbarToggleStyleButton]
@Deprecated('No longer used')
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;

@ -0,0 +1,83 @@
import 'package:flutter/cupertino.dart';
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 QuillToolbarStatefulBaseButton<
T extends QuillToolbarBaseButtonOptions<T, E>,
E extends QuillToolbarBaseButtonExtraOptions> extends StatefulWidget {
const QuillToolbarStatefulBaseButton(
{required this.controller, required this.options, super.key});
final T options;
final QuillController controller;
}
/// The [W] is the widget that creates this State
abstract class QuillToolbarBaseButtonState<
W extends QuillToolbarStatefulBaseButton<T, E>,
T extends QuillToolbarBaseButtonOptions<T, E>,
E extends QuillToolbarBaseButtonExtraOptions> extends State<W> {
T get options => widget.options;
QuillController get controller => widget.controller;
@override
void initState() {
super.initState();
controller.addListener(didChangeEditingValue);
}
void didChangeEditingValue();
@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);
}
}
String get defaultTooltip;
String get tooltip {
return options.tooltip ??
context.quillToolbarBaseButtonOptions?.tooltip ??
defaultTooltip;
}
double get iconSize {
final baseFontSize = context.quillToolbarBaseButtonOptions?.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;
}
}

@ -4,53 +4,36 @@ 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/stateful_base_button_ex.dart';
import '../base_toolbar.dart';
class QuillToolbarFontFamilyButton extends StatefulWidget {
class QuillToolbarFontFamilyButton extends QuillToolbarStatefulBaseButton<
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<QuillToolbarFontFamilyButton> {
class QuillToolbarFontFamilyButtonState extends QuillToolbarBaseButtonState<
QuillToolbarFontFamilyButton,
QuillToolbarFontFamilyButtonOptions,
QuillToolbarFontFamilyButtonExtraOptions> {
var _currentValue = '';
QuillToolbarFontFamilyButtonOptions get options {
return widget.options;
}
@override
void initState() {
super.initState();
_initState();
controller
.addListener(_didChangeEditingValue);
}
void _initState() {}
@override
void didChangeDependencies() {
super.didChangeDependencies();
@ -64,31 +47,18 @@ class QuillToolbarFontFamilyButtonState
context.loc.font;
}
@override
void didUpdateWidget(covariant QuillToolbarFontFamilyButton oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.controller != controller) {
oldWidget.controller.removeListener(_didChangeEditingValue);
controller.addListener(_didChangeEditingValue);
}
}
@override
void dispose() {
controller.removeListener(_didChangeEditingValue);
super.dispose();
void didChangeEditingValue() {
final attribute =
controller.getSelectionStyle().attributes[options.attribute.key];
if (attribute == null) {
setState(() => _currentValue = _defaultDisplayText);
return;
}
final keyName = _getKeyName(attribute.value);
setState(() => _currentValue = keyName ?? _defaultDisplayText);
}
void _didChangeEditingValue() {
final attribute = controller.getSelectionStyle().attributes[options.attribute.key];
if (attribute == null) {
setState(() => _currentValue = _defaultDisplayText);
return;
}
final keyName = _getKeyName(attribute.value);
setState(() => _currentValue = keyName ?? _defaultDisplayText);
}
Map<String, String> get rawItemsMap {
final rawItemsMap =
context.quillSimpleToolbarConfigurations?.fontFamilyValues ??
@ -116,38 +86,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) {
@ -216,7 +156,13 @@ class QuillToolbarFontFamilyButtonState
options.onSelected?.call(newValue);
}
});
},
if (fontFamily.value == 'Clear') {
controller.selectFontFamily(null);
return;
}
controller.selectFontFamily(fontFamily);
},
child: Text(
fontFamily.key.toString(),
style: TextStyle(

@ -5,44 +5,36 @@ 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/stateful_base_button_ex.dart';
import '../base_toolbar.dart';
class QuillToolbarFontSizeButton extends StatefulWidget {
class QuillToolbarFontSizeButton extends QuillToolbarStatefulBaseButton<
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<QuillToolbarFontSizeButton> {
class QuillToolbarFontSizeButtonState extends QuillToolbarBaseButtonState<
QuillToolbarFontSizeButton,
QuillToolbarFontSizeButtonOptions,
QuillToolbarFontSizeButtonExtraOptions> {
final _menuController = MenuController();
String _currentValue = '';
QuillToolbarFontSizeButtonOptions get options {
return widget.options;
}
Map<String, String> get rawItemsMap {
final fontSizes = options.rawItemsMap ??
context.quillSimpleToolbarConfigurations?.fontSizesValues ??
@ -72,16 +64,6 @@ class QuillToolbarFontSizeButtonState
context.loc.fontSize;
}
@override
void initState() {
super.initState();
_initState();
controller
.addListener(_didChangeEditingValue);
}
void _initState() {}
@override
void didChangeDependencies() {
super.didChangeDependencies();
@ -89,22 +71,9 @@ class QuillToolbarFontSizeButtonState
}
@override
void didUpdateWidget(covariant QuillToolbarFontSizeButton oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.controller != controller) {
oldWidget.controller.removeListener(_didChangeEditingValue);
controller.addListener(_didChangeEditingValue);
}
}
@override
void dispose() {
controller.removeListener(_didChangeEditingValue);
super.dispose();
}
void _didChangeEditingValue() {
final attribute = controller.getSelectionStyle().attributes[options.attribute.key];
void didChangeEditingValue() {
final attribute =
controller.getSelectionStyle().attributes[options.attribute.key];
if (attribute == null) {
setState(() => _currentValue = _defaultDisplayText);
return;
@ -122,38 +91,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) {
@ -206,6 +145,12 @@ class QuillToolbarFontSizeButtonState
options.onSelected?.call(newValue);
}
});
if (fontSize.value == '0') {
controller.selectFontSize(null);
return;
}
controller.selectFontSize(fontSize);
},
child: Text(
fontSize.key.toString(),
@ -248,8 +193,7 @@ class QuillToolbarFontSizeButtonState
enabled: hasFinalWidth,
wrapper: (child) => Expanded(child: child),
child: Text(
getLabel(_currentValue) ??
'',
getLabel(_currentValue) ?? '',
overflow: options.labelOverflow,
style: options.style ??
TextStyle(

@ -1,37 +1,37 @@
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/stateful_base_button_ex.dart';
import '../base_toolbar.dart';
class QuillToolbarToggleCheckListButton extends StatefulWidget {
class QuillToolbarToggleCheckListButton extends QuillToolbarStatefulBaseButton<
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<QuillToolbarToggleCheckListButton> {
extends QuillToolbarBaseButtonState<
QuillToolbarToggleCheckListButton,
QuillToolbarToggleCheckListButtonOptions,
QuillToolbarToggleCheckListButtonExtraOptions> {
bool? _isToggled;
Style get _selectionStyle => controller.getSelectionStyle();
void _didChangeEditingValue() {
@override
void didChangeEditingValue() {
setState(() {
_isToggled = _getIsToggled(controller.getSelectionStyle().attributes);
});
@ -41,7 +41,6 @@ class QuillToolbarToggleCheckListButtonState
void initState() {
super.initState();
_isToggled = _getIsToggled(_selectionStyle.attributes);
controller.addListener(_didChangeEditingValue);
}
bool _getIsToggled(Map<String, Attribute> attrs) {
@ -65,50 +64,12 @@ class QuillToolbarToggleCheckListButtonState
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 +77,6 @@ class QuillToolbarToggleCheckListButtonState
Icons.check_box;
}
String get tooltip {
return options.tooltip ??
baseButtonExtraOptions?.tooltip ??
context.loc.checkedList;
}
@override
Widget build(BuildContext context) {
final childBuilder =

@ -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/stateful_base_button_ex.dart';
import '../base_toolbar.dart';
typedef ToggleStyleButtonBuilder = Widget Function(
@ -21,67 +21,35 @@ typedef ToggleStyleButtonBuilder = Widget Function(
QuillIconTheme? iconTheme,
]);
class QuillToolbarToggleStyleButton extends StatefulWidget {
class QuillToolbarToggleStyleButton extends QuillToolbarStatefulBaseButton<
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<QuillToolbarToggleStyleButton> {
class QuillToolbarToggleStyleButtonState extends QuillToolbarBaseButtonState<
QuillToolbarToggleStyleButton,
QuillToolbarToggleStyleButtonOptions,
QuillToolbarToggleStyleButtonExtraOptions> {
bool? _isToggled;
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;
}
(String, IconData) get _defaultTooltipAndIconData {
@ -134,11 +102,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 ??
@ -187,19 +152,12 @@ class QuillToolbarToggleStyleButtonState
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() {
void didChangeEditingValue() {
setState(() => _isToggled = _getIsToggled(_selectionStyle.attributes));
}
@ -217,12 +175,11 @@ class QuillToolbarToggleStyleButtonState
}
void _toggleAttribute() {
controller
.formatSelection(
(_isToggled ?? false)
? Attribute.clone(widget.attribute, null)
: widget.attribute,
);
controller.formatSelection(
(_isToggled ?? false)
? Attribute.clone(widget.attribute, null)
: widget.attribute,
);
}
}

Loading…
Cancel
Save