@@ -128,140 +128,99 @@ class _WorkspaceDesktopState extends State<WorkspaceDesktop> {
128128 onTap: () {
129129 _focusNode.requestFocus ();
130130 },
131- child: Padding (
132- padding: EdgeInsets .symmetric (
133- horizontal: 40. w,
134- vertical: 40. h,
135- ),
136- child: Stack (
131+ child: Stack (
137132 clipBehavior: Clip .none,
138133 children: [
139- const CanvasPage (),
140- const WorkspaceDrawer (),
141- SizedBox (width: 20. w),
142- Positioned (
143- top: 0 ,
144- left: 0.21 .sw,
145- child: UndoRedoButton (su: suprovider),
146- ),
147- Positioned (
148- top: 0 ,
149- right: 0.001 .sw,
150- child: ExportProjectButton (
151- su: suprovider,
152- wp: provider,
153- ),
154- ),
155- Positioned (right: 0 , top: 0.10 .sh, child: ToolBar ()),
156- Positioned (
157- bottom: 0. h,
158- right: 0. w,
159- child: ZoomControlButton (),
160- ),
161- Consumer2 <WorkspaceProvider , CanvasProvider >(
162- builder: (
163- context,
164- workspaceProvider,
165- canvasProvider,
166- child,
167- ) {
168- return ListenableBuilder (
169- listenable:
170- canvasProvider.transformationController,
171- builder: (context, child) {
172- if (workspaceProvider.shouldShowObjectToolbox) {
173- final selectedObject =
174- workspaceProvider
175- .canvasObjects[workspaceProvider
176- .currentlySelectedObjectId! ]! ;
177-
178- final matrix =
179- canvasProvider
180- .transformationController
181- .value;
182- Offset screenPosition;
183- if (selectedObject is ConnectorObject ) {
184- // For connectors, position at midpoint of the line
185- final source =
186- workspaceProvider
187- .canvasObjects[selectedObject
188- .sourceId];
189- final target =
190- workspaceProvider
191- .canvasObjects[selectedObject
192- .targetId];
193-
194- if (source != null && target != null ) {
195- final startPoint = source
196- .getConnectionPoint (
197- selectedObject.sourceAlignment,
198- );
199- final endPoint = target
200- .getConnectionPoint (
201- selectedObject.targetAlignment,
202- );
203-
204- // Calculate midpoint
205- final midPoint = Offset (
206- (startPoint.dx + endPoint.dx) / 2 ,
207- (startPoint.dy + endPoint.dy) / 2 ,
208- );
209-
210- // Transform to screen coordinates
211- final transformedMidPoint = matrix
212- .transform3 (
213- vector_math.Vector3 (
214- midPoint.dx,
215- midPoint.dy,
216- 0 ,
134+ // Canvas fills entire area, no padding
135+ const Positioned .fill (child: CanvasPage ()),
136+ // UI overlay with 24px inset
137+ Positioned .fill (
138+ child: Padding (
139+ padding: const EdgeInsets .all (24 ),
140+ child: Stack (
141+ clipBehavior: Clip .none,
142+ children: [
143+ const WorkspaceDrawer (),
144+ Positioned (
145+ top: 0 ,
146+ left: 0.21 .sw,
147+ child: UndoRedoButton (su: suprovider),
148+ ),
149+ Positioned (
150+ top: 0 ,
151+ right: 0 ,
152+ child: ExportProjectButton (
153+ su: suprovider,
154+ wp: provider,
155+ ),
156+ ),
157+ Positioned (
158+ right: 0 ,
159+ top: 0 ,
160+ bottom: 0 ,
161+ child: Center (child: ToolBar ()),
162+ ),
163+ Positioned (
164+ bottom: 0 ,
165+ right: 0 ,
166+ child: ZoomControlButton (),
167+ ),
168+ Consumer2 <WorkspaceProvider , CanvasProvider >(
169+ builder: (context, workspaceProvider, canvasProvider, child) {
170+ return ListenableBuilder (
171+ listenable: canvasProvider.transformationController,
172+ builder: (context, child) {
173+ if (workspaceProvider.shouldShowObjectToolbox) {
174+ final selectedObject = workspaceProvider
175+ .canvasObjects[workspaceProvider.currentlySelectedObjectId! ]! ;
176+ final matrix = canvasProvider.transformationController.value;
177+ Offset screenPosition;
178+ if (selectedObject is ConnectorObject ) {
179+ final source = workspaceProvider.canvasObjects[selectedObject.sourceId];
180+ final target = workspaceProvider.canvasObjects[selectedObject.targetId];
181+ if (source != null && target != null ) {
182+ final startPoint = source.getConnectionPoint (selectedObject.sourceAlignment);
183+ final endPoint = target.getConnectionPoint (selectedObject.targetAlignment);
184+ final midPoint = Offset (
185+ (startPoint.dx + endPoint.dx) / 2 ,
186+ (startPoint.dy + endPoint.dy) / 2 ,
187+ );
188+ final transformedMidPoint = matrix.transform3 (
189+ vector_math.Vector3 (midPoint.dx, midPoint.dy, 0 ),
190+ );
191+ screenPosition = Offset (transformedMidPoint.x, transformedMidPoint.y);
192+ } else {
193+ return const SizedBox .shrink ();
194+ }
195+ } else {
196+ final objectBounds = selectedObject.getBounds ();
197+ final transformedTopCenter = matrix.transform3 (
198+ vector_math.Vector3 (objectBounds.topCenter.dx, objectBounds.topCenter.dy, 0 ),
199+ );
200+ screenPosition = Offset (transformedTopCenter.x, transformedTopCenter.y);
201+ }
202+ const double toolboxHeight = 48 ;
203+ return Positioned (
204+ left: screenPosition.dx,
205+ top: screenPosition.dy - toolboxHeight - 15 ,
206+ child: const FractionalTranslation (
207+ translation: Offset (- 0.5 , 0 ),
208+ child: NodeEditingToolbox (),
217209 ),
218210 );
219-
220- screenPosition = Offset (
221- transformedMidPoint.x,
222- transformedMidPoint.y,
223- );
224- } else {
225- return const SizedBox .shrink ();
226- }
227- } else {
228- // For shapes, use the top center as before
229- final objectBounds =
230- selectedObject.getBounds ();
231- final transformedTopCenter = matrix
232- .transform3 (
233- vector_math.Vector3 (
234- objectBounds.topCenter.dx,
235- objectBounds.topCenter.dy,
236- 0 ,
237- ),
238- );
239-
240- screenPosition = Offset (
241- transformedTopCenter.x,
242- transformedTopCenter.y,
211+ }
212+ return const SizedBox .shrink ();
213+ },
243214 );
244- }
245-
246- const double toolboxWidth = 240 ;
247- const double toolboxHeight = 48 ;
248-
249- return Positioned (
250- left:
251- screenPosition.dx - (toolboxWidth / 2 ),
252- top: screenPosition.dy - toolboxHeight - 15 ,
253- child: const NodeEditingToolbox (),
254- );
255- }
256- return const SizedBox .shrink ();
257- },
258- );
259- },
215+ },
216+ ),
217+ const ObjectTextEditor (),
218+ ],
219+ ),
220+ ),
260221 ),
261- const ObjectTextEditor (),
262222 ],
263223 ),
264- ),
265224 ),
266225 ),
267226 ),
0 commit comments