feat: refactor current selection and current selectedNodes in selection_service

This commit is contained in:
Lucas.Xu 2022-08-07 11:45:27 +08:00
parent 4b4ce1020d
commit 7e6c7a2b4e
8 changed files with 51 additions and 48 deletions

View file

@ -67,13 +67,13 @@ class _ToolbarWidgetState extends State<ToolbarWidget> {
void initState() { void initState() {
super.initState(); super.initState();
widget.editorState.service.selectionService.currentSelectedNodes widget.editorState.service.selectionService.currentSelection
.addListener(_onSelectionChange); .addListener(_onSelectionChange);
} }
@override @override
void dispose() { void dispose() {
widget.editorState.service.selectionService.currentSelectedNodes widget.editorState.service.selectionService.currentSelection
.removeListener(_onSelectionChange); .removeListener(_onSelectionChange);
super.dispose(); super.dispose();
} }

View file

@ -38,7 +38,7 @@ void formatBulletedList(EditorState editorState) {
} }
bool formatTextNodes(EditorState editorState, Attributes attributes) { bool formatTextNodes(EditorState editorState, Attributes attributes) {
final nodes = editorState.service.selectionService.currentSelectedNodes.value; final nodes = editorState.service.selectionService.currentSelectedNodes;
final textNodes = nodes.whereType<TextNode>().toList(); final textNodes = nodes.whereType<TextNode>().toList();
if (textNodes.isEmpty) { if (textNodes.isEmpty) {
@ -85,8 +85,8 @@ bool formatStrikethrough(EditorState editorState) {
} }
bool formatRichTextPartialStyle(EditorState editorState, String styleKey) { bool formatRichTextPartialStyle(EditorState editorState, String styleKey) {
final selection = editorState.service.selectionService.currentSelection; final selection = editorState.service.selectionService.currentSelection.value;
final nodes = editorState.service.selectionService.currentSelectedNodes.value; final nodes = editorState.service.selectionService.currentSelectedNodes;
final textNodes = nodes.whereType<TextNode>().toList(growable: false); final textNodes = nodes.whereType<TextNode>().toList(growable: false);
if (selection == null || textNodes.isEmpty) { if (selection == null || textNodes.isEmpty) {
@ -107,8 +107,8 @@ bool formatRichTextPartialStyle(EditorState editorState, String styleKey) {
} }
bool formatRichTextStyle(EditorState editorState, Attributes attributes) { bool formatRichTextStyle(EditorState editorState, Attributes attributes) {
final selection = editorState.service.selectionService.currentSelection; final selection = editorState.service.selectionService.currentSelection.value;
final nodes = editorState.service.selectionService.currentSelectedNodes.value; final nodes = editorState.service.selectionService.currentSelectedNodes;
final textNodes = nodes.whereType<TextNode>().toList(); final textNodes = nodes.whereType<TextNode>().toList();
if (selection == null || textNodes.isEmpty) { if (selection == null || textNodes.isEmpty) {

View file

@ -42,15 +42,15 @@ class _FlowyInputState extends State<FlowyInput>
void initState() { void initState() {
super.initState(); super.initState();
_editorState.service.selectionService.currentSelectedNodes _editorState.service.selectionService.currentSelection
.addListener(_onSelectedNodesChange); .addListener(_onSelectionChange);
} }
@override @override
void dispose() { void dispose() {
close(); close();
_editorState.service.selectionService.currentSelectedNodes _editorState.service.selectionService.currentSelection
.removeListener(_onSelectedNodesChange); .removeListener(_onSelectionChange);
super.dispose(); super.dispose();
} }
@ -105,13 +105,12 @@ class _FlowyInputState extends State<FlowyInput>
void _applyInsert(TextEditingDeltaInsertion delta) { void _applyInsert(TextEditingDeltaInsertion delta) {
final selectionService = _editorState.service.selectionService; final selectionService = _editorState.service.selectionService;
final currentSelection = selectionService.currentSelection; final currentSelection = selectionService.currentSelection.value;
if (currentSelection == null) { if (currentSelection == null) {
return; return;
} }
if (currentSelection.isSingle) { if (currentSelection.isSingle) {
final textNode = final textNode = selectionService.currentSelectedNodes.first as TextNode;
selectionService.currentSelectedNodes.value.first as TextNode;
TransactionBuilder(_editorState) TransactionBuilder(_editorState)
..insertText( ..insertText(
textNode, textNode,
@ -126,13 +125,12 @@ class _FlowyInputState extends State<FlowyInput>
void _applyReplacement(TextEditingDeltaReplacement delta) { void _applyReplacement(TextEditingDeltaReplacement delta) {
final selectionService = _editorState.service.selectionService; final selectionService = _editorState.service.selectionService;
final currentSelection = selectionService.currentSelection; final currentSelection = selectionService.currentSelection.value;
if (currentSelection == null) { if (currentSelection == null) {
return; return;
} }
if (currentSelection.isSingle) { if (currentSelection.isSingle) {
final textNode = final textNode = selectionService.currentSelectedNodes.first as TextNode;
selectionService.currentSelectedNodes.value.first as TextNode;
final length = delta.replacedRange.end - delta.replacedRange.start; final length = delta.replacedRange.end - delta.replacedRange.start;
TransactionBuilder(_editorState) TransactionBuilder(_editorState)
..replaceText( ..replaceText(
@ -209,11 +207,11 @@ class _FlowyInputState extends State<FlowyInput>
// TODO: implement updateFloatingCursor // TODO: implement updateFloatingCursor
} }
void _onSelectedNodesChange() { void _onSelectionChange() {
final textNodes = _editorState final textNodes = _editorState.service.selectionService.currentSelectedNodes
.service.selectionService.currentSelectedNodes.value
.whereType<TextNode>(); .whereType<TextNode>();
final selection = _editorState.service.selectionService.currentSelection; final selection =
_editorState.service.selectionService.currentSelection.value;
// FIXME: upward and selection update. // FIXME: upward and selection update.
if (textNodes.isNotEmpty && selection != null) { if (textNodes.isNotEmpty && selection != null) {
final text = textNodes.fold<String>( final text = textNodes.fold<String>(

View file

@ -9,12 +9,12 @@ FlowyKeyEventHandler deleteTextHandler = (editorState, event) {
return KeyEventResult.ignored; return KeyEventResult.ignored;
} }
final selection = editorState.service.selectionService.currentSelection; final selection = editorState.service.selectionService.currentSelection.value;
if (selection == null) { if (selection == null) {
return KeyEventResult.ignored; return KeyEventResult.ignored;
} }
final nodes = editorState.service.selectionService.currentSelectedNodes.value; final nodes = editorState.service.selectionService.currentSelectedNodes;
// make sure all nodes is [TextNode]. // make sure all nodes is [TextNode].
final textNodes = nodes.whereType<TextNode>().toList(); final textNodes = nodes.whereType<TextNode>().toList();
if (textNodes.length != nodes.length) { if (textNodes.length != nodes.length) {

View file

@ -18,8 +18,8 @@ FlowyKeyEventHandler enterInEdgeOfTextNodeHandler = (editorState, event) {
return KeyEventResult.ignored; return KeyEventResult.ignored;
} }
final nodes = editorState.service.selectionService.currentSelectedNodes.value; final nodes = editorState.service.selectionService.currentSelectedNodes;
final selection = editorState.service.selectionService.currentSelection; final selection = editorState.service.selectionService.currentSelection.value;
if (selection == null || if (selection == null ||
nodes.length != 1 || nodes.length != 1 ||
nodes.first is! TextNode || nodes.first is! TextNode ||

View file

@ -56,14 +56,13 @@ FlowyKeyEventHandler slashShortcutHandler = (editorState, event) {
return KeyEventResult.ignored; return KeyEventResult.ignored;
} }
final textNodes = editorState final textNodes = editorState.service.selectionService.currentSelectedNodes
.service.selectionService.currentSelectedNodes.value
.whereType<TextNode>(); .whereType<TextNode>();
if (textNodes.length != 1) { if (textNodes.length != 1) {
return KeyEventResult.ignored; return KeyEventResult.ignored;
} }
final selection = editorState.service.selectionService.currentSelection; final selection = editorState.service.selectionService.currentSelection.value;
final textNode = textNodes.first; final textNode = textNodes.first;
final context = textNode.context; final context = textNode.context;
final selectable = textNode.selectable; final selectable = textNode.selectable;
@ -97,9 +96,9 @@ FlowyKeyEventHandler slashShortcutHandler = (editorState, event) {
Overlay.of(context)?.insert(_popupListOverlay!); Overlay.of(context)?.insert(_popupListOverlay!);
editorState.service.selectionService.currentSelectedNodes editorState.service.selectionService.currentSelection
.removeListener(clearPopupListOverlay); .removeListener(clearPopupListOverlay);
editorState.service.selectionService.currentSelectedNodes editorState.service.selectionService.currentSelection
.addListener(clearPopupListOverlay); .addListener(clearPopupListOverlay);
// editorState.service.keyboardService?.disable(); // editorState.service.keyboardService?.disable();
_editorState = editorState; _editorState = editorState;

View file

@ -9,8 +9,8 @@ FlowyKeyEventHandler updateTextStyleByCommandXHandler = (editorState, event) {
return KeyEventResult.ignored; return KeyEventResult.ignored;
} }
final selection = editorState.service.selectionService.currentSelection; final selection = editorState.service.selectionService.currentSelection.value;
final nodes = editorState.service.selectionService.currentSelectedNodes.value; final nodes = editorState.service.selectionService.currentSelectedNodes;
final textNodes = nodes.whereType<TextNode>().toList(growable: false); final textNodes = nodes.whereType<TextNode>().toList(growable: false);
if (selection == null || textNodes.isEmpty) { if (selection == null || textNodes.isEmpty) {

View file

@ -17,20 +17,26 @@ import 'package:flowy_editor/render/selection/selection_widget.dart';
/// Process selection and cursor /// Process selection and cursor
mixin FlowySelectionService<T extends StatefulWidget> on State<T> { mixin FlowySelectionService<T extends StatefulWidget> on State<T> {
/// Returns the currently selected [Node]s. /// Returns the current [Selection]
ValueNotifier<Selection?> get currentSelection;
/// Returns the current selected [Node]s.
/// ///
/// The order of the return is determined according to the selected order. /// The order of the return is determined according to the selected order.
ValueNotifier<List<Node>> get currentSelectedNodes; List<Node> get currentSelectedNodes;
Selection? get currentSelection;
/// ------------------ Selection ------------------------
/// Update the selection or cursor.
/// ///
/// If selection is collapsed, this method will
/// update the position of the cursor.
/// Otherwise, will update the selection.
void updateSelection(Selection selection); void updateSelection(Selection selection);
/// /// Clear the selection or cursor.
void clearSelection(); void clearSelection();
/// ------------------ Selection ------------------------
List<Rect> rects(); List<Rect> rects();
Position? hitTest(Offset? offset); Position? hitTest(Offset? offset);
@ -124,10 +130,10 @@ class _FlowySelectionState extends State<FlowySelection>
EditorState get editorState => widget.editorState; EditorState get editorState => widget.editorState;
@override @override
Selection? currentSelection; ValueNotifier<Selection?> currentSelection = ValueNotifier(null);
@override @override
ValueNotifier<List<Node>> currentSelectedNodes = ValueNotifier([]); List<Node> currentSelectedNodes = [];
@override @override
List<Node> getNodesInSelection(Selection selection) => List<Node> getNodesInSelection(Selection selection) =>
@ -145,8 +151,8 @@ class _FlowySelectionState extends State<FlowySelection>
super.didChangeMetrics(); super.didChangeMetrics();
// Need to refresh the selection when the metrics changed. // Need to refresh the selection when the metrics changed.
if (currentSelection != null) { if (currentSelection.value != null) {
updateSelection(currentSelection!); updateSelection(currentSelection.value!);
} }
} }
@ -192,8 +198,8 @@ class _FlowySelectionState extends State<FlowySelection>
@override @override
void clearSelection() { void clearSelection() {
currentSelection = null; currentSelectedNodes = [];
currentSelectedNodes.value = []; currentSelection.value = null;
// clear selection // clear selection
_selectionOverlays _selectionOverlays
@ -399,8 +405,8 @@ class _FlowySelectionState extends State<FlowySelection>
void _updateSelection(Selection selection) { void _updateSelection(Selection selection) {
final nodes = _selectedNodesInSelection(editorState.document, selection); final nodes = _selectedNodesInSelection(editorState.document, selection);
currentSelection = selection; currentSelectedNodes = nodes;
currentSelectedNodes.value = nodes; currentSelection.value = selection;
Rect? topmostRect; Rect? topmostRect;
LayerLink? layerLink; LayerLink? layerLink;
@ -480,8 +486,8 @@ class _FlowySelectionState extends State<FlowySelection>
return; return;
} }
currentSelection = Selection.collapsed(position); currentSelectedNodes = [node];
currentSelectedNodes.value = [node]; currentSelection.value = Selection.collapsed(position);
final selectable = node.selectable; final selectable = node.selectable;
final rect = selectable?.getCursorRectInPosition(position); final rect = selectable?.getCursorRectInPosition(position);