@@ -192,95 +192,97 @@ class _WorkspaceState extends State<Workspace> {
192192 ),
193193 ),
194194 backgroundColor: const Color .fromARGB (255 , 255 , 255 , 255 ),
195- body: RepaintBoundary (
196- key: workProvider.repaintBoundaryKey,
197- child: Stack (
195+ body: Stack (
198196 children: [
199197 // The infinite canvas
200- InteractiveViewer (
201- transformationController:
202- workProvider.transformationController,
203- minScale: 0.1 , // Allow zoom out to 10%
204- maxScale: 5.0 ,
205- constrained:
206- false , // This is critical - don't constrain the canvas
207- boundaryMargin:
208- EdgeInsets .all (double .infinity), // Allow infinite panning
209- onInteractionStart: (details) {
210- workProvider.updatePanning (true );
211- },
212- onInteractionUpdate: (details) {
213- // Update provider with current scale and position for node dragging calculations
214- final Matrix4 matrix =
215- workProvider.transformationController.value;
216-
217- // Extract scale from the transformation matrix
218- final scaleX = math.sqrt (
219- matrix.getColumn (0 )[0 ] * matrix.getColumn (0 )[0 ] +
220- matrix.getColumn (0 )[1 ] * matrix.getColumn (0 )[1 ]);
221-
222- final translation = Offset (
223- matrix.getTranslation ().x, matrix.getTranslation ().y);
224-
225- workProvider.updateScale (scaleX);
226- workProvider.updatePosition (translation);
227- },
228- onInteractionEnd: (details) {
229- // Sync final state with provider
230- _syncWithProvider ();
231- workProvider.updatePanning (false );
232- },
233- child: SizedBox (
234- // Huge size for effectively infinite canvas
235- width: canvasDimension,
236- height: canvasDimension,
237- child: Stack (
238- children: [
239- // Background grid for better visual orientation
240- Positioned .fill (
241- child: CustomPaint (
242- painter: GridPainter (),
243- ),
244- ),
245-
246- // Draw connections
247- ...workProvider.connections.map ((connection) {
248- return CustomPaint (
249- size: Size .infinite,
250- painter: LinePainter (
251- start: workProvider
252- .nodeList[connection.sourceNodeId]! .position,
253- end: workProvider
254- .nodeList[connection.targetNodeId]! .position,
255- sourceNodeId: connection.sourceNodeId,
256- startPoint: connection.sourcePoint,
257- targetNodeId: connection.targetNodeId,
258- endPoint: connection.targetPoint,
259- scale: workProvider.scale,
260- connection: connection,
261- ),
262- );
263- }),
264-
265- // Draw nodes
266- ...workProvider.nodeList.entries.map ((entry) {
267- var id = entry.key;
268- var node = entry.value;
269- return Positioned (
270- left: node.position.dx,
271- top: node.position.dy,
272- child: Node (
273- id: id,
274- type: node.type,
275- onResize: (Size newSize) =>
276- workProvider.onResize (id, newSize),
277- onDrag: (offset) =>
278- workProvider.dragNode (id, offset),
279- position: node.position,
198+ RepaintBoundary (
199+ key: workProvider.repaintBoundaryKey,
200+ child: InteractiveViewer (
201+ transformationController:
202+ workProvider.transformationController,
203+ minScale: 0.1 , // Allow zoom out to 10%
204+ maxScale: 5.0 ,
205+ constrained:
206+ false , // This is critical - don't constrain the canvas
207+ boundaryMargin:
208+ EdgeInsets .all (double .infinity), // Allow infinite panning
209+ onInteractionStart: (details) {
210+ workProvider.updatePanning (true );
211+ },
212+ onInteractionUpdate: (details) {
213+ // Update provider with current scale and position for node dragging calculations
214+ final Matrix4 matrix =
215+ workProvider.transformationController.value;
216+
217+ // Extract scale from the transformation matrix
218+ final scaleX = math.sqrt (
219+ matrix.getColumn (0 )[0 ] * matrix.getColumn (0 )[0 ] +
220+ matrix.getColumn (0 )[1 ] * matrix.getColumn (0 )[1 ]);
221+
222+ final translation = Offset (
223+ matrix.getTranslation ().x, matrix.getTranslation ().y);
224+
225+ workProvider.updateScale (scaleX);
226+ workProvider.updatePosition (translation);
227+ },
228+ onInteractionEnd: (details) {
229+ // Sync final state with provider
230+ _syncWithProvider ();
231+ workProvider.updatePanning (false );
232+ },
233+ child: SizedBox (
234+ // Huge size for effectively infinite canvas
235+ width: canvasDimension,
236+ height: canvasDimension,
237+ child: Stack (
238+ children: [
239+ // Background grid for better visual orientation
240+ Positioned .fill (
241+ child: CustomPaint (
242+ painter: GridPainter (),
280243 ),
281- );
282- }),
283- ],
244+ ),
245+
246+ // Draw connections
247+ ...workProvider.connections.map ((connection) {
248+ return CustomPaint (
249+ size: Size .infinite,
250+ painter: LinePainter (
251+ start: workProvider
252+ .nodeList[connection.sourceNodeId]! .position,
253+ end: workProvider
254+ .nodeList[connection.targetNodeId]! .position,
255+ sourceNodeId: connection.sourceNodeId,
256+ startPoint: connection.sourcePoint,
257+ targetNodeId: connection.targetNodeId,
258+ endPoint: connection.targetPoint,
259+ scale: workProvider.scale,
260+ connection: connection,
261+ ),
262+ );
263+ }),
264+
265+ // Draw nodes
266+ ...workProvider.nodeList.entries.map ((entry) {
267+ var id = entry.key;
268+ var node = entry.value;
269+ return Positioned (
270+ left: node.position.dx,
271+ top: node.position.dy,
272+ child: Node (
273+ id: id,
274+ type: node.type,
275+ onResize: (Size newSize) =>
276+ workProvider.onResize (id, newSize),
277+ onDrag: (offset) =>
278+ workProvider.dragNode (id, offset),
279+ position: node.position,
280+ ),
281+ );
282+ }
283+ ),
284+ ],
285+ ),
284286 ),
285287 ),
286288 ),
@@ -346,7 +348,6 @@ class _WorkspaceState extends State<Workspace> {
346348 ),
347349 ],
348350 ),
349- ),
350351 );
351352 },
352353 );
0 commit comments