NodeFlowController<T> constructor

NodeFlowController<T>({
  1. GraphViewport? initialViewport,
  2. NodeFlowConfig? config,
  3. List<Node<T>>? nodes,
  4. List<Connection>? connections,
})

Creates a new node flow controller.

Parameters:

  • initialViewport - Initial viewport position and zoom (defaults to origin at 1x zoom)
  • config - Configuration settings for behavior like snap-to-grid, zoom limits, etc.
  • nodes - Optional initial nodes to populate the graph with
  • connections - Optional initial connections between nodes

Example:

// Create an empty controller
final controller = NodeFlowController<MyData>();

// Create a pre-populated controller
final controller = NodeFlowController<MyData>(
  nodes: [node1, node2, node3],
  connections: [conn1, conn2],
  initialViewport: GraphViewport(x: 0, y: 0, zoom: 1.0),
);

Implementation

NodeFlowController({
  GraphViewport? initialViewport,
  NodeFlowConfig? config,
  List<Node<T>>? nodes,
  List<Connection>? connections,
}) : _viewport = Observable(
       initialViewport ?? const GraphViewport(x: 0, y: 0, zoom: 1.0),
     ),
     _config = config ?? NodeFlowConfig.defaultConfig {
  // Initialize actions and shortcuts system
  shortcuts = NodeFlowShortcutManager<T>();
  shortcuts.registerActions(DefaultNodeFlowActions.createDefaultActions<T>());

  // Setup node monitoring reactions (for GroupNode tracking)
  _setupNodeMonitoringReactions();

  // Setup selection change reactions
  _setupSelectionReactions();

  // NOTE: Spatial index reactions are NOT set up here.
  // They are deferred to _initController() because the spatial index requires
  // callbacks (portSizeResolver, nodeShapeBuilder) that are set by the
  // editor widget. If reactions fire before callbacks are set, ports
  // will be indexed with incorrect bounds causing hit testing to fail.
  //
  // The canonical initialization point is _initController() in editor_init_api.dart.
  // That method sets up: theme, node shape builder, spatial index callbacks,
  // connection painter, hit testers, reactions, and initializes loaded nodes.

  // Load initial nodes and connections if provided
  if (nodes != null && nodes.isNotEmpty) {
    _loadInitialGraph(nodes, connections ?? const []);
  }
}