diff --git a/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart index 6b349374..12156b22 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart @@ -698,7 +698,7 @@ class _CommunityStructureAreaState extends State { final double verticalGap = 180.0; final double nodeWidth = 200; final double nodeHeight = 100; - final double breathingSpace = 300.0; // extra gap after original tree + final double breathingSpace = 300.0; /// Helper to recursively duplicate a node and its children SpaceModel duplicateRecursive(SpaceModel original, SpaceModel? duplicatedParent) { @@ -706,7 +706,7 @@ class _CommunityStructureAreaState extends State { final duplicated = SpaceModel( name: duplicatedName, icon: original.icon, - position: Offset.zero, + position: original.position, isPrivate: original.isPrivate, children: [], status: SpaceStatus.newSpace, @@ -725,11 +725,13 @@ class _CommunityStructureAreaState extends State { direction: "down", ); connections.add(newConnection); + duplicated.incomingConnection = newConnection; duplicatedParent.addOutgoingConnection(newConnection); duplicatedParent.children.add(duplicated); } + // Duplicate its children recursively for (var child in original.children) { duplicateRecursive(child, duplicated); } @@ -773,13 +775,63 @@ class _CommunityStructureAreaState extends State { setState(() { if (space.parent == null) { // Duplicating a ROOT node - SpaceModel duplicatedRoot = duplicateRecursive(space, null); + duplicateRecursive(space, null); + connections = createConnections(spaces); realignTree(); } else { - // Duplicating a CHILD node inside its parent - SpaceModel duplicated = duplicateRecursive(space, space.parent); + final parent = space.parent!; + + final duplicated = duplicateRecursive(space, parent); + final newConnection = Connection( + startSpace: parent, + endSpace: duplicated, + direction: "down", + ); + connections.add(newConnection); + duplicated.incomingConnection = newConnection; + parent.addOutgoingConnection(newConnection); + parent.children.add(duplicated); + connections = createConnections(spaces); realignTree(); + //_realignSubtree(space.parent!); } }); } + + void _realignSubtree(SpaceModel parent) { + const double nodeWidth = 200; + const double horizontalGap = 60; + const double verticalGap = 180; + + double calculateSubtreeWidth(SpaceModel node) { + if (node.children.isEmpty) return nodeWidth; + double width = 0; + for (var child in node.children) { + width += calculateSubtreeWidth(child) + horizontalGap; + } + return width - horizontalGap; + } + + void assignPositions(SpaceModel node, double startX, double startY) { + double subtreeWidth = calculateSubtreeWidth(node); + double centerX = startX + subtreeWidth / 2 - nodeWidth / 2; + node.position = Offset(centerX, startY); + + if (node.children.length == 1) { + assignPositions(node.children.first, centerX, startY + verticalGap); + } else { + double childX = startX; + for (var child in node.children) { + double childWidth = calculateSubtreeWidth(child); + assignPositions(child, childX, startY + verticalGap); + childX += childWidth + horizontalGap; + } + } + } + + // Start laying out from parent + assignPositions(parent, parent.position.dx - 150, parent.position.dy); + + _adjustCanvasSizeForSpaces(); + } }