Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

GraphTokens

Layer: graph · Path: src/graph/tokens.rs · Exports: GraphTokens

The single resolve point for everything the graph layer paints. A flat Copy struct of the exact resolved paint values (grid, edge, handle, selection, marquee, minimap), built from a Theme (colors) and core (geometry). It mirrors the ButtonTokens pattern: the paint-tier modules (grid, edge, handle, …) read from a resolved GraphTokens instead of touching Theme fields or core colors ad-hoc — which keeps the no_raw_values guard green and gives one place to retune the graph’s look.

Design

  • Purpose / when to use. Resolve once per frame at the top of GraphView::show and thread the value through the paint helpers. Read it inside the emit closure via GraphCtx::tokens(). Never read Theme/core directly in graph paint code — go through GraphTokens.
  • Anatomy. A #[derive(Clone, Copy, Debug)] struct of 17 leaf fields in six groups (grid / edges / handles / node selection / marquee / minimap). No nested structs, no methods beyond the two constructors.
  • Color vs geometry split. Every color is a pure Theme token; every size/radius/width is a core::* constant. The one synthesized value is marquee_fill, the focus ring re-tinted translucent via core::tint(theme.ring, core::MARQUEE_ALPHA).

Field → source map

Background grid

FieldTypeSource
grid_dotColor32theme.border
grid_dot_radiusf32core::GRID_DOT_RADIUS
grid_spacingf32core::GRID_SPACING

Edges (wires)

FieldTypeSource
edgeColor32theme.muted_foreground
edge_hoverColor32theme.primary
edge_selectedColor32theme.ring
edge_widthf32core::EDGE_WIDTH
edge_hit_radiusf32core::EDGE_HIT_RADIUS

Handles (ports)

FieldTypeSource
handle_fillColor32theme.primary
handle_borderColor32theme.border_strong
handle_radiusf32core::HANDLE_RADIUS
handle_hit_radiusf32core::HANDLE_RADIUS * 2.0

Node selection

FieldTypeSource
node_selected_ringColor32theme.ring

Box-select marquee

FieldTypeSource
marquee_fillColor32core::tint(theme.ring, core::MARQUEE_ALPHA) (translucent ring)
marquee_borderColor32theme.ring

Minimap

FieldTypeSource
minimap_nodeColor32theme.muted_foreground
minimap_viewColor32theme.ring

API

MethodSignatureEffect
resolvefn resolve(theme: &Theme) -> SelfMap a Theme (+ core geometry) onto all paint values.
getfn get(ui: &egui::Ui) -> SelfConvenience: resolve straight from the theme installed in ui (Self::resolve(&Theme::get(ui))).

All fields are public and the struct is Copy, so pass it by value freely.

Usage

#![allow(unused)]
fn main() {
use ouroboros_ui::graph::GraphTokens;

// Resolve once (the canvas does this internally each frame):
let gt = GraphTokens::get(ui);            // or GraphTokens::resolve(&theme);

// Paint-tier helper reading resolved values:
painter.circle_filled(handle_pos, gt.handle_radius, gt.handle_fill);
painter.line_segment([a, b], egui::Stroke::new(gt.edge_width, gt.edge_selected));

// Inside the GraphView::show closure:
GraphView::new("g").show(ui, |g| {
    let t = g.tokens();
    let hit = t.edge_hit_radius / g.scale().max(f32::EPSILON); // screen-px hit → world
    // ...
});
}

Composition / Notes

  • Two tiers, one token source. Both the paint tier (viewport/grid/edge/handle/resizer) and the compose tier (node/controls/minimap) draw only through GraphTokens (colors) and core::* (sizes). This is the layer invariant: graph is the one place outside atoms that paints, but every value still flows through a token.
  • Hit radii vs draw radii. handle_hit_radius is the draw radius; edge_hit_radius is a screen-px grab distance that callers divide by zoom to test in world space.
  • Retuning. Change the graph’s look in exactly one place — GraphTokens::resolve. Adding a new paint value means a new field here plus its core/Theme source, never a literal in a paint module.
  • Foundation: tokens · theming · architecture · guards. Layer overview: README.