fix: the magnifier doesn't disappear when the selection is collapsed (#675)

This commit is contained in:
Lucas.Xu 2024-01-15 14:33:58 +08:00 • committed by GitHub
commit 71521ca953
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 19 deletions

View file

@ -19,15 +19,15 @@ StreamController<int> appFlowyEditorOnTapSelectionArea =
enum MobileSelectionDragMode { enum MobileSelectionDragMode {
none, none,
leftSelectionHandler, leftSelectionHandle,
rightSelectionHandler, rightSelectionHandle,
cursor; cursor;
} }
enum MobileSelectionHandlerType { enum MobileSelectionHandlerType {
leftHandler, leftHandle,
rightHandler, rightHandle,
cursorHandler, cursorHandle,
} }
// the value type is MobileSelectionDragMode // the value type is MobileSelectionDragMode
@ -165,6 +165,14 @@ class _MobileSelectionServiceWidgetState
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
if (selection.isCollapsed &&
[
MobileSelectionDragMode.leftSelectionHandle,
MobileSelectionDragMode.rightSelectionHandle,
].contains(dragMode)) {
return const SizedBox.shrink();
}
selection = selection.normalized; selection = selection.normalized;
final node = editorState.getNodeAtPath(selection.start.path); final node = editorState.getNodeAtPath(selection.start.path);
@ -208,10 +216,24 @@ class _MobileSelectionServiceWidgetState
return ValueListenableBuilder( return ValueListenableBuilder(
valueListenable: selectionNotifierAfterLayout, valueListenable: selectionNotifierAfterLayout,
builder: (context, selection, _) { builder: (context, selection, _) {
if (selection == null || selection.isCollapsed) { if (selection == null) {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
if (selection.isCollapsed &&
[
MobileSelectionDragMode.none,
MobileSelectionDragMode.cursor,
].contains(dragMode)) {
return const SizedBox.shrink();
}
final isCollapsedWhenDraggingHandle = selection.isCollapsed &&
[
MobileSelectionDragMode.leftSelectionHandle,
MobileSelectionDragMode.rightSelectionHandle,
].contains(dragMode);
selection = selection.normalized; selection = selection.normalized;
final node = editorState.getNodeAtPath( final node = editorState.getNodeAtPath(
@ -220,10 +242,20 @@ class _MobileSelectionServiceWidgetState
: selection.end.path, : selection.end.path,
); );
final selectable = node?.selectable; final selectable = node?.selectable;
final rects = selectable?.getRectsInSelection(
selection, // get the cursor rect when the selection is collapsed.
shiftWithBaseOffset: true, final rects = isCollapsedWhenDraggingHandle
); ? [
selectable?.getCursorRectInPosition(
selection.start,
shiftWithBaseOffset: true,
) ??
Rect.zero,
]
: selectable?.getRectsInSelection(
selection,
shiftWithBaseOffset: true,
);
if (node == null || rects == null || rects.isEmpty) { if (node == null || rects == null || rects.isEmpty) {
return const SizedBox.shrink(); return const SizedBox.shrink();
@ -234,7 +266,9 @@ class _MobileSelectionServiceWidgetState
layerLink: node.layerLink, layerLink: node.layerLink,
rect: handleType == HandleType.left ? rects.first : rects.last, rect: handleType == HandleType.left ? rects.first : rects.last,
handleType: handleType, handleType: handleType,
handleColor: editorStyle.dragHandleColor, handleColor: isCollapsedWhenDraggingHandle
? Colors.transparent
: editorStyle.dragHandleColor,
handleWidth: editorStyle.mobileDragHandleWidth, handleWidth: editorStyle.mobileDragHandleWidth,
handleBallWidth: editorStyle.mobileDragHandleBallSize.width, handleBallWidth: editorStyle.mobileDragHandleBallSize.width,
enableHapticFeedbackOnAndroid: enableHapticFeedbackOnAndroid:
@ -276,6 +310,7 @@ class _MobileSelectionServiceWidgetState
void clearSelection() { void clearSelection() {
currentSelectedNodes = []; currentSelectedNodes = [];
currentSelection.value = null; currentSelection.value = null;
_lastPanOffset.value = null;
_clearSelection(); _clearSelection();
} }
@ -470,12 +505,12 @@ class _MobileSelectionServiceWidgetState
Selection? newSelection; Selection? newSelection;
if (end != null) { if (end != null) {
if (dragMode == MobileSelectionDragMode.leftSelectionHandler) { if (dragMode == MobileSelectionDragMode.leftSelectionHandle) {
newSelection = Selection( newSelection = Selection(
start: _panStartSelection!.normalized.end, start: _panStartSelection!.normalized.end,
end: end, end: end,
).normalized; ).normalized;
} else if (dragMode == MobileSelectionDragMode.rightSelectionHandler) { } else if (dragMode == MobileSelectionDragMode.rightSelectionHandle) {
newSelection = Selection( newSelection = Selection(
start: _panStartSelection!.normalized.start, start: _panStartSelection!.normalized.start,
end: end, end: end,

View file

@ -122,8 +122,8 @@ class _MobileFloatingToolbarState extends State<MobileFloatingToolbar>
_clear(); _clear();
final dragMode = editorState.selectionExtraInfo?[selectionDragModeKey]; final dragMode = editorState.selectionExtraInfo?[selectionDragModeKey];
if ([ if ([
MobileSelectionDragMode.leftSelectionHandler, MobileSelectionDragMode.leftSelectionHandle,
MobileSelectionDragMode.rightSelectionHandler, MobileSelectionDragMode.rightSelectionHandle,
].contains(dragMode)) { ].contains(dragMode)) {
return; return;
} }

View file

@ -23,9 +23,9 @@ enum HandleType {
case HandleType.none: case HandleType.none:
throw UnsupportedError('Unsupported handle type'); throw UnsupportedError('Unsupported handle type');
case HandleType.left: case HandleType.left:
return MobileSelectionDragMode.leftSelectionHandler; return MobileSelectionDragMode.leftSelectionHandle;
case HandleType.right: case HandleType.right:
return MobileSelectionDragMode.rightSelectionHandler; return MobileSelectionDragMode.rightSelectionHandle;
case HandleType.collapsed: case HandleType.collapsed:
return MobileSelectionDragMode.cursor; return MobileSelectionDragMode.cursor;
} }
@ -207,19 +207,25 @@ class _IOSDragHandle extends _IDragHandle {
final editorState = context.read<EditorState>(); final editorState = context.read<EditorState>();
final ballWidth = handleBallWidth; final ballWidth = handleBallWidth;
double offset = 0.0;
if (handleType == HandleType.left) {
offset = ballWidth;
} else if (handleType == HandleType.right) {
offset = -ballWidth;
}
child = GestureDetector( child = GestureDetector(
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
dragStartBehavior: DragStartBehavior.down, dragStartBehavior: DragStartBehavior.down,
onPanStart: (details) { onPanStart: (details) {
editorState.service.selectionService.onPanStart( editorState.service.selectionService.onPanStart(
details.translate(0, -ballWidth), details.translate(0, offset),
handleType.dragMode, handleType.dragMode,
); );
}, },
onPanUpdate: (details) { onPanUpdate: (details) {
editorState.service.selectionService.onPanUpdate( editorState.service.selectionService.onPanUpdate(
details.translate(0, -ballWidth), details.translate(0, offset),
handleType.dragMode, handleType.dragMode,
); );
}, },