iced_nodegraph

A node graph editor widget for iced

crates.io 0.5.0

Styling

Node, edge and pin styles are flat concrete structs. Override individual fields with struct-update over a theme-derived default, inside a .style() closure that also receives the element's status:

use iced::{widget::text, Color, Point};
use iced_nodegraph::{ColorQuad, Indexed, Node, NodeStyle, default_node_style, node};

let n: Node<'_, Indexed, Message, iced::Theme, iced::Renderer> = node(0, pos, body).style(|theme, status| NodeStyle {
    fill_color: ColorQuad::solid(Color::from_rgb(0.2, 0.3, 0.5)),
    ..default_node_style(theme, status)
});

The presets have the same shape as the defaults, so they drop straight into .style(..): NodeStyle::input, NodeStyle::process, NodeStyle::output, NodeStyle::comment; EdgeStyle::error, EdgeStyle::disabled, EdgeStyle::highlighted, EdgeStyle::data_flow, EdgeStyle::debug. All derive from the theme's palette, like iced's own button::success.

Pattern (re-exported from iced_nodegraph_sdf) controls every stroke: Pattern::solid(width), Pattern::dashed(width, dash, gap), Pattern::dotted(spacing, radius), plus .flow(speed) to animate it along the stroke. An animated pattern self-drives redraws - no host frame loop needed.

The style closure intentionally does not receive the node id: your view loop already has it, along with any per-node status. Derive the status there and capture it:

use iced::{widget::text, Point};
use iced_nodegraph::{NodeStyle, Pattern, default_node_style, node, node_graph};

let ng = node_graph::<Message, iced::Theme, iced::Renderer>().nodes(nodes.iter().map(|n| {
    let working = is_working(n.id);
    node(n.id, n.pos, text("body")).style(move |theme, status| {
        let base = default_node_style(theme, status);
        if working {
            NodeStyle { border_pattern: Pattern::dashed(2.0, 6.0, 4.0).flow(40.0), ..base }
        } else {
            base
        }
    })
}));

The chrome the widget draws itself follows the same closure-plus-default shape, one type per thing: GraphStyle (canvas background and tiling) via graph_style, SelectionBoxStyle via selection_box_style, CuttingToolStyle via cutting_tool_style, ParticleStyle via Particle::style, and MinimapStyle via minimap_style for the overview minimap puts in a corner. A selected node's look is not chrome - it comes from the node's own closure through NodeStatus.

Demo: styling
The styling demo: four preset-styled nodes with routing anchors and the style control panel
Stored image of the styling scene.