From 99ab28bf01d223b68b147d57aca8251b7a55bd1d Mon Sep 17 00:00:00 2001 From: Jonathan Salmon Date: Sun, 4 Sep 2022 22:12:17 +0100 Subject: [PATCH] Refactored embed button implementation --- example/lib/pages/home_page.dart | 6 +- example/lib/widgets/demo_scaffold.dart | 6 +- flutter_quill_extensions/README.md | 2 +- .../lib/embeds/toolbar.dart | 108 ------------------ .../lib/flutter_quill_extensions.dart | 80 ++++++++++++- lib/src/widgets/embeds.dart | 11 +- lib/src/widgets/toolbar.dart | 9 +- 7 files changed, 95 insertions(+), 127 deletions(-) delete mode 100644 flutter_quill_extensions/lib/embeds/toolbar.dart diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index 118f4efa..2d9b09b8 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -153,7 +153,7 @@ class _HomePageState extends State { } var toolbar = QuillToolbar.basic( controller: _controller!, - embedToolbar: QuillEmbedToolbar( + embedButtons: FlutterQuillEmbeds.buttons( // provide a callback to enable picking images from device. // if omit, "image" button only allows adding images from url. // same goes for videos. @@ -169,7 +169,7 @@ class _HomePageState extends State { if (kIsWeb) { toolbar = QuillToolbar.basic( controller: _controller!, - embedToolbar: QuillEmbedToolbar( + embedButtons: FlutterQuillEmbeds.buttons( onImagePickCallback: _onImagePickCallback, webImagePickImpl: _webImagePickImpl, ), @@ -179,7 +179,7 @@ class _HomePageState extends State { if (_isDesktop()) { toolbar = QuillToolbar.basic( controller: _controller!, - embedToolbar: QuillEmbedToolbar( + embedButtons: FlutterQuillEmbeds.buttons( onImagePickCallback: _onImagePickCallback, filePickImpl: openFileSystemPickerForDesktop, ), diff --git a/example/lib/widgets/demo_scaffold.dart b/example/lib/widgets/demo_scaffold.dart index 7f997062..0b14663c 100644 --- a/example/lib/widgets/demo_scaffold.dart +++ b/example/lib/widgets/demo_scaffold.dart @@ -92,13 +92,13 @@ class _DemoScaffoldState extends State { final actions = widget.actions ?? []; var toolbar = QuillToolbar.basic( controller: _controller!, - embedToolbar: QuillEmbedToolbar(), + embedButtons: FlutterQuillEmbeds.buttons(), ); if (_isDesktop()) { toolbar = QuillToolbar.basic( controller: _controller!, - embedToolbar: - QuillEmbedToolbar(filePickImpl: openFileSystemPickerForDesktop), + embedButtons: FlutterQuillEmbeds.buttons( + filePickImpl: openFileSystemPickerForDesktop), ); } return Scaffold( diff --git a/flutter_quill_extensions/README.md b/flutter_quill_extensions/README.md index f0a5f7aa..431f5eb4 100644 --- a/flutter_quill_extensions/README.md +++ b/flutter_quill_extensions/README.md @@ -17,6 +17,6 @@ QuillEditor.basic( ``` QuillToolbar.basic( controller: controller, - embedToolbar: QuillEmbedToolbar(), + embedButtons: FlutterQuillEmbeds.buttons(), ); ``` diff --git a/flutter_quill_extensions/lib/embeds/toolbar.dart b/flutter_quill_extensions/lib/embeds/toolbar.dart deleted file mode 100644 index 10c64f2b..00000000 --- a/flutter_quill_extensions/lib/embeds/toolbar.dart +++ /dev/null @@ -1,108 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_quill/flutter_quill.dart'; - -import 'embed_types.dart'; -import 'toolbar/camera_button.dart'; -import 'toolbar/formula_button.dart'; -import 'toolbar/image_button.dart'; -import 'toolbar/video_button.dart'; - -export 'toolbar/image_button.dart'; -export 'toolbar/image_video_utils.dart'; -export 'toolbar/video_button.dart'; -export 'toolbar/formula_button.dart'; -export 'toolbar/camera_button.dart'; - -class QuillEmbedToolbar implements EmbedToolbar { - QuillEmbedToolbar({ - this.showImageButton = true, - this.showVideoButton = true, - this.showCameraButton = true, - this.showFormulaButton = false, - this.onImagePickCallback, - this.onVideoPickCallback, - this.mediaPickSettingSelector, - this.cameraPickSettingSelector, - this.filePickImpl, - this.webImagePickImpl, - this.webVideoPickImpl, - }); - - final bool showImageButton; - final bool showVideoButton; - final bool showCameraButton; - final bool showFormulaButton; - - final OnImagePickCallback? onImagePickCallback; - final OnVideoPickCallback? onVideoPickCallback; - final MediaPickSettingSelector? mediaPickSettingSelector; - final MediaPickSettingSelector? cameraPickSettingSelector; - final FilePickImpl? filePickImpl; - final WebImagePickImpl? webImagePickImpl; - final WebVideoPickImpl? webVideoPickImpl; - - @override - bool get notEmpty => - showImageButton || - showVideoButton || - (showCameraButton && - (onImagePickCallback != null || onVideoPickCallback != null)) || - showFormulaButton; - - @override - Iterable build(QuillController controller, double toolbarIconSize, - QuillIconTheme? iconTheme, QuillDialogTheme? dialogTheme) { - return [ - if (showImageButton) - ImageButton( - icon: Icons.image, - iconSize: toolbarIconSize, - controller: controller, - onImagePickCallback: onImagePickCallback, - filePickImpl: filePickImpl, - webImagePickImpl: webImagePickImpl, - mediaPickSettingSelector: mediaPickSettingSelector, - iconTheme: iconTheme, - dialogTheme: dialogTheme, - ), - if (showVideoButton) - VideoButton( - icon: Icons.movie_creation, - iconSize: toolbarIconSize, - controller: controller, - onVideoPickCallback: onVideoPickCallback, - filePickImpl: filePickImpl, - webVideoPickImpl: webImagePickImpl, - mediaPickSettingSelector: mediaPickSettingSelector, - iconTheme: iconTheme, - dialogTheme: dialogTheme, - ), - if ((onImagePickCallback != null || onVideoPickCallback != null) && - showCameraButton) - CameraButton( - icon: Icons.photo_camera, - iconSize: toolbarIconSize, - controller: controller, - onImagePickCallback: onImagePickCallback, - onVideoPickCallback: onVideoPickCallback, - filePickImpl: filePickImpl, - webImagePickImpl: webImagePickImpl, - webVideoPickImpl: webVideoPickImpl, - cameraPickSettingSelector: cameraPickSettingSelector, - iconTheme: iconTheme, - ), - if (showFormulaButton) - FormulaButton( - icon: Icons.functions, - iconSize: toolbarIconSize, - controller: controller, - onImagePickCallback: onImagePickCallback, - filePickImpl: filePickImpl, - webImagePickImpl: webImagePickImpl, - mediaPickSettingSelector: mediaPickSettingSelector, - iconTheme: iconTheme, - dialogTheme: dialogTheme, - ) - ]; - } -} diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index c5da4d6f..e23b9d66 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -1,12 +1,21 @@ library flutter_quill_extensions; +import 'package:flutter/material.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'embeds/builders.dart'; +import 'embeds/embed_types.dart'; +import 'embeds/toolbar/camera_button.dart'; +import 'embeds/toolbar/formula_button.dart'; +import 'embeds/toolbar/image_button.dart'; +import 'embeds/toolbar/video_button.dart'; -export 'embeds/toolbar.dart'; -export 'embeds/builders.dart'; export 'embeds/embed_types.dart'; +export 'embeds/toolbar/camera_button.dart'; +export 'embeds/toolbar/formula_button.dart'; +export 'embeds/toolbar/image_button.dart'; +export 'embeds/toolbar/image_video_utils.dart'; +export 'embeds/toolbar/video_button.dart'; export 'embeds/utils.dart'; class FlutterQuillEmbeds { @@ -15,4 +24,71 @@ class FlutterQuillEmbeds { VideoEmbedBuilder(), FormulaEmbedBuilder(), ]; + + static List buttons({ + bool showImageButton = true, + bool showVideoButton = true, + bool showCameraButton = true, + bool showFormulaButton = false, + OnImagePickCallback? onImagePickCallback, + OnVideoPickCallback? onVideoPickCallback, + MediaPickSettingSelector? mediaPickSettingSelector, + MediaPickSettingSelector? cameraPickSettingSelector, + FilePickImpl? filePickImpl, + WebImagePickImpl? webImagePickImpl, + WebVideoPickImpl? webVideoPickImpl, + }) { + return [ + if (showImageButton) + (controller, toolbarIconSize, iconTheme, dialogTheme) => ImageButton( + icon: Icons.image, + iconSize: toolbarIconSize, + controller: controller, + onImagePickCallback: onImagePickCallback, + filePickImpl: filePickImpl, + webImagePickImpl: webImagePickImpl, + mediaPickSettingSelector: mediaPickSettingSelector, + iconTheme: iconTheme, + dialogTheme: dialogTheme, + ), + if (showVideoButton) + (controller, toolbarIconSize, iconTheme, dialogTheme) => VideoButton( + icon: Icons.movie_creation, + iconSize: toolbarIconSize, + controller: controller, + onVideoPickCallback: onVideoPickCallback, + filePickImpl: filePickImpl, + webVideoPickImpl: webImagePickImpl, + mediaPickSettingSelector: mediaPickSettingSelector, + iconTheme: iconTheme, + dialogTheme: dialogTheme, + ), + if ((onImagePickCallback != null || onVideoPickCallback != null) && + showCameraButton) + (controller, toolbarIconSize, iconTheme, dialogTheme) => CameraButton( + icon: Icons.photo_camera, + iconSize: toolbarIconSize, + controller: controller, + onImagePickCallback: onImagePickCallback, + onVideoPickCallback: onVideoPickCallback, + filePickImpl: filePickImpl, + webImagePickImpl: webImagePickImpl, + webVideoPickImpl: webVideoPickImpl, + cameraPickSettingSelector: cameraPickSettingSelector, + iconTheme: iconTheme, + ), + if (showFormulaButton) + (controller, toolbarIconSize, iconTheme, dialogTheme) => FormulaButton( + icon: Icons.functions, + iconSize: toolbarIconSize, + controller: controller, + onImagePickCallback: onImagePickCallback, + filePickImpl: filePickImpl, + webImagePickImpl: webImagePickImpl, + mediaPickSettingSelector: mediaPickSettingSelector, + iconTheme: iconTheme, + dialogTheme: dialogTheme, + ) + ]; + } } diff --git a/lib/src/widgets/embeds.dart b/lib/src/widgets/embeds.dart index 516a8fcf..ffbcd14a 100644 --- a/lib/src/widgets/embeds.dart +++ b/lib/src/widgets/embeds.dart @@ -17,9 +17,8 @@ abstract class EmbedBuilder { ); } -abstract class EmbedToolbar { - Iterable build(QuillController controller, double toolbarIconSize, - QuillIconTheme? iconTheme, QuillDialogTheme? dialogTheme); - - bool get notEmpty; -} +typedef EmbedButtonBuilder = Widget Function( + QuillController controller, + double toolbarIconSize, + QuillIconTheme? iconTheme, + QuillDialogTheme? dialogTheme); diff --git a/lib/src/widgets/toolbar.dart b/lib/src/widgets/toolbar.dart index 9a37a2fe..715be887 100644 --- a/lib/src/widgets/toolbar.dart +++ b/lib/src/widgets/toolbar.dart @@ -99,7 +99,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { Map? fontFamilyValues, /// Toolbar items to display for controls of embed blocks - EmbedToolbar? embedToolbar, + List? embedButtons, ///The theme to use for the icons in the toolbar, uses type [QuillIconTheme] QuillIconTheme? iconTheme, @@ -125,7 +125,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { showColorButton || showBackgroundColorButton || showClearFormat || - embedToolbar?.notEmpty == true, + embedButtons?.isNotEmpty == true, showAlignmentButtons || showDirection, showLeftAlignment, showCenterAlignment, @@ -301,8 +301,9 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { controller: controller, iconTheme: iconTheme, ), - ...?embedToolbar?.build( - controller, toolbarIconSize, iconTheme, dialogTheme), + if (embedButtons != null) + for (final builder in embedButtons) + builder(controller, toolbarIconSize, iconTheme, dialogTheme), if (showDividers && isButtonGroupShown[0] && (isButtonGroupShown[1] ||