瀏覽代碼

chore: add overlap dragTarget interceptor

appflowy 2 年之前
父節點
當前提交
9ea4c8b260

+ 122 - 19
frontend/app_flowy/packages/flowy_board/lib/src/widgets/board.dart

@@ -4,7 +4,8 @@ import 'package:flutter/material.dart';
 import 'package:provider/provider.dart';
 import '../../flowy_board.dart';
 
-import 'column_container.dart';
+import '../rendering/board_overlay.dart';
+import 'flex/drag_target_inteceptor.dart';
 import 'flex/reorder_flex.dart';
 import 'phantom/phantom_controller.dart';
 
@@ -57,22 +58,24 @@ class Board extends StatelessWidget {
   Widget build(BuildContext context) {
     return ChangeNotifierProvider.value(
       value: dataController,
-      child: Consumer(
+      child: Consumer<BoardDataController>(
         builder: (context, notifier, child) {
-          List<Widget> children = [];
-          List<String> acceptColumns =
-              dataController.columnControllers.keys.toList();
+          List<Widget> children = dataController.columnDatas.map((columnData) {
+            final controller = dataController.columnController(columnData.id);
 
-          dataController.columnControllers.forEach((columnId, controller) {
-            Widget child = _buildColumn(columnId, acceptColumns, controller);
-            children.add(child);
-          });
+            return _buildColumn(
+              columnData.id,
+              dataController.columnIds,
+              controller,
+            );
+          }).toList();
 
           return BoardColumnContainer(
-            onReorder: (fromIndex, toIndex) {},
+            onReorder: dataController.onReorder,
             boardDataController: dataController,
             background: background,
             spacing: spacing,
+            delegate: phantomController,
             children: children,
           );
         },
@@ -97,7 +100,7 @@ class Board extends StatelessWidget {
               headerBuilder: headerBuilder,
               footBuilder: footBuilder,
               cardBuilder: cardBuilder,
-              acceptColumns: acceptColumns,
+              acceptedColumns: acceptColumns,
               dataController: dataController,
               scrollController: ScrollController(),
               onReorder: (_, int fromIndex, int toIndex) {
@@ -114,33 +117,133 @@ class Board extends StatelessWidget {
 
 class BoardDataController extends ChangeNotifier
     with EquatableMixin, BoardPhantomControllerDelegate, ReoderFlextDataSource {
-  final LinkedHashMap<String, BoardColumnData> columnDatas = LinkedHashMap();
-  final LinkedHashMap<String, BoardColumnDataController> columnControllers =
+  final List<BoardColumnData> _columnDatas = [];
+
+  List<BoardColumnData> get columnDatas => _columnDatas;
+
+  List<String> get columnIds =>
+      _columnDatas.map((columnData) => columnData.id).toList();
+
+  final LinkedHashMap<String, BoardColumnDataController> _columnControllers =
       LinkedHashMap();
 
   BoardDataController();
 
   void setColumnData(BoardColumnData columnData) {
     final controller = BoardColumnDataController(columnData: columnData);
-    columnDatas[columnData.id] = columnData;
-    columnControllers[columnData.id] = controller;
+    _columnDatas.add(columnData);
+    _columnControllers[columnData.id] = controller;
+  }
+
+  BoardColumnDataController columnController(String columnId) {
+    return _columnControllers[columnId]!;
+  }
+
+  void onReorder(int fromIndex, int toIndex) {
+    final columnData = _columnDatas.removeAt(fromIndex);
+    _columnDatas.insert(toIndex, columnData);
+    notifyListeners();
   }
 
   @override
   List<Object?> get props {
-    return [columnDatas.values];
+    return [_columnDatas];
   }
 
   @override
   BoardColumnDataController? controller(String columnId) {
-    return columnControllers[columnId];
+    return _columnControllers[columnId];
   }
 
   @override
   String get identifier => '$BoardDataController';
 
   @override
-  List<ReoderFlextItem> get items => columnDatas.values.toList();
+  List<ReoderFlexItem> get items => _columnDatas;
+}
+
+class BoardColumnContainer extends StatefulWidget {
+  final ScrollController? scrollController;
+  final OnDragStarted? onDragStarted;
+  final OnReorder onReorder;
+  final OnDragEnded? onDragEnded;
+  final BoardDataController boardDataController;
+  final List<Widget> children;
+  final Widget? background;
+  final double spacing;
+  final ReorderFlexConfig config;
+
+  final OverlapReorderFlexDragTargetDelegate delegate;
+
+  const BoardColumnContainer({
+    required this.onReorder,
+    required this.children,
+    required this.delegate,
+    required this.boardDataController,
+    this.onDragStarted,
+    this.onDragEnded,
+    this.scrollController,
+    this.background,
+    this.spacing = 0.0,
+    this.config = const ReorderFlexConfig(),
+    Key? key,
+  }) : super(key: key);
+
+  @override
+  State<BoardColumnContainer> createState() => _BoardColumnContainerState();
 }
 
-class BoardDataIdentifier {}
+class _BoardColumnContainerState extends State<BoardColumnContainer> {
+  final GlobalKey _columnContainerOverlayKey =
+      GlobalKey(debugLabel: '$BoardColumnContainer overlay key');
+  late BoardOverlayEntry _overlayEntry;
+
+  @override
+  void initState() {
+    _overlayEntry = BoardOverlayEntry(
+      builder: (BuildContext context) {
+        final interceptor = OverlapReorderFlexDragTargetInteceptor(
+          reorderFlexId: widget.boardDataController.identifier,
+          acceptedReorderFlexId: widget.boardDataController.columnIds,
+          delegate: widget.delegate,
+        );
+
+        Widget reorderFlex = ReorderFlex(
+          key: widget.key,
+          scrollController: widget.scrollController,
+          config: widget.config,
+          onDragStarted: widget.onDragStarted,
+          onReorder: widget.onReorder,
+          onDragEnded: widget.onDragEnded,
+          dataSource: widget.boardDataController,
+          direction: Axis.horizontal,
+          spacing: widget.spacing,
+          interceptor: interceptor,
+          children: widget.children,
+        );
+
+        return _wrapStack(reorderFlex);
+      },
+      opaque: false,
+    );
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return BoardOverlay(
+      key: _columnContainerOverlayKey,
+      initialEntries: [_overlayEntry],
+    );
+  }
+
+  Widget _wrapStack(Widget child) {
+    return Stack(
+      alignment: AlignmentDirectional.topStart,
+      children: [
+        if (widget.background != null) widget.background!,
+        child,
+      ],
+    );
+  }
+}

+ 4 - 4
frontend/app_flowy/packages/flowy_board/lib/src/widgets/board_column/board_column.dart

@@ -36,7 +36,7 @@ class BoardColumnWidget extends StatefulWidget {
 
   String get columnId => dataController.identifier;
 
-  final List<String> acceptColumns;
+  final List<String> acceptedColumns;
 
   final BoardColumnCardBuilder cardBuilder;
 
@@ -54,7 +54,7 @@ class BoardColumnWidget extends StatefulWidget {
     required this.onReorder,
     required this.dataController,
     required this.phantomController,
-    required this.acceptColumns,
+    required this.acceptedColumns,
     this.config = const ReorderFlexConfig(),
     this.spacing,
     this.onDragStarted,
@@ -89,7 +89,7 @@ class _BoardColumnWidgetState extends State<BoardColumnWidget> {
         final interceptor = CrossReorderFlexDragTargetInterceptor(
           reorderFlexId: widget.columnId,
           delegate: widget.phantomController,
-          acceptReorderFlexIds: widget.acceptColumns,
+          acceptedReorderFlexIds: widget.acceptedColumns,
           draggableTargetBuilder: PhantomDraggableBuilder(),
         );
 
@@ -153,7 +153,7 @@ class _BoardColumnWidgetState extends State<BoardColumnWidget> {
 }
 
 void _printItems(BoardColumnDataController dataController) {
-  String msg = '';
+  String msg = 'Column${dataController.columnData} data: ';
   for (var element in dataController.items) {
     msg = '$msg$element,';
   }

+ 3 - 4
frontend/app_flowy/packages/flowy_board/lib/src/widgets/board_column/data_controller.dart

@@ -3,9 +3,7 @@ import 'package:flutter/material.dart';
 import '../../utils/log.dart';
 import '../flex/reorder_flex.dart';
 
-abstract class ColumnItem extends ReoderFlextItem {
-  String get id;
-
+abstract class ColumnItem extends ReoderFlexItem {
   bool get isPhantom => false;
 
   @override
@@ -14,7 +12,8 @@ abstract class ColumnItem extends ReoderFlextItem {
   }
 }
 
-class BoardColumnData extends ReoderFlextItem with EquatableMixin {
+class BoardColumnData extends ReoderFlexItem with EquatableMixin {
+  @override
   final String id;
   final List<ColumnItem> items;
 

+ 0 - 88
frontend/app_flowy/packages/flowy_board/lib/src/widgets/column_container.dart

@@ -1,88 +0,0 @@
-import 'package:flutter/material.dart';
-
-import '../../flowy_board.dart';
-import '../rendering/board_overlay.dart';
-import 'flex/reorder_flex.dart';
-
-class BoardColumnContainer extends StatefulWidget {
-  final ScrollController? scrollController;
-  final OnDragStarted? onDragStarted;
-  final OnReorder onReorder;
-  final OnDragEnded? onDragEnded;
-  final BoardDataController boardDataController;
-  final List<Widget> children;
-  final EdgeInsets? padding;
-  final Widget? background;
-  final double spacing;
-  final ReorderFlexConfig config;
-
-  const BoardColumnContainer({
-    required this.boardDataController,
-    required this.onReorder,
-    required this.children,
-    this.onDragStarted,
-    this.onDragEnded,
-    this.scrollController,
-    this.padding,
-    this.background,
-    this.spacing = 0.0,
-    this.config = const ReorderFlexConfig(),
-    Key? key,
-  }) : super(key: key);
-
-  @override
-  State<BoardColumnContainer> createState() => _BoardColumnContainerState();
-}
-
-class _BoardColumnContainerState extends State<BoardColumnContainer> {
-  final GlobalKey _columnContainerOverlayKey =
-      GlobalKey(debugLabel: '$BoardColumnContainer overlay key');
-  late BoardOverlayEntry _overlayEntry;
-
-  @override
-  void initState() {
-    _overlayEntry = BoardOverlayEntry(
-        builder: (BuildContext context) {
-          Widget reorderFlex = ReorderFlex(
-            key: widget.key,
-            scrollController: widget.scrollController,
-            config: widget.config,
-            onDragStarted: (index) {},
-            onReorder: ((fromIndex, toIndex) {}),
-            onDragEnded: () {},
-            dataSource: widget.boardDataController,
-            direction: Axis.horizontal,
-            spacing: widget.spacing,
-            children: widget.children,
-          );
-
-          if (widget.padding != null) {
-            reorderFlex = Padding(
-              padding: widget.padding!,
-              child: reorderFlex,
-            );
-          }
-          return _wrapStack(reorderFlex);
-        },
-        opaque: false);
-    super.initState();
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return BoardOverlay(
-      key: _columnContainerOverlayKey,
-      initialEntries: [_overlayEntry],
-    );
-  }
-
-  Widget _wrapStack(Widget child) {
-    return Stack(
-      alignment: AlignmentDirectional.topStart,
-      children: [
-        if (widget.background != null) widget.background!,
-        child,
-      ],
-    );
-  }
-}

+ 13 - 5
frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/drag_state.dart

@@ -17,24 +17,32 @@ class FlexDragTargetData extends DragTargetData {
 
   Size? get draggingFeedbackSize => state.feedbackSize;
 
-  /// Indicate the dargging come from which [ReorderFlex].
+  /// Indicate the dragTarget come from which [ReorderFlex].
   final DraggingReorderFlex draggingReorderFlex;
 
-  ReoderFlextItem get columnItem =>
+  final String dragTargetId;
+
+  ReoderFlexItem get reorderFlexItem =>
       draggingReorderFlex.itemAtIndex(draggingIndex);
 
-  String get reorderFlexId => draggingReorderFlex.id;
+  String get reorderFlexId => draggingReorderFlex.reorderFlexId;
 
   FlexDragTargetData({
+    required this.dragTargetId,
     required this.draggingIndex,
     required this.state,
     required this.draggingReorderFlex,
   });
+
+  @override
+  String toString() {
+    return 'ReorderFlexId: $reorderFlexId, dragTargetId: $dragTargetId';
+  }
 }
 
 abstract class DraggingReorderFlex {
-  String get id;
-  ReoderFlextItem itemAtIndex(int index);
+  String get reorderFlexId;
+  ReoderFlexItem itemAtIndex(int index);
 }
 
 class DraggingState {

+ 78 - 32
frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/drag_target_inteceptor.dart

@@ -8,12 +8,13 @@ import 'reorder_flex.dart';
 abstract class ReorderFlexDragTargetInterceptor {
   bool canHandler(FlexDragTargetData dragTargetData);
 
-  bool onWillAccept(
-    BuildContext context,
-    ReorderFlexState reorderFlexState,
-    FlexDragTargetData dragTargetData,
-    int itemIndex,
-  );
+  bool onWillAccept({
+    required BuildContext context,
+    required ReorderFlexState reorderFlexState,
+    required FlexDragTargetData dragTargetData,
+    required String dragTargetId,
+    required int dragTargetIndex,
+  });
 
   void onAccept(FlexDragTargetData dragTargetData);
 
@@ -22,6 +23,51 @@ abstract class ReorderFlexDragTargetInterceptor {
   ReorderFlexDraggableTargetBuilder? get draggableTargetBuilder;
 }
 
+abstract class OverlapReorderFlexDragTargetDelegate
+    extends CrossReorderFlexDragTargetDelegate {}
+
+class OverlapReorderFlexDragTargetInteceptor
+    extends ReorderFlexDragTargetInterceptor {
+  final String reorderFlexId;
+  final List<String> acceptedReorderFlexId;
+  final OverlapReorderFlexDragTargetDelegate delegate;
+
+  OverlapReorderFlexDragTargetInteceptor({
+    required this.delegate,
+    required this.reorderFlexId,
+    required this.acceptedReorderFlexId,
+  });
+
+  @override
+  bool canHandler(FlexDragTargetData dragTargetData) {
+    return acceptedReorderFlexId.contains(dragTargetData.reorderFlexId);
+  }
+
+  @override
+  ReorderFlexDraggableTargetBuilder? get draggableTargetBuilder => null;
+
+  @override
+  void onAccept(FlexDragTargetData dragTargetData) {}
+
+  @override
+  void onLeave(FlexDragTargetData dragTargetData) {}
+
+  @override
+  bool onWillAccept(
+      {required BuildContext context,
+      required ReorderFlexState reorderFlexState,
+      required FlexDragTargetData dragTargetData,
+      required String dragTargetId,
+      required int dragTargetIndex}) {
+    Log.trace('dragTargetData: $dragTargetData');
+    Log.trace('currentDragTargetId: $dragTargetId');
+    //
+    Log.debug('Switch to $dragTargetId');
+
+    return true;
+  }
+}
+
 abstract class CrossReorderFlexDragTargetDelegate {
   bool acceptNewDragTargetData(
     String columnId,
@@ -38,7 +84,7 @@ abstract class CrossReorderFlexDragTargetDelegate {
 class CrossReorderFlexDragTargetInterceptor
     extends ReorderFlexDragTargetInterceptor {
   final String reorderFlexId;
-  final List<String> acceptReorderFlexIds;
+  final List<String> acceptedReorderFlexIds;
   final CrossReorderFlexDragTargetDelegate delegate;
   @override
   final ReorderFlexDraggableTargetBuilder? draggableTargetBuilder;
@@ -46,17 +92,17 @@ class CrossReorderFlexDragTargetInterceptor
   CrossReorderFlexDragTargetInterceptor({
     required this.reorderFlexId,
     required this.delegate,
-    required this.acceptReorderFlexIds,
+    required this.acceptedReorderFlexIds,
     this.draggableTargetBuilder,
   });
 
   @override
   bool canHandler(FlexDragTargetData dragTargetData) {
-    if (acceptReorderFlexIds.isEmpty) {
-      return true;
+    if (acceptedReorderFlexIds.isEmpty) {
+      return false;
     }
 
-    if (acceptReorderFlexIds.contains(dragTargetData.reorderFlexId)) {
+    if (acceptedReorderFlexIds.contains(dragTargetData.reorderFlexId)) {
       /// If the columnId equal to the dragTargetData's columnId,
       /// it means the dragTarget is dragging on the top of its own list.
       /// Otherwise, it means the dargTarget was moved to another list.
@@ -66,49 +112,49 @@ class CrossReorderFlexDragTargetInterceptor
     }
   }
 
+  @override
+  void onAccept(FlexDragTargetData dragTargetData) {
+    Log.trace(
+        '[$CrossReorderFlexDragTargetInterceptor] Column$reorderFlexId on onAccept');
+  }
+
+  @override
+  void onLeave(FlexDragTargetData dragTargetData) {
+    Log.trace(
+        '[$CrossReorderFlexDragTargetInterceptor] Column$reorderFlexId on leave');
+  }
+
   @override
   bool onWillAccept(
-    BuildContext context,
-    ReorderFlexState reorderFlexState,
-    FlexDragTargetData dragTargetData,
-    int itemIndex,
-  ) {
+      {required BuildContext context,
+      required ReorderFlexState reorderFlexState,
+      required FlexDragTargetData dragTargetData,
+      required String dragTargetId,
+      required int dragTargetIndex}) {
     final isNewDragTarget = delegate.acceptNewDragTargetData(
       reorderFlexId,
       dragTargetData,
-      itemIndex,
+      dragTargetIndex,
     );
 
     if (isNewDragTarget == false) {
       delegate.updateDragTargetData(
         reorderFlexId,
         dragTargetData,
-        itemIndex,
+        dragTargetIndex,
       );
 
       reorderFlexState.onWillAccept(
         context,
         dragTargetData.draggingIndex,
-        itemIndex,
+        dragTargetIndex,
       );
     } else {
       Log.debug(
           '[$CrossReorderFlexDragTargetInterceptor] move Column${dragTargetData.reorderFlexId}:${dragTargetData.draggingIndex} '
-          'to Column$reorderFlexId:$itemIndex');
+          'to Column$reorderFlexId:$dragTargetIndex');
     }
 
     return true;
   }
-
-  @override
-  void onAccept(FlexDragTargetData dragTargetData) {
-    Log.trace(
-        '[$CrossReorderFlexDragTargetInterceptor] Column$reorderFlexId on onAccept');
-  }
-
-  @override
-  void onLeave(FlexDragTargetData dragTargetData) {
-    Log.trace(
-        '[$CrossReorderFlexDragTargetInterceptor] Column$reorderFlexId on leave');
-  }
 }

+ 22 - 13
frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/reorder_flex.dart

@@ -18,10 +18,12 @@ typedef OnReveivePassedInPhantom = void Function(
 
 abstract class ReoderFlextDataSource {
   String get identifier;
-  List<ReoderFlextItem> get items;
+  List<ReoderFlexItem> get items;
 }
 
-abstract class ReoderFlextItem {}
+abstract class ReoderFlexItem {
+  String get id;
+}
 
 class ReorderFlexConfig {
   final bool needsLongPressDraggable = true;
@@ -68,10 +70,10 @@ class ReorderFlex extends StatefulWidget with DraggingReorderFlex {
   State<ReorderFlex> createState() => ReorderFlexState();
 
   @override
-  String get id => dataSource.identifier;
+  String get reorderFlexId => dataSource.identifier;
 
   @override
-  ReoderFlextItem itemAtIndex(int index) {
+  ReoderFlexItem itemAtIndex(int index) {
     return dataSource.items[index];
   }
 }
@@ -90,7 +92,7 @@ class ReorderFlexState extends State<ReorderFlex>
 
   @override
   void initState() {
-    dragState = DraggingState(widget.id);
+    dragState = DraggingState(widget.reorderFlexId);
 
     _dragAnimationController = DragAnimationController(
       reorderAnimationDuration: widget.config.reorderAnimationDuration,
@@ -135,6 +137,7 @@ class ReorderFlexState extends State<ReorderFlex>
 
     for (int i = 0; i < widget.children.length; i += 1) {
       Widget child = widget.children[i];
+
       if (widget.spacing != null) {
         children.add(SizedBox(width: widget.spacing!));
       }
@@ -283,12 +286,17 @@ class ReorderFlexState extends State<ReorderFlex>
   }
 
   ReorderDragTarget _buildDragTarget(
-      BuildContext builderContext, Widget child, int childIndex) {
+    BuildContext builderContext,
+    Widget child,
+    int dragTargetIndex,
+  ) {
+    final ReoderFlexItem item = widget.dataSource.items[dragTargetIndex];
     return ReorderDragTarget<FlexDragTargetData>(
       dragTargetData: FlexDragTargetData(
-        draggingIndex: childIndex,
+        draggingIndex: dragTargetIndex,
         state: dragState,
         draggingReorderFlex: widget,
+        dragTargetId: item.id,
       ),
       onDragStarted: (draggingWidget, draggingIndex, size) {
         Log.debug("Column${widget.dataSource.identifier} start dragging");
@@ -308,15 +316,16 @@ class ReorderFlexState extends State<ReorderFlex>
         });
       },
       onWillAccept: (FlexDragTargetData dragTargetData) {
-        assert(widget.dataSource.items.length > childIndex);
+        assert(widget.dataSource.items.length > dragTargetIndex);
 
         if (_interceptDragTarget(
           dragTargetData,
           (interceptor) => interceptor.onWillAccept(
-            builderContext,
-            this,
-            dragTargetData,
-            childIndex,
+            context: builderContext,
+            reorderFlexState: this,
+            dragTargetData: dragTargetData,
+            dragTargetId: item.id,
+            dragTargetIndex: dragTargetIndex,
           ),
         )) {
           return true;
@@ -324,7 +333,7 @@ class ReorderFlexState extends State<ReorderFlex>
           Log.debug(
               '[$ReorderDragTarget] ${widget.dataSource.identifier} on will accept, count: ${widget.dataSource.items.length}');
           final dragIndex = dragTargetData.draggingIndex;
-          return onWillAccept(builderContext, dragIndex, childIndex);
+          return onWillAccept(builderContext, dragIndex, dragTargetIndex);
         }
       },
       onAccept: (dragTargetData) {

+ 15 - 10
frontend/app_flowy/packages/flowy_board/lib/src/widgets/phantom/phantom_controller.dart

@@ -14,7 +14,10 @@ mixin ColumnDataPhantomMixim {
   BoardColumnDataController? get;
 }
 
-class BoardPhantomController extends CrossReorderFlexDragTargetDelegate {
+class BoardPhantomController
+    with
+        CrossReorderFlexDragTargetDelegate,
+        OverlapReorderFlexDragTargetDelegate {
   final BoardPhantomControllerDelegate delegate;
 
   PhantomRecord? phantomRecord;
@@ -142,17 +145,19 @@ class BoardPhantomController extends CrossReorderFlexDragTargetDelegate {
   }
 
   void _removePhantom(String columnId) {
-    final items = delegate.controller(columnId)?.items;
-    if (items == null) {
-      return;
-    }
+    final index = delegate
+        .controller(columnId)
+        ?.items
+        .indexWhere((item) => item.isPhantom);
+
+    if (index == null) return;
 
-    final index = items.indexWhere((item) => item.isPhantom);
     assert(index != -1);
+
     if (index != -1) {
-      items.removeAt(index);
+      delegate.controller(columnId)?.removeAt(index);
       Log.debug(
-          '[$BoardPhantomController] Column$columnId remove phantom, current count: ${items.length}');
+          '[$BoardPhantomController] Column$columnId remove phantom, current count: ${delegate.controller(columnId)?.items.length}');
       columnsState.notifyDidRemovePhantom(columnId);
       columnsState.removeColumnListener(columnId);
     }
@@ -195,7 +200,7 @@ class BoardPhantomController extends CrossReorderFlexDragTargetDelegate {
     phantomRecord = PhantomRecord(
       toColumnId: columnId,
       toColumnIndex: index,
-      item: dragTargetData.columnItem as ColumnItem,
+      item: dragTargetData.reorderFlexItem as ColumnItem,
       fromColumnId: dragTargetData.reorderFlexId,
       fromColumnIndex: dragTargetData.draggingIndex,
     );
@@ -275,7 +280,7 @@ class PassthroughPhantomContext extends FakeDragTargetEventTrigger
 
   Widget? get draggingWidget => dragTargetData.draggingWidget;
 
-  ColumnItem get itemData => dragTargetData.columnItem as ColumnItem;
+  ColumnItem get itemData => dragTargetData.reorderFlexItem as ColumnItem;
 
   @override
   VoidCallback? onInserted;