feat: add interceptor into selection service to custom the drag target node (#1044)
This commit is contained in:
parent
c1e9d15572
commit
400083fde6
4 changed files with 70 additions and 16 deletions
|
|
@ -437,12 +437,21 @@ class _DesktopSelectionServiceWidgetState
|
||||||
void renderDropTargetForOffset(
|
void renderDropTargetForOffset(
|
||||||
Offset offset, {
|
Offset offset, {
|
||||||
DragAreaBuilder? builder,
|
DragAreaBuilder? builder,
|
||||||
|
DragTargetNodeInterceptor? interceptor,
|
||||||
}) {
|
}) {
|
||||||
removeDropTarget();
|
removeDropTarget();
|
||||||
|
|
||||||
final node = getNodeInOffset(offset);
|
Node? node = getNodeInOffset(offset);
|
||||||
final selectable = node?.selectable;
|
if (node == null) {
|
||||||
if (node == null || selectable == null) {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interceptor != null) {
|
||||||
|
node = interceptor(context, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
final selectable = node.selectable;
|
||||||
|
if (selectable == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -461,7 +470,7 @@ class _DesktopSelectionServiceWidgetState
|
||||||
|
|
||||||
_dropTargetEntry = OverlayEntry(
|
_dropTargetEntry = OverlayEntry(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
if (builder != null) {
|
if (builder != null && node != null) {
|
||||||
return builder(
|
return builder(
|
||||||
context,
|
context,
|
||||||
DragAreaBuilderData(
|
DragAreaBuilderData(
|
||||||
|
|
@ -507,9 +516,21 @@ class _DesktopSelectionServiceWidgetState
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
DropTargetRenderData? getDropTargetRenderData(Offset offset) {
|
DropTargetRenderData? getDropTargetRenderData(
|
||||||
final node = getNodeInOffset(offset);
|
Offset offset, {
|
||||||
final selectable = node?.selectable;
|
DragTargetNodeInterceptor? interceptor,
|
||||||
|
}) {
|
||||||
|
Node? node = getNodeInOffset(offset);
|
||||||
|
|
||||||
|
if (node == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interceptor != null) {
|
||||||
|
node = interceptor(context, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
final selectable = node.selectable;
|
||||||
if (selectable == null) {
|
if (selectable == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -527,10 +548,10 @@ class _DesktopSelectionServiceWidgetState
|
||||||
|
|
||||||
final isCloserToStart = topDistance < bottomDistance;
|
final isCloserToStart = topDistance < bottomDistance;
|
||||||
|
|
||||||
final dropPath = isCloserToStart ? node?.path : node?.path.next;
|
final dropPath = isCloserToStart ? node.path : node.path.next;
|
||||||
|
|
||||||
return DropTargetRenderData(
|
return DropTargetRenderData(
|
||||||
dropPath: dropPath ?? node?.path,
|
dropPath: dropPath,
|
||||||
cursorNode: node,
|
cursorNode: node,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -881,10 +881,18 @@ class _MobileSelectionServiceWidgetState
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void renderDropTargetForOffset(Offset offset, {DragAreaBuilder? builder}) {
|
void renderDropTargetForOffset(
|
||||||
|
Offset offset, {
|
||||||
|
DragAreaBuilder? builder,
|
||||||
|
DragTargetNodeInterceptor? interceptor,
|
||||||
|
}) {
|
||||||
// Do nothing on mobile
|
// Do nothing on mobile
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
DropTargetRenderData? getDropTargetRenderData(Offset offset) => null;
|
DropTargetRenderData? getDropTargetRenderData(
|
||||||
|
Offset offset, {
|
||||||
|
DragTargetNodeInterceptor? interceptor,
|
||||||
|
}) =>
|
||||||
|
null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,11 @@ typedef DragAreaBuilder = Widget Function(
|
||||||
DragAreaBuilderData data,
|
DragAreaBuilderData data,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typedef DragTargetNodeInterceptor = Node Function(
|
||||||
|
BuildContext context,
|
||||||
|
Node node,
|
||||||
|
);
|
||||||
|
|
||||||
/// [AppFlowySelectionService] is responsible for processing
|
/// [AppFlowySelectionService] is responsible for processing
|
||||||
/// the [Selection] changes and updates.
|
/// the [Selection] changes and updates.
|
||||||
///
|
///
|
||||||
|
|
@ -105,9 +110,12 @@ abstract class AppFlowySelectionService {
|
||||||
///
|
///
|
||||||
/// If [builder] is provided, the line will be drawn by [builder].
|
/// If [builder] is provided, the line will be drawn by [builder].
|
||||||
/// Otherwise, the line will be drawn by default [DropTargetStyle].
|
/// Otherwise, the line will be drawn by default [DropTargetStyle].
|
||||||
|
///
|
||||||
|
/// If [interceptor] is provided, the node will be intercepted by [interceptor].
|
||||||
void renderDropTargetForOffset(
|
void renderDropTargetForOffset(
|
||||||
Offset offset, {
|
Offset offset, {
|
||||||
DragAreaBuilder? builder,
|
DragAreaBuilder? builder,
|
||||||
|
DragTargetNodeInterceptor? interceptor,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// Removes the horizontal line drawn by [renderDropTargetForOffset].
|
/// Removes the horizontal line drawn by [renderDropTargetForOffset].
|
||||||
|
|
@ -116,7 +124,10 @@ abstract class AppFlowySelectionService {
|
||||||
|
|
||||||
/// Returns the [DropTargetRenderData] for the [offset].
|
/// Returns the [DropTargetRenderData] for the [offset].
|
||||||
///
|
///
|
||||||
DropTargetRenderData? getDropTargetRenderData(Offset offset);
|
DropTargetRenderData? getDropTargetRenderData(
|
||||||
|
Offset offset, {
|
||||||
|
DragTargetNodeInterceptor? interceptor,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class SelectionGestureInterceptor {
|
class SelectionGestureInterceptor {
|
||||||
|
|
|
||||||
|
|
@ -124,10 +124,24 @@ class _SelectionServiceWidgetState extends State<SelectionServiceWidget>
|
||||||
void removeDropTarget() => forward.removeDropTarget();
|
void removeDropTarget() => forward.removeDropTarget();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void renderDropTargetForOffset(Offset offset, {DragAreaBuilder? builder}) =>
|
void renderDropTargetForOffset(
|
||||||
forward.renderDropTargetForOffset(offset, builder: builder);
|
Offset offset, {
|
||||||
|
DragAreaBuilder? builder,
|
||||||
|
DragTargetNodeInterceptor? interceptor,
|
||||||
|
}) =>
|
||||||
|
forward.renderDropTargetForOffset(
|
||||||
|
offset,
|
||||||
|
builder: builder,
|
||||||
|
interceptor: interceptor,
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
DropTargetRenderData? getDropTargetRenderData(Offset offset) =>
|
DropTargetRenderData? getDropTargetRenderData(
|
||||||
forward.getDropTargetRenderData(offset);
|
Offset offset, {
|
||||||
|
DragTargetNodeInterceptor? interceptor,
|
||||||
|
}) =>
|
||||||
|
forward.getDropTargetRenderData(
|
||||||
|
offset,
|
||||||
|
interceptor: interceptor,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue