|
@@ -1,3 +1,4 @@
|
|
|
|
+import 'package:flowy_editor/flowy_cursor_widget.dart';
|
|
import 'package:flutter/gestures.dart';
|
|
import 'package:flutter/gestures.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
@@ -15,9 +16,9 @@ mixin _FlowySelectionService<T extends StatefulWidget> on State<T> {
|
|
/// Tap
|
|
/// Tap
|
|
Offset? tapOffset;
|
|
Offset? tapOffset;
|
|
|
|
|
|
- void updateSelection();
|
|
|
|
|
|
+ void updateSelection(Offset start, Offset end);
|
|
|
|
|
|
- void updateCursor();
|
|
|
|
|
|
+ void updateCursor(Offset offset);
|
|
|
|
|
|
/// Returns selected node(s)
|
|
/// Returns selected node(s)
|
|
/// Returns empty list if no nodes are being selected.
|
|
/// Returns empty list if no nodes are being selected.
|
|
@@ -66,6 +67,8 @@ class FlowySelectionWidget extends StatefulWidget {
|
|
|
|
|
|
class _FlowySelectionWidgetState extends State<FlowySelectionWidget>
|
|
class _FlowySelectionWidgetState extends State<FlowySelectionWidget>
|
|
with _FlowySelectionService {
|
|
with _FlowySelectionService {
|
|
|
|
+ final _cursorKey = GlobalKey(debugLabel: 'cursor');
|
|
|
|
+
|
|
List<OverlayEntry> selectionOverlays = [];
|
|
List<OverlayEntry> selectionOverlays = [];
|
|
|
|
|
|
EditorState get editorState => widget.editorState;
|
|
EditorState get editorState => widget.editorState;
|
|
@@ -98,14 +101,12 @@ class _FlowySelectionWidgetState extends State<FlowySelectionWidget>
|
|
}
|
|
}
|
|
|
|
|
|
@override
|
|
@override
|
|
- void updateSelection() {
|
|
|
|
|
|
+ void updateSelection(Offset start, Offset end) {
|
|
_clearOverlay();
|
|
_clearOverlay();
|
|
|
|
|
|
final nodes = selectedNodes;
|
|
final nodes = selectedNodes;
|
|
editorState.selectedNodes = nodes;
|
|
editorState.selectedNodes = nodes;
|
|
- if (nodes.isEmpty || panStartOffset == null || panEndOffset == null) {
|
|
|
|
- assert(panStartOffset == null);
|
|
|
|
- assert(panEndOffset == null);
|
|
|
|
|
|
+ if (nodes.isEmpty) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -114,8 +115,8 @@ class _FlowySelectionWidgetState extends State<FlowySelectionWidget>
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
final selectable = node.key?.currentState as Selectable;
|
|
final selectable = node.key?.currentState as Selectable;
|
|
- final selectionRects = selectable.getSelectionRectsInSelection(
|
|
|
|
- panStartOffset!, panEndOffset!);
|
|
|
|
|
|
+ final selectionRects =
|
|
|
|
+ selectable.getSelectionRectsInSelection(start, end);
|
|
for (final rect in selectionRects) {
|
|
for (final rect in selectionRects) {
|
|
final overlay = OverlayEntry(
|
|
final overlay = OverlayEntry(
|
|
builder: ((context) => Positioned.fromRect(
|
|
builder: ((context) => Positioned.fromRect(
|
|
@@ -132,14 +133,9 @@ class _FlowySelectionWidgetState extends State<FlowySelectionWidget>
|
|
}
|
|
}
|
|
|
|
|
|
@override
|
|
@override
|
|
- void updateCursor() {
|
|
|
|
|
|
+ void updateCursor(Offset offset) {
|
|
_clearOverlay();
|
|
_clearOverlay();
|
|
|
|
|
|
- if (tapOffset == null) {
|
|
|
|
- assert(tapOffset == null);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
final nodes = selectedNodes;
|
|
final nodes = selectedNodes;
|
|
editorState.selectedNodes = nodes;
|
|
editorState.selectedNodes = nodes;
|
|
if (nodes.isEmpty) {
|
|
if (nodes.isEmpty) {
|
|
@@ -151,13 +147,13 @@ class _FlowySelectionWidgetState extends State<FlowySelectionWidget>
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
final selectable = selectedNode.key?.currentState as Selectable;
|
|
final selectable = selectedNode.key?.currentState as Selectable;
|
|
- final rect = selectable.getCursorRect(tapOffset!);
|
|
|
|
|
|
+ final rect = selectable.getCursorRect(offset);
|
|
final cursor = OverlayEntry(
|
|
final cursor = OverlayEntry(
|
|
- builder: ((context) => Positioned.fromRect(
|
|
|
|
|
|
+ builder: ((context) => FlowyCursorWidget(
|
|
|
|
+ key: _cursorKey,
|
|
rect: rect,
|
|
rect: rect,
|
|
- child: Container(
|
|
|
|
- color: Colors.blue,
|
|
|
|
- ),
|
|
|
|
|
|
+ color: Colors.red,
|
|
|
|
+ layerLink: selectedNode.layerLink,
|
|
)),
|
|
)),
|
|
);
|
|
);
|
|
selectionOverlays.add(cursor);
|
|
selectionOverlays.add(cursor);
|
|
@@ -251,7 +247,7 @@ class _FlowySelectionWidgetState extends State<FlowySelectionWidget>
|
|
panStartOffset = null;
|
|
panStartOffset = null;
|
|
panEndOffset = null;
|
|
panEndOffset = null;
|
|
|
|
|
|
- updateCursor();
|
|
|
|
|
|
+ updateCursor(tapOffset!);
|
|
}
|
|
}
|
|
|
|
|
|
void _onPanStart(DragStartDetails details) {
|
|
void _onPanStart(DragStartDetails details) {
|
|
@@ -268,7 +264,7 @@ class _FlowySelectionWidgetState extends State<FlowySelectionWidget>
|
|
panEndOffset = details.globalPosition;
|
|
panEndOffset = details.globalPosition;
|
|
tapOffset = null;
|
|
tapOffset = null;
|
|
|
|
|
|
- updateSelection();
|
|
|
|
|
|
+ updateSelection(panStartOffset!, panEndOffset!);
|
|
}
|
|
}
|
|
|
|
|
|
void _onPanEnd(DragEndDetails details) {
|
|
void _onPanEnd(DragEndDetails details) {
|