Crate iced_nodegraph

Crate iced_nodegraph 

Source
Expand description

§iced_nodegraph

A high-performance node graph editor widget for the Iced GUI framework, featuring SDF-based rendering and type-safe coordinate transformations.

§Features

  • Nodes - Draggable containers for your custom widgets
  • Pins - Connection points on nodes with type checking and visual feedback
  • Edges - Connect pins to build data flow graphs with type-safe PinReference
  • Interactive Connections - Drag to connect, click edges to re-route (cable-like unplugging)
  • Selection - Multi-select with box selection, clone (Ctrl+D), delete (Delete key)
  • Zoom & Pan - Smooth infinite canvas navigation with Camera2D
  • GPU Rendering - High-performance visualization with custom WGPU shaders
  • Smooth Animations - Monitor-synchronized pin pulsing and transitions
  • Theme Support - Integrates with Iced’s theming system

§Quick Start

use iced_nodegraph::{NodeGraph, PinRef, node_graph};
use iced::{Element, Theme, Point};
use iced::widget::text;
use iced_wgpu::Renderer;

#[derive(Debug, Clone)]
enum Message {
    EdgeConnected { from: PinRef<usize, usize>, to: PinRef<usize, usize> },
    NodeMoved { node_id: usize, position: Point },
}

fn view(edges: &[(PinRef<usize, usize>, PinRef<usize, usize>)]) -> Element<'_, Message, Theme, Renderer> {
    let mut ng = node_graph()
        .on_connect(|from, to| Message::EdgeConnected { from, to })
        .on_move(|node_id, position| Message::NodeMoved { node_id, position });

    // Add nodes with IDs
    ng.push_node(0, Point::new(100.0, 100.0), text("Node A"));
    ng.push_node(1, Point::new(300.0, 100.0), text("Node B"));

    // Add edges using type-safe PinRef
    for (from, to) in edges {
        ng.push_edge(*from, *to);
    }

    ng.into()
}

§Core Types

§PinReference

Type-safe identifier for pin connections:

use iced_nodegraph::PinReference;

let pin = PinReference::new(0, 1); // node 0, pin 1
assert_eq!(pin.node_id, 0);
assert_eq!(pin.pin_id, 1);

§NodeGraphEvent

Unified event enum for all graph interactions:

  • EdgeConnected / EdgeDisconnected - Connection changes
  • NodeMoved / GroupMoved - Position changes
  • SelectionChanged - Selection updates
  • CloneRequested / DeleteRequested - Edit operations

§Camera2D

Programmatic access to zoom and pan state.

§Demonstration Projects

§hello_world

Basic node graph with command palette:

  • Node creation and positioning
  • Pin connections with type colors
  • Camera controls (pan/zoom)
  • Theme switching with live preview
  • Email processing workflow example
cargo run -p demo_hello_world

§styling

Visual customization showcase:

  • Custom node styles (colors, borders, opacity)
  • Live style controls with sliders
  • Preset styles (Input, Process, Output, Comment)
  • Theme switching
cargo run -p demo_styling

§500_nodes

Performance benchmark with 500+ nodes:

  • Procedural shader graph generation
  • Stress tests GPU rendering pipeline
  • Multiple node types and connection patterns
cargo run -p demo_500_nodes

§shader_editor

Visual WGSL shader editor:

  • Math, Vector, Color, Texture nodes
  • Real-time shader compilation
  • Command palette for node spawning
cargo run -p demo_shader_editor

§Platform Support

§Native (Windows, macOS, Linux)

Full WGPU with custom shaders for high-performance rendering.

§WebAssembly (Browser)

WebGPU acceleration with fallback to WebGL where needed.

§Architecture

§Coordinate System

The widget uses two distinct coordinate spaces with compile-time type safety via the euclid crate:

  • Screen Space - Pixel coordinates from user input (mouse, viewport)
  • World Space - Virtual infinite canvas where nodes exist

Transformations use mathematically consistent formulas:

  • Screen -> World: world = screen / zoom - position
  • World -> Screen: screen = (world + position) * zoom
  • Zoom at Cursor: new_pos = old_pos + cursor_screen * (1/new_zoom - 1/old_zoom)

See Camera2D for implementation details and comprehensive test coverage.

§Custom Rendering

Uses WGPU shaders for high-performance rendering:

  • Background/Foreground layers for proper rendering order
  • GPU-accelerated with custom vertex/fragment shaders
  • Cross-platform support (native WGPU + WebGPU)

§Interaction

ActionInput
Pan canvasMiddle mouse drag
ZoomMouse wheel (maintains cursor position)
Connect pinsLeft-click source pin, drag to target
Re-route edgeClick on edge endpoint to unplug
Move nodeLeft-click and drag node
Box selectLeft-click on empty space, drag
Clone selectionCtrl+D
Delete selectionDelete key
Add to selectionShift+click

§Plug Behavior

Edge connections behave like physical plugs:

  • Snap: When dragging an edge close to a compatible pin, it “snaps” and EdgeConnected fires immediately (not on mouse release)
  • Unsnap: Moving away from the snapped pin fires EdgeDisconnected
  • Release: Releasing the mouse while snapped keeps the connection; releasing while not snapped discards the drag

§State Query Methods

let graph: NodeGraph = ...;

// Query graph state
let count = graph.node_count();
let edges = graph.edge_count();
let pos = graph.node_position(0); // Option<Point>

// Iterate edges
for (from, to, style) in graph.edges() {
    println!("Edge: {:?} -> {:?}", from, to);
}

Re-exports§

pub use content::NodeContentStyle;
pub use content::node_header;
pub use content::simple_node;
pub use helpers::CloneResult;
pub use helpers::DeleteResult;
pub use helpers::NodeHandle;
pub use helpers::PinHandle;
pub use helpers::SelectionHelper;
pub use helpers::clone_nodes;
pub use helpers::delete_nodes;
pub use ids::EdgeId;
pub use ids::IdMap;
pub use ids::IdMaps;
pub use ids::NodeId;
pub use ids::PinId;
pub use style::EdgeConfig;
pub use style::EdgeCurve;
pub use style::EdgeStyle;
pub use style::EdgeStyleFn;
pub use style::EdgeBorder;
pub use style::EdgeShadow;
pub use style::GraphConfig;
pub use style::GraphStyle;
pub use style::NodeBorder;
pub use style::NodeConfig;
pub use style::NodeShadow;
pub use style::NodeStyle;
pub use style::NodeStyleFn;
pub use style::PinConfig;
pub use style::PinShape;
pub use style::PinStatus;
pub use style::PinStyle;
pub use style::PinStyleFn;
pub use style::STANDARD_THEMES;
pub use style::EdgeStatus;
pub use style::NodeStatus;
pub use style::SelectionConfig;
pub use style::SelectionStyle;
pub use style::ShadowConfig;
pub use style::is_dark_theme;
pub use style::relative_luminance;
pub use style::theme_name;
pub use iced;

Modules§

content
Node content styling helpers.
helpers
Helper utilities for common node graph operations.
ids
Generic ID types for user-defined node, pin, and edge identification.
prelude
Convenience re-exports for common usage.
style
Style definitions for NodeGraph visual customization.

Macros§

pin
Macro for creating pins with concise syntax.

Structs§

Camera2D
NodeGraph
Node graph widget with generic ID types.
NodePin
A transparent wrapper used as a marker within NodeGraph.
Pattern
Pattern configuration for SDF rendering.
PinRef
Generic pin reference with user-defined ID types.
PinReference
A reference to a specific pin on a specific node.
SdfDebug
Per-layer SDF tile debug toggles.

Enums§

NodeGraphEvent
Events emitted by the NodeGraph widget.
NodeGraphMessage
Generic message enum for graph interactions with user-defined ID types.
PinDirection
Direction of data flow for a pin.
PinSide
Which side of a node this pin attaches to. Determines the tangent direction for edge bezier curves.
SdfPatternType
Pattern type for stroke rendering.

Functions§

node_graph
Creates a new NodeGraph with default usize-based IDs.
node_pin