Restore old feel and look (#1621)

* Restore correct feel&look of `QuillToolbarIconButton`

* Export `QuillToolbarSelectAlignmentButtons`

* Restore old call of `QuillToolbarIconButton`

* Restore old call of `QuillToolbarIconButton`

* Resore original button PR #1575

* Restore old feel&look of buttons

* Restore original `QuillToolbarSelectAlignmentButton`

* Restore original `QuillToolbarLinkStyleButton2`

* Make `options` optional

* Restore old `QuillToolbarFontFamilyButton` build

* Restore old build of `QuillToolbarFontSizeButton`

* Change `textStyle` to `style`

* Remove redundant export

---------

Co-authored-by: Ellet Hnewa <73608287+ellet0@users.noreply.github.com>
pull/1624/head
MacDeveloper1 1 year ago committed by GitHub
parent d23b80707f
commit e820c5b29d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      example/lib/presentation/quill/my_quill_toolbar.dart
  2. 1
      flutter_quill_extensions/lib/embeds/formula/toolbar/formula_button.dart
  3. 1
      flutter_quill_extensions/lib/embeds/image/toolbar/image_button.dart
  4. 2
      flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart
  5. 1
      flutter_quill_extensions/lib/embeds/video/toolbar/video_button.dart
  6. 17
      lib/src/models/config/toolbar/buttons/font_family_configurations.dart
  7. 25
      lib/src/models/config/toolbar/buttons/font_size_configurations.dart
  8. 82
      lib/src/models/config/toolbar/buttons/select_header_style_dropdown_button_configurations.dart
  9. 1
      lib/src/widgets/toolbar/base_toolbar.dart
  10. 281
      lib/src/widgets/toolbar/buttons/alignment/select_alignment_button_original.dart
  11. 10
      lib/src/widgets/toolbar/buttons/clear_format_button.dart
  12. 16
      lib/src/widgets/toolbar/buttons/color/color_button.dart
  13. 1
      lib/src/widgets/toolbar/buttons/custom_button_button.dart
  14. 13
      lib/src/widgets/toolbar/buttons/font_family_button.dart
  15. 20
      lib/src/widgets/toolbar/buttons/font_size_button.dart
  16. 349
      lib/src/widgets/toolbar/buttons/hearder_style/select_header_style_dropdown_button.dart
  17. 1
      lib/src/widgets/toolbar/buttons/history_button.dart
  18. 10
      lib/src/widgets/toolbar/buttons/indent_button.dart
  19. 10
      lib/src/widgets/toolbar/buttons/link_style2_button.dart
  20. 1
      lib/src/widgets/toolbar/buttons/link_style_button.dart
  21. 56
      lib/src/widgets/toolbar/buttons/quill_icon_button.dart
  22. 1
      lib/src/widgets/toolbar/buttons/search/search_button.dart
  23. 17
      lib/src/widgets/toolbar/buttons/toggle_style_button.dart

@ -210,7 +210,7 @@ class MyQuillToolbar extends StatelessWidget {
),
selectHeaderStyleDropdownButton:
const QuillToolbarSelectHeaderStyleDropdownButtonOptions(
textStyle: TextStyle(
style: TextStyle(
fontSize: 20,
),
iconTheme: QuillIconTheme(

@ -94,7 +94,6 @@ class QuillToolbarFormulaButton extends StatelessWidget {
icon: Icon(iconData, size: iconSize * iconButtonFactor, color: iconColor),
tooltip: tooltip,
onPressed: () => _sharedOnPressed(context),
isFilled: false,
);
}

@ -109,7 +109,6 @@ class QuillToolbarImageButton extends StatelessWidget {
color: iconColor,
),
tooltip: tooltip,
isFilled: false,
onPressed: () => _sharedOnPressed(context),
);
}

@ -108,8 +108,6 @@ class QuillToolbarCameraButton extends StatelessWidget {
return QuillToolbarIconButton(
icon: Icon(iconData, size: iconButtonFactor * iconSize, color: iconColor),
tooltip: tooltip,
isFilled: false,
// isDesktop(supportWeb: false) ? null :
onPressed: () => _sharedOnPressed(context),
);
}

@ -108,7 +108,6 @@ class QuillToolbarVideoButton extends StatelessWidget {
return QuillToolbarIconButton(
icon: Icon(iconData, size: iconSize * iconButtonFactor, color: iconColor),
tooltip: tooltip,
isFilled: false,
onPressed: () => _sharedOnPressed(context),
);
}

@ -49,11 +49,18 @@ class QuillToolbarFontFamilyButtonOptions extends QuillToolbarBaseButtonOptions<
this.itemPadding,
this.defaultItemColor = Colors.red,
this.renderFontFamilies = true,
this.highlightElevation = 1,
this.hoverElevation = 1,
this.fillColor,
this.iconSize,
this.iconButtonFactor,
});
/// By default it will be [fontFamilyValues] from [QuillSimpleToolbarConfigurations]
final Color? fillColor;
final double hoverElevation;
final double highlightElevation;
/// By default it will be [fontFamilyValues] from [QuillToolbarConfigurations]
/// You can override this if you want
final Map<String, String>? rawItemsMap;
final ValueChanged<String>? onSelected;
@ -75,6 +82,9 @@ class QuillToolbarFontFamilyButtonOptions extends QuillToolbarBaseButtonOptions<
final double? iconButtonFactor;
QuillToolbarFontFamilyButtonOptions copyWith({
Color? fillColor,
double? hoverElevation,
double? highlightElevation,
List<PopupMenuEntry<String>>? items,
Map<String, String>? rawItemsMap,
ValueChanged<String>? onSelected,
@ -91,6 +101,8 @@ class QuillToolbarFontFamilyButtonOptions extends QuillToolbarBaseButtonOptions<
Color? defaultItemColor,
double? iconSize,
double? iconButtonFactor,
// Add properties to override inherited properties
QuillController? controller,
IconData? iconData,
VoidCallback? afterButtonPressed,
String? tooltip,
@ -117,6 +129,9 @@ class QuillToolbarFontFamilyButtonOptions extends QuillToolbarBaseButtonOptions<
defaultItemColor: defaultItemColor ?? this.defaultItemColor,
iconSize: iconSize ?? this.iconSize,
iconButtonFactor: iconButtonFactor ?? this.iconButtonFactor,
fillColor: fillColor ?? this.fillColor,
hoverElevation: hoverElevation ?? this.hoverElevation,
highlightElevation: highlightElevation ?? this.highlightElevation,
);
}
}

@ -2,15 +2,9 @@ import 'dart:ui';
import 'package:flutter/foundation.dart' show immutable;
import 'package:flutter/material.dart'
show ButtonStyle, Colors, PopupMenuEntry, ValueChanged;
show Colors, PopupMenuEntry, ValueChanged;
import 'package:flutter/widgets.dart'
show
Color,
EdgeInsets,
EdgeInsetsGeometry,
OutlinedBorder,
TextOverflow,
TextStyle;
show Color, EdgeInsets, EdgeInsetsGeometry, TextOverflow, TextStyle;
import '../../../documents/attribute.dart';
import '../../quill_configurations.dart';
@ -35,6 +29,9 @@ class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions<
const QuillToolbarFontSizeButtonOptions({
this.iconSize,
this.iconButtonFactor,
this.fillColor,
this.hoverElevation = 1,
this.highlightElevation = 1,
this.rawItemsMap,
this.onSelected,
this.attribute = Attribute.size,
@ -49,15 +46,15 @@ class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions<
this.itemPadding,
this.defaultItemColor = Colors.red,
super.childBuilder,
this.shape,
});
final double? iconSize;
final double? iconButtonFactor;
final Color? fillColor;
final double hoverElevation;
final double highlightElevation;
final ButtonStyle? shape;
/// By default it will be [fontSizesValues] from [QuillSimpleToolbarConfigurations]
/// By default it will be [fontSizesValues] from [QuillToolbarConfigurations]
/// You can override this if you want
final Map<String, String>? rawItemsMap;
final ValueChanged<String>? onSelected;
@ -91,11 +88,13 @@ class QuillToolbarFontSizeButtonOptions extends QuillToolbarBaseButtonOptions<
Color? defaultItemColor,
VoidCallback? afterButtonPressed,
String? tooltip,
OutlinedBorder? shape,
}) {
return QuillToolbarFontSizeButtonOptions(
iconSize: iconSize ?? this.iconSize,
iconButtonFactor: iconButtonFactor ?? this.iconButtonFactor,
fillColor: fillColor ?? this.fillColor,
hoverElevation: hoverElevation ?? this.hoverElevation,
highlightElevation: highlightElevation ?? this.highlightElevation,
rawItemsMap: rawItemsMap ?? this.rawItemsMap,
onSelected: onSelected ?? this.onSelected,
attribute: attribute ?? this.attribute,

@ -1,9 +1,9 @@
import 'package:flutter/widgets.dart'
show IconData, TextStyle, ValueChanged, VoidCallback;
import 'package:flutter/material.dart';
import '../../../../widgets/toolbar/base_toolbar.dart';
import '../../../../widgets/quill/quill_controller.dart';
import '../../../documents/attribute.dart';
import '../../../themes/quill_icon_theme.dart';
import '../../quill_configurations.dart';
class QuillToolbarSelectHeaderStyleDropdownButtonExtraOptions
extends QuillToolbarBaseButtonExtraOptions {
@ -21,46 +21,68 @@ class QuillToolbarSelectHeaderStyleDropdownButtonOptions
QuillToolbarSelectHeaderStyleDropdownButtonOptions,
QuillToolbarSelectHeaderStyleDropdownButtonExtraOptions> {
const QuillToolbarSelectHeaderStyleDropdownButtonOptions({
super.iconData,
super.afterButtonPressed,
super.childBuilder,
super.iconTheme,
super.tooltip,
super.iconTheme,
super.childBuilder,
this.iconSize,
this.iconButtonFactor,
this.textStyle,
super.iconData,
this.fillColor,
this.hoverElevation = 0,
this.highlightElevation = 0,
this.onSelected,
this.attributes,
this.padding,
this.style,
this.width,
this.labelOverflow = TextOverflow.visible,
this.itemHeight,
this.itemPadding,
this.defaultItemColor,
this.renderItemTextStyle = false,
});
/// By default we will the toolbar axis from [QuillSimpleToolbarConfigurations]
final double? iconSize;
final double? iconButtonFactor;
final TextStyle? textStyle;
/// Header attributes, defaults to:
/// ```dart
/// [
/// Attribute.h1,
/// Attribute.h2,
/// Attribute.h3,
/// Attribute.h4,
/// Attribute.h5,
/// Attribute.h6,
/// Attribute.header,
/// ]
/// ```
final List<Attribute<int>>? attributes;
final Color? fillColor;
final double hoverElevation;
final double highlightElevation;
final ValueChanged<String>? onSelected;
final List<Attribute>? attributes;
final EdgeInsetsGeometry? padding;
final TextStyle? style;
final double? width;
final TextOverflow labelOverflow;
final double? itemHeight;
final EdgeInsets? itemPadding;
final Color? defaultItemColor;
final bool renderItemTextStyle;
QuillToolbarSelectHeaderStyleDropdownButtonOptions copyWith({
Color? fillColor,
double? hoverElevation,
double? highlightElevation,
List<PopupMenuEntry<String>>? items,
ValueChanged<String>? onSelected,
List<Attribute<int>>? attributes,
List<Attribute>? attributes,
EdgeInsetsGeometry? padding,
TextStyle? style,
double? width,
TextOverflow? labelOverflow,
bool? renderFontFamilies,
bool? overrideTooltipByFontFamily,
double? itemHeight,
EdgeInsets? itemPadding,
Color? defaultItemColor,
double? iconSize,
double? iconButtonFactor,
QuillController? controller,
IconData? iconData,
VoidCallback? afterButtonPressed,
String? tooltip,
QuillIconTheme? iconTheme,
bool? renderItemTextStyle,
}) {
return QuillToolbarSelectHeaderStyleDropdownButtonOptions(
attributes: attributes ?? this.attributes,
@ -68,8 +90,20 @@ class QuillToolbarSelectHeaderStyleDropdownButtonOptions
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,
labelOverflow: labelOverflow ?? this.labelOverflow,
itemHeight: itemHeight ?? this.itemHeight,
itemPadding: itemPadding ?? this.itemPadding,
defaultItemColor: defaultItemColor ?? this.defaultItemColor,
iconSize: iconSize ?? this.iconSize,
iconButtonFactor: iconButtonFactor ?? this.iconButtonFactor,
fillColor: fillColor ?? this.fillColor,
hoverElevation: hoverElevation ?? this.hoverElevation,
highlightElevation: highlightElevation ?? this.highlightElevation,
renderItemTextStyle: renderItemTextStyle ?? this.renderItemTextStyle,
);
}
}

@ -9,6 +9,7 @@ import 'simple_toolbar.dart';
export '../../models/config/toolbar/base_button_configurations.dart';
export '../../models/config/toolbar/simple_toolbar_configurations.dart';
export 'buttons/alignment/select_alignment_button_original.dart';
export 'buttons/clear_format_button.dart';
export 'buttons/color/color_button.dart';
export 'buttons/custom_button_button.dart';

@ -0,0 +1,281 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import '../../../../../translations.dart';
import '../../../../extensions/quill_configurations_ext.dart';
import '../../../../models/config/quill_configurations.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';
class QuillToolbarSelectAlignmentButton extends StatefulWidget {
const QuillToolbarSelectAlignmentButton({
required this.controller,
this.options = const QuillToolbarSelectAlignmentButtonOptions(),
this.showLeftAlignment = true,
this.showCenterAlignment = true,
this.showRightAlignment = true,
this.showJustifyAlignment = true,
this.padding,
super.key,
});
final QuillController controller;
final QuillToolbarSelectAlignmentButtonOptions options;
final bool showLeftAlignment;
final bool showCenterAlignment;
final bool showRightAlignment;
final bool showJustifyAlignment;
final EdgeInsetsGeometry? padding;
@override
QuillToolbarSelectAlignmentButtonState createState() =>
QuillToolbarSelectAlignmentButtonState();
}
class QuillToolbarSelectAlignmentButtonState
extends State<QuillToolbarSelectAlignmentButton> {
Attribute? _value;
Style get _selectionStyle => controller.getSelectionStyle();
@override
void initState() {
super.initState();
setState(() {
_value = _selectionStyle.attributes[Attribute.align.key] ??
Attribute.leftAlignment;
});
controller.addListener(_didChangeEditingValue);
}
QuillToolbarSelectAlignmentButtonOptions get options {
return widget.options;
}
QuillController get controller {
return widget.controller;
}
double get _iconSize {
final baseFontSize = baseButtonExtraOptions.globalIconSize;
final iconSize = options.iconSize;
return iconSize ?? baseFontSize;
}
double get _iconButtonFactor {
final baseIconFactor = baseButtonExtraOptions.globalIconButtonFactor;
final iconButtonFactor = options.iconButtonFactor;
return iconButtonFactor ?? baseIconFactor;
}
VoidCallback? get _afterButtonPressed {
return options.afterButtonPressed ??
baseButtonExtraOptions.afterButtonPressed;
}
QuillIconTheme? get _iconTheme {
return options.iconTheme ?? baseButtonExtraOptions.iconTheme;
}
QuillToolbarBaseButtonOptions get baseButtonExtraOptions {
return context.requireQuillToolbarBaseButtonOptions;
}
QuillSelectAlignmentValues<IconData> get _iconsData {
final iconsData = options.iconsData;
if (iconsData != null) {
return iconsData;
}
final baseIconData = baseButtonExtraOptions.iconData;
if (baseIconData != null) {
return QuillSelectAlignmentValues(
leftAlignment: baseIconData,
centerAlignment: baseIconData,
rightAlignment: baseIconData,
justifyAlignment: baseIconData,
);
}
return const QuillSelectAlignmentValues(
leftAlignment: Icons.format_align_left,
centerAlignment: Icons.format_align_center,
rightAlignment: Icons.format_align_right,
justifyAlignment: Icons.format_align_justify,
);
}
QuillSelectAlignmentValues<String> get _tooltips {
final tooltips = options.tooltips;
if (tooltips != null) {
return tooltips;
}
final baseToolTip = baseButtonExtraOptions.tooltip;
if (baseToolTip != null) {
return QuillSelectAlignmentValues(
leftAlignment: baseToolTip,
centerAlignment: baseToolTip,
rightAlignment: baseToolTip,
justifyAlignment: baseToolTip,
);
}
return QuillSelectAlignmentValues(
leftAlignment: context.loc.alignLeft,
centerAlignment: context.loc.alignCenter,
rightAlignment: context.loc.alignRight,
justifyAlignment: context.loc.justifyWinWidth,
);
}
void _didChangeEditingValue() {
setState(() {
_value = _selectionStyle.attributes[Attribute.align.key] ??
Attribute.leftAlignment;
});
}
@override
void didUpdateWidget(covariant QuillToolbarSelectAlignmentButton oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.controller != controller) {
oldWidget.controller.removeListener(_didChangeEditingValue);
controller.addListener(_didChangeEditingValue);
_value = _selectionStyle.attributes[Attribute.align.key] ??
Attribute.leftAlignment;
}
}
@override
void dispose() {
controller.removeListener(_didChangeEditingValue);
super.dispose();
}
@override
Widget build(BuildContext context) {
final valueToText = <Attribute, String>{
if (widget.showLeftAlignment)
Attribute.leftAlignment: Attribute.leftAlignment.value!,
if (widget.showCenterAlignment)
Attribute.centerAlignment: Attribute.centerAlignment.value!,
if (widget.showRightAlignment)
Attribute.rightAlignment: Attribute.rightAlignment.value!,
if (widget.showJustifyAlignment)
Attribute.justifyAlignment: Attribute.justifyAlignment.value!,
};
final valueAttribute = <Attribute>[
if (widget.showLeftAlignment) Attribute.leftAlignment,
if (widget.showCenterAlignment) Attribute.centerAlignment,
if (widget.showRightAlignment) Attribute.rightAlignment,
if (widget.showJustifyAlignment) Attribute.justifyAlignment
];
final valueString = <String>[
if (widget.showLeftAlignment) Attribute.leftAlignment.value!,
if (widget.showCenterAlignment) Attribute.centerAlignment.value!,
if (widget.showRightAlignment) Attribute.rightAlignment.value!,
if (widget.showJustifyAlignment) Attribute.justifyAlignment.value!,
];
// final _valueToButtons = <Attribute, ToolbarButtons>{
// if (widget.showLeftAlignment!)
// Attribute.leftAlignment: ToolbarButtons.leftAlignment,
// if (widget.showCenterAlignment!)
// Attribute.centerAlignment: ToolbarButtons.centerAlignment,
// if (widget.showRightAlignment!)
// Attribute.rightAlignment: ToolbarButtons.rightAlignment,
// if (widget.showJustifyAlignment!)
// Attribute.justifyAlignment: ToolbarButtons.justifyAlignment,
// };
final buttonCount = ((widget.showLeftAlignment) ? 1 : 0) +
((widget.showCenterAlignment) ? 1 : 0) +
((widget.showRightAlignment) ? 1 : 0) +
((widget.showJustifyAlignment) ? 1 : 0);
final childBuilder =
options.childBuilder ?? baseButtonExtraOptions.childBuilder;
void sharedOnPressed(int index) {
valueAttribute[index] == Attribute.leftAlignment
? controller.formatSelection(
Attribute.clone(Attribute.align, null),
)
: controller.formatSelection(valueAttribute[index]);
_afterButtonPressed?.call();
}
return Row(
mainAxisSize: MainAxisSize.min,
children: List.generate(buttonCount, (index) {
if (childBuilder != null) {
return childBuilder(
QuillToolbarSelectAlignmentButtonOptions(
afterButtonPressed: _afterButtonPressed,
iconSize: _iconSize,
iconButtonFactor: _iconButtonFactor,
iconTheme: _iconTheme,
tooltips: _tooltips,
iconsData: _iconsData,
),
QuillToolbarSelectAlignmentButtonExtraOptions(
context: context,
controller: controller,
onPressed: () => sharedOnPressed(index),
),
);
}
final theme = Theme.of(context);
return Padding(
padding: widget.padding ??
const EdgeInsets.symmetric(horizontal: !kIsWeb ? 1.0 : 5.0),
child: ConstrainedBox(
constraints: BoxConstraints.tightFor(
width: _iconSize * _iconButtonFactor,
height: _iconSize * _iconButtonFactor,
),
child: UtilityWidgets.maybeTooltip(
message: valueString[index] == Attribute.leftAlignment.value
? _tooltips.leftAlignment
: valueString[index] == Attribute.centerAlignment.value
? _tooltips.centerAlignment
: valueString[index] == Attribute.rightAlignment.value
? _tooltips.rightAlignment
: _tooltips.justifyAlignment,
child: RawMaterialButton(
hoverElevation: 0,
highlightElevation: 0,
elevation: 0,
visualDensity: VisualDensity.compact,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(_iconTheme?.borderRadius ?? 2)),
fillColor: valueToText[_value] == valueString[index]
? (_iconTheme?.iconSelectedFillColor ?? theme.primaryColor)
: (_iconTheme?.iconUnselectedFillColor ??
theme.canvasColor),
onPressed: () => sharedOnPressed(index),
child: Icon(
valueString[index] == Attribute.leftAlignment.value
? _iconsData.leftAlignment
: valueString[index] == Attribute.centerAlignment.value
? _iconsData.centerAlignment
: valueString[index] == Attribute.rightAlignment.value
? _iconsData.rightAlignment
: _iconsData.justifyAlignment,
size: _iconSize,
color: valueToText[_value] == valueString[index]
? (_iconTheme?.iconSelectedColor ??
theme.primaryIconTheme.color)
: (_iconTheme?.iconUnselectedColor ??
theme.iconTheme.color),
),
),
),
),
);
}),
);
}
}

@ -107,11 +107,17 @@ class QuillToolbarClearFormatButton extends StatelessWidget {
final theme = Theme.of(context);
final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color;
final iconFillColor =
iconTheme?.iconUnselectedFillColor ?? theme.canvasColor;
return QuillToolbarIconButton(
tooltip: tooltip,
icon: Icon(iconData, size: iconSize * iconButtonFactor, color: iconColor),
isFilled: false,
highlightElevation: 0,
hoverElevation: 0,
size: iconSize * iconButtonFactor,
icon: Icon(iconData, size: iconSize, color: iconColor),
fillColor: iconFillColor,
borderRadius: iconTheme?.borderRadius ?? 2,
onPressed: _sharedOnPressed,
afterPressed: afterButtonPressed,
);

@ -194,14 +194,18 @@ class QuillToolbarColorButtonState extends State<QuillToolbarColorButton> {
);
}
return IconButton(
return QuillToolbarIconButton(
tooltip: tooltip,
iconSize: iconSize * iconButtonFactor,
icon: Icon(
iconData,
color: widget.isBackground ? iconColorBackground : iconColor,
),
highlightElevation: 0,
hoverElevation: 0,
size: iconSize * iconButtonFactor,
icon: Icon(iconData,
size: iconSize,
color: widget.isBackground ? iconColorBackground : iconColor),
fillColor: widget.isBackground ? fillColorBackground : fillColor,
borderRadius: iconTheme?.borderRadius ?? 2,
onPressed: _showColorPicker,
afterPressed: afterButtonPressed,
);
}

@ -81,7 +81,6 @@ class QuillToolbarCustomButton extends StatelessWidget {
return QuillToolbarIconButton(
icon: options.icon ?? const SizedBox.shrink(),
isFilled: false,
tooltip: tooltip,
onPressed: () => _onPressed(context),
afterPressed: afterButtonPressed,

@ -188,6 +188,15 @@ class QuillToolbarFontFamilyButtonState
final isMaterial3 = Theme.of(context).useMaterial3;
if (!isMaterial3) {
return RawMaterialButton(
visualDensity: VisualDensity.compact,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(iconTheme?.borderRadius ?? 2),
),
fillColor: options.fillColor,
elevation: 0,
hoverElevation: options.hoverElevation,
highlightElevation: options.hoverElevation,
onPressed: _onPressed,
child: _buildContent(context),
);
@ -198,8 +207,8 @@ class QuillToolbarFontFamilyButtonState
style: IconButton.styleFrom(
shape: iconTheme?.borderRadius != null
? RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
iconTheme?.borderRadius ?? -1),
borderRadius:
BorderRadius.circular(iconTheme?.borderRadius ?? 2),
)
: null,
),

@ -146,9 +146,21 @@ class QuillToolbarFontSizeButtonState
builder: (context) {
final isMaterial3 = Theme.of(context).useMaterial3;
if (!isMaterial3) {
return RawMaterialButton(
onPressed: _onPressed,
child: _buildContent(context),
return Tooltip(
message: tooltip,
child: RawMaterialButton(
visualDensity: VisualDensity.compact,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(iconTheme?.borderRadius ?? 2),
),
fillColor: options.fillColor,
elevation: 0,
hoverElevation: options.hoverElevation,
highlightElevation: options.hoverElevation,
onPressed: _onPressed,
child: _buildContent(context),
),
);
}
return IconButton(
@ -158,7 +170,7 @@ class QuillToolbarFontSizeButtonState
shape: iconTheme?.borderRadius != null
? RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(iconTheme?.borderRadius ?? -1),
BorderRadius.circular(iconTheme?.borderRadius ?? 2),
)
: null,
),

@ -1,11 +1,15 @@
import 'package:flutter/material.dart';
import '../../../../../extensions.dart';
import '../../../../../translations.dart';
import '../../../../extensions/quill_configurations_ext.dart';
import '../../../../models/config/toolbar/base_button_configurations.dart';
import '../../../../models/config/toolbar/buttons/select_header_style_dropdown_button_configurations.dart';
import '../../../../models/documents/attribute.dart';
import '../../../../models/documents/style.dart';
import '../../../../models/themes/quill_icon_theme.dart';
import '../../../others/default_styles.dart';
import '../../../quill/quill_controller.dart';
import '../../base_toolbar.dart';
class QuillToolbarSelectHeaderStyleDropdownButton extends StatefulWidget {
const QuillToolbarSelectHeaderStyleDropdownButton({
@ -14,6 +18,8 @@ class QuillToolbarSelectHeaderStyleDropdownButton extends StatefulWidget {
super.key,
});
/// 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 QuillToolbarSelectHeaderStyleDropdownButtonOptions options;
@ -24,190 +30,263 @@ class QuillToolbarSelectHeaderStyleDropdownButton extends StatefulWidget {
class _QuillToolbarSelectHeaderStyleDropdownButtonState
extends State<QuillToolbarSelectHeaderStyleDropdownButton> {
Attribute<dynamic> _selectedItem = Attribute.header;
Attribute? _selectedAttribute;
final _menuController = MenuController();
@override
void initState() {
super.initState();
widget.controller.addListener(_didChangeEditingValue);
}
Style get _selectionStyle => controller.getSelectionStyle();
@override
void dispose() {
widget.controller.removeListener(_didChangeEditingValue);
super.dispose();
}
late final _valueToText = <Attribute, String>{
Attribute.h1: context.loc.heading1,
Attribute.h2: context.loc.heading2,
Attribute.h3: context.loc.heading3,
Attribute.h4: context.loc.heading4,
Attribute.h5: context.loc.heading5,
Attribute.h6: context.loc.heading6,
Attribute.header: context.loc.normal,
};
@override
void didUpdateWidget(
covariant QuillToolbarSelectHeaderStyleDropdownButton oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.controller == widget.controller) {
return;
}
widget.controller
..removeListener(_didChangeEditingValue)
..addListener(_didChangeEditingValue);
}
Map<Attribute, TextStyle>? _headerTextStyles;
void _didChangeEditingValue() {
final newSelectedItem = _getHeaderValue();
if (newSelectedItem == _selectedItem) {
return;
}
setState(() {
_selectedItem = newSelectedItem;
});
QuillToolbarSelectHeaderStyleDropdownButtonOptions get options {
return widget.options;
}
Attribute<dynamic> _getHeaderValue() {
final attr = widget.controller.toolbarButtonToggler[Attribute.header.key];
if (attr != null) {
// checkbox tapping causes controller.selection to go to offset 0
widget.controller.toolbarButtonToggler.remove(Attribute.header.key);
return attr;
}
return widget.controller
.getSelectionStyle()
.attributes[Attribute.header.key] ??
Attribute.header;
}
String _label(Attribute<dynamic> value) {
final label = switch (value) {
Attribute.h1 => context.loc.heading1,
Attribute.h2 => context.loc.heading2,
Attribute.h3 => context.loc.heading3,
Attribute.h4 => context.loc.heading4,
Attribute.h5 => context.loc.heading5,
Attribute.h6 => context.loc.heading6,
Attribute.header => context.loc.normal,
Attribute<dynamic>() => throw ArgumentError(),
};
return label;
QuillController get controller {
return widget.controller;
}
double get iconSize {
final baseFontSize = context.quillToolbarBaseButtonOptions?.globalIconSize;
final iconSize = widget.options.iconSize;
return iconSize ?? baseFontSize ?? kDefaultIconSize;
final baseFontSize = baseButtonExtraOptions.globalIconSize;
final iconSize = options.iconSize;
return iconSize ?? baseFontSize;
}
double get iconButtonFactor {
final baseIconFactor =
context.quillToolbarBaseButtonOptions?.globalIconButtonFactor;
final iconButtonFactor = widget.options.iconButtonFactor;
return iconButtonFactor ?? baseIconFactor ?? kIconButtonFactor;
final baseIconFactor = baseButtonExtraOptions.globalIconButtonFactor;
final iconButtonFactor = options.iconButtonFactor;
return iconButtonFactor ?? baseIconFactor;
}
QuillIconTheme? get iconTheme {
return widget.options.iconTheme ??
context.quillToolbarBaseButtonOptions?.iconTheme;
VoidCallback? get afterButtonPressed {
return options.afterButtonPressed ??
baseButtonExtraOptions.afterButtonPressed;
}
List<Attribute<int?>> get headerAttributes {
return widget.options.attributes ??
[
Attribute.h1,
Attribute.h2,
Attribute.h3,
Attribute.h4,
Attribute.h5,
Attribute.h6,
Attribute.header,
];
QuillIconTheme? get iconTheme {
return options.iconTheme ?? baseButtonExtraOptions.iconTheme;
}
QuillToolbarBaseButtonOptions get baseButtonExtraOptions {
return context.requireQuillToolbarBaseButtonOptions;
}
VoidCallback? get afterButtonPressed {
return widget.options.afterButtonPressed ??
baseButtonExtraOptions.afterButtonPressed;
String get tooltip {
return options.tooltip ??
baseButtonExtraOptions.tooltip ??
context.loc.headerStyle;
}
void _onPressed(Attribute<int?> e) {
setState(() => _selectedItem = e);
widget.controller.formatSelection(_selectedItem);
List<Attribute> get _attrbuites {
return options.attributes ?? _valueToText.keys.toList();
}
@override
void dispose() {
controller.removeListener(_didChangeEditingValue);
super.dispose();
}
@override
void didUpdateWidget(
covariant QuillToolbarSelectHeaderStyleDropdownButton oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.controller != controller) {
oldWidget.controller.removeListener(_didChangeEditingValue);
controller.addListener(_didChangeEditingValue);
_selectedAttribute = _getHeaderValue();
}
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
if (_headerTextStyles == null) {
final defaultStyles = DefaultStyles.getInstance(context);
_headerTextStyles = {
Attribute.h1: defaultStyles.h1!.style,
Attribute.h2: defaultStyles.h2!.style,
Attribute.h3: defaultStyles.h3!.style,
Attribute.h4: defaultStyles.h4!.style,
Attribute.h5: defaultStyles.h5!.style,
Attribute.h6: defaultStyles.h6!.style,
Attribute.header:
widget.options.style ?? defaultStyles.paragraph!.style,
};
}
}
@override
void initState() {
super.initState();
controller.addListener(_didChangeEditingValue);
_selectedAttribute = _getHeaderValue();
}
@override
Widget build(BuildContext context) {
assert(_attrbuites.every((element) => _valueToText.keys.contains(element)));
final baseButtonConfigurations =
context.requireQuillToolbarBaseButtonOptions;
final childBuilder =
widget.options.childBuilder ?? baseButtonConfigurations.childBuilder;
options.childBuilder ?? baseButtonConfigurations.childBuilder;
if (childBuilder != null) {
return childBuilder(
widget.options.copyWith(
options.copyWith(
iconSize: iconSize,
iconTheme: iconTheme,
tooltip: tooltip,
afterButtonPressed: afterButtonPressed,
),
QuillToolbarSelectHeaderStyleDropdownButtonExtraOptions(
currentValue: _selectedItem,
currentValue: _selectedAttribute!,
controller: controller,
context: context,
controller: widget.controller,
onPressed: () {
throw UnimplementedError('Not implemented yet.');
},
onPressed: _onPressed,
),
);
}
return MenuAnchor(
controller: _menuController,
menuChildren: headerAttributes
.map(
(e) => MenuItemButton(
onPressed: () {
_onPressed(e);
},
child: Text(_label(e)),
return ConstrainedBox(
constraints: BoxConstraints.tightFor(
height: iconSize * 1.81,
width: options.width,
),
child: UtilityWidgets.maybeTooltip(
message: tooltip,
child: RawMaterialButton(
visualDensity: VisualDensity.compact,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(iconTheme?.borderRadius ?? 2),
),
fillColor: options.fillColor,
elevation: 0,
hoverElevation: options.hoverElevation,
highlightElevation: options.hoverElevation,
onPressed: _onPressed,
child: _buildContent(context),
),
),
);
}
void _didChangeEditingValue() {
setState(() {
_selectedAttribute = _getHeaderValue();
});
}
Attribute<dynamic> _getHeaderValue() {
final attr = controller.toolbarButtonToggler[Attribute.header.key];
if (attr != null) {
// checkbox tapping causes controller.selection to go to offset 0
controller.toolbarButtonToggler.remove(Attribute.header.key);
return attr;
}
return _selectionStyle.attributes[Attribute.header.key] ?? Attribute.header;
}
Widget _buildContent(BuildContext context) {
final theme = Theme.of(context);
final hasFinalWidth = options.width != null;
return Padding(
padding: options.padding ?? const EdgeInsets.fromLTRB(10, 0, 0, 0),
child: Row(
mainAxisSize: !hasFinalWidth ? MainAxisSize.min : MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
UtilityWidgets.maybeWidget(
enabled: hasFinalWidth,
wrapper: (child) => Expanded(child: child),
child: Text(
_valueToText[_selectedAttribute]!,
overflow: options.labelOverflow,
style: options.style ??
TextStyle(
fontSize: iconSize / 1.15,
color:
iconTheme?.iconUnselectedColor ?? theme.iconTheme.color,
),
),
),
const SizedBox(width: 3),
Icon(
Icons.arrow_drop_down,
size: iconSize / 1.15,
color: iconTheme?.iconUnselectedColor ?? theme.iconTheme.color,
)
.toList(),
child: Builder(
builder: (context) {
final isMaterial3 = Theme.of(context).useMaterial3;
final child = Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
_label(_selectedItem),
style: widget.options.textStyle ??
TextStyle(
fontSize: iconSize / 1.15,
),
),
Icon(
Icons.arrow_drop_down,
size: iconSize * iconButtonFactor,
),
],
);
if (!isMaterial3) {
return RawMaterialButton(
onPressed: _onDropdownButtonPressed,
child: child,
);
}
return IconButton(
onPressed: _onDropdownButtonPressed,
icon: child,
);
},
],
),
);
}
void _onDropdownButtonPressed() {
if (_menuController.isOpen) {
_menuController.close();
void _onPressed() {
_showMenu();
options.afterButtonPressed?.call();
}
Future<void> _showMenu() async {
final popupMenuTheme = PopupMenuTheme.of(context);
final button = context.findRenderObject() as RenderBox;
final overlay = Overlay.of(context).context.findRenderObject() as RenderBox;
final position = RelativeRect.fromRect(
Rect.fromPoints(
button.localToGlobal(Offset.zero, ancestor: overlay),
button.localToGlobal(button.size.bottomLeft(Offset.zero),
ancestor: overlay),
),
Offset.zero & overlay.size,
);
final newValue = await showMenu<Attribute>(
context: context,
elevation: 4,
items: [
for (final header in _valueToText.entries)
PopupMenuItem<Attribute>(
key: ValueKey(header.value),
value: header.key,
height: options.itemHeight ?? kMinInteractiveDimension,
padding: options.itemPadding,
child: Text(
header.value,
style: TextStyle(
fontSize: options.renderItemTextStyle
? _headerStyle(header.key).fontSize ??
DefaultTextStyle.of(context).style.fontSize ??
14
: null,
color: header.key == _selectedAttribute
? options.defaultItemColor
: null,
),
),
),
],
position: position,
shape: popupMenuTheme.shape,
color: popupMenuTheme.color,
);
if (newValue == null) {
return;
}
_menuController.open();
final attribute0 =
_selectedAttribute == newValue ? Attribute.header : newValue;
controller.formatSelection(attribute0);
afterButtonPressed?.call();
}
TextStyle _headerStyle(Attribute attribute) {
assert(_headerTextStyles!.containsKey(attribute));
return _headerTextStyles![attribute]!;
}
}

@ -105,7 +105,6 @@ class QuillToolbarHistoryButtonState extends State<QuillToolbarHistoryButton> {
? iconTheme?.iconUnselectedColor ?? theme.iconTheme.color
: iconTheme?.disabledIconColor ?? theme.disabledColor,
),
isFilled: false,
onPressed: _updateHistory,
afterPressed: afterButtonPressed,
);

@ -107,10 +107,16 @@ class QuillToolbarIndentButtonState extends State<QuillToolbarIndentButton> {
final theme = Theme.of(context);
final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color;
final iconFillColor =
iconTheme?.iconUnselectedFillColor ?? theme.canvasColor;
return QuillToolbarIconButton(
tooltip: tooltip,
icon: Icon(iconData, size: iconSize * iconButtonFactor, color: iconColor),
isFilled: false,
highlightElevation: 0,
hoverElevation: 0,
size: iconSize * iconButtonFactor,
icon: Icon(iconData, size: iconSize, color: iconColor),
fillColor: iconFillColor,
borderRadius: iconTheme?.borderRadius ?? 2,
onPressed: _sharedOnPressed,
afterPressed: afterButtonPressed,
);

@ -148,14 +148,20 @@ class _QuillToolbarLinkStyleButton2State
final isToggled = _getLinkAttributeValue() != null;
return QuillToolbarIconButton(
tooltip: tooltip,
highlightElevation: 0,
hoverElevation: 0,
size: iconSize * iconButtonFactor,
icon: Icon(
iconData,
size: iconSize * iconButtonFactor,
size: iconSize,
color: isToggled
? (iconTheme?.iconSelectedColor ?? theme.primaryIconTheme.color)
: (iconTheme?.iconUnselectedColor ?? theme.iconTheme.color),
),
isFilled: isToggled,
fillColor: isToggled
? (iconTheme?.iconSelectedFillColor ?? theme.primaryColor)
: (iconTheme?.iconUnselectedFillColor ?? theme.canvasColor),
borderRadius: iconTheme?.borderRadius ?? 2,
onPressed: _openLinkDialog,
afterPressed: afterButtonPressed,
);

@ -147,7 +147,6 @@ class QuillToolbarLinkStyleButtonState
? (iconTheme?.iconSelectedColor ?? theme.primaryIconTheme.color)
: (iconTheme?.iconUnselectedColor ?? theme.iconTheme.color),
),
isFilled: isToggled,
onPressed: () => _openLinkDialog(context),
afterPressed: afterButtonPressed,
);

@ -1,13 +1,18 @@
import 'package:flutter/material.dart';
import '../../../utils/widgets.dart';
class QuillToolbarIconButton extends StatelessWidget {
const QuillToolbarIconButton({
required this.onPressed,
required this.icon,
required this.isFilled,
this.afterPressed,
this.icon,
this.size = 40,
this.fillColor,
this.hoverElevation = 1,
this.highlightElevation = 1,
this.borderRadius = 2,
this.tooltip,
this.padding,
super.key,
this.iconFilledStyle,
this.iconStyle,
@ -15,32 +20,39 @@ class QuillToolbarIconButton extends StatelessWidget {
final VoidCallback? onPressed;
final VoidCallback? afterPressed;
final Widget icon;
final Widget? icon;
final double size;
final Color? fillColor;
final double hoverElevation;
final double highlightElevation;
final double borderRadius;
final String? tooltip;
final EdgeInsets? padding;
final bool isFilled;
final ButtonStyle? iconStyle;
final ButtonStyle? iconFilledStyle;
@override
Widget build(BuildContext context) {
if (isFilled) {
return IconButton.filled(
padding: padding,
onPressed: onPressed,
icon: icon,
style: iconStyle,
);
}
return IconButton(
padding: padding,
onPressed: () {
onPressed?.call();
afterPressed?.call();
},
icon: icon,
style: iconFilledStyle,
return ConstrainedBox(
constraints: BoxConstraints.tightFor(width: size, height: size),
child: UtilityWidgets.maybeTooltip(
message: tooltip,
child: RawMaterialButton(
visualDensity: VisualDensity.compact,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(borderRadius),
),
fillColor: fillColor,
elevation: 0,
hoverElevation: hoverElevation,
highlightElevation: hoverElevation,
onPressed: () {
onPressed?.call();
afterPressed?.call();
},
child: icon,
),
),
);
}
}

@ -118,7 +118,6 @@ class QuillToolbarSearchButton extends StatelessWidget {
size: iconSize * iconButtonFactor,
color: iconColor,
),
isFilled: false,
onPressed: () => _sharedOnPressed(context),
afterPressed: afterButtonPressed,
);

@ -252,11 +252,22 @@ Widget defaultToggleStyleButtonBuilder(
.primaryIconTheme.color) //You can specify your own icon color
: (iconTheme?.iconUnselectedColor ?? theme.iconTheme.color)
: (iconTheme?.disabledIconColor ?? theme.disabledColor);
final fill = isEnabled
? isToggled == true
? (iconTheme?.iconSelectedFillColor ??
Theme.of(context).primaryColor) //Selected icon fill color
: (iconTheme?.iconUnselectedFillColor ??
theme.canvasColor) //Unselected icon fill color :
: (iconTheme?.disabledIconFillColor ??
(fillColor ?? theme.canvasColor)); //Disabled icon fill color
return QuillToolbarIconButton(
icon: Icon(icon, size: iconSize * iconButtonFactor, color: iconColor),
isFilled: isEnabled ? isToggled == true : false,
highlightElevation: 0,
hoverElevation: 0,
size: iconSize * iconButtonFactor,
icon: Icon(icon, size: iconSize, color: iconColor),
fillColor: fill,
onPressed: onPressed,
afterPressed: afterPressed,
padding: iconTheme?.padding,
borderRadius: iconTheme?.borderRadius ?? 2,
);
}

Loading…
Cancel
Save