feat: handle delete keys

This commit is contained in:
Vincent Chan 2022-08-11 16:09:45 +08:00
parent a2c11f96d1
commit 4794203e74

View File

@ -2,14 +2,8 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flowy_editor/flowy_editor.dart';
import 'package:flowy_editor/src/service/keyboard_service.dart';
// Handle delete text.
FlowyKeyEventHandler deleteTextHandler = (editorState, event) {
if (event.logicalKey != LogicalKeyboardKey.backspace) {
return KeyEventResult.ignored;
}
KeyEventResult _handleBackspace(EditorState editorState, RawKeyEvent event) {
final selection = editorState.service.selectionService.currentSelection.value;
if (selection == null) {
return KeyEventResult.ignored;
@ -22,7 +16,7 @@ FlowyKeyEventHandler deleteTextHandler = (editorState, event) {
return KeyEventResult.ignored;
}
TransactionBuilder transactionBuilder = TransactionBuilder(editorState);
final transactionBuilder = TransactionBuilder(editorState);
if (textNodes.length == 1) {
final textNode = textNodes.first;
final index = textNode.delta.prevRunePosition(selection.start.offset);
@ -74,23 +68,90 @@ FlowyKeyEventHandler deleteTextHandler = (editorState, event) {
}
}
} else {
final first = textNodes.first;
final last = textNodes.last;
var content = textNodes.last.toRawString();
content = content.substring(selection.end.offset, content.length);
// Merge the fist and the last text node content,
// and delete the all nodes expect for the first.
transactionBuilder
..deleteNodes(textNodes.sublist(1))
..mergeText(
first,
last,
firstOffset: selection.start.offset,
secondOffset: selection.end.offset,
);
_deleteNodes(transactionBuilder, textNodes, selection);
}
transactionBuilder.commit();
return KeyEventResult.handled;
}
KeyEventResult _handleDelete(EditorState editorState, RawKeyEvent event) {
final selection = editorState.service.selectionService.currentSelection.value;
if (selection == null) {
return KeyEventResult.ignored;
}
final nodes = editorState.service.selectionService.currentSelectedNodes;
// make sure all nodes is [TextNode].
final textNodes = nodes.whereType<TextNode>().toList();
if (textNodes.length != nodes.length) {
return KeyEventResult.ignored;
}
final transactionBuilder = TransactionBuilder(editorState);
if (textNodes.length == 1) {
final textNode = textNodes.first;
if (selection.start.offset >= textNode.delta.length) {
debugPrint("merge next line");
final nextNode = textNode.next;
if (nextNode == null) {
return KeyEventResult.ignored;
}
if (nextNode is TextNode) {
transactionBuilder.mergeText(textNode, nextNode);
}
transactionBuilder.deleteNode(nextNode);
} else {
final index = textNode.delta.nextRunePosition(selection.start.offset);
if (selection.isCollapsed) {
transactionBuilder.deleteText(
textNode,
selection.start.offset,
index - selection.start.offset,
);
} else {
transactionBuilder.deleteText(
textNode,
selection.start.offset,
selection.end.offset - selection.start.offset,
);
}
}
} else {
_deleteNodes(transactionBuilder, textNodes, selection);
}
transactionBuilder.commit();
return KeyEventResult.handled;
}
void _deleteNodes(TransactionBuilder transactionBuilder,
List<TextNode> textNodes, Selection selection) {
final first = textNodes.first;
final last = textNodes.last;
var content = textNodes.last.toRawString();
content = content.substring(selection.end.offset, content.length);
// Merge the fist and the last text node content,
// and delete the all nodes expect for the first.
transactionBuilder
..deleteNodes(textNodes.sublist(1))
..mergeText(
first,
last,
firstOffset: selection.start.offset,
secondOffset: selection.end.offset,
);
}
// Handle delete text.
FlowyKeyEventHandler deleteTextHandler = (editorState, event) {
if (event.logicalKey == LogicalKeyboardKey.backspace) {
return _handleBackspace(editorState, event);
}
if (event.logicalKey == LogicalKeyboardKey.delete) {
return _handleDelete(editorState, event);
}
return KeyEventResult.ignored;
};