Major update 6 (#1456)
parent
9b380e4866
commit
6cf9cd0f0c
32 changed files with 791 additions and 406 deletions
@ -0,0 +1,39 @@ |
|||||||
|
import 'package:flutter/widgets.dart' show Color; |
||||||
|
|
||||||
|
import '../../../../widgets/toolbar/toolbar.dart'; |
||||||
|
import '../../../structs/link_dialog_action.dart'; |
||||||
|
import '../../../themes/quill_dialog_theme.dart'; |
||||||
|
|
||||||
|
class QuillToolbarLinkStyleButtonExtraOptions |
||||||
|
extends QuillToolbarBaseButtonExtraOptions { |
||||||
|
const QuillToolbarLinkStyleButtonExtraOptions({ |
||||||
|
required super.controller, |
||||||
|
required super.context, |
||||||
|
required super.onPressed, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
class QuillToolbarLinkStyleButtonOptions extends QuillToolbarBaseButtonOptions< |
||||||
|
QuillToolbarLinkStyleButtonOptions, |
||||||
|
QuillToolbarLinkStyleButtonExtraOptions> { |
||||||
|
const QuillToolbarLinkStyleButtonOptions({ |
||||||
|
this.dialogTheme, |
||||||
|
this.linkRegExp, |
||||||
|
this.linkDialogAction, |
||||||
|
this.dialogBarrierColor, |
||||||
|
this.iconSize, |
||||||
|
super.iconData, |
||||||
|
super.globalIconSize, |
||||||
|
super.afterButtonPressed, |
||||||
|
super.tooltip, |
||||||
|
super.iconTheme, |
||||||
|
super.childBuilder, |
||||||
|
super.controller, |
||||||
|
}); |
||||||
|
|
||||||
|
final double? iconSize; |
||||||
|
final QuillDialogTheme? dialogTheme; |
||||||
|
final RegExp? linkRegExp; |
||||||
|
final LinkDialogAction? linkDialogAction; |
||||||
|
final Color? dialogBarrierColor; |
||||||
|
} |
@ -0,0 +1,61 @@ |
|||||||
|
import 'package:flutter/widgets.dart' show Color; |
||||||
|
|
||||||
|
import '../../../../../flutter_quill.dart'; |
||||||
|
|
||||||
|
class QuillToolbarSearchButtonExtraOptions |
||||||
|
extends QuillToolbarBaseButtonExtraOptions { |
||||||
|
const QuillToolbarSearchButtonExtraOptions({ |
||||||
|
required super.controller, |
||||||
|
required super.context, |
||||||
|
required super.onPressed, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
class QuillToolbarSearchButtonOptions extends QuillToolbarBaseButtonOptions { |
||||||
|
const QuillToolbarSearchButtonOptions({ |
||||||
|
super.iconData, |
||||||
|
super.controller, |
||||||
|
super.childBuilder, |
||||||
|
super.tooltip, |
||||||
|
super.afterButtonPressed, |
||||||
|
super.iconTheme, |
||||||
|
this.dialogTheme, |
||||||
|
this.iconSize, |
||||||
|
this.dialogBarrierColor, |
||||||
|
this.fillColor, |
||||||
|
this.customOnPressedCallback, |
||||||
|
}); |
||||||
|
|
||||||
|
final QuillDialogTheme? dialogTheme; |
||||||
|
final double? iconSize; |
||||||
|
|
||||||
|
/// By default will be [dialogBarrierColor] from [QuillSharedConfigurations] |
||||||
|
final Color? dialogBarrierColor; |
||||||
|
|
||||||
|
final Color? fillColor; |
||||||
|
|
||||||
|
/// By default we will show simple search dialog ui |
||||||
|
/// you can pass value to this callback to change this |
||||||
|
final QuillToolbarSearchButtomOnPressedCallback? customOnPressedCallback; |
||||||
|
} |
||||||
|
|
||||||
|
typedef QuillToolbarSearchButtomOnPressedCallback = Future<void> Function( |
||||||
|
QuillController controller, |
||||||
|
); |
||||||
|
|
||||||
|
// typedef QuillToolbarSearchButtonFindTextCallback = List<int> Function({ |
||||||
|
// required int index, |
||||||
|
// required String text, |
||||||
|
// required QuillController controller, |
||||||
|
// required List<int> offsets, |
||||||
|
// required bool wholeWord, |
||||||
|
// required bool caseSensitive, |
||||||
|
// bool moveToPosition, |
||||||
|
// }); |
||||||
|
|
||||||
|
// typedef QuillToolbarSearchButtonMoveToPositionCallback = void Function({ |
||||||
|
// required int index, |
||||||
|
// required String text, |
||||||
|
// required QuillController controller, |
||||||
|
// required List<int> offsets, |
||||||
|
// }); |
@ -0,0 +1,41 @@ |
|||||||
|
import 'package:flutter/widgets.dart' show Axis; |
||||||
|
|
||||||
|
import '../../../../widgets/toolbar/toolbar.dart'; |
||||||
|
import '../../../documents/attribute.dart'; |
||||||
|
|
||||||
|
class QuillToolbarSelectHeaderStyleButtonExtraOptions |
||||||
|
extends QuillToolbarBaseButtonExtraOptions { |
||||||
|
const QuillToolbarSelectHeaderStyleButtonExtraOptions({ |
||||||
|
required super.controller, |
||||||
|
required super.context, |
||||||
|
required super.onPressed, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
class QuillToolbarSelectHeaderStyleButtonsOptions |
||||||
|
extends QuillToolbarBaseButtonOptions< |
||||||
|
QuillToolbarSelectHeaderStyleButtonsOptions, |
||||||
|
QuillToolbarSelectHeaderStyleButtonExtraOptions> { |
||||||
|
const QuillToolbarSelectHeaderStyleButtonsOptions({ |
||||||
|
super.afterButtonPressed, |
||||||
|
super.childBuilder, |
||||||
|
super.controller, |
||||||
|
super.iconData, |
||||||
|
super.iconTheme, |
||||||
|
super.tooltip, |
||||||
|
this.axis, |
||||||
|
this.attributes = const [ |
||||||
|
Attribute.header, |
||||||
|
Attribute.h1, |
||||||
|
Attribute.h2, |
||||||
|
Attribute.h3, |
||||||
|
], |
||||||
|
this.iconSize, |
||||||
|
}); |
||||||
|
|
||||||
|
final List<Attribute> attributes; |
||||||
|
|
||||||
|
/// By default we will the toolbar axis from [QuillToolbarConfigurations] |
||||||
|
final Axis? axis; |
||||||
|
final double? iconSize; |
||||||
|
} |
@ -1,72 +0,0 @@ |
|||||||
import 'package:flutter/material.dart'; |
|
||||||
|
|
||||||
import '../../../models/themes/quill_dialog_theme.dart'; |
|
||||||
import '../../../models/themes/quill_icon_theme.dart'; |
|
||||||
import '../../controller.dart'; |
|
||||||
import '../search_dialog.dart'; |
|
||||||
import '../toolbar.dart'; |
|
||||||
|
|
||||||
class QuillToolbarSearchButton extends StatelessWidget { |
|
||||||
const QuillToolbarSearchButton({ |
|
||||||
required this.icon, |
|
||||||
required this.controller, |
|
||||||
this.iconSize = kDefaultIconSize, |
|
||||||
this.fillColor, |
|
||||||
this.iconTheme, |
|
||||||
this.dialogBarrierColor = Colors.black54, |
|
||||||
this.dialogTheme, |
|
||||||
this.afterButtonPressed, |
|
||||||
this.tooltip, |
|
||||||
Key? key, |
|
||||||
}) : super(key: key); |
|
||||||
|
|
||||||
final IconData icon; |
|
||||||
final double iconSize; |
|
||||||
|
|
||||||
final QuillController controller; |
|
||||||
final Color? fillColor; |
|
||||||
final Color dialogBarrierColor; |
|
||||||
final QuillIconTheme? iconTheme; |
|
||||||
|
|
||||||
final QuillDialogTheme? dialogTheme; |
|
||||||
final VoidCallback? afterButtonPressed; |
|
||||||
final String? tooltip; |
|
||||||
|
|
||||||
@override |
|
||||||
Widget build(BuildContext context) { |
|
||||||
final theme = Theme.of(context); |
|
||||||
|
|
||||||
final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; |
|
||||||
final iconFillColor = |
|
||||||
iconTheme?.iconUnselectedFillColor ?? (fillColor ?? theme.canvasColor); |
|
||||||
|
|
||||||
return QuillToolbarIconButton( |
|
||||||
tooltip: tooltip, |
|
||||||
icon: Icon(icon, size: iconSize, color: iconColor), |
|
||||||
highlightElevation: 0, |
|
||||||
hoverElevation: 0, |
|
||||||
size: iconSize * kIconButtonFactor, |
|
||||||
fillColor: iconFillColor, |
|
||||||
borderRadius: iconTheme?.borderRadius ?? 2, |
|
||||||
onPressed: () => _onPressedHandler(context), |
|
||||||
afterPressed: afterButtonPressed, |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
Future<void> _onPressedHandler(BuildContext context) async { |
|
||||||
final value = await showDialog<String>( |
|
||||||
barrierColor: dialogBarrierColor, |
|
||||||
context: context, |
|
||||||
builder: (_) => SearchDialog( |
|
||||||
controller: controller, |
|
||||||
dialogTheme: dialogTheme, |
|
||||||
text: '', |
|
||||||
), |
|
||||||
); |
|
||||||
_searchSubmitted(value); |
|
||||||
} |
|
||||||
|
|
||||||
void _searchSubmitted(String? value) { |
|
||||||
// If we are doing nothing here then why we care about the result?? |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,187 @@ |
|||||||
|
import 'package:flutter/material.dart'; |
||||||
|
|
||||||
|
import '../../../../../translations.dart'; |
||||||
|
import '../../../../models/themes/quill_dialog_theme.dart'; |
||||||
|
import '../../../../models/themes/quill_icon_theme.dart'; |
||||||
|
import '../../../../utils/extensions/build_context.dart'; |
||||||
|
import '../../../controller.dart'; |
||||||
|
import '../../toolbar.dart'; |
||||||
|
|
||||||
|
class QuillToolbarSearchButton extends StatelessWidget { |
||||||
|
const QuillToolbarSearchButton({ |
||||||
|
required QuillController controller, |
||||||
|
required this.options, |
||||||
|
super.key, |
||||||
|
}) : _controller = controller; |
||||||
|
|
||||||
|
final QuillController _controller; |
||||||
|
final QuillToolbarSearchButtonOptions options; |
||||||
|
|
||||||
|
QuillController get controller { |
||||||
|
return _controller; |
||||||
|
} |
||||||
|
|
||||||
|
double _iconSize(BuildContext context) { |
||||||
|
final baseFontSize = baseButtonExtraOptions(context).globalIconSize; |
||||||
|
final iconSize = options.iconSize; |
||||||
|
return iconSize ?? baseFontSize; |
||||||
|
} |
||||||
|
|
||||||
|
VoidCallback? _afterButtonPressed(BuildContext context) { |
||||||
|
return options.afterButtonPressed ?? |
||||||
|
baseButtonExtraOptions(context).afterButtonPressed; |
||||||
|
} |
||||||
|
|
||||||
|
QuillIconTheme? _iconTheme(BuildContext context) { |
||||||
|
return options.iconTheme ?? baseButtonExtraOptions(context).iconTheme; |
||||||
|
} |
||||||
|
|
||||||
|
QuillToolbarBaseButtonOptions baseButtonExtraOptions(BuildContext context) { |
||||||
|
return context.requireQuillToolbarBaseButtonOptions; |
||||||
|
} |
||||||
|
|
||||||
|
IconData _iconData(BuildContext context) { |
||||||
|
return options.iconData ?? |
||||||
|
baseButtonExtraOptions(context).iconData ?? |
||||||
|
Icons.search; |
||||||
|
} |
||||||
|
|
||||||
|
String _tooltip(BuildContext context) { |
||||||
|
return options.tooltip ?? |
||||||
|
baseButtonExtraOptions(context).tooltip ?? |
||||||
|
('Search'.i18n); |
||||||
|
} |
||||||
|
|
||||||
|
Color _dialogBarrierColor(BuildContext context) { |
||||||
|
return options.dialogBarrierColor ?? |
||||||
|
context.requireQuillSharedConfigurations.dialogBarrierColor; |
||||||
|
} |
||||||
|
|
||||||
|
QuillDialogTheme? _dialogTheme(BuildContext context) { |
||||||
|
return options.dialogTheme ?? |
||||||
|
context.requireQuillSharedConfigurations.dialogTheme; |
||||||
|
} |
||||||
|
|
||||||
|
@override |
||||||
|
Widget build(BuildContext context) { |
||||||
|
final theme = Theme.of(context); |
||||||
|
|
||||||
|
final iconTheme = _iconTheme(context); |
||||||
|
final tooltip = _tooltip(context); |
||||||
|
final iconData = _iconData(context); |
||||||
|
final iconSize = _iconSize(context); |
||||||
|
final afterButtonPressed = _afterButtonPressed(context); |
||||||
|
|
||||||
|
final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; |
||||||
|
final iconFillColor = iconTheme?.iconUnselectedFillColor ?? |
||||||
|
(options.fillColor ?? theme.canvasColor); |
||||||
|
|
||||||
|
final childBuilder = |
||||||
|
options.childBuilder ?? baseButtonExtraOptions(context).childBuilder; |
||||||
|
|
||||||
|
if (childBuilder != null) { |
||||||
|
return childBuilder( |
||||||
|
QuillToolbarSearchButtonOptions( |
||||||
|
afterButtonPressed: afterButtonPressed, |
||||||
|
controller: controller, |
||||||
|
dialogBarrierColor: _dialogBarrierColor(context), |
||||||
|
dialogTheme: _dialogTheme(context), |
||||||
|
fillColor: options.fillColor, |
||||||
|
iconData: _iconData(context), |
||||||
|
iconSize: _iconSize(context), |
||||||
|
tooltip: _tooltip(context), |
||||||
|
iconTheme: _iconTheme(context), |
||||||
|
), |
||||||
|
QuillToolbarSearchButtonExtraOptions( |
||||||
|
controller: controller, |
||||||
|
context: context, |
||||||
|
onPressed: () { |
||||||
|
_sharedOnPressed(context); |
||||||
|
afterButtonPressed?.call(); |
||||||
|
}, |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
return QuillToolbarIconButton( |
||||||
|
tooltip: tooltip, |
||||||
|
icon: Icon( |
||||||
|
iconData, |
||||||
|
size: iconSize, |
||||||
|
color: iconColor, |
||||||
|
), |
||||||
|
highlightElevation: 0, |
||||||
|
hoverElevation: 0, |
||||||
|
size: iconSize * kIconButtonFactor, |
||||||
|
fillColor: iconFillColor, |
||||||
|
borderRadius: iconTheme?.borderRadius ?? 2, |
||||||
|
onPressed: () => _sharedOnPressed(context), |
||||||
|
afterPressed: afterButtonPressed, |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
Future<void> _sharedOnPressed(BuildContext context) async { |
||||||
|
final customCallback = options.customOnPressedCallback; |
||||||
|
if (customCallback != null) { |
||||||
|
await customCallback( |
||||||
|
controller, |
||||||
|
); |
||||||
|
return; |
||||||
|
} |
||||||
|
await showDialog<String>( |
||||||
|
barrierColor: _dialogBarrierColor(context), |
||||||
|
context: context, |
||||||
|
builder: (_) => QuillToolbarSearchDialog( |
||||||
|
controller: controller, |
||||||
|
dialogTheme: _dialogTheme(context), |
||||||
|
text: '', |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
// Those functions ((findText, moveToPosition)) are not ready yet. |
||||||
|
// but consider moving them to a better place |
||||||
|
// List<int> _findText({ |
||||||
|
// required int index, |
||||||
|
// required String text, |
||||||
|
// required QuillController controller, |
||||||
|
// required List<int> offsets, |
||||||
|
// required bool wholeWord, |
||||||
|
// required bool caseSensitive, |
||||||
|
// bool moveToPosition = true, |
||||||
|
// }) { |
||||||
|
// if (text.isEmpty) { |
||||||
|
// return List.empty(); |
||||||
|
// } |
||||||
|
// final newOffsets = controller.document.search( |
||||||
|
// text, |
||||||
|
// caseSensitive: caseSensitive, |
||||||
|
// wholeWord: wholeWord, |
||||||
|
// ); |
||||||
|
// index = 0; // TODO: This might need to be updated... |
||||||
|
// if (offsets.isNotEmpty && moveToPosition) { |
||||||
|
// _moveToPosition( |
||||||
|
// index: index, |
||||||
|
// text: text, |
||||||
|
// controller: controller, |
||||||
|
// offsets: offsets, |
||||||
|
// ); |
||||||
|
// } |
||||||
|
// return newOffsets; |
||||||
|
// } |
||||||
|
|
||||||
|
// void _moveToPosition({ |
||||||
|
// required int index, |
||||||
|
// required String text, |
||||||
|
// required QuillController controller, |
||||||
|
// required List<int> offsets, |
||||||
|
// }) { |
||||||
|
// controller.updateSelection( |
||||||
|
// TextSelection( |
||||||
|
// baseOffset: offsets[index], |
||||||
|
// extentOffset: offsets[index] + text.length, |
||||||
|
// ), |
||||||
|
// ChangeSource.LOCAL, |
||||||
|
// ); |
||||||
|
// } |
||||||
|
} |
Loading…
Reference in new issue