feat: refactor copy / paste / redo / undo / select all / format event handler

This commit is contained in:
Lucas.Xu 2022-09-06 10:55:29 +08:00
parent 804b2b27c1
commit 73cfe39e41
6 changed files with 172 additions and 106 deletions

View File

@ -1,9 +1,7 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/infra/html_converter.dart';
import 'package:appflowy_editor/src/document/node_iterator.dart';
import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event_handler.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:rich_clipboard/rich_clipboard.dart';
_handleCopy(EditorState editorState) async {
@ -304,18 +302,17 @@ _deleteSelectedContent(EditorState editorState) {
tb.commit();
}
ShortcutEventHandler copyPasteKeysHandler = (editorState, event) {
if (event.isMetaPressed && event.logicalKey == LogicalKeyboardKey.keyC) {
ShortcutEventHandler copyEventHandler = (editorState, event) {
_handleCopy(editorState);
return KeyEventResult.handled;
}
if (event.isMetaPressed && event.logicalKey == LogicalKeyboardKey.keyV) {
};
ShortcutEventHandler pasteEventHandler = (editorState, event) {
_handlePaste(editorState);
return KeyEventResult.handled;
}
if (event.isMetaPressed && event.logicalKey == LogicalKeyboardKey.keyX) {
};
ShortcutEventHandler cutEventHandler = (editorState, event) {
_handleCut(editorState);
return KeyEventResult.handled;
}
return KeyEventResult.ignored;
};

View File

@ -0,0 +1,75 @@
import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event_handler.dart';
import 'package:flutter/material.dart';
import 'package:appflowy_editor/src/document/node.dart';
import 'package:appflowy_editor/src/service/default_text_operations/format_rich_text_style.dart';
ShortcutEventHandler formatBoldEventHandler = (editorState, event) {
final selection = editorState.service.selectionService.currentSelection.value;
final nodes = editorState.service.selectionService.currentSelectedNodes;
final textNodes = nodes.whereType<TextNode>().toList(growable: false);
if (selection == null || textNodes.isEmpty) {
return KeyEventResult.ignored;
}
formatBold(editorState);
return KeyEventResult.handled;
};
ShortcutEventHandler formatItalicEventHandler = (editorState, event) {
final selection = editorState.service.selectionService.currentSelection.value;
final nodes = editorState.service.selectionService.currentSelectedNodes;
final textNodes = nodes.whereType<TextNode>().toList(growable: false);
if (selection == null || textNodes.isEmpty) {
return KeyEventResult.ignored;
}
formatItalic(editorState);
return KeyEventResult.handled;
};
ShortcutEventHandler formatUnderlineEventHandler = (editorState, event) {
final selection = editorState.service.selectionService.currentSelection.value;
final nodes = editorState.service.selectionService.currentSelectedNodes;
final textNodes = nodes.whereType<TextNode>().toList(growable: false);
if (selection == null || textNodes.isEmpty) {
return KeyEventResult.ignored;
}
formatUnderline(editorState);
return KeyEventResult.handled;
};
ShortcutEventHandler formatStrikethroughEventHandler = (editorState, event) {
final selection = editorState.service.selectionService.currentSelection.value;
final nodes = editorState.service.selectionService.currentSelectedNodes;
final textNodes = nodes.whereType<TextNode>().toList(growable: false);
if (selection == null || textNodes.isEmpty) {
return KeyEventResult.ignored;
}
formatStrikethrough(editorState);
return KeyEventResult.handled;
};
ShortcutEventHandler formatHighlightEventHandler = (editorState, event) {
final selection = editorState.service.selectionService.currentSelection.value;
final nodes = editorState.service.selectionService.currentSelectedNodes;
final textNodes = nodes.whereType<TextNode>().toList(growable: false);
if (selection == null || textNodes.isEmpty) {
return KeyEventResult.ignored;
}
formatHighlight(editorState);
return KeyEventResult.handled;
};
ShortcutEventHandler formatLinkEventHandler = (editorState, event) {
final selection = editorState.service.selectionService.currentSelection.value;
final nodes = editorState.service.selectionService.currentSelectedNodes;
final textNodes = nodes.whereType<TextNode>().toList(growable: false);
if (selection == null || textNodes.isEmpty) {
return KeyEventResult.ignored;
}
if (editorState.service.toolbarService
?.triggerHandler('appflowy.toolbar.link') ==
true) {
return KeyEventResult.handled;
}
return KeyEventResult.ignored;
};

View File

@ -1,15 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event_handler.dart';
ShortcutEventHandler redoUndoKeysHandler = (editorState, event) {
if (event.isMetaPressed && event.logicalKey == LogicalKeyboardKey.keyZ) {
if (event.isShiftPressed) {
ShortcutEventHandler redoEventHandler = (editorState, event) {
editorState.undoManager.redo();
} else {
editorState.undoManager.undo();
}
return KeyEventResult.handled;
}
return KeyEventResult.ignored;
};
ShortcutEventHandler undoEventHandler = (editorState, event) {
editorState.undoManager.undo();
return KeyEventResult.handled;
};

View File

@ -1,9 +1,10 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/document/node.dart';
import 'package:appflowy_editor/src/document/position.dart';
import 'package:appflowy_editor/src/document/selection.dart';
import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event_handler.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
KeyEventResult _selectAll(EditorState editorState) {
ShortcutEventHandler selectAllHandler = (editorState, event) {
if (editorState.document.root.children.isEmpty) {
return KeyEventResult.handled;
}
@ -13,15 +14,11 @@ KeyEventResult _selectAll(EditorState editorState) {
if (lastNode is TextNode) {
offset = lastNode.delta.length;
}
editorState.updateCursorSelection(Selection(
editorState.updateCursorSelection(
Selection(
start: Position(path: firstNode.path, offset: 0),
end: Position(path: lastNode.path, offset: offset)));
end: Position(path: lastNode.path, offset: offset),
),
);
return KeyEventResult.handled;
}
ShortcutEventHandler selectAllHandler = (editorState, event) {
if (event.isMetaPressed && event.logicalKey == LogicalKeyboardKey.keyA) {
return _selectAll(editorState);
}
return KeyEventResult.ignored;
};

View File

@ -1,48 +0,0 @@
import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event_handler.dart';
import 'package:flutter/material.dart';
import 'package:appflowy_editor/src/document/node.dart';
import 'package:appflowy_editor/src/service/default_text_operations/format_rich_text_style.dart';
import 'package:flutter/services.dart';
ShortcutEventHandler updateTextStyleByCommandXHandler = (editorState, event) {
if (!event.isMetaPressed) {
return KeyEventResult.ignored;
}
final selection = editorState.service.selectionService.currentSelection.value;
final nodes = editorState.service.selectionService.currentSelectedNodes;
final textNodes = nodes.whereType<TextNode>().toList(growable: false);
if (selection == null || textNodes.isEmpty) {
return KeyEventResult.ignored;
}
if (event.logicalKey == LogicalKeyboardKey.keyB) {
formatBold(editorState);
return KeyEventResult.handled;
} else if (event.logicalKey == LogicalKeyboardKey.keyI) {
formatItalic(editorState);
return KeyEventResult.handled;
} else if (event.logicalKey == LogicalKeyboardKey.keyU) {
formatUnderline(editorState);
return KeyEventResult.handled;
} else if (event.logicalKey == LogicalKeyboardKey.keyS &&
event.isShiftPressed) {
formatStrikethrough(editorState);
return KeyEventResult.handled;
} else if (event.logicalKey == LogicalKeyboardKey.keyH &&
event.isShiftPressed) {
formatHighlight(editorState);
return KeyEventResult.handled;
} else if (event.logicalKey == LogicalKeyboardKey.keyK) {
if (editorState.service.toolbarService
?.triggerHandler('appflowy.toolbar.link') ==
true) {
return KeyEventResult.handled;
}
}
return KeyEventResult.ignored;
};

View File

@ -8,7 +8,7 @@ import 'package:appflowy_editor/src/service/internal_key_event_handlers/page_up_
import 'package:appflowy_editor/src/service/internal_key_event_handlers/redo_undo_handler.dart';
import 'package:appflowy_editor/src/service/internal_key_event_handlers/select_all_handler.dart';
import 'package:appflowy_editor/src/service/internal_key_event_handlers/slash_handler.dart';
import 'package:appflowy_editor/src/service/internal_key_event_handlers/update_text_style_by_command_x_handler.dart';
import 'package:appflowy_editor/src/service/internal_key_event_handlers/format_style_handler.dart';
import 'package:appflowy_editor/src/service/internal_key_event_handlers/whitespace_handler.dart';
import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event.dart';
@ -102,6 +102,72 @@ List<ShortcutEvent> builtInShortcutEvents = [
windowsCommand: 'ctrl+shift+arrow right',
handler: cursorEndSelect,
),
ShortcutEvent(
key: 'Redo',
command: 'meta+shift+z',
windowsCommand: 'ctrl+shift+z',
handler: redoEventHandler,
),
ShortcutEvent(
key: 'Undo',
command: 'meta+z',
windowsCommand: 'ctrl+z',
handler: undoEventHandler,
),
ShortcutEvent(
key: 'Format bold',
command: 'meta+b',
windowsCommand: 'ctrl+b',
handler: formatBoldEventHandler,
),
ShortcutEvent(
key: 'Format italic',
command: 'meta+i',
windowsCommand: 'ctrl+i',
handler: formatItalicEventHandler,
),
ShortcutEvent(
key: 'Format underline',
command: 'meta+u',
windowsCommand: 'ctrl+u',
handler: formatUnderlineEventHandler,
),
ShortcutEvent(
key: 'Format strikethrough',
command: 'meta+shift+s',
windowsCommand: 'ctrl+shift+s',
handler: formatStrikethroughEventHandler,
),
ShortcutEvent(
key: 'Format highlight',
command: 'meta+shift+h',
windowsCommand: 'ctrl+shift+h',
handler: formatHighlightEventHandler,
),
ShortcutEvent(
key: 'Format link',
command: 'meta+k',
windowsCommand: 'ctrl+k',
handler: formatLinkEventHandler,
),
ShortcutEvent(
key: 'Copy',
command: 'meta+c',
windowsCommand: 'ctrl+c',
handler: copyEventHandler,
),
ShortcutEvent(
key: 'Paste',
command: 'meta+v',
windowsCommand: 'ctrl+v',
handler: pasteEventHandler,
),
ShortcutEvent(
key: 'Paste',
command: 'meta+x',
windowsCommand: 'ctrl+x',
handler: cutEventHandler,
),
// TODO: split the keys.
ShortcutEvent(
key: 'Delete Text',
@ -113,29 +179,11 @@ List<ShortcutEvent> builtInShortcutEvents = [
command: 'slash',
handler: slashShortcutHandler,
),
ShortcutEvent(
key: 'copy / paste',
command: 'meta+c,meta+v',
windowsCommand: 'ctrl+c,ctrl+v',
handler: copyPasteKeysHandler,
),
ShortcutEvent(
key: 'redo / undo',
command: 'meta+z,meta+meta+shift+z',
windowsCommand: 'ctrl+z,meta+ctrl+shift+z',
handler: redoUndoKeysHandler,
),
ShortcutEvent(
key: 'enter',
command: 'enter',
handler: enterWithoutShiftInTextNodesHandler,
),
ShortcutEvent(
key: 'update text style',
command: 'meta+b,meta+i,meta+u,meta+shift+s,meta+shift+h,meta+k',
windowsCommand: 'ctrl+b,ctrl+i,ctrl+u,ctrl+shift+s,ctrl+shift+h,ctrl+k',
handler: updateTextStyleByCommandXHandler,
),
ShortcutEvent(
key: 'markdown',
command: 'space',