mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-16 01:56:24 +00:00
added position elements to space
This commit is contained in:
@ -1,10 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/pages/common/buttons/add_space_button.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/view/curved_line_painter.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/view/dialogs/create_space_dialog.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/view/sidebar_widget.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/view/space_card_widget.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/view/space_container_widget.dart';
|
||||
import 'package:syncrow_web/services/space_mana_api.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
@ -41,7 +43,7 @@ class SpaceManagementPageState extends State<SpaceManagementPage> {
|
||||
List<SpaceModel> spaces = await _api.getSpaceHierarchy(community.uuid);
|
||||
|
||||
// Store the result in the communitySpaces map
|
||||
communitySpaces[community.name] = spaces;
|
||||
community.spaces = spaces;
|
||||
}
|
||||
|
||||
// Update the state to reflect loaded data
|
||||
@ -128,7 +130,8 @@ class SpaceManagementPageState extends State<SpaceManagementPage> {
|
||||
child: Container(
|
||||
width: 2000, // Large canvas
|
||||
height: 2000, // Large canvas
|
||||
color: ColorsManager.transparentColor, // Transparent background
|
||||
color: ColorsManager
|
||||
.transparentColor, // Transparent background
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
@ -149,8 +152,51 @@ class SpaceManagementPageState extends State<SpaceManagementPage> {
|
||||
children: spaces
|
||||
.asMap()
|
||||
.entries
|
||||
.map((entry) => _buildSpaceCard(
|
||||
entry.key, screenSize))
|
||||
.map((entry) => SpaceCardWidget(
|
||||
index: entry.key,
|
||||
screenSize: screenSize,
|
||||
position: spaces[entry.key]
|
||||
.position,
|
||||
isHovered: spaces[entry.key]
|
||||
.isHovered,
|
||||
onPanUpdate: (int index,
|
||||
Offset delta) {
|
||||
setState(() {
|
||||
spaces[index]
|
||||
.position += delta;
|
||||
});
|
||||
},
|
||||
onHoverChanged: (int index,
|
||||
bool isHovered) {
|
||||
setState(() {
|
||||
spaces[index]
|
||||
.isHovered =
|
||||
isHovered;
|
||||
});
|
||||
},
|
||||
onButtonTap: (int index,
|
||||
Offset newPosition,
|
||||
String direction) {
|
||||
_showCreateSpaceDialog(
|
||||
screenSize,
|
||||
position: spaces[index]
|
||||
.position +
|
||||
newPosition,
|
||||
parentIndex: index,
|
||||
direction: direction,
|
||||
);
|
||||
},
|
||||
buildSpaceContainer:
|
||||
(int index) {
|
||||
return SpaceContainerWidget(
|
||||
index: index,
|
||||
icon:
|
||||
spaces[index].icon,
|
||||
name:
|
||||
spaces[index].name,
|
||||
);
|
||||
},
|
||||
))
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
@ -224,139 +270,6 @@ class SpaceManagementPageState extends State<SpaceManagementPage> {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Function to build a draggable space card
|
||||
Widget _buildSpaceCard(int index, Size screenSize) {
|
||||
return Positioned(
|
||||
left: spaces[index].position.dx,
|
||||
top: spaces[index].position.dy,
|
||||
child: GestureDetector(
|
||||
onPanUpdate: (details) {
|
||||
// Update the position of the space card while dragging
|
||||
setState(() {
|
||||
spaces[index].position += details.delta;
|
||||
});
|
||||
},
|
||||
child: MouseRegion(
|
||||
onEnter: (_) {
|
||||
// Show plus buttons on hover
|
||||
setState(() {
|
||||
spaces[index].isHovered = true;
|
||||
});
|
||||
},
|
||||
onExit: (_) {
|
||||
// Hide plus buttons when not hovered
|
||||
setState(() {
|
||||
spaces[index].isHovered = false;
|
||||
});
|
||||
},
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
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),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Function to build the space container with the styled format
|
||||
Widget _buildSpaceContainer(int index) {
|
||||
return Container(
|
||||
width: 150,
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsManager.whiteColors,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 5,
|
||||
offset: const Offset(0, 3),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 40,
|
||||
height: 60,
|
||||
decoration: const BoxDecoration(
|
||||
color: ColorsManager.secondaryColor,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(15),
|
||||
bottomLeft: Radius.circular(15),
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: SvgPicture.asset(
|
||||
spaces[index].icon,
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
spaces[index].name,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Function to build plus buttons for new space creation
|
||||
Widget _buildPlusButton(
|
||||
int index, String direction, Offset offset, Size screenSize) {
|
||||
return Positioned(
|
||||
left: offset.dx,
|
||||
top: offset.dy,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Offset newPosition;
|
||||
switch (direction) {
|
||||
case 'left':
|
||||
newPosition = spaces[index].position + const Offset(-200, 0);
|
||||
break;
|
||||
case 'right':
|
||||
newPosition = spaces[index].position + const Offset(200, 0);
|
||||
break;
|
||||
case 'down':
|
||||
newPosition = spaces[index].position + const Offset(0, 150);
|
||||
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, direction: direction);
|
||||
},
|
||||
child: Container(
|
||||
width: 30,
|
||||
height: 30,
|
||||
decoration: const BoxDecoration(
|
||||
color: ColorsManager.secondaryColor,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: const Icon(Icons.add, color: Colors.white, size: 20),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Model for storing space information
|
||||
@ -386,61 +299,3 @@ class Connection {
|
||||
required this.direction});
|
||||
}
|
||||
|
||||
// Custom painter to draw lines between connected spaces
|
||||
|
||||
class CurvedLinePainter extends CustomPainter {
|
||||
final List<Connection> connections;
|
||||
|
||||
CurvedLinePainter(this.connections);
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final paint = Paint()
|
||||
..color = ColorsManager.blackColor
|
||||
..strokeWidth = 2
|
||||
..style = PaintingStyle.stroke;
|
||||
|
||||
// Ensure connections exist before painting
|
||||
if (connections.isEmpty) {
|
||||
return; // Nothing to paint if there are no connections
|
||||
}
|
||||
|
||||
for (var connection in connections) {
|
||||
// Ensure positions are valid before drawing lines
|
||||
if (connection.startSpace.position == null ||
|
||||
connection.endSpace.position == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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);
|
||||
} else if (connection.direction == 'right') {
|
||||
// Straight line for right connections
|
||||
canvas.drawLine(start, end, paint);
|
||||
} else if (connection.direction == 'left') {
|
||||
// Straight line for left connections
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(covariant CustomPainter oldDelegate) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user