Moved embed toolbar items out

pull/933/head
Jonathan Salmon 3 years ago
parent 606806ff6f
commit 97375b5262
  1. 32
      example/lib/pages/home_page.dart
  2. 11
      example/lib/widgets/demo_scaffold.dart
  3. 2
      lib/flutter_quill.dart
  4. 13
      lib/src/embeds/default_embed_builder.dart
  5. 111
      lib/src/embeds/default_embed_toolbar.dart
  6. 20
      lib/src/embeds/embed_types.dart
  7. 1
      lib/src/embeds/toolbar/camera_button.dart
  8. 1
      lib/src/embeds/toolbar/formula_button.dart
  9. 1
      lib/src/embeds/toolbar/image_button.dart
  10. 9
      lib/src/embeds/toolbar/image_video_utils.dart
  11. 1
      lib/src/embeds/toolbar/video_button.dart
  12. 78
      lib/src/widgets/toolbar.dart

@ -152,30 +152,36 @@ class _HomePageState extends State<HomePage> {
}
var toolbar = QuillToolbar.basic(
controller: _controller!,
// provide a callback to enable picking images from device.
// if omit, "image" button only allows adding images from url.
// same goes for videos.
onImagePickCallback: _onImagePickCallback,
onVideoPickCallback: _onVideoPickCallback,
// uncomment to provide a custom "pick from" dialog.
// mediaPickSettingSelector: _selectMediaPickSetting,
// uncomment to provide a custom "pick from" dialog.
// cameraPickSettingSelector: _selectCameraPickSetting,
embedToolbar: EmbedToolbar(
// provide a callback to enable picking images from device.
// if omit, "image" button only allows adding images from url.
// same goes for videos.
onImagePickCallback: _onImagePickCallback,
onVideoPickCallback: _onVideoPickCallback,
// uncomment to provide a custom "pick from" dialog.
// mediaPickSettingSelector: _selectMediaPickSetting,
// uncomment to provide a custom "pick from" dialog.
// cameraPickSettingSelector: _selectCameraPickSetting,
),
showAlignmentButtons: true,
);
if (kIsWeb) {
toolbar = QuillToolbar.basic(
controller: _controller!,
onImagePickCallback: _onImagePickCallback,
webImagePickImpl: _webImagePickImpl,
embedToolbar: EmbedToolbar(
onImagePickCallback: _onImagePickCallback,
webImagePickImpl: _webImagePickImpl,
),
showAlignmentButtons: true,
);
}
if (_isDesktop()) {
toolbar = QuillToolbar.basic(
controller: _controller!,
onImagePickCallback: _onImagePickCallback,
filePickImpl: openFileSystemPickerForDesktop,
embedToolbar: EmbedToolbar(
onImagePickCallback: _onImagePickCallback,
filePickImpl: openFileSystemPickerForDesktop,
),
showAlignmentButtons: true,
);
}

@ -89,11 +89,16 @@ class _DemoScaffoldState extends State<DemoScaffold> {
return const Scaffold(body: Center(child: Text('Loading...')));
}
final actions = widget.actions ?? <Widget>[];
var toolbar = QuillToolbar.basic(controller: _controller!);
var toolbar = QuillToolbar.basic(
controller: _controller!,
embedToolbar: EmbedToolbar(),
);
if (_isDesktop()) {
toolbar = QuillToolbar.basic(
controller: _controller!,
filePickImpl: openFileSystemPickerForDesktop);
controller: _controller!,
embedToolbar:
EmbedToolbar(filePickImpl: openFileSystemPickerForDesktop),
);
}
return Scaffold(
key: _scaffoldKey,

@ -1,6 +1,8 @@
library flutter_quill;
export 'src/embeds/default_embed_builder.dart';
export 'src/embeds/default_embed_toolbar.dart';
export 'src/embeds/embed_types.dart';
export 'src/embeds/widgets/image.dart';
export 'src/models/documents/attribute.dart';
export 'src/models/documents/document.dart';

@ -1,5 +1,3 @@
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
@ -16,7 +14,6 @@ import '../utils/embeds.dart';
import '../utils/platform.dart';
import '../utils/string.dart';
import '../widgets/controller.dart';
import 'toolbar/image_video_utils.dart';
import 'widgets/image.dart';
import 'widgets/image_resizer.dart';
import 'widgets/video_app.dart';
@ -26,16 +23,6 @@ export 'toolbar/image_button.dart';
export 'toolbar/image_video_utils.dart';
export 'toolbar/video_button.dart';
typedef OnImagePickCallback = Future<String?> Function(File file);
typedef OnVideoPickCallback = Future<String?> Function(File file);
typedef FilePickImpl = Future<String?> Function(BuildContext context);
typedef WebImagePickImpl = Future<String?> Function(
OnImagePickCallback onImagePickCallback);
typedef WebVideoPickImpl = Future<String?> Function(
OnVideoPickCallback onImagePickCallback);
typedef MediaPickSettingSelector = Future<MediaPickSetting?> Function(
BuildContext context);
abstract class IEmbedBuilder {
String get key;

@ -0,0 +1,111 @@
import 'package:flutter/material.dart';
import '../models/themes/quill_dialog_theme.dart';
import '../models/themes/quill_icon_theme.dart';
import '../widgets/controller.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';
abstract class IEmbedToolbar {
Iterable<Widget> build(QuillController controller, double toolbarIconSize,
QuillIconTheme? iconTheme, QuillDialogTheme? dialogTheme);
bool get notEmpty;
}
class EmbedToolbar implements IEmbedToolbar {
EmbedToolbar({
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<Widget> 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,
)
];
}
}

@ -0,0 +1,20 @@
import 'dart:io';
import 'package:flutter/material.dart';
typedef OnImagePickCallback = Future<String?> Function(File file);
typedef OnVideoPickCallback = Future<String?> Function(File file);
typedef FilePickImpl = Future<String?> Function(BuildContext context);
typedef WebImagePickImpl = Future<String?> Function(
OnImagePickCallback onImagePickCallback);
typedef WebVideoPickImpl = Future<String?> Function(
OnVideoPickCallback onImagePickCallback);
typedef MediaPickSettingSelector = Future<MediaPickSetting?> Function(
BuildContext context);
enum MediaPickSetting {
Gallery,
Link,
Camera,
Video,
}

@ -6,6 +6,7 @@ import '../../translations/toolbar.i18n.dart';
import '../../widgets/controller.dart';
import '../../widgets/toolbar.dart';
import '../default_embed_builder.dart';
import '../embed_types.dart';
import 'image_video_utils.dart';
class CameraButton extends StatelessWidget {

@ -6,6 +6,7 @@ import '../../models/themes/quill_icon_theme.dart';
import '../../widgets/controller.dart';
import '../../widgets/toolbar.dart';
import '../default_embed_builder.dart';
import '../embed_types.dart';
class FormulaButton extends StatelessWidget {
const FormulaButton({

@ -7,6 +7,7 @@ import '../../models/themes/quill_icon_theme.dart';
import '../../widgets/controller.dart';
import '../../widgets/toolbar.dart';
import '../default_embed_builder.dart';
import '../embed_types.dart';
import 'image_video_utils.dart';
class ImageButton extends StatelessWidget {

@ -10,7 +10,7 @@ import '../../models/themes/quill_dialog_theme.dart';
import '../../translations/toolbar.i18n.dart';
import '../../utils/platform.dart';
import '../../widgets/controller.dart';
import '../default_embed_builder.dart';
import '../embed_types.dart';
class LinkDialog extends StatefulWidget {
const LinkDialog({this.dialogTheme, this.link, Key? key}) : super(key: key);
@ -75,13 +75,6 @@ class LinkDialogState extends State<LinkDialog> {
}
}
enum MediaPickSetting {
Gallery,
Link,
Camera,
Video,
}
class ImageVideoUtils {
static Future<MediaPickSetting?> selectMediaPickSetting(
BuildContext context,

@ -7,6 +7,7 @@ import '../../models/themes/quill_icon_theme.dart';
import '../../widgets/controller.dart';
import '../../widgets/toolbar.dart';
import '../default_embed_builder.dart';
import '../embed_types.dart';
import 'image_video_utils.dart';
class VideoButton extends StatelessWidget {

@ -1,11 +1,7 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:i18n_extension/i18n_widget.dart';
import '../embeds/default_embed_builder.dart';
import '../embeds/toolbar/camera_button.dart';
import '../embeds/toolbar/formula_button.dart';
import '../embeds/default_embed_toolbar.dart';
import '../models/documents/attribute.dart';
import '../models/themes/quill_custom_button.dart';
import '../models/themes/quill_dialog_theme.dart';
@ -54,7 +50,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
this.toolbarSectionSpacing = 4,
this.multiRowsDisplay = true,
this.color,
this.filePickImpl,
this.customButtons = const [],
this.locale,
Key? key,
@ -93,19 +88,8 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
bool showUndo = true,
bool showRedo = true,
bool multiRowsDisplay = true,
bool showImageButton = true,
bool showVideoButton = true,
bool showFormulaButton = false,
bool showCameraButton = true,
bool showDirection = false,
bool showSearchButton = true,
OnImagePickCallback? onImagePickCallback,
OnVideoPickCallback? onVideoPickCallback,
MediaPickSettingSelector? mediaPickSettingSelector,
MediaPickSettingSelector? cameraPickSettingSelector,
FilePickImpl? filePickImpl,
WebImagePickImpl? webImagePickImpl,
WebVideoPickImpl? webVideoPickImpl,
List<QuillCustomButton> customButtons = const [],
///Map of font sizes in string
@ -114,6 +98,9 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
///Map of font families in string
Map<String, String>? fontFamilyValues,
/// Toolbar items to display for controls of embed blocks
IEmbedToolbar? embedToolbar,
///The theme to use for the icons in the toolbar, uses type [QuillIconTheme]
QuillIconTheme? iconTheme,
@ -138,8 +125,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
showColorButton ||
showBackgroundColorButton ||
showClearFormat ||
onImagePickCallback != null ||
onVideoPickCallback != null,
embedToolbar?.notEmpty == true,
showAlignmentButtons || showDirection,
showLeftAlignment,
showCenterAlignment,
@ -315,56 +301,8 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
controller: controller,
iconTheme: iconTheme,
),
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,
),
...?embedToolbar?.build(
controller, toolbarIconSize, iconTheme, dialogTheme),
if (showDividers &&
isButtonGroupShown[0] &&
(isButtonGroupShown[1] ||
@ -539,8 +477,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
/// is given.
final Color? color;
final FilePickImpl? filePickImpl;
/// The locale to use for the editor toolbar, defaults to system locale
/// More https://github.com/singerdmx/flutter-quill#translation
final Locale? locale;

Loading…
Cancel
Save