diff --git a/frontend/app_flowy/packages/flowy_editor/lib/render/selection/toolbar_widget.dart b/frontend/app_flowy/packages/flowy_editor/lib/render/selection/toolbar_widget.dart index 1314260bca..4423e674dc 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/render/selection/toolbar_widget.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/render/selection/toolbar_widget.dart @@ -67,13 +67,13 @@ class _ToolbarWidgetState extends State { void initState() { super.initState(); - widget.editorState.service.selectionService.currentSelectedNodes + widget.editorState.service.selectionService.currentSelection .addListener(_onSelectionChange); } @override void dispose() { - widget.editorState.service.selectionService.currentSelectedNodes + widget.editorState.service.selectionService.currentSelection .removeListener(_onSelectionChange); super.dispose(); } diff --git a/frontend/app_flowy/packages/flowy_editor/lib/service/default_text_operations/format_rich_text_style.dart b/frontend/app_flowy/packages/flowy_editor/lib/service/default_text_operations/format_rich_text_style.dart index 8e0e3e35b0..46c7d3278f 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/service/default_text_operations/format_rich_text_style.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/service/default_text_operations/format_rich_text_style.dart @@ -38,7 +38,7 @@ void formatBulletedList(EditorState editorState) { } bool formatTextNodes(EditorState editorState, Attributes attributes) { - final nodes = editorState.service.selectionService.currentSelectedNodes.value; + final nodes = editorState.service.selectionService.currentSelectedNodes; final textNodes = nodes.whereType().toList(); if (textNodes.isEmpty) { @@ -85,8 +85,8 @@ bool formatStrikethrough(EditorState editorState) { } bool formatRichTextPartialStyle(EditorState editorState, String styleKey) { - final selection = editorState.service.selectionService.currentSelection; - final nodes = editorState.service.selectionService.currentSelectedNodes.value; + final selection = editorState.service.selectionService.currentSelection.value; + final nodes = editorState.service.selectionService.currentSelectedNodes; final textNodes = nodes.whereType().toList(growable: false); if (selection == null || textNodes.isEmpty) { @@ -107,8 +107,8 @@ bool formatRichTextPartialStyle(EditorState editorState, String styleKey) { } bool formatRichTextStyle(EditorState editorState, Attributes attributes) { - final selection = editorState.service.selectionService.currentSelection; - final nodes = editorState.service.selectionService.currentSelectedNodes.value; + final selection = editorState.service.selectionService.currentSelection.value; + final nodes = editorState.service.selectionService.currentSelectedNodes; final textNodes = nodes.whereType().toList(); if (selection == null || textNodes.isEmpty) { diff --git a/frontend/app_flowy/packages/flowy_editor/lib/service/input_service.dart b/frontend/app_flowy/packages/flowy_editor/lib/service/input_service.dart index 0d6f9aabd8..9d6e0f7470 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/service/input_service.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/service/input_service.dart @@ -42,15 +42,15 @@ class _FlowyInputState extends State void initState() { super.initState(); - _editorState.service.selectionService.currentSelectedNodes - .addListener(_onSelectedNodesChange); + _editorState.service.selectionService.currentSelection + .addListener(_onSelectionChange); } @override void dispose() { close(); - _editorState.service.selectionService.currentSelectedNodes - .removeListener(_onSelectedNodesChange); + _editorState.service.selectionService.currentSelection + .removeListener(_onSelectionChange); super.dispose(); } @@ -105,13 +105,12 @@ class _FlowyInputState extends State void _applyInsert(TextEditingDeltaInsertion delta) { final selectionService = _editorState.service.selectionService; - final currentSelection = selectionService.currentSelection; + final currentSelection = selectionService.currentSelection.value; if (currentSelection == null) { return; } if (currentSelection.isSingle) { - final textNode = - selectionService.currentSelectedNodes.value.first as TextNode; + final textNode = selectionService.currentSelectedNodes.first as TextNode; TransactionBuilder(_editorState) ..insertText( textNode, @@ -126,13 +125,12 @@ class _FlowyInputState extends State void _applyReplacement(TextEditingDeltaReplacement delta) { final selectionService = _editorState.service.selectionService; - final currentSelection = selectionService.currentSelection; + final currentSelection = selectionService.currentSelection.value; if (currentSelection == null) { return; } if (currentSelection.isSingle) { - final textNode = - selectionService.currentSelectedNodes.value.first as TextNode; + final textNode = selectionService.currentSelectedNodes.first as TextNode; final length = delta.replacedRange.end - delta.replacedRange.start; TransactionBuilder(_editorState) ..replaceText( @@ -209,11 +207,11 @@ class _FlowyInputState extends State // TODO: implement updateFloatingCursor } - void _onSelectedNodesChange() { - final textNodes = _editorState - .service.selectionService.currentSelectedNodes.value + void _onSelectionChange() { + final textNodes = _editorState.service.selectionService.currentSelectedNodes .whereType(); - final selection = _editorState.service.selectionService.currentSelection; + final selection = + _editorState.service.selectionService.currentSelection.value; // FIXME: upward and selection update. if (textNodes.isNotEmpty && selection != null) { final text = textNodes.fold( diff --git a/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/delete_text_handler.dart b/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/delete_text_handler.dart index 498fd845b2..5f59f4266d 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/delete_text_handler.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/delete_text_handler.dart @@ -9,12 +9,12 @@ FlowyKeyEventHandler deleteTextHandler = (editorState, event) { return KeyEventResult.ignored; } - final selection = editorState.service.selectionService.currentSelection; + final selection = editorState.service.selectionService.currentSelection.value; if (selection == null) { return KeyEventResult.ignored; } - final nodes = editorState.service.selectionService.currentSelectedNodes.value; + final nodes = editorState.service.selectionService.currentSelectedNodes; // make sure all nodes is [TextNode]. final textNodes = nodes.whereType().toList(); if (textNodes.length != nodes.length) { diff --git a/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/enter_in_edge_of_text_node_handler.dart b/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/enter_in_edge_of_text_node_handler.dart index ccdfcad5dc..9ea754e162 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/enter_in_edge_of_text_node_handler.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/enter_in_edge_of_text_node_handler.dart @@ -18,8 +18,8 @@ FlowyKeyEventHandler enterInEdgeOfTextNodeHandler = (editorState, event) { return KeyEventResult.ignored; } - final nodes = editorState.service.selectionService.currentSelectedNodes.value; - final selection = editorState.service.selectionService.currentSelection; + final nodes = editorState.service.selectionService.currentSelectedNodes; + final selection = editorState.service.selectionService.currentSelection.value; if (selection == null || nodes.length != 1 || nodes.first is! TextNode || diff --git a/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/slash_handler.dart b/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/slash_handler.dart index db3db2e1ad..d985e2beb7 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/slash_handler.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/slash_handler.dart @@ -56,14 +56,13 @@ FlowyKeyEventHandler slashShortcutHandler = (editorState, event) { return KeyEventResult.ignored; } - final textNodes = editorState - .service.selectionService.currentSelectedNodes.value + final textNodes = editorState.service.selectionService.currentSelectedNodes .whereType(); if (textNodes.length != 1) { return KeyEventResult.ignored; } - final selection = editorState.service.selectionService.currentSelection; + final selection = editorState.service.selectionService.currentSelection.value; final textNode = textNodes.first; final context = textNode.context; final selectable = textNode.selectable; @@ -97,9 +96,9 @@ FlowyKeyEventHandler slashShortcutHandler = (editorState, event) { Overlay.of(context)?.insert(_popupListOverlay!); - editorState.service.selectionService.currentSelectedNodes + editorState.service.selectionService.currentSelection .removeListener(clearPopupListOverlay); - editorState.service.selectionService.currentSelectedNodes + editorState.service.selectionService.currentSelection .addListener(clearPopupListOverlay); // editorState.service.keyboardService?.disable(); _editorState = editorState; diff --git a/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/update_text_style_by_command_x_handler.dart b/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/update_text_style_by_command_x_handler.dart index b062480cf2..220643cf6f 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/update_text_style_by_command_x_handler.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/update_text_style_by_command_x_handler.dart @@ -9,8 +9,8 @@ FlowyKeyEventHandler updateTextStyleByCommandXHandler = (editorState, event) { return KeyEventResult.ignored; } - final selection = editorState.service.selectionService.currentSelection; - final nodes = editorState.service.selectionService.currentSelectedNodes.value; + final selection = editorState.service.selectionService.currentSelection.value; + final nodes = editorState.service.selectionService.currentSelectedNodes; final textNodes = nodes.whereType().toList(growable: false); if (selection == null || textNodes.isEmpty) { diff --git a/frontend/app_flowy/packages/flowy_editor/lib/service/selection_service.dart b/frontend/app_flowy/packages/flowy_editor/lib/service/selection_service.dart index 0e2ad6267e..2775bdfee1 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/service/selection_service.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/service/selection_service.dart @@ -17,20 +17,26 @@ import 'package:flowy_editor/render/selection/selection_widget.dart'; /// Process selection and cursor mixin FlowySelectionService on State { - /// Returns the currently selected [Node]s. + /// Returns the current [Selection] + ValueNotifier get currentSelection; + + /// Returns the current selected [Node]s. /// /// The order of the return is determined according to the selected order. - ValueNotifier> get currentSelectedNodes; - Selection? get currentSelection; - - /// ------------------ Selection ------------------------ + List get currentSelectedNodes; + /// 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); - /// + /// Clear the selection or cursor. void clearSelection(); + /// ------------------ Selection ------------------------ + List rects(); Position? hitTest(Offset? offset); @@ -124,10 +130,10 @@ class _FlowySelectionState extends State EditorState get editorState => widget.editorState; @override - Selection? currentSelection; + ValueNotifier currentSelection = ValueNotifier(null); @override - ValueNotifier> currentSelectedNodes = ValueNotifier([]); + List currentSelectedNodes = []; @override List getNodesInSelection(Selection selection) => @@ -145,8 +151,8 @@ class _FlowySelectionState extends State super.didChangeMetrics(); // Need to refresh the selection when the metrics changed. - if (currentSelection != null) { - updateSelection(currentSelection!); + if (currentSelection.value != null) { + updateSelection(currentSelection.value!); } } @@ -192,8 +198,8 @@ class _FlowySelectionState extends State @override void clearSelection() { - currentSelection = null; - currentSelectedNodes.value = []; + currentSelectedNodes = []; + currentSelection.value = null; // clear selection _selectionOverlays @@ -399,8 +405,8 @@ class _FlowySelectionState extends State void _updateSelection(Selection selection) { final nodes = _selectedNodesInSelection(editorState.document, selection); - currentSelection = selection; - currentSelectedNodes.value = nodes; + currentSelectedNodes = nodes; + currentSelection.value = selection; Rect? topmostRect; LayerLink? layerLink; @@ -480,8 +486,8 @@ class _FlowySelectionState extends State return; } - currentSelection = Selection.collapsed(position); - currentSelectedNodes.value = [node]; + currentSelectedNodes = [node]; + currentSelection.value = Selection.collapsed(position); final selectable = node.selectable; final rect = selectable?.getCursorRectInPosition(position);