From e5f70331b3f97d50d47bba8cc1f8c21083aec9a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C5=A1per=20Glin=C5=A1ek?= Date: Wed, 3 Apr 2024 13:36:18 +0200 Subject: [PATCH 1/3] fix when moving boxes parent views don't always update properly --- lib/widgets/draggable_multi_list_view.dart | 535 ++++++++++++--------- 1 file changed, 318 insertions(+), 217 deletions(-) diff --git a/lib/widgets/draggable_multi_list_view.dart b/lib/widgets/draggable_multi_list_view.dart index e1c1d2f..9eec953 100644 --- a/lib/widgets/draggable_multi_list_view.dart +++ b/lib/widgets/draggable_multi_list_view.dart @@ -26,7 +26,7 @@ class DraggableMultiListView extends SerializableMultiSplitView { class _DraggableMultiListViewState extends State { static const _rootKey = ValueKey("root"); final _controllers = {}; - final _widgets = []; + var _widgets = []; final _movingControllerMap = >{}; final _movedControllerMap = >{}; final _removedControllerMap = >{}; @@ -47,7 +47,7 @@ class _DraggableMultiListViewState extends State { // setState(() => _isMoving = isMoving); }); _movedControllerMap[key] = StreamController(); - _movedControllerMap[key]!.stream.listen(_movedControllerHandler); + //_movedControllerMap[key]!.stream.listen(_movedControllerHandler); _edgeControllerMap[key] = StreamController(); _edgeControllerMap[key]!.stream.listen(_edgeControllerHandler); _removedControllerMap[key] = StreamController(); @@ -97,22 +97,13 @@ class _DraggableMultiListViewState extends State { }); } - Widget? _recursiveWidgetSearchByKey(Key key) { - for (final widget in _widgets) { - final result = _recursiveWidgetSearch(widget, key); - if (result != null) { - return result; + Widget? _recursiveSearch(List widgets, Key key) { + for (final widget in widgets) { + if (widget.key == key) { + return widget; } - } - return null; - } - - Widget? _recursiveWidgetSearch(Widget widget, Key key) { - if (widget.key == key) { - return widget; - } else if (widget is SerializableMultiSplitView) { - for (final child in widget.children) { - final result = _recursiveWidgetSearch(child, key); + else if (widget is SerializableMultiSplitView) { + final result = _recursiveSearch(widget.children, key); if (result != null) { return result; } @@ -121,35 +112,119 @@ class _DraggableMultiListViewState extends State { return null; } - SerializableMultiSplitView? _getMovableBoxParentViewRecursive( - MovableBox box, List widgets) { - for (final widget in widgets) { + List _removeEmptySplitViews(List widgets) { + var cleanedWidgets = widgets; + var widgetList = List.of(widgets); + for (var widget in widgetList) { if (widget is SerializableMultiSplitView) { - for (final child in widget.children) { - if (child.key == box.key) { - return widget; - } else { - final result = - _getMovableBoxParentViewRecursive(box, widget.children); - if (result != null) { - return result; + if (widget.children.isEmpty) { + if (_areaMap.containsKey(widget.key)) { + _areaMap.remove(widget.key); + } + cleanedWidgets.remove(widget); + } + else { + var cleanedWidget = _removeEmptyChildren(widget); + if (cleanedWidget == null) { + if (_areaMap.containsKey(widget.key)) { + _areaMap.remove(widget.key); } + cleanedWidgets.remove(widget); + } + else { + cleanedWidgets[cleanedWidgets.indexWhere((element) => element == widget)] = cleanedWidget; + } } } + _controllers[widget.key]!.areas = List.from(_controllers[widget.key]!.areas); } - return null; + _controllers[_rootKey]!.areas = List.from(_controllers[_rootKey]!.areas); + return cleanedWidgets; } - SerializableMultiSplitView? _getParentView( - SerializableMultiSplitView view, List widgets) { + Widget? _removeEmptyChildren(SerializableMultiSplitView widget) { + final widgetChildren = List.of(widget.children); + for (final child in widgetChildren) { + if (child is SerializableMultiSplitView) { + if (child.children.isNotEmpty) { + var childWidget = _removeEmptyChildren(child); + if (childWidget == null){ + if (_areaMap.containsKey(child.key)) { + _areaMap.remove(child.key); + } + widget.children.remove(child); + } + else { + widget.children[widget.children.indexWhere((element) => element == child)] = childWidget; + } + } + if (child.children.isEmpty) { + if (_areaMap.containsKey(child.key)) { + _areaMap.remove(child.key); + } + widget.children.remove(child); + } + } + } + if (widget.children.isEmpty) { + return null; + } + + // // 5. update the areas of the target parent multi split view + // final targetAreas = + // List.from(_controllers[targetBoxParentKey]!.areas); + // _controllers[targetBoxParentKey]!.areas = targetAreas; + // // 6. update the areas of the moved parent multi split view, if the moved parent is not empty + // if (!movedParentEmpty) { + // final movedBoxParentAreas = + // List.from(_controllers[movedBoxParentKey]!.areas); + // movedBoxParentAreas.removeAt(0); + // _controllers[movedBoxParentKey]!.areas = movedBoxParentAreas; + // } + // // 7. update the areas of the new multi split view + // _controllers[newMultiSplitViewKey]!.areas = + // List.generate(2, (index) => Area()); + + + _controllers[widget.key]!.areas = List.from(_controllers[widget.key]!.areas); + return widget; + } + + // Widget? _recursiveSearch(Key key) { + // for (final widget in _widgets) { + // final result = _recursiveWidgetSearch(widget, key); + // if (result != null) { + // return result; + // } + // } + // return null; + // } + + // Widget? _recursiveWidgetSearch(Widget widget, Key key) { + // if (widget.key == key) { + // return widget; + // } else if (widget is SerializableMultiSplitView) { + // for (final child in widget.children) { + // final result = _recursiveWidgetSearch(child, key); + // if (result != null) { + // return result; + // } + // } + // } + // return null; + // } + + SerializableMultiSplitView? _getMovableBoxParentViewRecursive( + MovableBox box, List widgets) { for (final widget in widgets) { if (widget is SerializableMultiSplitView) { for (final child in widget.children) { - if (child.key == view.key) { + if (child.key == box.key) { return widget; } else { - final result = _getParentView(view, widget.children); + final result = + _getMovableBoxParentViewRecursive(box, widget.children); if (result != null) { return result; } @@ -160,6 +235,25 @@ class _DraggableMultiListViewState extends State { return null; } + // SerializableMultiSplitView? _getParentView( + // SerializableMultiSplitView view, List widgets) { + // for (final widget in widgets) { + // if (widget is SerializableMultiSplitView) { + // for (final child in widget.children) { + // if (child.key == view.key) { + // return widget; + // } else { + // final result = _getParentView(view, widget.children); + // if (result != null) { + // return result; + // } + // } + // } + // } + // } + // return null; + // } + // void _removeEmptyParentViewsRecursive(List widgets) { // for (final widget in widgets) { // if (widget is SerializableMultiSplitView) { @@ -179,160 +273,160 @@ class _DraggableMultiListViewState extends State { // } // } - _movedControllerHandler(MoveRecord data) { - final movedWidget = data.movedBox; - final targetWidget = data.targetBox; - final movedWidgetParentKey = - _getMovableBoxParentViewRecursive(movedWidget, _widgets)?.key; - final targetWidgetParentKey = - _getMovableBoxParentViewRecursive(targetWidget, _widgets)?.key; - - if (movedWidget.key == targetWidget.key) { - return; - } - - debugPrint( - "Moved MovedWidgetParentKey: $movedWidgetParentKey; TargetWidgetParentKey: $targetWidgetParentKey"); - - // 1. both widgets are children of the root multi split view - if (movedWidgetParentKey == null && targetWidgetParentKey == null) { - // 1. get the index of the target widget - final targetWidgetIndex = - _widgets.indexWhere((w) => w.key == targetWidget.key); - // 2. remove the moved widget from the root multi split view - _widgets.remove(movedWidget); - // 3. insert the moved widget to the root multi split view at the index of the target widget - _widgets.insert(targetWidgetIndex, movedWidget); - // 4. update the areas of the root multi split view - final rootAreas = List.from(_controllers[_rootKey]!.areas); - _controllers[_rootKey]!.areas = rootAreas; - } - - // 2. target widget is on the root multi split view and moved widget is a child of a child multi split view - if (targetWidgetParentKey == null && movedWidgetParentKey != null) { - // 1. remove the moved widget from the child multi split view - (_recursiveWidgetSearchByKey(movedWidgetParentKey)! - as SerializableMultiSplitView) - .children - .remove(movedWidget); - // 1.1 remove the parent if empty - bool movedParentEmpty = false; - if ((_recursiveWidgetSearchByKey(movedWidgetParentKey)! - as SerializableMultiSplitView) - .children - .isEmpty) { - movedParentEmpty = true; - _widgets.remove(_recursiveWidgetSearchByKey(movedWidgetParentKey)!); - } - // 2. get the index of the target widget - final targetIndex = _widgets.indexWhere((w) => w.key == targetWidget.key); - // 3. insert the moved widget to the root multi split view at the index of the target widget - _widgets.insert(targetIndex, movedWidget); - // 4. update the areas of the moved widget parent - if (!movedParentEmpty) { - _controllers[movedWidgetParentKey]!.areas = - List.from(_controllers[movedWidgetParentKey]!.areas) - ..removeAt(0); - } - // 5. update the areas of the root multi split view - final rootAreas = List.from(_controllers[_rootKey]!.areas); - rootAreas.insert(targetIndex, Area()); - _controllers[_rootKey]!.areas = rootAreas; - - // 6. remove the moved parent if it has only one child and put the child in the parent's place - if ((_recursiveWidgetSearchByKey(movedWidgetParentKey)! - as SerializableMultiSplitView) - .children - .length == - 1) { - final parent = _recursiveWidgetSearchByKey(movedWidgetParentKey)! - as SerializableMultiSplitView; - final parentsParent = _getParentView(parent, _widgets); - int parentIndex = 0; - - if (parentsParent != null) { - // TODO Check if this is valid!!! - parentIndex = - parentsParent.children.indexWhere((w) => w.key == parent.key); - parentsParent.children.removeAt(parentIndex); - parentsParent.children.insert(parentIndex, parent.children.first); - final areas = List.from(_controllers[parentsParent.key]!.areas); - _controllers[parentsParent.key]!.areas = areas; - } else { - parentIndex = _widgets.indexWhere((w) => w.key == parent.key); - _widgets.remove(parent); - _widgets.insert(parentIndex, parent.children.first); - final areas = List.from(_controllers[_rootKey]!.areas); - _controllers[_rootKey]!.areas = areas; - } - } - } - - // 3. old widget is a child of root - if (movedWidgetParentKey == null && targetWidgetParentKey != null) { - final targetWidgetIndex = - (_recursiveWidgetSearchByKey(targetWidgetParentKey)! - as SerializableMultiSplitView) - .children - .indexWhere((element) => element.key == targetWidget.key); - (_recursiveWidgetSearchByKey(targetWidgetParentKey)! - as SerializableMultiSplitView) - .children - .insert(targetWidgetIndex, movedWidget); - - final movedWidgetIndex = - _widgets.indexWhere((w) => w.key == movedWidget.key); - // _widgets.insert(movedWidgetIndex, targetWidget); - _widgets.removeAt(movedWidgetIndex); - - final areas = List.from(_controllers[targetWidgetParentKey]!.areas); - areas.add(Area()); - _controllers[targetWidgetParentKey]!.areas = areas; - - final rootAreas = List.from(_controllers[_rootKey]!.areas); - rootAreas.removeAt(0); - _controllers[_rootKey]!.areas = rootAreas; - } - - // 4. both parents are multi split views - if (movedWidgetParentKey != null && targetWidgetParentKey != null) { - final movedWidgetIndex = - (_recursiveWidgetSearchByKey(movedWidgetParentKey)! - as SerializableMultiSplitView) - .children - .indexWhere((w) => w.key == movedWidget.key); - final targetWidgetIndex = - (_recursiveWidgetSearchByKey(targetWidgetParentKey)! - as SerializableMultiSplitView) - .children - .indexWhere((w) => w.key == targetWidget.key); - // remove the new widget from their parent - (_recursiveWidgetSearchByKey(targetWidgetParentKey)! - as SerializableMultiSplitView) - .children - .removeAt(targetWidgetIndex); - // remove parent if empty - if ((_recursiveWidgetSearchByKey(targetWidgetParentKey)! - as SerializableMultiSplitView) - .children - .isEmpty) { - _widgets.remove(_recursiveWidgetSearchByKey(targetWidgetParentKey)!); - } - // add the new widget to the old parent - (_recursiveWidgetSearchByKey(movedWidgetParentKey)! - as SerializableMultiSplitView) - .children - .insert(movedWidgetIndex, targetWidget); - final movedWidgetParentAreas = - List.from(_controllers[movedWidgetParentKey]!.areas); - movedWidgetParentAreas.removeAt(0); - _controllers[movedWidgetParentKey]!.areas = movedWidgetParentAreas; - final targetWidgetParentAreas = - List.from(_controllers[targetWidgetParentKey]!.areas); - targetWidgetParentAreas.add(Area()); - _controllers[targetWidgetParentKey]!.areas = targetWidgetParentAreas; - } - } + // _movedControllerHandler(MoveRecord data) { + // final movedWidget = data.movedBox; + // final targetWidget = data.targetBox; + // final movedWidgetParentKey = + // _getMovableBoxParentViewRecursive(movedWidget, _widgets)?.key; + // final targetWidgetParentKey = + // _getMovableBoxParentViewRecursive(targetWidget, _widgets)?.key; + // + // if (movedWidget.key == targetWidget.key) { + // return; + // } + // + // debugPrint( + // "Moved MovedWidgetParentKey: $movedWidgetParentKey; TargetWidgetParentKey: $targetWidgetParentKey"); + // + // // 1. both widgets are children of the root multi split view + // if (movedWidgetParentKey == null && targetWidgetParentKey == null) { + // // 1. get the index of the target widget + // final targetWidgetIndex = + // _widgets.indexWhere((w) => w.key == targetWidget.key); + // // 2. remove the moved widget from the root multi split view + // _widgets.remove(movedWidget); + // // 3. insert the moved widget to the root multi split view at the index of the target widget + // _widgets.insert(targetWidgetIndex, movedWidget); + // // 4. update the areas of the root multi split view + // final rootAreas = List.from(_controllers[_rootKey]!.areas); + // _controllers[_rootKey]!.areas = rootAreas; + // } + // + // // 2. target widget is on the root multi split view and moved widget is a child of a child multi split view + // if (targetWidgetParentKey == null && movedWidgetParentKey != null) { + // // 1. remove the moved widget from the child multi split view + // (_recursiveSearch(_widgets, movedWidgetParentKey)! + // as SerializableMultiSplitView) + // .children + // .remove(movedWidget); + // // 1.1 remove the parent if empty + // bool movedParentEmpty = false; + // if ((_recursiveSearch(_widgets, movedWidgetParentKey)! + // as SerializableMultiSplitView) + // .children + // .isEmpty) { + // movedParentEmpty = true; + // _widgets.remove(_recursiveSearch(_widgets, movedWidgetParentKey)!); + // } + // // 2. get the index of the target widget + // final targetIndex = _widgets.indexWhere((w) => w.key == targetWidget.key); + // // 3. insert the moved widget to the root multi split view at the index of the target widget + // _widgets.insert(targetIndex, movedWidget); + // // 4. update the areas of the moved widget parent + // if (!movedParentEmpty) { + // _controllers[movedWidgetParentKey]!.areas = + // List.from(_controllers[movedWidgetParentKey]!.areas) + // ..removeAt(0); + // } + // // 5. update the areas of the root multi split view + // final rootAreas = List.from(_controllers[_rootKey]!.areas); + // rootAreas.insert(targetIndex, Area()); + // _controllers[_rootKey]!.areas = rootAreas; + // + // // 6. remove the moved parent if it has only one child and put the child in the parent's place + // if ((_recursiveSearch(_widgets, movedWidgetParentKey)! + // as SerializableMultiSplitView) + // .children + // .length == + // 1) { + // final parent = _recursiveSearch(_widgets, movedWidgetParentKey)! + // as SerializableMultiSplitView; + // final parentsParent = _getParentView(parent, _widgets); + // int parentIndex = 0; + // + // if (parentsParent != null) { + // // TODO Check if this is valid!!! + // parentIndex = + // parentsParent.children.indexWhere((w) => w.key == parent.key); + // parentsParent.children.removeAt(parentIndex); + // parentsParent.children.insert(parentIndex, parent.children.first); + // final areas = List.from(_controllers[parentsParent.key]!.areas); + // _controllers[parentsParent.key]!.areas = areas; + // } else { + // parentIndex = _widgets.indexWhere((w) => w.key == parent.key); + // _widgets.remove(parent); + // _widgets.insert(parentIndex, parent.children.first); + // final areas = List.from(_controllers[_rootKey]!.areas); + // _controllers[_rootKey]!.areas = areas; + // } + // } + // } + // + // // 3. old widget is a child of root + // if (movedWidgetParentKey == null && targetWidgetParentKey != null) { + // final targetWidgetIndex = + // (_recursiveSearch(_widgets, targetWidgetParentKey)! + // as SerializableMultiSplitView) + // .children + // .indexWhere((element) => element.key == targetWidget.key); + // (_recursiveSearch(_widgets, targetWidgetParentKey)! + // as SerializableMultiSplitView) + // .children + // .insert(targetWidgetIndex, movedWidget); + // + // final movedWidgetIndex = + // _widgets.indexWhere((w) => w.key == movedWidget.key); + // // _widgets.insert(movedWidgetIndex, targetWidget); + // _widgets.removeAt(movedWidgetIndex); + // + // final areas = List.from(_controllers[targetWidgetParentKey]!.areas); + // areas.add(Area()); + // _controllers[targetWidgetParentKey]!.areas = areas; + // + // final rootAreas = List.from(_controllers[_rootKey]!.areas); + // rootAreas.removeAt(0); + // _controllers[_rootKey]!.areas = rootAreas; + // } + // + // // 4. both parents are multi split views + // if (movedWidgetParentKey != null && targetWidgetParentKey != null) { + // final movedWidgetIndex = + // (_recursiveSearch(_widgets, movedWidgetParentKey)! + // as SerializableMultiSplitView) + // .children + // .indexWhere((w) => w.key == movedWidget.key); + // final targetWidgetIndex = + // (_recursiveSearch(_widgets, targetWidgetParentKey)! + // as SerializableMultiSplitView) + // .children + // .indexWhere((w) => w.key == targetWidget.key); + // // remove the new widget from their parent + // (_recursiveSearch(_widgets, targetWidgetParentKey)! + // as SerializableMultiSplitView) + // .children + // .removeAt(targetWidgetIndex); + // // remove parent if empty + // if ((_recursiveSearch(_widgets, targetWidgetParentKey)! + // as SerializableMultiSplitView) + // .children + // .isEmpty) { + // _widgets.remove(_recursiveSearch(_widgets, targetWidgetParentKey)!); + // } + // // add the new widget to the old parent + // (_recursiveSearch(_widgets, movedWidgetParentKey)! + // as SerializableMultiSplitView) + // .children + // .insert(movedWidgetIndex, targetWidget); + // final movedWidgetParentAreas = + // List.from(_controllers[movedWidgetParentKey]!.areas); + // movedWidgetParentAreas.removeAt(0); + // _controllers[movedWidgetParentKey]!.areas = movedWidgetParentAreas; + // final targetWidgetParentAreas = + // List.from(_controllers[targetWidgetParentKey]!.areas); + // targetWidgetParentAreas.add(Area()); + // _controllers[targetWidgetParentKey]!.areas = targetWidgetParentAreas; + // } + // } _edgeControllerHandler(EdgeRecord record) { debugPrint("EdgeRecord: $record"); @@ -379,15 +473,15 @@ class _DraggableMultiListViewState extends State { // if both boxes are children of the root multi split view if (targetBoxParentKey == null && movedBoxParentKey == null) { - // 1. get the target box index from the root multi split view + // 1. get the target & moved box index from the root multi split view final targetBoxIndex = _widgets.indexWhere((w) => w.key == targetBox.key); - // 2. remove target & moved box from the root multi split view - _widgets.remove(targetBox); + //final movedBoxIndex = _widgets.indexWhere((w) => w.key == movedBox.key); + // 2. remove moved box from the root multi split view _widgets.remove(movedBox); - // 3. remove moved box from the root multi split view - final movedBoxIndex = _widgets.indexWhere((w) => w.key == movedBox.key); - // 4. insert the new multi split view to the root multi split view on the target box index + // 3. insert the new multi split view to the root multi split view on the target box index _widgets.insert(targetBoxIndex, newMultiSplitView); + // 4. remove target box from the root multi split view + _widgets.remove(targetBox); // 5. update the areas of the root multi split view final rootAreas = List.from(_controllers[_rootKey]!.areas); rootAreas.removeAt(0); @@ -402,18 +496,18 @@ class _DraggableMultiListViewState extends State { // 1. get the index of the target box from the root multi split view final targetBoxIndex = _widgets.indexWhere((w) => w.key == targetBox.key); // 2. remove the moved box from the child multi split view - (_recursiveWidgetSearchByKey(movedBoxParentKey)! + (_recursiveSearch(_widgets, movedBoxParentKey)! as SerializableMultiSplitView) .children .remove(movedBox); // 2.1 remove the parent if empty bool movedParentEmpty = false; - if ((_recursiveWidgetSearchByKey(movedBoxParentKey)! + if ((_recursiveSearch(_widgets, movedBoxParentKey)! as SerializableMultiSplitView) .children .isEmpty) { movedParentEmpty = true; - _widgets.remove(_recursiveWidgetSearchByKey(movedBoxParentKey)!); + _widgets.remove(_recursiveSearch(_widgets, movedBoxParentKey)!); } // 3. remove the target box from the root multi split view _widgets.remove(targetBox); @@ -434,19 +528,19 @@ class _DraggableMultiListViewState extends State { // if the moved box is a child of the root multi split view, but the target box is a child of a child multi split view if (targetBoxParentKey != null && movedBoxParentKey == null) { // 1. get the index of the target box in the target parent multi split view - final targetBoxIndex = (_recursiveWidgetSearchByKey(targetBoxParentKey)! + final targetBoxIndex = (_recursiveSearch(_widgets, targetBoxParentKey)! as SerializableMultiSplitView) .children .indexWhere((element) => element.key == targetBox.key); // 2. remove the target box from the target parent multi split view - (_recursiveWidgetSearchByKey(targetBoxParentKey)! + (_recursiveSearch(_widgets, targetBoxParentKey)! as SerializableMultiSplitView) .children .remove(targetBox); // 3. remove the moved box from the root multi split view _widgets.remove(movedBox); // 4. insert the new multi split view to the target parent multi split view on the target box index - (_recursiveWidgetSearchByKey(targetBoxParentKey)! + (_recursiveSearch(_widgets, targetBoxParentKey)! as SerializableMultiSplitView) .children .insert(targetBoxIndex, newMultiSplitView); @@ -465,31 +559,31 @@ class _DraggableMultiListViewState extends State { // if both boxes are children of a child multi split view if (targetBoxParentKey != null && movedBoxParentKey != null) { // 1. get the index of the target box in the target parent multi split view - final targetBoxIndex = (_recursiveWidgetSearchByKey(targetBoxParentKey)! + final targetBoxIndex = (_recursiveSearch(_widgets, targetBoxParentKey)! as SerializableMultiSplitView) .children .indexWhere((element) => element.key == targetBox.key); // 2. remove the target box from the target parent multi split view - (_recursiveWidgetSearchByKey(targetBoxParentKey)! + (_recursiveSearch(_widgets, targetBoxParentKey)! as SerializableMultiSplitView) .children .remove(targetBox); // 3. remove the moved box from the moved parent multi split view - (_recursiveWidgetSearchByKey(movedBoxParentKey)! + (_recursiveSearch(_widgets, movedBoxParentKey)! as SerializableMultiSplitView) .children .remove(movedBox); // 3.a remove the parent if empty bool movedParentEmpty = false; - if ((_recursiveWidgetSearchByKey(movedBoxParentKey)! + if ((_recursiveSearch(_widgets, movedBoxParentKey)! as SerializableMultiSplitView) .children .isEmpty) { movedParentEmpty = true; - _widgets.remove(_recursiveWidgetSearchByKey(movedBoxParentKey)!); + _widgets.remove(_recursiveSearch(_widgets, movedBoxParentKey)!); } // 4. insert the new multi split view to the target parent multi split view on the target box index - (_recursiveWidgetSearchByKey(targetBoxParentKey)! + (_recursiveSearch(_widgets, targetBoxParentKey)! as SerializableMultiSplitView) .children .insert(targetBoxIndex, newMultiSplitView); @@ -507,18 +601,25 @@ class _DraggableMultiListViewState extends State { // 7. update the areas of the new multi split view _controllers[newMultiSplitViewKey]!.areas = List.generate(2, (index) => Area()); + + if (movedParentEmpty) { + debugPrint("movedparentempty"); + _controllers.remove(movedBoxParentKey); + } } + _widgets = _removeEmptySplitViews(_widgets); + // if (targetBoxParentKey != null) { - // (_recursiveWidgetSearchByKey(targetBoxParentKey)! + // (_recursiveSearch(_widgets, targetBoxParentKey)! // as SerializableMultiSplitView) // .children // .remove(targetBox); - // if ((_recursiveWidgetSearchByKey(targetBoxParentKey)! + // if ((_recursiveSearch(_widgets, targetBoxParentKey)! // as SerializableMultiSplitView) // .children // .isEmpty) { - // _widgets.remove(_recursiveWidgetSearchByKey(targetBoxParentKey)!); + // _widgets.remove(_recursiveSearch(_widgets, targetBoxParentKey)!); // } // final targetAreas = // List.from(_controllers[targetBoxParentKey]!.areas); @@ -529,15 +630,15 @@ class _DraggableMultiListViewState extends State { // final movedBoxParentKey = // _getWidgetParentViewRecursive(movedBox, _widgets)?.key; // if (movedBoxParentKey != null) { - // final newIdx = (_recursiveWidgetSearchByKey(movedBoxParentKey)! + // final newIdx = (_recursiveSearch(_widgets, movedBoxParentKey)! // as SerializableMultiSplitView) // .children // .indexWhere((element) => element.key == movedBox.key); - // (_recursiveWidgetSearchByKey(movedBoxParentKey)! + // (_recursiveSearch(_widgets, movedBoxParentKey)! // as SerializableMultiSplitView) // .children // .remove(movedBox); - // setState(() => (_recursiveWidgetSearchByKey(movedBoxParentKey)! + // setState(() => (_recursiveSearch(_widgets, movedBoxParentKey)! // as SerializableMultiSplitView) // .children // .insert(newIdx, newMultiSplitView)); @@ -549,15 +650,15 @@ class _DraggableMultiListViewState extends State { // rootAreas.removeAt(0); // _controllers[_rootKey]!.areas = rootAreas; // // 3. add the new multi split view in to the target parent view - // final newIdx = (_recursiveWidgetSearchByKey(targetBoxParentKey)! + // final newIdx = (_recursiveSearch(_widgets, targetBoxParentKey)! // as SerializableMultiSplitView) // .children // .indexWhere((element) => element.key == movedBox.key); - // (_recursiveWidgetSearchByKey(targetBoxParentKey)! + // (_recursiveSearch(_widgets, targetBoxParentKey)! // as SerializableMultiSplitView) // .children // .remove(movedBox); - // setState(() => (_recursiveWidgetSearchByKey(targetBoxParentKey)! + // setState(() => (_recursiveSearch(_widgets, targetBoxParentKey)! // as SerializableMultiSplitView) // .children // .insert(newIdx, newMultiSplitView)); @@ -589,15 +690,15 @@ class _DraggableMultiListViewState extends State { // _getWidgetParentViewRecursive(movedBox, _widgets)?.key!; // // if (movedBoxParentKey != null) { - // final newIdx = (_recursiveWidgetSearchByKey(movedBoxParentKey)! + // final newIdx = (_recursiveSearch(_widgets, movedBoxParentKey)! // as SerializableMultiSplitView) // .children // .indexWhere((element) => element.key == movedBox.key); - // (_recursiveWidgetSearchByKey(movedBoxParentKey)! + // (_recursiveSearch(_widgets, movedBoxParentKey)! // as SerializableMultiSplitView) // .children // .remove(movedBox); - // setState(() => (_recursiveWidgetSearchByKey(movedBoxParentKey)! + // setState(() => (_recursiveSearch(_widgets, movedBoxParentKey)! // as SerializableMultiSplitView) // .children // .insert(newIdx, newMultiSplitView)); From 7e6a04b526129b3e9e72ef2f012607909b39ae48 Mon Sep 17 00:00:00 2001 From: GGlinsek Date: Thu, 16 May 2024 11:00:53 +0200 Subject: [PATCH 2/3] deleting commented code --- lib/widgets/draggable_multi_list_view.dart | 341 ---------- .../draggable_tree_multi_list_view.dart | 608 ------------------ 2 files changed, 949 deletions(-) delete mode 100644 lib/widgets/draggable_tree_multi_list_view.dart diff --git a/lib/widgets/draggable_multi_list_view.dart b/lib/widgets/draggable_multi_list_view.dart index 9eec953..e9f431c 100644 --- a/lib/widgets/draggable_multi_list_view.dart +++ b/lib/widgets/draggable_multi_list_view.dart @@ -171,50 +171,12 @@ class _DraggableMultiListViewState extends State { return null; } - // // 5. update the areas of the target parent multi split view - // final targetAreas = - // List.from(_controllers[targetBoxParentKey]!.areas); - // _controllers[targetBoxParentKey]!.areas = targetAreas; - // // 6. update the areas of the moved parent multi split view, if the moved parent is not empty - // if (!movedParentEmpty) { - // final movedBoxParentAreas = - // List.from(_controllers[movedBoxParentKey]!.areas); - // movedBoxParentAreas.removeAt(0); - // _controllers[movedBoxParentKey]!.areas = movedBoxParentAreas; - // } - // // 7. update the areas of the new multi split view - // _controllers[newMultiSplitViewKey]!.areas = - // List.generate(2, (index) => Area()); _controllers[widget.key]!.areas = List.from(_controllers[widget.key]!.areas); return widget; } - // Widget? _recursiveSearch(Key key) { - // for (final widget in _widgets) { - // final result = _recursiveWidgetSearch(widget, key); - // if (result != null) { - // return result; - // } - // } - // return null; - // } - - // Widget? _recursiveWidgetSearch(Widget widget, Key key) { - // if (widget.key == key) { - // return widget; - // } else if (widget is SerializableMultiSplitView) { - // for (final child in widget.children) { - // final result = _recursiveWidgetSearch(child, key); - // if (result != null) { - // return result; - // } - // } - // } - // return null; - // } - SerializableMultiSplitView? _getMovableBoxParentViewRecursive( MovableBox box, List widgets) { for (final widget in widgets) { @@ -235,199 +197,6 @@ class _DraggableMultiListViewState extends State { return null; } - // SerializableMultiSplitView? _getParentView( - // SerializableMultiSplitView view, List widgets) { - // for (final widget in widgets) { - // if (widget is SerializableMultiSplitView) { - // for (final child in widget.children) { - // if (child.key == view.key) { - // return widget; - // } else { - // final result = _getParentView(view, widget.children); - // if (result != null) { - // return result; - // } - // } - // } - // } - // } - // return null; - // } - - // void _removeEmptyParentViewsRecursive(List widgets) { - // for (final widget in widgets) { - // if (widget is SerializableMultiSplitView) { - // for (final child in widget.children) { - // if (child is SerializableMultiSplitView) { - // if (child.children.isEmpty) { - // widget.children.remove(child); - // if (_areaMap.containsKey(widget.key)) { - // _areaMap.remove(widget.key); - // } - // } else { - // _removeEmptyParentViewsRecursive(child.children); - // } - // } - // } - // } - // } - // } - - // _movedControllerHandler(MoveRecord data) { - // final movedWidget = data.movedBox; - // final targetWidget = data.targetBox; - // final movedWidgetParentKey = - // _getMovableBoxParentViewRecursive(movedWidget, _widgets)?.key; - // final targetWidgetParentKey = - // _getMovableBoxParentViewRecursive(targetWidget, _widgets)?.key; - // - // if (movedWidget.key == targetWidget.key) { - // return; - // } - // - // debugPrint( - // "Moved MovedWidgetParentKey: $movedWidgetParentKey; TargetWidgetParentKey: $targetWidgetParentKey"); - // - // // 1. both widgets are children of the root multi split view - // if (movedWidgetParentKey == null && targetWidgetParentKey == null) { - // // 1. get the index of the target widget - // final targetWidgetIndex = - // _widgets.indexWhere((w) => w.key == targetWidget.key); - // // 2. remove the moved widget from the root multi split view - // _widgets.remove(movedWidget); - // // 3. insert the moved widget to the root multi split view at the index of the target widget - // _widgets.insert(targetWidgetIndex, movedWidget); - // // 4. update the areas of the root multi split view - // final rootAreas = List.from(_controllers[_rootKey]!.areas); - // _controllers[_rootKey]!.areas = rootAreas; - // } - // - // // 2. target widget is on the root multi split view and moved widget is a child of a child multi split view - // if (targetWidgetParentKey == null && movedWidgetParentKey != null) { - // // 1. remove the moved widget from the child multi split view - // (_recursiveSearch(_widgets, movedWidgetParentKey)! - // as SerializableMultiSplitView) - // .children - // .remove(movedWidget); - // // 1.1 remove the parent if empty - // bool movedParentEmpty = false; - // if ((_recursiveSearch(_widgets, movedWidgetParentKey)! - // as SerializableMultiSplitView) - // .children - // .isEmpty) { - // movedParentEmpty = true; - // _widgets.remove(_recursiveSearch(_widgets, movedWidgetParentKey)!); - // } - // // 2. get the index of the target widget - // final targetIndex = _widgets.indexWhere((w) => w.key == targetWidget.key); - // // 3. insert the moved widget to the root multi split view at the index of the target widget - // _widgets.insert(targetIndex, movedWidget); - // // 4. update the areas of the moved widget parent - // if (!movedParentEmpty) { - // _controllers[movedWidgetParentKey]!.areas = - // List.from(_controllers[movedWidgetParentKey]!.areas) - // ..removeAt(0); - // } - // // 5. update the areas of the root multi split view - // final rootAreas = List.from(_controllers[_rootKey]!.areas); - // rootAreas.insert(targetIndex, Area()); - // _controllers[_rootKey]!.areas = rootAreas; - // - // // 6. remove the moved parent if it has only one child and put the child in the parent's place - // if ((_recursiveSearch(_widgets, movedWidgetParentKey)! - // as SerializableMultiSplitView) - // .children - // .length == - // 1) { - // final parent = _recursiveSearch(_widgets, movedWidgetParentKey)! - // as SerializableMultiSplitView; - // final parentsParent = _getParentView(parent, _widgets); - // int parentIndex = 0; - // - // if (parentsParent != null) { - // // TODO Check if this is valid!!! - // parentIndex = - // parentsParent.children.indexWhere((w) => w.key == parent.key); - // parentsParent.children.removeAt(parentIndex); - // parentsParent.children.insert(parentIndex, parent.children.first); - // final areas = List.from(_controllers[parentsParent.key]!.areas); - // _controllers[parentsParent.key]!.areas = areas; - // } else { - // parentIndex = _widgets.indexWhere((w) => w.key == parent.key); - // _widgets.remove(parent); - // _widgets.insert(parentIndex, parent.children.first); - // final areas = List.from(_controllers[_rootKey]!.areas); - // _controllers[_rootKey]!.areas = areas; - // } - // } - // } - // - // // 3. old widget is a child of root - // if (movedWidgetParentKey == null && targetWidgetParentKey != null) { - // final targetWidgetIndex = - // (_recursiveSearch(_widgets, targetWidgetParentKey)! - // as SerializableMultiSplitView) - // .children - // .indexWhere((element) => element.key == targetWidget.key); - // (_recursiveSearch(_widgets, targetWidgetParentKey)! - // as SerializableMultiSplitView) - // .children - // .insert(targetWidgetIndex, movedWidget); - // - // final movedWidgetIndex = - // _widgets.indexWhere((w) => w.key == movedWidget.key); - // // _widgets.insert(movedWidgetIndex, targetWidget); - // _widgets.removeAt(movedWidgetIndex); - // - // final areas = List.from(_controllers[targetWidgetParentKey]!.areas); - // areas.add(Area()); - // _controllers[targetWidgetParentKey]!.areas = areas; - // - // final rootAreas = List.from(_controllers[_rootKey]!.areas); - // rootAreas.removeAt(0); - // _controllers[_rootKey]!.areas = rootAreas; - // } - // - // // 4. both parents are multi split views - // if (movedWidgetParentKey != null && targetWidgetParentKey != null) { - // final movedWidgetIndex = - // (_recursiveSearch(_widgets, movedWidgetParentKey)! - // as SerializableMultiSplitView) - // .children - // .indexWhere((w) => w.key == movedWidget.key); - // final targetWidgetIndex = - // (_recursiveSearch(_widgets, targetWidgetParentKey)! - // as SerializableMultiSplitView) - // .children - // .indexWhere((w) => w.key == targetWidget.key); - // // remove the new widget from their parent - // (_recursiveSearch(_widgets, targetWidgetParentKey)! - // as SerializableMultiSplitView) - // .children - // .removeAt(targetWidgetIndex); - // // remove parent if empty - // if ((_recursiveSearch(_widgets, targetWidgetParentKey)! - // as SerializableMultiSplitView) - // .children - // .isEmpty) { - // _widgets.remove(_recursiveSearch(_widgets, targetWidgetParentKey)!); - // } - // // add the new widget to the old parent - // (_recursiveSearch(_widgets, movedWidgetParentKey)! - // as SerializableMultiSplitView) - // .children - // .insert(movedWidgetIndex, targetWidget); - // final movedWidgetParentAreas = - // List.from(_controllers[movedWidgetParentKey]!.areas); - // movedWidgetParentAreas.removeAt(0); - // _controllers[movedWidgetParentKey]!.areas = movedWidgetParentAreas; - // final targetWidgetParentAreas = - // List.from(_controllers[targetWidgetParentKey]!.areas); - // targetWidgetParentAreas.add(Area()); - // _controllers[targetWidgetParentKey]!.areas = targetWidgetParentAreas; - // } - // } - _edgeControllerHandler(EdgeRecord record) { debugPrint("EdgeRecord: $record"); MovableBox targetBox = record.targetBox; @@ -607,116 +376,6 @@ class _DraggableMultiListViewState extends State { _controllers.remove(movedBoxParentKey); } } - _widgets = _removeEmptySplitViews(_widgets); - - // if (targetBoxParentKey != null) { - // (_recursiveSearch(_widgets, targetBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .remove(targetBox); - // if ((_recursiveSearch(_widgets, targetBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .isEmpty) { - // _widgets.remove(_recursiveSearch(_widgets, targetBoxParentKey)!); - // } - // final targetAreas = - // List.from(_controllers[targetBoxParentKey]!.areas); - // targetAreas.removeAt(0); - // _controllers[targetBoxParentKey]!.areas = targetAreas; - // - // // get the new widget parent; if null, the parent is root - // final movedBoxParentKey = - // _getWidgetParentViewRecursive(movedBox, _widgets)?.key; - // if (movedBoxParentKey != null) { - // final newIdx = (_recursiveSearch(_widgets, movedBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .indexWhere((element) => element.key == movedBox.key); - // (_recursiveSearch(_widgets, movedBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .remove(movedBox); - // setState(() => (_recursiveSearch(_widgets, movedBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .insert(newIdx, newMultiSplitView)); - // } else { - // // 1. remove the old movable box from the root multi split view - // _widgets.remove(movedBox); - // // 2. remove the area from the root multi split view - // final rootAreas = List.from(_controllers[_rootKey]!.areas); - // rootAreas.removeAt(0); - // _controllers[_rootKey]!.areas = rootAreas; - // // 3. add the new multi split view in to the target parent view - // final newIdx = (_recursiveSearch(_widgets, targetBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .indexWhere((element) => element.key == movedBox.key); - // (_recursiveSearch(_widgets, targetBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .remove(movedBox); - // setState(() => (_recursiveSearch(_widgets, targetBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .insert(newIdx, newMultiSplitView)); - // //_widgets.insert(0, newMultiSplitView); - // } - // _controllers[newMultiSplitViewKey]!.areas = - // List.generate(2, (index) => Area()); - // - // _removeEmptyParentViewsRecursive(_widgets); - // - // for (final controller in _controllers.values) { - // final listOfAreas = List.from(controller.areas); - // controller.areas = listOfAreas; - // } - // } else { - // // the parent widget is root - // // create a new multi split view with the two widgets - // // remove the old widgets from the widgets - // - // final movedBoxIndex = - // _widgets.indexWhere((element) => element.key == movedBox.key); - // final targetBoxIndex = _widgets.indexOf(targetBox); - // _widgets.removeAt(targetBoxIndex); - // final areas = List.from(_controllers[_rootKey]!.areas); - // //_controllers[_rootKey]!.areas = areas; - // - // // get the new widget parent - // final movedBoxParentKey = - // _getWidgetParentViewRecursive(movedBox, _widgets)?.key!; - // - // if (movedBoxParentKey != null) { - // final newIdx = (_recursiveSearch(_widgets, movedBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .indexWhere((element) => element.key == movedBox.key); - // (_recursiveSearch(_widgets, movedBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .remove(movedBox); - // setState(() => (_recursiveSearch(_widgets, movedBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .insert(newIdx, newMultiSplitView)); - // _controllers[newMultiSplitViewKey]!.areas = - // List.generate(2, (index) => Area()); - // } else { - // _widgets.remove(movedBox); - // _widgets.insert(targetBoxIndex, newMultiSplitView); - // areas.removeAt(targetBoxIndex); - // _controllers[_rootKey]!.areas = areas; - // } - // - // _removeEmptyParentViewsRecursive(_widgets); - // - // for (final controller in _controllers.values) { - // final listOfAreas = List.from(controller.areas); - // controller.areas = listOfAreas; - // } - // } } } diff --git a/lib/widgets/draggable_tree_multi_list_view.dart b/lib/widgets/draggable_tree_multi_list_view.dart deleted file mode 100644 index 5d6da92..0000000 --- a/lib/widgets/draggable_tree_multi_list_view.dart +++ /dev/null @@ -1,608 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:multi_split_view/multi_split_view.dart'; -import 'package:test_multi_split_view/widgets/serializable_multi_split_view.dart'; - -import '../data_types/tree.dart'; -import 'movable_box.dart'; - -class DraggableTreeMultiListView extends StatefulWidget { - final StreamController onWidgetInController; - final StreamController<(MovableBox, MoveDirection)> - onWidgetMovedOutController; - final Axis axis; - final Tree tree; - - const DraggableTreeMultiListView({ - super.key, - required this.axis, - required this.onWidgetInController, - required this.onWidgetMovedOutController, - required this.tree, - }); - - @override - State createState() => _DraggableMultiListViewState(); -} - -class _DraggableMultiListViewState extends State { - static const _rootKey = ValueKey("root"); - final _controllers = {}; - final _widgets = []; - final _movingControllerMap = >{}; - final _movedControllerMap = >{}; - final _removedControllerMap = >{}; - final _edgeControllerMap = >{}; - - final _areaMap = >{}; - - @override - void initState() { - _areaMap[_rootKey] = []; - _controllers[_rootKey] = MultiSplitViewController(); - - if (!widget.onWidgetInController.hasListener) { - widget.onWidgetInController.stream.listen((event) { - final key = UniqueKey(); - _movingControllerMap[key] = StreamController(); - _movingControllerMap[key]!.stream.listen((isMoving) { - // setState(() => _isMoving = isMoving); - }); - _movedControllerMap[key] = StreamController(); - _movedControllerMap[key]!.stream.listen(_movedControllerHandler); - _edgeControllerMap[key] = StreamController(); - _edgeControllerMap[key]!.stream.listen(_edgeControllerHandler); - _removedControllerMap[key] = StreamController(); - _widgets.add( - MovableBox( - key: key, - onMoveController: _movingControllerMap[key]!, - onMovedController: _movedControllerMap[key]!, - removedController: _removedControllerMap[key]!, - onEdgeController: _edgeControllerMap[key]!, - child: event, - ), - ); - }); - } - - super.initState(); - } - - @override - void dispose() { - super.dispose(); - for (final controller in _movingControllerMap.values) { - controller.close(); - } - for (final controller in _movedControllerMap.values) { - controller.close(); - } - for (final controller in _removedControllerMap.values) { - controller.close(); - } - } - - @override - Widget build(BuildContext context) { - return MultiSplitView( - key: _rootKey, - resizable: false, - antiAliasingWorkaround: false, - controller: _controllers[_rootKey]!, - axis: widget.axis, - children: _widgets, - onWeightChange: () { - _areaMap[_rootKey] = List.generate( - _widgets.length, - (index) => _controllers[_rootKey]!.areas[index].weight!, - ); - debugPrint("Root AreaMap: ${_areaMap[_rootKey]}"); - }); - } - - Widget? _recursiveWidgetSearchByKey(Key key) { - for (final widget in _widgets) { - final result = _recursiveWidgetSearch(widget, key); - if (result != null) { - return result; - } - } - return null; - } - - Widget? _recursiveWidgetSearch(Widget widget, Key key) { - if (widget.key == key) { - return widget; - } else if (widget is SerializableMultiSplitView) { - for (final child in widget.children) { - final result = _recursiveWidgetSearch(child, key); - if (result != null) { - return result; - } - } - } - return null; - } - - SerializableMultiSplitView? _getMovableBoxParentViewRecursive( - MovableBox box, List widgets) { - for (final widget in widgets) { - if (widget is SerializableMultiSplitView) { - for (final child in widget.children) { - if (child.key == box.key) { - return widget; - } else { - final result = - _getMovableBoxParentViewRecursive(box, widget.children); - if (result != null) { - return result; - } - } - } - } - } - return null; - } - - SerializableMultiSplitView? _getParentView( - SerializableMultiSplitView view, List widgets) { - for (final widget in widgets) { - if (widget is SerializableMultiSplitView) { - for (final child in widget.children) { - if (child.key == view.key) { - return widget; - } else { - final result = _getParentView(view, widget.children); - if (result != null) { - return result; - } - } - } - } - } - return null; - } - - - _movedControllerHandler(MoveRecord data) { - final movedWidget = data.movedBox; - final targetWidget = data.targetBox; - final movedWidgetParentKey = - _getMovableBoxParentViewRecursive(movedWidget, _widgets)?.key; - final targetWidgetParentKey = - _getMovableBoxParentViewRecursive(targetWidget, _widgets)?.key; - - if (movedWidget.key == targetWidget.key) { - return; - } - - debugPrint( - "Moved MovedWidgetParentKey: $movedWidgetParentKey; TargetWidgetParentKey: $targetWidgetParentKey"); - - // 1. both widgets are children of the root multi split view - if (movedWidgetParentKey == null && targetWidgetParentKey == null) { - // 1. get the index of the target widget - final targetWidgetIndex = - _widgets.indexWhere((w) => w.key == targetWidget.key); - // 2. remove the moved widget from the root multi split view - _widgets.remove(movedWidget); - // 3. insert the moved widget to the root multi split view at the index of the target widget - _widgets.insert(targetWidgetIndex, movedWidget); - // 4. update the areas of the root multi split view - final rootAreas = List.from(_controllers[_rootKey]!.areas); - _controllers[_rootKey]!.areas = rootAreas; - } - - // 2. target widget is on the root multi split view and moved widget is a child of a child multi split view - if (targetWidgetParentKey == null && movedWidgetParentKey != null) { - // 1. remove the moved widget from the child multi split view - (_recursiveWidgetSearchByKey(movedWidgetParentKey)! - as SerializableMultiSplitView) - .children - .remove(movedWidget); - // 1.1 remove the parent if empty - bool movedParentEmpty = false; - if ((_recursiveWidgetSearchByKey(movedWidgetParentKey)! - as SerializableMultiSplitView) - .children - .isEmpty) { - movedParentEmpty = true; - _widgets.remove(_recursiveWidgetSearchByKey(movedWidgetParentKey)!); - } - // 2. get the index of the target widget - final targetIndex = _widgets.indexWhere((w) => w.key == targetWidget.key); - // 3. insert the moved widget to the root multi split view at the index of the target widget - _widgets.insert(targetIndex, movedWidget); - // 4. update the areas of the moved widget parent - if (!movedParentEmpty) { - _controllers[movedWidgetParentKey]!.areas = - List.from(_controllers[movedWidgetParentKey]!.areas) - ..removeAt(0); - } - // 5. update the areas of the root multi split view - final rootAreas = List.from(_controllers[_rootKey]!.areas); - rootAreas.insert(targetIndex, Area()); - _controllers[_rootKey]!.areas = rootAreas; - - // 6. remove the moved parent if it has only one child and put the child in the parent's place - if ((_recursiveWidgetSearchByKey(movedWidgetParentKey)! - as SerializableMultiSplitView) - .children - .length == - 1) { - final parent = _recursiveWidgetSearchByKey(movedWidgetParentKey)! - as SerializableMultiSplitView; - final parentsParent = _getParentView(parent, _widgets); - int parentIndex = 0; - - if (parentsParent != null) { - // TODO Check if this is valid!!! - parentIndex = - parentsParent.children.indexWhere((w) => w.key == parent.key); - parentsParent.children.removeAt(parentIndex); - parentsParent.children.insert(parentIndex, parent.children.first); - final areas = List.from(_controllers[parentsParent.key]!.areas); - _controllers[parentsParent.key]!.areas = areas; - } else { - parentIndex = _widgets.indexWhere((w) => w.key == parent.key); - _widgets.remove(parent); - _widgets.insert(parentIndex, parent.children.first); - final areas = List.from(_controllers[_rootKey]!.areas); - _controllers[_rootKey]!.areas = areas; - } - } - } - - // 3. old widget is a child of root - if (movedWidgetParentKey == null && targetWidgetParentKey != null) { - final targetWidgetIndex = - (_recursiveWidgetSearchByKey(targetWidgetParentKey)! - as SerializableMultiSplitView) - .children - .indexWhere((element) => element.key == targetWidget.key); - (_recursiveWidgetSearchByKey(targetWidgetParentKey)! - as SerializableMultiSplitView) - .children - .insert(targetWidgetIndex, movedWidget); - - final movedWidgetIndex = - _widgets.indexWhere((w) => w.key == movedWidget.key); - // _widgets.insert(movedWidgetIndex, targetWidget); - _widgets.removeAt(movedWidgetIndex); - - final areas = List.from(_controllers[targetWidgetParentKey]!.areas); - areas.add(Area()); - _controllers[targetWidgetParentKey]!.areas = areas; - - final rootAreas = List.from(_controllers[_rootKey]!.areas); - rootAreas.removeAt(0); - _controllers[_rootKey]!.areas = rootAreas; - } - - // 4. both parents are multi split views - if (movedWidgetParentKey != null && targetWidgetParentKey != null) { - final movedWidgetIndex = - (_recursiveWidgetSearchByKey(movedWidgetParentKey)! - as SerializableMultiSplitView) - .children - .indexWhere((w) => w.key == movedWidget.key); - final targetWidgetIndex = - (_recursiveWidgetSearchByKey(targetWidgetParentKey)! - as SerializableMultiSplitView) - .children - .indexWhere((w) => w.key == targetWidget.key); - // remove the new widget from their parent - (_recursiveWidgetSearchByKey(targetWidgetParentKey)! - as SerializableMultiSplitView) - .children - .removeAt(targetWidgetIndex); - // remove parent if empty - if ((_recursiveWidgetSearchByKey(targetWidgetParentKey)! - as SerializableMultiSplitView) - .children - .isEmpty) { - _widgets.remove(_recursiveWidgetSearchByKey(targetWidgetParentKey)!); - } - // add the new widget to the old parent - (_recursiveWidgetSearchByKey(movedWidgetParentKey)! - as SerializableMultiSplitView) - .children - .insert(movedWidgetIndex, targetWidget); - final movedWidgetParentAreas = - List.from(_controllers[movedWidgetParentKey]!.areas); - movedWidgetParentAreas.removeAt(0); - _controllers[movedWidgetParentKey]!.areas = movedWidgetParentAreas; - final targetWidgetParentAreas = - List.from(_controllers[targetWidgetParentKey]!.areas); - targetWidgetParentAreas.add(Area()); - _controllers[targetWidgetParentKey]!.areas = targetWidgetParentAreas; - } - } - - _edgeControllerHandler(EdgeRecord record) { - debugPrint("EdgeRecord: $record"); - MovableBox targetBox = record.targetBox; - MovableBox movedBox = record.movedBox; - MoveDirection direction = record.moveDirection; - // ignore if the boxes are the same - if (targetBox.key == movedBox.key) { - debugPrint("same widget!!"); - return; - } - // merge the two boxes into a new multi split view - // the new view must have a controller - final newMultiSplitViewKey = UniqueKey(); - _controllers[newMultiSplitViewKey] = MultiSplitViewController(); - final newMultiSplitView = SerializableMultiSplitView( - key: newMultiSplitViewKey, - controller: _controllers[newMultiSplitViewKey], - axis: direction == MoveDirection.up || direction == MoveDirection.down - ? Axis.vertical - : Axis.horizontal, - children: - (direction == MoveDirection.up || direction == MoveDirection.left) - ? [targetBox, movedBox] - : [movedBox, targetBox], - onWeightChange: () { - final newWeights = []; - for (final a in _controllers[newMultiSplitViewKey]!.areas) { - newWeights.add(a.weight!); - } - _areaMap[newMultiSplitViewKey] = newWeights; - debugPrint( - "$newMultiSplitViewKey AreaMap: ${_areaMap[newMultiSplitViewKey]}"); - }, - ); - - final targetBoxParentKey = - _getMovableBoxParentViewRecursive(targetBox, _widgets)?.key; - final movedBoxParentKey = - _getMovableBoxParentViewRecursive(movedBox, _widgets)?.key; - - debugPrint( - "Edge MovedWidgetParentKey: $movedBoxParentKey; TargetWidgetParentKey: $targetBoxParentKey"); - - // if both boxes are children of the root multi split view - if (targetBoxParentKey == null && movedBoxParentKey == null) { - // 1. get the target box index from the root multi split view - final targetBoxIndex = _widgets.indexWhere((w) => w.key == targetBox.key); - // 2. remove target & moved box from the root multi split view - _widgets.remove(targetBox); - _widgets.remove(movedBox); - // 3. remove moved box from the root multi split view - final movedBoxIndex = _widgets.indexWhere((w) => w.key == movedBox.key); - // 4. insert the new multi split view to the root multi split view on the target box index - _widgets.insert(targetBoxIndex, newMultiSplitView); - // 5. update the areas of the root multi split view - final rootAreas = List.from(_controllers[_rootKey]!.areas); - rootAreas.removeAt(0); - _controllers[_rootKey]!.areas = rootAreas; - // 6. update the areas of the new multi split view - _controllers[newMultiSplitViewKey]!.areas = - List.generate(2, (index) => Area()); - } - - // if the target box is a child of the root multi split view, but the moved box is a child of a child multi split view - if (targetBoxParentKey == null && movedBoxParentKey != null) { - // 1. get the index of the target box from the root multi split view - final targetBoxIndex = _widgets.indexWhere((w) => w.key == targetBox.key); - // 2. remove the moved box from the child multi split view - (_recursiveWidgetSearchByKey(movedBoxParentKey)! - as SerializableMultiSplitView) - .children - .remove(movedBox); - // 2.1 remove the parent if empty - bool movedParentEmpty = false; - if ((_recursiveWidgetSearchByKey(movedBoxParentKey)! - as SerializableMultiSplitView) - .children - .isEmpty) { - movedParentEmpty = true; - _widgets.remove(_recursiveWidgetSearchByKey(movedBoxParentKey)!); - } - // 3. remove the target box from the root multi split view - _widgets.remove(targetBox); - // 4. insert the new multi split view to the root multi split view on the target box index - _widgets.insert(targetBoxIndex, newMultiSplitView); - // 5. update the areas of the new multi split view - _controllers[newMultiSplitViewKey]!.areas = - List.generate(2, (index) => Area()); - // 6. update the areas of the moved box parent, if the moved parent is not empty - if (!movedParentEmpty) { - final movedBoxParentAreas = - List.from(_controllers[movedBoxParentKey]!.areas); - movedBoxParentAreas.removeAt(0); - _controllers[movedBoxParentKey]!.areas = movedBoxParentAreas; - } - } - - // if the moved box is a child of the root multi split view, but the target box is a child of a child multi split view - if (targetBoxParentKey != null && movedBoxParentKey == null) { - // 1. get the index of the target box in the target parent multi split view - final targetBoxIndex = (_recursiveWidgetSearchByKey(targetBoxParentKey)! - as SerializableMultiSplitView) - .children - .indexWhere((element) => element.key == targetBox.key); - // 2. remove the target box from the target parent multi split view - (_recursiveWidgetSearchByKey(targetBoxParentKey)! - as SerializableMultiSplitView) - .children - .remove(targetBox); - // 3. remove the moved box from the root multi split view - _widgets.remove(movedBox); - // 4. insert the new multi split view to the target parent multi split view on the target box index - (_recursiveWidgetSearchByKey(targetBoxParentKey)! - as SerializableMultiSplitView) - .children - .insert(targetBoxIndex, newMultiSplitView); - // 5. update the areas of the target parent multi split view - final targetAreas = - List.from(_controllers[targetBoxParentKey]!.areas); - _controllers[targetBoxParentKey]!.areas = targetAreas; - // 6. update the areas of the new multi split view - _controllers[newMultiSplitViewKey]!.areas = - List.generate(2, (index) => Area()); - final rootAreas = List.from(_controllers[_rootKey]!.areas); - rootAreas.removeAt(0); - _controllers[_rootKey]!.areas = rootAreas; - } - - // if both boxes are children of a child multi split view - if (targetBoxParentKey != null && movedBoxParentKey != null) { - // 1. get the index of the target box in the target parent multi split view - final targetBoxIndex = (_recursiveWidgetSearchByKey(targetBoxParentKey)! - as SerializableMultiSplitView) - .children - .indexWhere((element) => element.key == targetBox.key); - // 2. remove the target box from the target parent multi split view - (_recursiveWidgetSearchByKey(targetBoxParentKey)! - as SerializableMultiSplitView) - .children - .remove(targetBox); - // 3. remove the moved box from the moved parent multi split view - (_recursiveWidgetSearchByKey(movedBoxParentKey)! - as SerializableMultiSplitView) - .children - .remove(movedBox); - // 3.a remove the parent if empty - bool movedParentEmpty = false; - if ((_recursiveWidgetSearchByKey(movedBoxParentKey)! - as SerializableMultiSplitView) - .children - .isEmpty) { - movedParentEmpty = true; - _widgets.remove(_recursiveWidgetSearchByKey(movedBoxParentKey)!); - } - // 4. insert the new multi split view to the target parent multi split view on the target box index - (_recursiveWidgetSearchByKey(targetBoxParentKey)! - as SerializableMultiSplitView) - .children - .insert(targetBoxIndex, newMultiSplitView); - // 5. update the areas of the target parent multi split view - final targetAreas = - List.from(_controllers[targetBoxParentKey]!.areas); - _controllers[targetBoxParentKey]!.areas = targetAreas; - // 6. update the areas of the moved parent multi split view, if the moved parent is not empty - if (!movedParentEmpty) { - final movedBoxParentAreas = - List.from(_controllers[movedBoxParentKey]!.areas); - movedBoxParentAreas.removeAt(0); - _controllers[movedBoxParentKey]!.areas = movedBoxParentAreas; - } - // 7. update the areas of the new multi split view - _controllers[newMultiSplitViewKey]!.areas = - List.generate(2, (index) => Area()); - } - - // if (targetBoxParentKey != null) { - // (_recursiveWidgetSearchByKey(targetBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .remove(targetBox); - // if ((_recursiveWidgetSearchByKey(targetBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .isEmpty) { - // _widgets.remove(_recursiveWidgetSearchByKey(targetBoxParentKey)!); - // } - // final targetAreas = - // List.from(_controllers[targetBoxParentKey]!.areas); - // targetAreas.removeAt(0); - // _controllers[targetBoxParentKey]!.areas = targetAreas; - // - // // get the new widget parent; if null, the parent is root - // final movedBoxParentKey = - // _getWidgetParentViewRecursive(movedBox, _widgets)?.key; - // if (movedBoxParentKey != null) { - // final newIdx = (_recursiveWidgetSearchByKey(movedBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .indexWhere((element) => element.key == movedBox.key); - // (_recursiveWidgetSearchByKey(movedBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .remove(movedBox); - // setState(() => (_recursiveWidgetSearchByKey(movedBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .insert(newIdx, newMultiSplitView)); - // } else { - // // 1. remove the old movable box from the root multi split view - // _widgets.remove(movedBox); - // // 2. remove the area from the root multi split view - // final rootAreas = List.from(_controllers[_rootKey]!.areas); - // rootAreas.removeAt(0); - // _controllers[_rootKey]!.areas = rootAreas; - // // 3. add the new multi split view in to the target parent view - // final newIdx = (_recursiveWidgetSearchByKey(targetBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .indexWhere((element) => element.key == movedBox.key); - // (_recursiveWidgetSearchByKey(targetBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .remove(movedBox); - // setState(() => (_recursiveWidgetSearchByKey(targetBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .insert(newIdx, newMultiSplitView)); - // //_widgets.insert(0, newMultiSplitView); - // } - // _controllers[newMultiSplitViewKey]!.areas = - // List.generate(2, (index) => Area()); - // - // _removeEmptyParentViewsRecursive(_widgets); - // - // for (final controller in _controllers.values) { - // final listOfAreas = List.from(controller.areas); - // controller.areas = listOfAreas; - // } - // } else { - // // the parent widget is root - // // create a new multi split view with the two widgets - // // remove the old widgets from the widgets - // - // final movedBoxIndex = - // _widgets.indexWhere((element) => element.key == movedBox.key); - // final targetBoxIndex = _widgets.indexOf(targetBox); - // _widgets.removeAt(targetBoxIndex); - // final areas = List.from(_controllers[_rootKey]!.areas); - // //_controllers[_rootKey]!.areas = areas; - // - // // get the new widget parent - // final movedBoxParentKey = - // _getWidgetParentViewRecursive(movedBox, _widgets)?.key!; - // - // if (movedBoxParentKey != null) { - // final newIdx = (_recursiveWidgetSearchByKey(movedBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .indexWhere((element) => element.key == movedBox.key); - // (_recursiveWidgetSearchByKey(movedBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .remove(movedBox); - // setState(() => (_recursiveWidgetSearchByKey(movedBoxParentKey)! - // as SerializableMultiSplitView) - // .children - // .insert(newIdx, newMultiSplitView)); - // _controllers[newMultiSplitViewKey]!.areas = - // List.generate(2, (index) => Area()); - // } else { - // _widgets.remove(movedBox); - // _widgets.insert(targetBoxIndex, newMultiSplitView); - // areas.removeAt(targetBoxIndex); - // _controllers[_rootKey]!.areas = areas; - // } - // - // _removeEmptyParentViewsRecursive(_widgets); - // - // for (final controller in _controllers.values) { - // final listOfAreas = List.from(controller.areas); - // controller.areas = listOfAreas; - // } - // } - } -} From 9ac3be4fa6d2303e9c914652d5d20c2010a6e207 Mon Sep 17 00:00:00 2001 From: GGlinsek Date: Thu, 16 May 2024 13:53:38 +0200 Subject: [PATCH 3/3] updated multi split view --- lib/main.dart | 5 +- lib/widgets/draggable_multi_list_view.dart | 524 +++++++++--------- lib/widgets/layout_widget.dart | 13 +- .../serializable_multi_split_view.dart | 33 +- pubspec.lock | 30 +- pubspec.yaml | 2 +- 6 files changed, 316 insertions(+), 291 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index c03a700..a58566f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; +import 'package:multi_split_view/multi_split_view.dart'; import 'package:test_multi_split_view/widgets/layout_widget.dart'; void main() => runApp(const MultiSplitViewExampleApp()); @@ -48,7 +49,7 @@ class MultiSplitViewExample extends StatefulWidget { } class MultiSplitViewExampleState extends State { - final _widgetInController = StreamController(); + final _widgetInController = StreamController(); @override initState() { @@ -108,6 +109,6 @@ class MultiSplitViewExampleState extends State { ], ); _widgetCounter++; - _widgetInController.add(controlWidget); + _widgetInController.add(Area(data:controlWidget)); } } diff --git a/lib/widgets/draggable_multi_list_view.dart b/lib/widgets/draggable_multi_list_view.dart index e9f431c..42ea26a 100644 --- a/lib/widgets/draggable_multi_list_view.dart +++ b/lib/widgets/draggable_multi_list_view.dart @@ -7,7 +7,7 @@ import 'package:test_multi_split_view/widgets/serializable_multi_split_view.dart import 'movable_box.dart'; class DraggableMultiListView extends SerializableMultiSplitView { - final StreamController onWidgetInController; + final StreamController onWidgetInController; final StreamController<(MovableBox, MoveDirection)> onWidgetMovedOutController; @@ -16,7 +16,9 @@ class DraggableMultiListView extends SerializableMultiSplitView { super.axis, required this.onWidgetInController, required this.onWidgetMovedOutController, - required super.children, + super.controller, + // super.initialAreas, + super.onDividerDragUpdate, }); @override @@ -26,7 +28,6 @@ class DraggableMultiListView extends SerializableMultiSplitView { class _DraggableMultiListViewState extends State { static const _rootKey = ValueKey("root"); final _controllers = {}; - var _widgets = []; final _movingControllerMap = >{}; final _movedControllerMap = >{}; final _removedControllerMap = >{}; @@ -36,8 +37,10 @@ class _DraggableMultiListViewState extends State { @override void initState() { + super.initState(); _areaMap[_rootKey] = []; _controllers[_rootKey] = MultiSplitViewController(); + // _controllers[_rootKey]?.addArea(Area(builder: (BuildContext context, Area area) => const Text("sam mal"))); if (!widget.onWidgetInController.hasListener) { widget.onWidgetInController.stream.listen((event) { @@ -47,24 +50,22 @@ class _DraggableMultiListViewState extends State { // setState(() => _isMoving = isMoving); }); _movedControllerMap[key] = StreamController(); - //_movedControllerMap[key]!.stream.listen(_movedControllerHandler); _edgeControllerMap[key] = StreamController(); _edgeControllerMap[key]!.stream.listen(_edgeControllerHandler); _removedControllerMap[key] = StreamController(); - _widgets.add( + _controllers[_rootKey]?.addArea(Area(data: key, builder: (BuildContext context, Area area) => MovableBox( key: key, onMoveController: _movingControllerMap[key]!, onMovedController: _movedControllerMap[key]!, removedController: _removedControllerMap[key]!, onEdgeController: _edgeControllerMap[key]!, - child: event, + child: event.data, ), - ); + ),); }); } - super.initState(); } @override @@ -83,114 +84,137 @@ class _DraggableMultiListViewState extends State { @override Widget build(BuildContext context) { - return SerializableMultiSplitView( + if (_controllers[_rootKey]?.areasCount != 0) { + return SerializableMultiSplitView( key: _rootKey, controller: _controllers[_rootKey]!, axis: widget.axis, - children: _widgets, - onWeightChange: () { - _areaMap[_rootKey] = List.generate( - _widgets.length, - (index) => _controllers[_rootKey]!.areas[index].weight!, - ); - debugPrint("Root AreaMap: ${_areaMap[_rootKey]}"); - }); - } - Widget? _recursiveSearch(List widgets, Key key) { - for (final widget in widgets) { - if (widget.key == key) { - return widget; - } - else if (widget is SerializableMultiSplitView) { - final result = _recursiveSearch(widget.children, key); - if (result != null) { - return result; - } - } + // onWeightChange: () { + // _areaMap[_rootKey] = List.generate( + // _widgets.length, + // (index) => _controllers[_rootKey]!.areas[index].weight!, + // ); + // debugPrint("Root AreaMap: ${_areaMap[_rootKey]}"); + // }, + ); } - return null; - } - - List _removeEmptySplitViews(List widgets) { - var cleanedWidgets = widgets; - var widgetList = List.of(widgets); - for (var widget in widgetList) { - if (widget is SerializableMultiSplitView) { - if (widget.children.isEmpty) { - if (_areaMap.containsKey(widget.key)) { - _areaMap.remove(widget.key); - } - cleanedWidgets.remove(widget); - } - else { - var cleanedWidget = _removeEmptyChildren(widget); - if (cleanedWidget == null) { - if (_areaMap.containsKey(widget.key)) { - _areaMap.remove(widget.key); - } - cleanedWidgets.remove(widget); - } - else { - cleanedWidgets[cleanedWidgets.indexWhere((element) => element == widget)] = cleanedWidget; - - } - } - } - _controllers[widget.key]!.areas = List.from(_controllers[widget.key]!.areas); + else { + return const Text("Add a widget"); } - _controllers[_rootKey]!.areas = List.from(_controllers[_rootKey]!.areas); - return cleanedWidgets; } - Widget? _removeEmptyChildren(SerializableMultiSplitView widget) { - final widgetChildren = List.of(widget.children); - for (final child in widgetChildren) { - if (child is SerializableMultiSplitView) { - if (child.children.isNotEmpty) { - var childWidget = _removeEmptyChildren(child); - if (childWidget == null){ - if (_areaMap.containsKey(child.key)) { - _areaMap.remove(child.key); - } - widget.children.remove(child); - } - else { - widget.children[widget.children.indexWhere((element) => element == child)] = childWidget; - } - } - if (child.children.isEmpty) { - if (_areaMap.containsKey(child.key)) { - _areaMap.remove(child.key); - } - widget.children.remove(child); - } - } - } - if (widget.children.isEmpty) { - return null; - } + // Widget? _recursiveSearch(List widgets, Key key) { + // for (final widget in widgets) { + // if (widget.key == key) { + // return widget; + // } + // else if (widget is SerializableMultiSplitView) { + // final result = _recursiveSearch(widget.children, key); + // if (result != null) { + // return result; + // } + // } + // } + // return null; + // } + // List _removeEmptySplitViews(List widgets) { + // var cleanedWidgets = widgets; + // var widgetList = List.of(widgets); + // for (var widget in widgetList) { + // if (widget is SerializableMultiSplitView) { + // if (widget.children.isEmpty) { + // if (_areaMap.containsKey(widget.key)) { + // _areaMap.remove(widget.key); + // } + // cleanedWidgets.remove(widget); + // } + // else { + // var cleanedWidget = _removeEmptyChildren(widget); + // if (cleanedWidget == null) { + // if (_areaMap.containsKey(widget.key)) { + // _areaMap.remove(widget.key); + // } + // cleanedWidgets.remove(widget); + // } + // else { + // cleanedWidgets[cleanedWidgets.indexWhere((element) => element == widget)] = cleanedWidget; + // + // } + // } + // } + // _controllers[widget.key]!.areas = List.from(_controllers[widget.key]!.areas); + // } + // _controllers[_rootKey]!.areas = List.from(_controllers[_rootKey]!.areas); + // return cleanedWidgets; + // } + // Widget? _removeEmptyChildren(SerializableMultiSplitView widget) { + // final widgetChildren = List.of(widget.children); + // for (final child in widgetChildren) { + // if (child is SerializableMultiSplitView) { + // if (child.children.isNotEmpty) { + // var childWidget = _removeEmptyChildren(child); + // if (childWidget == null){ + // if (_areaMap.containsKey(child.key)) { + // _areaMap.remove(child.key); + // } + // widget.children.remove(child); + // } + // else { + // widget.children[widget.children.indexWhere((element) => element == child)] = childWidget; + // } + // } + // if (child.children.isEmpty) { + // if (_areaMap.containsKey(child.key)) { + // _areaMap.remove(child.key); + // } + // widget.children.remove(child); + // } + // } + // } + // if (widget.children.isEmpty) { + // return null; + // } + // + // + // + // _controllers[widget.key]!.areas = List.from(_controllers[widget.key]!.areas); + // return widget; + // } - _controllers[widget.key]!.areas = List.from(_controllers[widget.key]!.areas); - return widget; - } + // SerializableMultiSplitView? _getMovableBoxParentViewRecursive1( + // MovableBox box, List widgets) { + // for (final widget in widgets) { + // if (widget is SerializableMultiSplitView) { + // for (final child in widget.children) { + // if (child.key == box.key) { + // return widget; + // } else { + // final result = + // _getMovableBoxParentViewKeyRecursive(box, widget.children); + // if (result != null) { + // return result; + // } + // } + // } + // } + // } + // return null; + // } - SerializableMultiSplitView? _getMovableBoxParentViewRecursive( - MovableBox box, List widgets) { - for (final widget in widgets) { - if (widget is SerializableMultiSplitView) { - for (final child in widget.children) { - if (child.key == box.key) { - return widget; - } else { - final result = - _getMovableBoxParentViewRecursive(box, widget.children); - if (result != null) { - return result; - } - } + Key? _getMovableBoxParentViewKeyRecursive( + MovableBox box, Key key) { + + for (Area asd in _controllers[key]!.areas) { + if (asd.data == box.key) { + return key; + } + else if (asd.builder is SerializableMultiSplitView) { + final result = _getMovableBoxParentViewKeyRecursive(box, key); + if (result != null) { + return result; } } } @@ -211,171 +235,177 @@ class _DraggableMultiListViewState extends State { // the new view must have a controller final newMultiSplitViewKey = UniqueKey(); _controllers[newMultiSplitViewKey] = MultiSplitViewController(); + _controllers[newMultiSplitViewKey]?.areas = + (direction == MoveDirection.down || direction == MoveDirection.right) + ? [Area(data: newMultiSplitViewKey, builder: (BuildContext context, Area area) => targetBox), Area(data: newMultiSplitViewKey, builder: (BuildContext context, Area area) => movedBox)] + : [Area(data: newMultiSplitViewKey, builder: (BuildContext context, Area area) => movedBox), Area(data: newMultiSplitViewKey, builder: (BuildContext context, Area area) => targetBox)]; + final newMultiSplitView = SerializableMultiSplitView( key: newMultiSplitViewKey, controller: _controllers[newMultiSplitViewKey], axis: direction == MoveDirection.up || direction == MoveDirection.down ? Axis.vertical : Axis.horizontal, - children: - (direction == MoveDirection.down || direction == MoveDirection.right) - ? [targetBox, movedBox] - : [movedBox, targetBox], - onWeightChange: () { - final newWeights = []; - for (final a in _controllers[newMultiSplitViewKey]!.areas) { - newWeights.add(a.weight!); - } - _areaMap[newMultiSplitViewKey] = newWeights; - debugPrint( - "$newMultiSplitViewKey AreaMap: ${_areaMap[newMultiSplitViewKey]}"); - }, + + // onWeightChange: () { + // final newWeights = []; + // for (final a in _controllers[newMultiSplitViewKey]!.areas) { + // newWeights.add(a.weight!); + // } + // _areaMap[newMultiSplitViewKey] = newWeights; + // debugPrint( + // "$newMultiSplitViewKey AreaMap: ${_areaMap[newMultiSplitViewKey]}"); + // }, ); final targetBoxParentKey = - _getMovableBoxParentViewRecursive(targetBox, _widgets)?.key; + _getMovableBoxParentViewKeyRecursive(targetBox, _rootKey); final movedBoxParentKey = - _getMovableBoxParentViewRecursive(movedBox, _widgets)?.key; + _getMovableBoxParentViewKeyRecursive(movedBox, _rootKey); debugPrint( "Edge MovedWidgetParentKey: $movedBoxParentKey; TargetWidgetParentKey: $targetBoxParentKey"); // if both boxes are children of the root multi split view - if (targetBoxParentKey == null && movedBoxParentKey == null) { + if (targetBoxParentKey == _rootKey && movedBoxParentKey == _rootKey) { // 1. get the target & moved box index from the root multi split view - final targetBoxIndex = _widgets.indexWhere((w) => w.key == targetBox.key); - //final movedBoxIndex = _widgets.indexWhere((w) => w.key == movedBox.key); + final targetBoxIndex = _controllers[targetBoxParentKey]?.areas.indexWhere((w) => w.data == targetBox.key); + final movedBoxIndex = _controllers[movedBoxParentKey]?.areas.indexWhere((w) => w.data == movedBox.key); // 2. remove moved box from the root multi split view - _widgets.remove(movedBox); + _controllers[movedBoxParentKey]?.removeAreaAt(movedBoxIndex!); // 3. insert the new multi split view to the root multi split view on the target box index - _widgets.insert(targetBoxIndex, newMultiSplitView); - // 4. remove target box from the root multi split view - _widgets.remove(targetBox); - // 5. update the areas of the root multi split view - final rootAreas = List.from(_controllers[_rootKey]!.areas); - rootAreas.removeAt(0); - _controllers[_rootKey]!.areas = rootAreas; - // 6. update the areas of the new multi split view - _controllers[newMultiSplitViewKey]!.areas = - List.generate(2, (index) => Area()); - } + var areas = _controllers[targetBoxParentKey]?.areas.toList(); - // if the target box is a child of the root multi split view, but the moved box is a child of a child multi split view - if (targetBoxParentKey == null && movedBoxParentKey != null) { - // 1. get the index of the target box from the root multi split view - final targetBoxIndex = _widgets.indexWhere((w) => w.key == targetBox.key); - // 2. remove the moved box from the child multi split view - (_recursiveSearch(_widgets, movedBoxParentKey)! - as SerializableMultiSplitView) - .children - .remove(movedBox); - // 2.1 remove the parent if empty - bool movedParentEmpty = false; - if ((_recursiveSearch(_widgets, movedBoxParentKey)! - as SerializableMultiSplitView) - .children - .isEmpty) { - movedParentEmpty = true; - _widgets.remove(_recursiveSearch(_widgets, movedBoxParentKey)!); - } - // 3. remove the target box from the root multi split view - _widgets.remove(targetBox); - // 4. insert the new multi split view to the root multi split view on the target box index - _widgets.insert(targetBoxIndex, newMultiSplitView); - // 5. update the areas of the new multi split view - _controllers[newMultiSplitViewKey]!.areas = - List.generate(2, (index) => Area()); - // 6. update the areas of the moved box parent, if the moved parent is not empty - if (!movedParentEmpty) { - final movedBoxParentAreas = - List.from(_controllers[movedBoxParentKey]!.areas); - movedBoxParentAreas.removeAt(0); - _controllers[movedBoxParentKey]!.areas = movedBoxParentAreas; - } - } + areas?.insert(targetBoxIndex!, Area(data: newMultiSplitViewKey, builder: (BuildContext context, Area area) => newMultiSplitView)); + // 4. remove target box from the root multi split view + areas?.removeWhere((w) => w.data == targetBox.key); - // if the moved box is a child of the root multi split view, but the target box is a child of a child multi split view - if (targetBoxParentKey != null && movedBoxParentKey == null) { - // 1. get the index of the target box in the target parent multi split view - final targetBoxIndex = (_recursiveSearch(_widgets, targetBoxParentKey)! - as SerializableMultiSplitView) - .children - .indexWhere((element) => element.key == targetBox.key); - // 2. remove the target box from the target parent multi split view - (_recursiveSearch(_widgets, targetBoxParentKey)! - as SerializableMultiSplitView) - .children - .remove(targetBox); - // 3. remove the moved box from the root multi split view - _widgets.remove(movedBox); - // 4. insert the new multi split view to the target parent multi split view on the target box index - (_recursiveSearch(_widgets, targetBoxParentKey)! - as SerializableMultiSplitView) - .children - .insert(targetBoxIndex, newMultiSplitView); - // 5. update the areas of the target parent multi split view - final targetAreas = - List.from(_controllers[targetBoxParentKey]!.areas); - _controllers[targetBoxParentKey]!.areas = targetAreas; - // 6. update the areas of the new multi split view - _controllers[newMultiSplitViewKey]!.areas = - List.generate(2, (index) => Area()); + _controllers[targetBoxParentKey]?.areas = areas!; + // 5. update the areas of the root multi split view final rootAreas = List.from(_controllers[_rootKey]!.areas); - rootAreas.removeAt(0); - _controllers[_rootKey]!.areas = rootAreas; + // rootAreas.removeAt(0); + // _controllers[_rootKey]!.areas = rootAreas; + // // 6. update the areas of the new multi split view + // _controllers[newMultiSplitViewKey]!.areas = + // List.generate(2, (index) => Area()); } - // if both boxes are children of a child multi split view - if (targetBoxParentKey != null && movedBoxParentKey != null) { - // 1. get the index of the target box in the target parent multi split view - final targetBoxIndex = (_recursiveSearch(_widgets, targetBoxParentKey)! - as SerializableMultiSplitView) - .children - .indexWhere((element) => element.key == targetBox.key); - // 2. remove the target box from the target parent multi split view - (_recursiveSearch(_widgets, targetBoxParentKey)! - as SerializableMultiSplitView) - .children - .remove(targetBox); - // 3. remove the moved box from the moved parent multi split view - (_recursiveSearch(_widgets, movedBoxParentKey)! - as SerializableMultiSplitView) - .children - .remove(movedBox); - // 3.a remove the parent if empty - bool movedParentEmpty = false; - if ((_recursiveSearch(_widgets, movedBoxParentKey)! - as SerializableMultiSplitView) - .children - .isEmpty) { - movedParentEmpty = true; - _widgets.remove(_recursiveSearch(_widgets, movedBoxParentKey)!); - } - // 4. insert the new multi split view to the target parent multi split view on the target box index - (_recursiveSearch(_widgets, targetBoxParentKey)! - as SerializableMultiSplitView) - .children - .insert(targetBoxIndex, newMultiSplitView); - // 5. update the areas of the target parent multi split view - final targetAreas = - List.from(_controllers[targetBoxParentKey]!.areas); - _controllers[targetBoxParentKey]!.areas = targetAreas; - // 6. update the areas of the moved parent multi split view, if the moved parent is not empty - if (!movedParentEmpty) { - final movedBoxParentAreas = - List.from(_controllers[movedBoxParentKey]!.areas); - movedBoxParentAreas.removeAt(0); - _controllers[movedBoxParentKey]!.areas = movedBoxParentAreas; - } - // 7. update the areas of the new multi split view - _controllers[newMultiSplitViewKey]!.areas = - List.generate(2, (index) => Area()); - - if (movedParentEmpty) { - debugPrint("movedparentempty"); - _controllers.remove(movedBoxParentKey); - } - } - _widgets = _removeEmptySplitViews(_widgets); + // // if the target box is a child of the root multi split view, but the moved box is a child of a child multi split view + // if (targetBoxParentKey == null && movedBoxParentKey != null) { + // // 1. get the index of the target box from the root multi split view + // final targetBoxIndex = _widgets.indexWhere((w) => w.key == targetBox.key); + // // 2. remove the moved box from the child multi split view + // (_recursiveSearch(_widgets, movedBoxParentKey)! + // as SerializableMultiSplitView) + // .children + // .remove(movedBox); + // // 2.1 remove the parent if empty + // bool movedParentEmpty = false; + // if ((_recursiveSearch(_widgets, movedBoxParentKey)! + // as SerializableMultiSplitView) + // .children + // .isEmpty) { + // movedParentEmpty = true; + // _widgets.remove(_recursiveSearch(_widgets, movedBoxParentKey)!); + // } + // // 3. remove the target box from the root multi split view + // _widgets.remove(targetBox); + // // 4. insert the new multi split view to the root multi split view on the target box index + // _widgets.insert(targetBoxIndex, newMultiSplitView); + // // 5. update the areas of the new multi split view + // _controllers[newMultiSplitViewKey]!.areas = + // List.generate(2, (index) => Area()); + // // 6. update the areas of the moved box parent, if the moved parent is not empty + // if (!movedParentEmpty) { + // final movedBoxParentAreas = + // List.from(_controllers[movedBoxParentKey]!.areas); + // movedBoxParentAreas.removeAt(0); + // _controllers[movedBoxParentKey]!.areas = movedBoxParentAreas; + // } + // } + // + // // if the moved box is a child of the root multi split view, but the target box is a child of a child multi split view + // if (targetBoxParentKey != null && movedBoxParentKey == null) { + // // 1. get the index of the target box in the target parent multi split view + // final targetBoxIndex = (_recursiveSearch(_widgets, targetBoxParentKey)! + // as SerializableMultiSplitView) + // .children + // .indexWhere((element) => element.key == targetBox.key); + // // 2. remove the target box from the target parent multi split view + // (_recursiveSearch(_widgets, targetBoxParentKey)! + // as SerializableMultiSplitView) + // .children + // .remove(targetBox); + // // 3. remove the moved box from the root multi split view + // _widgets.remove(movedBox); + // // 4. insert the new multi split view to the target parent multi split view on the target box index + // (_recursiveSearch(_widgets, targetBoxParentKey)! + // as SerializableMultiSplitView) + // .children + // .insert(targetBoxIndex, newMultiSplitView); + // // 5. update the areas of the target parent multi split view + // final targetAreas = + // List.from(_controllers[targetBoxParentKey]!.areas); + // _controllers[targetBoxParentKey]!.areas = targetAreas; + // // 6. update the areas of the new multi split view + // _controllers[newMultiSplitViewKey]!.areas = + // List.generate(2, (index) => Area()); + // final rootAreas = List.from(_controllers[_rootKey]!.areas); + // rootAreas.removeAt(0); + // _controllers[_rootKey]!.areas = rootAreas; + // } + // + // // if both boxes are children of a child multi split view + // if (targetBoxParentKey != null && movedBoxParentKey != null) { + // // 1. get the index of the target box in the target parent multi split view + // final targetBoxIndex = (_recursiveSearch(_widgets, targetBoxParentKey)! + // as SerializableMultiSplitView) + // .children + // .indexWhere((element) => element.key == targetBox.key); + // // 2. remove the target box from the target parent multi split view + // (_recursiveSearch(_widgets, targetBoxParentKey)! + // as SerializableMultiSplitView) + // .children + // .remove(targetBox); + // // 3. remove the moved box from the moved parent multi split view + // (_recursiveSearch(_widgets, movedBoxParentKey)! + // as SerializableMultiSplitView) + // .children + // .remove(movedBox); + // // 3.a remove the parent if empty + // bool movedParentEmpty = false; + // if ((_recursiveSearch(_widgets, movedBoxParentKey)! + // as SerializableMultiSplitView) + // .children + // .isEmpty) { + // movedParentEmpty = true; + // _widgets.remove(_recursiveSearch(_widgets, movedBoxParentKey)!); + // } + // // 4. insert the new multi split view to the target parent multi split view on the target box index + // (_recursiveSearch(_widgets, targetBoxParentKey)! + // as SerializableMultiSplitView) + // .children + // .insert(targetBoxIndex, newMultiSplitView); + // // 5. update the areas of the target parent multi split view + // final targetAreas = + // List.from(_controllers[targetBoxParentKey]!.areas); + // _controllers[targetBoxParentKey]!.areas = targetAreas; + // // 6. update the areas of the moved parent multi split view, if the moved parent is not empty + // if (!movedParentEmpty) { + // final movedBoxParentAreas = + // List.from(_controllers[movedBoxParentKey]!.areas); + // movedBoxParentAreas.removeAt(0); + // _controllers[movedBoxParentKey]!.areas = movedBoxParentAreas; + // } + // // 7. update the areas of the new multi split view + // _controllers[newMultiSplitViewKey]!.areas = + // List.generate(2, (index) => Area()); + // + // if (movedParentEmpty) { + // debugPrint("movedparentempty"); + // _controllers.remove(movedBoxParentKey); + // } + // } + // _widgets = _removeEmptySplitViews(_widgets); } } diff --git a/lib/widgets/layout_widget.dart b/lib/widgets/layout_widget.dart index 2c95243..e105d40 100644 --- a/lib/widgets/layout_widget.dart +++ b/lib/widgets/layout_widget.dart @@ -7,7 +7,7 @@ import 'package:test_multi_split_view/widgets/draggable_multi_list_view.dart'; import 'movable_box.dart'; class LayoutWidget extends StatefulWidget { - final StreamController? addWidgetController; + final StreamController? addWidgetController; final Axis axis; const LayoutWidget({ @@ -21,19 +21,15 @@ class LayoutWidget extends StatefulWidget { } class _LayoutWidgetState extends State with AutomaticKeepAliveClientMixin { - final widgets = []; - final _widgetInController = StreamController(); + final _widgetInController = StreamController(); final _widgetMovedOutController = StreamController<(MovableBox, MoveDirection)>(); @override void initState() { if (widget.addWidgetController?.hasListener != null) { - widget.addWidgetController?.stream.listen((widget) { - setState(() { - widgets.add(widget); - }); - _widgetInController.add(widget); + widget.addWidgetController?.stream.listen((area) { + _widgetInController.add(area); }); } if (!_widgetMovedOutController.hasListener) { @@ -57,7 +53,6 @@ class _LayoutWidgetState extends State with AutomaticKeepAliveClie axis: widget.axis, onWidgetInController: _widgetInController, onWidgetMovedOutController: _widgetMovedOutController, - children: widgets, ), ); } diff --git a/lib/widgets/serializable_multi_split_view.dart b/lib/widgets/serializable_multi_split_view.dart index a6d724e..f8a0539 100644 --- a/lib/widgets/serializable_multi_split_view.dart +++ b/lib/widgets/serializable_multi_split_view.dart @@ -7,25 +7,24 @@ class SerializableMultiSplitView extends MultiSplitView { SerializableMultiSplitView({ super.axis, super.controller, - super.onWeightChange, + super.onDividerDragUpdate, super.resizable, required super.key, - required super.children, }); - toJson() { - return { - 'key': key ?? UniqueKey(), - 'children': jsonEncode(children), - 'axis': axis, - }; - } - - static SerializableMultiSplitView fromJson(Map json) { - return SerializableMultiSplitView( - key: json.containsKey("key") ? json['key'] : UniqueKey(), - children: json['children'], - axis: json['axis'], - ); - } + // toJson() { + // return { + // 'key': key ?? UniqueKey(), + // 'children': jsonEncode(children), + // 'axis': axis, + // }; + // } + // + // static SerializableMultiSplitView fromJson(Map json) { + // return SerializableMultiSplitView( + // key: json.containsKey("key") ? json['key'] : UniqueKey(), + // children: json['children'], + // axis: json['axis'], + // ); + // } } diff --git a/pubspec.lock b/pubspec.lock index b89f0e9..e34f338 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -79,26 +79,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.4" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.3" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" lints: dependency: transitive description: @@ -127,18 +127,18 @@ packages: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.12.0" multi_split_view: dependency: "direct main" description: name: multi_split_view - sha256: d68e129bff71fc9e6b66de59e1b79deaf4b91f30940130bfbd2d704c1c713499 + sha256: "596d71fd30f006a1b8878a2308e794f52bd0ea750f05bbaa0b18cb50c0f79325" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "3.1.0" path: dependency: transitive description: @@ -196,10 +196,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.0" vector_math: dependency: transitive description: @@ -212,10 +212,10 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "14.2.1" sdks: dart: ">=3.3.0 <4.0.0" - flutter: ">=1.17.0" + flutter: ">=3.18.0-18.0.pre.54" diff --git a/pubspec.yaml b/pubspec.yaml index 59c799c..d8bd071 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,7 +35,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.6 - multi_split_view: ^2.4.0 + multi_split_view: ^3.1.0 dev_dependencies: flutter_test: