diff --git a/lib/pages/spaces_management/view/spaces_management_page.dart b/lib/pages/spaces_management/view/spaces_management_page.dart index 929da5b1..a1a211b9 100644 --- a/lib/pages/spaces_management/view/spaces_management_page.dart +++ b/lib/pages/spaces_management/view/spaces_management_page.dart @@ -19,39 +19,50 @@ class SpaceManagementPageState extends State { Size screenSize = MediaQuery.of(context).size; return Scaffold( - backgroundColor: ColorsManager.whiteColors, - appBar: AppBar( - title: const Text('Space Management'), - ), - body: Stack( - children: [ - // Draw lines using a CustomPaint widget - CustomPaint( - size: Size.infinite, - painter: CurvedLinePainter(connections), - ), - Center( - child: spaces.isEmpty - ? AddSpaceButton( - onTap: () { - _showCreateSpaceDialog(screenSize); - }, - ) - : Stack( - children: spaces - .asMap() - .entries - .map((entry) => _buildSpaceCard(entry.key, screenSize)) - .toList(), + backgroundColor: ColorsManager.whiteColors, + appBar: AppBar( + title: const Text('Space Management'), + ), + body: InteractiveViewer( + boundaryMargin: const EdgeInsets.all( + double.infinity), // Allow panning to any side + minScale: 0.5, // Minimum zoom scale + maxScale: 2.5, // Maximum zoom scale + panEnabled: true, // Enable panning (move left/right) + scaleEnabled: true, // Enable zooming + child: MouseRegion( + cursor: SystemMouseCursors.grab, + child: Stack( + children: [ + // Draw lines using a CustomPaint widget + CustomPaint( + size: Size.infinite, + painter: CurvedLinePainter(connections), ), - ), - ], - ), - ); + Center( + child: spaces.isEmpty + ? AddSpaceButton( + onTap: () { + _showCreateSpaceDialog(screenSize); + }, + ) + : Stack( + children: spaces + .asMap() + .entries + .map((entry) => + _buildSpaceCard(entry.key, screenSize)) + .toList(), + ), + ), + ], + ), + ))); } // Function to open the Create Space dialog - void _showCreateSpaceDialog(Size screenSize, {Offset? position, int? parentIndex, bool addConnection = false}) { + void _showCreateSpaceDialog(Size screenSize, + {Offset? position, int? parentIndex, String? direction}) { showDialog( context: context, builder: (BuildContext context) { @@ -62,17 +73,20 @@ class SpaceManagementPageState extends State { Offset centerPosition = position ?? Offset( screenSize.width / 2 - 75, // Center horizontally - screenSize.height / 2 - 100, // Slightly above the center vertically + screenSize.height / 2 - + 100, // Slightly above the center vertically ); - SpaceData newSpace = SpaceData(name: name, icon: icon, position: centerPosition); + SpaceData newSpace = + SpaceData(name: name, icon: icon, position: centerPosition); spaces.add(newSpace); // Add connection for down-button - if (addConnection && parentIndex != null) { + if (parentIndex != null && direction != null) { connections.add(Connection( startSpace: spaces[parentIndex], endSpace: newSpace, + direction: direction, )); } }); @@ -112,9 +126,12 @@ class SpaceManagementPageState extends State { children: [ _buildSpaceContainer(index), if (spaces[index].isHovered) ...[ - _buildPlusButton(index, 'left', const Offset(-21, 20), screenSize), - _buildPlusButton(index, 'right', const Offset(140, 20), screenSize), - _buildPlusButton(index, 'down', const Offset(63, 50), screenSize), + _buildPlusButton( + index, 'left', const Offset(-21, 20), screenSize), + _buildPlusButton( + index, 'right', const Offset(140, 20), screenSize), + _buildPlusButton( + index, 'down', const Offset(63, 50), screenSize), ], ], ), @@ -152,16 +169,15 @@ class SpaceManagementPageState extends State { bottomLeft: Radius.circular(15), ), ), - child: Center( - child: SvgPicture.asset( - spaces[index].icon, - width: 24, - height: 24, - color: Colors.white, - ), + child: Center( + child: SvgPicture.asset( + spaces[index].icon, + width: 24, + height: 24, + color: Colors.white, ), ), - + ), const SizedBox(width: 10), Text( spaces[index].name, @@ -176,14 +192,14 @@ class SpaceManagementPageState extends State { } // Function to build plus buttons for new space creation - Widget _buildPlusButton(int index, String direction, Offset offset, Size screenSize) { + Widget _buildPlusButton( + int index, String direction, Offset offset, Size screenSize) { return Positioned( left: offset.dx, top: offset.dy, child: GestureDetector( onTap: () { Offset newPosition; - bool addConnection = false; switch (direction) { case 'left': newPosition = spaces[index].position + const Offset(-200, 0); @@ -193,13 +209,13 @@ class SpaceManagementPageState extends State { break; case 'down': newPosition = spaces[index].position + const Offset(0, 150); - addConnection = true; break; default: newPosition = spaces[index].position; } // Open the dialog to create a new space and pass down the new position - _showCreateSpaceDialog(screenSize, position: newPosition, parentIndex: index, addConnection: addConnection); + _showCreateSpaceDialog(screenSize, + position: newPosition, parentIndex: index, direction: direction); }, child: Container( width: 30, @@ -234,8 +250,12 @@ class SpaceData { class Connection { final SpaceData startSpace; final SpaceData endSpace; + final String direction; - Connection({required this.startSpace, required this.endSpace}); + Connection( + {required this.startSpace, + required this.endSpace, + required this.direction}); } // Custom painter to draw lines between connected spaces @@ -253,23 +273,47 @@ class CurvedLinePainter extends CustomPainter { ..style = PaintingStyle.stroke; for (var connection in connections) { - final start = connection.startSpace.position + Offset(75, 60); // Bottom center of the starting space - final end = connection.endSpace.position + Offset(75, 0); // Top center of the ending space + Offset start = connection.startSpace.position + + Offset(75, 60); // Center bottom of start space + Offset end = connection.endSpace.position + + Offset(75, 0); // Center top of end space - // Calculate control point for Bézier curve (to create a curve) - final controlPoint = Offset((start.dx + end.dx) / 2, start.dy + 50); - - // Draw the Bézier curve - final path = Path() - ..moveTo(start.dx, start.dy) - ..quadraticBezierTo(controlPoint.dx, controlPoint.dy, end.dx, end.dy); - - canvas.drawPath(path, paint); + // Draw straight line for left/right connections and curved line for down connections + if (connection.direction == 'down') { + // Curved line for down connections + final controlPoint = Offset((start.dx + end.dx) / 2, start.dy + 50); + final path = Path() + ..moveTo(start.dx, start.dy) + ..quadraticBezierTo(controlPoint.dx, controlPoint.dy, end.dx, end.dy); + canvas.drawPath(path, paint); + } + if (connection.direction == 'right') { + start = Offset( + connection.startSpace.position.dx + 150, + connection.startSpace.position.dy + + 30); // Right center of the first space + end = Offset( + connection.endSpace.position.dx, + connection.endSpace.position.dy + + 30); // Left center of the new space + canvas.drawLine(start, end, paint); + } else if (connection.direction == 'left') { + // Straight line for left/right connections + start = Offset( + connection.startSpace.position.dx, + connection.startSpace.position.dy + + 30); // Left center of the first space + end = Offset( + connection.endSpace.position.dx + 150, + connection.endSpace.position.dy + + 30); // Right center of the new space + canvas.drawLine(start, end, paint); + } // Draw small connection dots at the start and end points final dotPaint = Paint()..color = ColorsManager.blackColor; canvas.drawCircle(start, 5, dotPaint); // Start dot - canvas.drawCircle(end, 5, dotPaint); // End dot + canvas.drawCircle(end, 5, dotPaint); // End dot } } @@ -277,4 +321,4 @@ class CurvedLinePainter extends CustomPainter { bool shouldRepaint(covariant CustomPainter oldDelegate) { return true; } -} \ No newline at end of file +}