Update `RawEditor` with new actions

pull/1185/head
bambinoua 2 years ago
parent 144360b638
commit e0425ff271
  1. 291
      lib/src/widgets/raw_editor.dart

@ -42,46 +42,47 @@ import 'raw_editor/raw_editor_state_text_input_client_mixin.dart';
import 'text_block.dart'; import 'text_block.dart';
import 'text_line.dart'; import 'text_line.dart';
import 'text_selection.dart'; import 'text_selection.dart';
import 'toolbar/link_style_button.dart';
import 'toolbar/search_dialog.dart'; import 'toolbar/search_dialog.dart';
class RawEditor extends StatefulWidget { class RawEditor extends StatefulWidget {
const RawEditor( const RawEditor({
{required this.controller, required this.controller,
required this.focusNode, required this.focusNode,
required this.scrollController, required this.scrollController,
required this.scrollBottomInset, required this.scrollBottomInset,
required this.cursorStyle, required this.cursorStyle,
required this.selectionColor, required this.selectionColor,
required this.selectionCtrls, required this.selectionCtrls,
required this.embedBuilder, required this.embedBuilder,
Key? key, Key? key,
this.scrollable = true, this.scrollable = true,
this.padding = EdgeInsets.zero, this.padding = EdgeInsets.zero,
this.readOnly = false, this.readOnly = false,
this.placeholder, this.placeholder,
this.onLaunchUrl, this.onLaunchUrl,
this.contextMenuBuilder = defaultContextMenuBuilder, this.contextMenuBuilder = defaultContextMenuBuilder,
this.showSelectionHandles = false, this.showSelectionHandles = false,
bool? showCursor, bool? showCursor,
this.textCapitalization = TextCapitalization.none, this.textCapitalization = TextCapitalization.none,
this.maxHeight, this.maxHeight,
this.minHeight, this.minHeight,
this.maxContentWidth, this.maxContentWidth,
this.customStyles, this.customStyles,
this.customShortcuts, this.customShortcuts,
this.customActions, this.customActions,
this.expands = false, this.expands = false,
this.autoFocus = false, this.autoFocus = false,
this.enableUnfocusOnTapOutside = true, this.enableUnfocusOnTapOutside = true,
this.keyboardAppearance = Brightness.light, this.keyboardAppearance = Brightness.light,
this.enableInteractiveSelection = true, this.enableInteractiveSelection = true,
this.scrollPhysics, this.scrollPhysics,
this.linkActionPickerDelegate = defaultLinkActionPickerDelegate, this.linkActionPickerDelegate = defaultLinkActionPickerDelegate,
this.customStyleBuilder, this.customStyleBuilder,
this.floatingCursorDisabled = false, this.floatingCursorDisabled = false,
this.onImagePaste, this.onImagePaste,
this.customLinkPrefixes = const <String>[]}) this.customLinkPrefixes = const <String>[],
: assert(maxHeight == null || maxHeight > 0, 'maxHeight cannot be null'), }) : assert(maxHeight == null || maxHeight > 0, 'maxHeight cannot be null'),
assert(minHeight == null || minHeight >= 0, 'minHeight cannot be null'), assert(minHeight == null || minHeight >= 0, 'minHeight cannot be null'),
assert(maxHeight == null || minHeight == null || maxHeight >= minHeight, assert(maxHeight == null || minHeight == null || maxHeight >= minHeight,
'maxHeight cannot be null'), 'maxHeight cannot be null'),
@ -495,77 +496,148 @@ class RawEditorState extends EditorState
minHeight: widget.minHeight ?? 0.0, minHeight: widget.minHeight ?? 0.0,
maxHeight: widget.maxHeight ?? double.infinity); maxHeight: widget.maxHeight ?? double.infinity);
final isMacOS = Theme.of(context).platform == TargetPlatform.macOS;
return TextFieldTapRegion( return TextFieldTapRegion(
enabled: widget.enableUnfocusOnTapOutside, enabled: widget.enableUnfocusOnTapOutside,
onTapOutside: _defaultOnTapOutside, onTapOutside: _defaultOnTapOutside,
child: QuillStyles( child: QuillStyles(
data: _styles!, data: _styles!,
child: Shortcuts( child: Shortcuts(
shortcuts: <LogicalKeySet, Intent>{ shortcuts: <ShortcutActivator, Intent>{
// shortcuts added for Desktop platforms. // shortcuts added for Desktop platforms.
LogicalKeySet(LogicalKeyboardKey.escape): const SingleActivator(
const HideSelectionToolbarIntent(), LogicalKeyboardKey.escape,
LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyZ): ): const HideSelectionToolbarIntent(),
const UndoTextIntent(SelectionChangedCause.keyboard), SingleActivator(
LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyY): LogicalKeyboardKey.keyZ,
const RedoTextIntent(SelectionChangedCause.keyboard), control: !isMacOS,
meta: isMacOS,
): const UndoTextIntent(SelectionChangedCause.keyboard),
SingleActivator(
LogicalKeyboardKey.keyY,
control: !isMacOS,
meta: isMacOS,
): const RedoTextIntent(SelectionChangedCause.keyboard),
// Selection formatting. // Selection formatting.
LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyB): SingleActivator(
const ToggleTextStyleIntent(Attribute.bold), LogicalKeyboardKey.keyB,
LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyU): control: !isMacOS,
const ToggleTextStyleIntent(Attribute.underline), meta: isMacOS,
LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyI): ): const ToggleTextStyleIntent(Attribute.bold),
const ToggleTextStyleIntent(Attribute.italic), SingleActivator(
LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.shift, LogicalKeyboardKey.keyU,
LogicalKeyboardKey.keyS): control: !isMacOS,
const ToggleTextStyleIntent(Attribute.strikeThrough), meta: isMacOS,
LogicalKeySet( ): const ToggleTextStyleIntent(Attribute.underline),
LogicalKeyboardKey.control, LogicalKeyboardKey.backquote): SingleActivator(
const ToggleTextStyleIntent(Attribute.inlineCode), LogicalKeyboardKey.keyI,
LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyL): control: !isMacOS,
const ToggleTextStyleIntent(Attribute.ul), meta: isMacOS,
LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyO): ): const ToggleTextStyleIntent(Attribute.italic),
const ToggleTextStyleIntent(Attribute.ol), SingleActivator(
LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.shift, LogicalKeyboardKey.keyS,
LogicalKeyboardKey.keyB): control: !isMacOS,
const ToggleTextStyleIntent(Attribute.blockQuote), meta: isMacOS,
LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.shift, shift: true,
LogicalKeyboardKey.tilde): ): const ToggleTextStyleIntent(Attribute.strikeThrough),
const ToggleTextStyleIntent(Attribute.codeBlock), SingleActivator(
// Indent LogicalKeyboardKey.backquote,
LogicalKeySet(LogicalKeyboardKey.control, control: !isMacOS,
LogicalKeyboardKey.bracketRight): meta: isMacOS,
const IndentSelectionIntent(true), ): const ToggleTextStyleIntent(Attribute.inlineCode),
LogicalKeySet( SingleActivator(
LogicalKeyboardKey.control, LogicalKeyboardKey.bracketLeft): LogicalKeyboardKey.tilde,
const IndentSelectionIntent(false), control: !isMacOS,
meta: isMacOS,
LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyF): shift: true,
const OpenSearchIntent(), ): const ToggleTextStyleIntent(Attribute.codeBlock),
SingleActivator(
LogicalKeySet( LogicalKeyboardKey.keyB,
LogicalKeyboardKey.control, LogicalKeyboardKey.digit1): control: !isMacOS,
const ApplyHeaderIntent(Attribute.h1), meta: isMacOS,
LogicalKeySet( shift: true,
LogicalKeyboardKey.control, LogicalKeyboardKey.digit2): ): const ToggleTextStyleIntent(Attribute.blockQuote),
const ApplyHeaderIntent(Attribute.h2), SingleActivator(
LogicalKeySet( LogicalKeyboardKey.keyK,
LogicalKeyboardKey.control, LogicalKeyboardKey.digit3): control: !isMacOS,
const ApplyHeaderIntent(Attribute.h3), meta: isMacOS,
LogicalKeySet( ): const ApplyLinkIntent(),
LogicalKeyboardKey.control, LogicalKeyboardKey.digit0):
const ApplyHeaderIntent(Attribute.header), // Lists
SingleActivator(
LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.shift, LogicalKeyboardKey.keyL,
LogicalKeyboardKey.keyL): const ApplyCheckListIntent(), control: !isMacOS,
meta: isMacOS,
if (widget.customShortcuts != null) ...widget.customShortcuts!, shift: true,
): const ToggleTextStyleIntent(Attribute.ul),
SingleActivator(
LogicalKeyboardKey.keyO,
control: !isMacOS,
meta: isMacOS,
shift: true,
): const ToggleTextStyleIntent(Attribute.ol),
SingleActivator(
LogicalKeyboardKey.keyC,
control: !isMacOS,
meta: isMacOS,
shift: true,
): const ApplyCheckListIntent(),
// Indents
SingleActivator(
LogicalKeyboardKey.keyM,
control: !isMacOS,
meta: isMacOS,
): const IndentSelectionIntent(true),
SingleActivator(
LogicalKeyboardKey.keyM,
control: !isMacOS,
meta: isMacOS,
shift: true,
): const IndentSelectionIntent(false),
// Headers
SingleActivator(
LogicalKeyboardKey.digit1,
control: !isMacOS,
meta: isMacOS,
): const ApplyHeaderIntent(Attribute.h1),
SingleActivator(
LogicalKeyboardKey.digit2,
control: !isMacOS,
meta: isMacOS,
): const ApplyHeaderIntent(Attribute.h2),
SingleActivator(
LogicalKeyboardKey.digit3,
control: !isMacOS,
meta: isMacOS,
): const ApplyHeaderIntent(Attribute.h3),
SingleActivator(
LogicalKeyboardKey.digit0,
control: !isMacOS,
meta: isMacOS,
): const ApplyHeaderIntent(Attribute.header),
SingleActivator(
LogicalKeyboardKey.keyG,
control: !isMacOS,
meta: isMacOS,
): const InsertEmbedIntent(Attribute.image),
SingleActivator(
LogicalKeyboardKey.keyF,
control: !isMacOS,
meta: isMacOS,
): const OpenSearchIntent(),
...?widget.customShortcuts,
}, },
child: Actions( child: Actions(
actions: { actions: {
..._actions, ..._actions,
if (widget.customActions != null) ...widget.customActions!, ...?widget.customActions,
}, },
child: Focus( child: Focus(
focusNode: widget.focusNode, focusNode: widget.focusNode,
@ -1570,11 +1642,13 @@ class RawEditorState extends EditorState
RedoTextIntent: _makeOverridable(_RedoKeyboardAction(this)), RedoTextIntent: _makeOverridable(_RedoKeyboardAction(this)),
OpenSearchIntent: _openSearchAction, OpenSearchIntent: _openSearchAction,
// Selection Formatting // Selection Formatting
ToggleTextStyleIntent: _formatSelectionAction, ToggleTextStyleIntent: _formatSelectionAction,
IndentSelectionIntent: _indentSelectionAction, IndentSelectionIntent: _indentSelectionAction,
ApplyHeaderIntent: _applyHeaderAction, ApplyHeaderIntent: _applyHeaderAction,
ApplyCheckListIntent: _applyCheckListAction, ApplyCheckListIntent: _applyCheckListAction,
ApplyLinkIntent: ApplyLinkAction(this)
}; };
@override @override
@ -2490,6 +2564,33 @@ class _ApplyCheckListAction extends Action<ApplyCheckListIntent> {
bool get isActionEnabled => true; bool get isActionEnabled => true;
} }
class ApplyLinkIntent extends Intent {
const ApplyLinkIntent();
}
class ApplyLinkAction extends Action<ApplyLinkIntent> {
ApplyLinkAction(this.state);
final RawEditorState state;
@override
Object? invoke(ApplyLinkIntent intent) {
showDialog(
context: state.context,
builder: (context) {
return const LinkStyleDialog();
},
);
return null;
}
}
class InsertEmbedIntent extends Intent {
const InsertEmbedIntent(this.type);
final Attribute type;
}
/// Signature for a widget builder that builds a context menu for the given /// Signature for a widget builder that builds a context menu for the given
/// [RawEditorState]. /// [RawEditorState].
/// ///

Loading…
Cancel
Save