mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: refactor current selection and current selectedNodes in selection_service
This commit is contained in:
parent
4b4ce1020d
commit
7e6c7a2b4e
@ -67,13 +67,13 @@ class _ToolbarWidgetState extends State<ToolbarWidget> {
|
||||
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();
|
||||
}
|
||||
|
@ -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<TextNode>().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<TextNode>().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<TextNode>().toList();
|
||||
|
||||
if (selection == null || textNodes.isEmpty) {
|
||||
|
@ -42,15 +42,15 @@ class _FlowyInputState extends State<FlowyInput>
|
||||
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<FlowyInput>
|
||||
|
||||
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<FlowyInput>
|
||||
|
||||
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<FlowyInput>
|
||||
// TODO: implement updateFloatingCursor
|
||||
}
|
||||
|
||||
void _onSelectedNodesChange() {
|
||||
final textNodes = _editorState
|
||||
.service.selectionService.currentSelectedNodes.value
|
||||
void _onSelectionChange() {
|
||||
final textNodes = _editorState.service.selectionService.currentSelectedNodes
|
||||
.whereType<TextNode>();
|
||||
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<String>(
|
||||
|
@ -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<TextNode>().toList();
|
||||
if (textNodes.length != nodes.length) {
|
||||
|
@ -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 ||
|
||||
|
@ -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<TextNode>();
|
||||
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;
|
||||
|
@ -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<TextNode>().toList(growable: false);
|
||||
|
||||
if (selection == null || textNodes.isEmpty) {
|
||||
|
@ -17,20 +17,26 @@ import 'package:flowy_editor/render/selection/selection_widget.dart';
|
||||
|
||||
/// Process selection and cursor
|
||||
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.
|
||||
ValueNotifier<List<Node>> get currentSelectedNodes;
|
||||
Selection? get currentSelection;
|
||||
|
||||
/// ------------------ Selection ------------------------
|
||||
List<Node> 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<Rect> rects();
|
||||
|
||||
Position? hitTest(Offset? offset);
|
||||
@ -124,10 +130,10 @@ class _FlowySelectionState extends State<FlowySelection>
|
||||
EditorState get editorState => widget.editorState;
|
||||
|
||||
@override
|
||||
Selection? currentSelection;
|
||||
ValueNotifier<Selection?> currentSelection = ValueNotifier(null);
|
||||
|
||||
@override
|
||||
ValueNotifier<List<Node>> currentSelectedNodes = ValueNotifier([]);
|
||||
List<Node> currentSelectedNodes = [];
|
||||
|
||||
@override
|
||||
List<Node> getNodesInSelection(Selection selection) =>
|
||||
@ -145,8 +151,8 @@ class _FlowySelectionState extends State<FlowySelection>
|
||||
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<FlowySelection>
|
||||
|
||||
@override
|
||||
void clearSelection() {
|
||||
currentSelection = null;
|
||||
currentSelectedNodes.value = [];
|
||||
currentSelectedNodes = [];
|
||||
currentSelection.value = null;
|
||||
|
||||
// clear selection
|
||||
_selectionOverlays
|
||||
@ -399,8 +405,8 @@ class _FlowySelectionState extends State<FlowySelection>
|
||||
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<FlowySelection>
|
||||
return;
|
||||
}
|
||||
|
||||
currentSelection = Selection.collapsed(position);
|
||||
currentSelectedNodes.value = [node];
|
||||
currentSelectedNodes = [node];
|
||||
currentSelection.value = Selection.collapsed(position);
|
||||
|
||||
final selectable = node.selectable;
|
||||
final rect = selectable?.getCursorRectInPosition(position);
|
||||
|
Loading…
Reference in New Issue
Block a user