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 e1c1d2f..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 = {}; - final _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,255 +84,141 @@ 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? _recursiveWidgetSearchByKey(Key key) { - for (final widget in _widgets) { - final result = _recursiveWidgetSearch(widget, 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; - } - - 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; - } - } + else { + return const Text("Add a widget"); } - 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; - } + // 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; + // } - 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; - } + // 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; + // } - // void _removeEmptyParentViewsRecursive(List widgets) { + // SerializableMultiSplitView? _getMovableBoxParentViewRecursive1( + // MovableBox box, 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); + // if (child.key == box.key) { + // return widget; + // } else { + // final result = + // _getMovableBoxParentViewKeyRecursive(box, 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; - } + Key? _getMovableBoxParentViewKeyRecursive( + MovableBox box, Key key) { - // 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)!); + for (Area asd in _controllers[key]!.areas) { + if (asd.data == box.key) { + return key; } - // 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; + else if (asd.builder is SerializableMultiSplitView) { + final result = _getMovableBoxParentViewKeyRecursive(box, key); + if (result != null) { + return result; } } } - - // 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; - } + return null; } _edgeControllerHandler(EdgeRecord record) { @@ -348,274 +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) { - // 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); + if (targetBoxParentKey == _rootKey && movedBoxParentKey == _rootKey) { + // 1. get the target & moved box index from the root multi split view + 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 + _controllers[movedBoxParentKey]?.removeAreaAt(movedBoxIndex!); + // 3. insert the new multi split view to the root multi split view on the target box index + var areas = _controllers[targetBoxParentKey]?.areas.toList(); + + 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); + + _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; - // 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()); + // 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 (targetBoxParentKey != null) { - // (_recursiveWidgetSearchByKey(targetBoxParentKey)! + // // 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(targetBox); - // if ((_recursiveWidgetSearchByKey(targetBoxParentKey)! + // .remove(movedBox); + // // 2.1 remove the parent if empty + // bool movedParentEmpty = false; + // if ((_recursiveSearch(_widgets, movedBoxParentKey)! // as SerializableMultiSplitView) // .children // .isEmpty) { - // _widgets.remove(_recursiveWidgetSearchByKey(targetBoxParentKey)!); + // 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); - // 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); - // } + // // 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; + // } // - // _removeEmptyParentViewsRecursive(_widgets); - // - // for (final controller in _controllers.values) { - // final listOfAreas = List.from(controller.areas); - // controller.areas = listOfAreas; + // // 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)!); // } - // } 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; + // // 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()); // - // _removeEmptyParentViewsRecursive(_widgets); - // - // for (final controller in _controllers.values) { - // final listOfAreas = List.from(controller.areas); - // controller.areas = listOfAreas; + // if (movedParentEmpty) { + // debugPrint("movedparentempty"); + // _controllers.remove(movedBoxParentKey); // } // } + // _widgets = _removeEmptySplitViews(_widgets); } } 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; - // } - // } - } -} 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: