dasImguiNodeEditor documentation Logo
2.0

Contents

  • dasImguiNodeEditor tutorials
    • First graph
      • Walkthrough
        • EditorContext
        • Nodes and pins
        • Links
    • Connecting by drag
      • Walkthrough
        • The create scope
        • Driving it from a test
    • Deleting & selection
      • Walkthrough
        • The delete scope
        • The cascade
        • Driving the delete
    • Context menus
      • Walkthrough
        • The suspend island
        • Which menu fired
        • Driving it from a test
    • Create by drag
      • Walkthrough
        • The create scope
        • The auto-connect
        • Driving it from a test
    • Clipboard
      • Walkthrough
        • The app owns the clipboard
        • Flag now, act later
        • Driving it from a test
    • Styling
      • Walkthrough
        • Canvas theme
        • Per-node tint
        • Scoped style var + color
        • Pin pivots
        • Background draw list
    • Groups
      • Walkthrough
        • A group is a node
        • Membership is spatial
        • Editor-owned geometry
        • The zoomed-out label
    • Navigation
      • Walkthrough
        • Two view ops and one node move
        • Placement: inside vs outside the block
        • Driving it from a test
  • dasImguiNodeEditor v2.0
    • 1. Boost v2 — the node-editor DSL
      • 1.1. Boost v2 — the node-editor DSL: graph entities, link/delete queues, selection, context menus, shortcuts, styling
        • 1.1.1. Type aliases
        • 1.1.2. Call macros
        • 1.1.3. Editor lifecycle
        • 1.1.4. Node geometry & view
        • 1.1.5. Selection
        • 1.1.6. Link creation
        • 1.1.7. Item deletion
        • 1.1.8. Context menus
        • 1.1.9. Clipboard & shortcuts
        • 1.1.10. Styling
        • 1.1.11. Drawing & hints
        • 1.1.12. Flow animation
    • 2. Canvas theme
      • 2.1. Canvas theme — daslang-styled node-editor colors and style vars
        • 2.1.1. Canvas theme
    • 3. Testing harness
      • 3.1. App harness — with_node_editor_app + with_node_editor_recording_app, thin node-editor delegates over imgui_playwright’s with_imgui_app / with_recording_app
        • 3.1.1. App harness
      • 3.2. Editor playwright — node-editor-aware test layer over imgui_playwright (EditorSession + ne_* helpers)
        • 3.2.1. Structures
        • 3.2.2. Session
        • 3.2.3. Actions
        • 3.2.4. Snapshots & queries
        • 3.2.5. Polling / await
    • 4. Live commands
    • 5. Consumer lint
    • 6. External types
      • 6.1. Node / pin / link ids
      • 6.2. imgui_node_editor::EditorContext
      • 6.3. imgui_node_editor::PinKind
      • 6.4. imgui_node_editor::FlowDirection
      • 6.5. imgui_node_editor::StyleColor
      • 6.6. imgui_node_editor::StyleVar
      • 6.7. imgui::ImDrawList
      • 6.8. imgui_playwright::ImguiApp
dasImguiNodeEditor documentation
  • dasImguiNodeEditor v2.0
  • 1. Boost v2 — the node-editor DSL
  • 1.1. Boost v2 — the node-editor DSL: graph entities, link/delete queues, selection, context menus, shortcuts, styling
  • Edit on GitHub

1.1. Boost v2 — the node-editor DSL: graph entities, link/delete queues, selection, context menus, shortcuts, styling

The v2 DSL for imgui-node-editor. Every entry point is bracketed by an app-owned EditorContext? (from create_node_editor() / destroy_node_editor(ctx)) — there is no singleton, so one app can drive N editors. intptr(ctx) is the stable handle that crosses the live / JSON boundary; handle_to_editor(handle) reinterprets it back.

The four graph entities are forward_argument [widget] / [container] macros keyed by a runtime integer id (not a state struct), so the app models its graph however it likes — the editor only needs the ids:

node_editor(ctx, "shader_graph") <| {
    for (n in graph.nodes) {
        node(n.id) <| {
            text(n.title)
            pin(n.in_pin,  PinKind.Input)  <| { text("in") }
            pin(n.out_pin, PinKind.Output) <| { text("out") }
        }
    }
    for (l in graph.links) {
        link(l.id, l.from_pin, l.to_pin)
    }
}

Entities register lazily under nested telemetry paths (MAIN_WIN/<editor>/node_<id>/pin_<id>, link_<id>) and build their snapshot payload only when a snapshot is taken — node {id, bbox, selected}, pin {id, kind}, link {id, from_pin, to_pin, selected}. The editor owns geometry (NodeId is its internal handle; bbox comes from the canvas, seeded once via set_node_position); the app owns topology and reads it back through the create / delete events.

The function groups below cover the imperative surface: editor lifecycle, node geometry & view ops, selection, the queue-injectable link-creation and item-deletion protocols (begin_create / begin_delete plus the enqueue_* rails that replay an action through the same handler the mouse drives, so headless tests and the live UI share one path), context-menu events, clipboard & shortcut events, per-scope styling, node-background draw-list access, and one-shot flow link animation.

1.1.1. Type aliases

LinkId = int

typedef LinkId = int aka LinkId

PinId = int

typedef PinId = int aka PinId

NodeId = int

typedef NodeId = int aka NodeId

1.1.2. Call macros

link

Function annotation link

pin

Function annotation pin

node_group

Function annotation node_group

node_editor

Function annotation node_editor

node

Function annotation node

1.1.3. Editor lifecycle

  • create_node_editor () : EditorContext?

  • destroy_node_editor (ctx: EditorContext?)

  • handle_to_editor (handle: uint64) : EditorContext?

  • set_node_editor_id_tracking (on: bool)

create_node_editor(): EditorContext? 

def create_node_editor () : EditorContext?

destroy_node_editor(ctx: EditorContext? )

def destroy_node_editor (ctx: EditorContext?)

Arguments:
  • ctx : EditorContext?

handle_to_editor(handle: uint64 ): EditorContext? 

def handle_to_editor (handle: uint64) : EditorContext?

Arguments:
  • handle : uint64

set_node_editor_id_tracking(on: bool )

def set_node_editor_id_tracking (on: bool)

Arguments:
  • on : bool

1.1.4. Node geometry & view

  • center_node_on_screen (ctx: EditorContext?; id: NodeId) : bool

  • get_node_position (ctx: EditorContext?; id: NodeId) : float2

  • get_ordered_node_ids (ctx: EditorContext?) : array<NodeId>

  • navigate_to_selection (ctx: EditorContext?; zoom_in: bool = false; duration: float = -1f) : bool

  • restore_node_state (ctx: EditorContext?; id: NodeId) : bool

  • set_group_size (ctx: EditorContext?; id: NodeId; size: float2) : bool

  • set_node_position (ctx: EditorContext?; id: NodeId; pos: float2) : bool

  • set_node_z_position (ctx: EditorContext?; id: NodeId; z: float) : bool

center_node_on_screen(ctx: EditorContext?; id: NodeId ): bool 

def center_node_on_screen (ctx: EditorContext?; id: NodeId) : bool

Arguments:
  • ctx : EditorContext?

  • id : NodeId

get_node_position(ctx: EditorContext?; id: NodeId ): float2 

def get_node_position (ctx: EditorContext?; id: NodeId) : float2

Arguments:
  • ctx : EditorContext?

  • id : NodeId

get_ordered_node_ids(ctx: EditorContext? ): array<NodeId> 

def get_ordered_node_ids (ctx: EditorContext?) : array<NodeId>

Arguments:
  • ctx : EditorContext?

navigate_to_selection(ctx: EditorContext?; zoom_in: bool = false; duration: float = -1f ): bool 

def navigate_to_selection (ctx: EditorContext?; zoom_in: bool = false; duration: float = -1f) : bool

Arguments:
  • ctx : EditorContext?

  • zoom_in : bool

  • duration : float

restore_node_state(ctx: EditorContext?; id: NodeId ): bool 

def restore_node_state (ctx: EditorContext?; id: NodeId) : bool

Arguments:
  • ctx : EditorContext?

  • id : NodeId

set_group_size(ctx: EditorContext?; id: NodeId; size: float2 ): bool 

def set_group_size (ctx: EditorContext?; id: NodeId; size: float2) : bool

Arguments:
  • ctx : EditorContext?

  • id : NodeId

  • size : float2

set_node_position(ctx: EditorContext?; id: NodeId; pos: float2 ): bool 

def set_node_position (ctx: EditorContext?; id: NodeId; pos: float2) : bool

Arguments:
  • ctx : EditorContext?

  • id : NodeId

  • pos : float2

set_node_z_position(ctx: EditorContext?; id: NodeId; z: float ): bool 

def set_node_z_position (ctx: EditorContext?; id: NodeId; z: float) : bool

Arguments:
  • ctx : EditorContext?

  • id : NodeId

  • z : float

1.1.5. Selection

  • clear_selection (ctx: EditorContext?)

  • get_action_context_links (ctx: EditorContext?) : array<LinkId>

  • get_action_context_nodes (ctx: EditorContext?) : array<NodeId>

  • get_selected_links (ctx: EditorContext?) : array<LinkId>

  • get_selected_nodes (ctx: EditorContext?) : array<NodeId>

  • select_link (ctx: EditorContext?; id: LinkId; on: bool)

  • select_node (ctx: EditorContext?; id: NodeId; on: bool)

clear_selection(ctx: EditorContext? )

def clear_selection (ctx: EditorContext?)

Arguments:
  • ctx : EditorContext?

get_action_context_links(ctx: EditorContext? ): array<LinkId> 

def get_action_context_links (ctx: EditorContext?) : array<LinkId>

Arguments:
  • ctx : EditorContext?

get_action_context_nodes(ctx: EditorContext? ): array<NodeId> 

def get_action_context_nodes (ctx: EditorContext?) : array<NodeId>

Arguments:
  • ctx : EditorContext?

get_selected_links(ctx: EditorContext? ): array<LinkId> 

def get_selected_links (ctx: EditorContext?) : array<LinkId>

Arguments:
  • ctx : EditorContext?

get_selected_nodes(ctx: EditorContext? ): array<NodeId> 

def get_selected_nodes (ctx: EditorContext?) : array<NodeId>

Arguments:
  • ctx : EditorContext?

select_link(ctx: EditorContext?; id: LinkId; on: bool )

def select_link (ctx: EditorContext?; id: LinkId; on: bool)

Arguments:
  • ctx : EditorContext?

  • id : LinkId

  • on : bool

select_node(ctx: EditorContext?; id: NodeId; on: bool )

def select_node (ctx: EditorContext?; id: NodeId; on: bool)

Arguments:
  • ctx : EditorContext?

  • id : NodeId

  • on : bool

1.1.6. Link creation

  • accept_new_item (ctx: EditorContext?) : bool

  • begin_create (ctx: EditorContext?; blk: block<():void>)

  • clear_pending_links (ctx: EditorContext?)

  • enqueue_new_link (ctx: EditorContext?; from: PinId; to: PinId) : bool

  • enqueue_new_node_drag (ctx: EditorContext?; from_pin: PinId; pos: float2) : bool

  • query_new_link (ctx: EditorContext?; var from_pin: PinId; var to_pin: PinId) : bool

  • reject_new_item (ctx: EditorContext?)

  • show_new_node_drag (ctx: EditorContext?; var from_pin: PinId; var drop_pos: float2&) : bool

accept_new_item(ctx: EditorContext? ): bool 

def accept_new_item (ctx: EditorContext?) : bool

Arguments:
  • ctx : EditorContext?

begin_create(ctx: EditorContext?; blk: block<():void> )

def begin_create (ctx: EditorContext?; blk: block<():void>)

Arguments:
  • ctx : EditorContext?

  • blk : block<void>

clear_pending_links(ctx: EditorContext? )

def clear_pending_links (ctx: EditorContext?)

Arguments:
  • ctx : EditorContext?

enqueue_new_link(ctx: EditorContext?; from: PinId; to: PinId ): bool 

def enqueue_new_link (ctx: EditorContext?; from: PinId; to: PinId) : bool

Arguments:
  • ctx : EditorContext?

  • from : PinId

  • to : PinId

enqueue_new_node_drag(ctx: EditorContext?; from_pin: PinId; pos: float2 ): bool 

def enqueue_new_node_drag (ctx: EditorContext?; from_pin: PinId; pos: float2) : bool

Arguments:
  • ctx : EditorContext?

  • from_pin : PinId

  • pos : float2

query_new_link(ctx: EditorContext?; from_pin: PinId; to_pin: PinId ): bool 

def query_new_link (ctx: EditorContext?; var from_pin: PinId; var to_pin: PinId) : bool

Arguments:
  • ctx : EditorContext?

  • from_pin : PinId

  • to_pin : PinId

reject_new_item(ctx: EditorContext? )

def reject_new_item (ctx: EditorContext?)

Arguments:
  • ctx : EditorContext?

show_new_node_drag(ctx: EditorContext?; from_pin: PinId; drop_pos: float2& ): bool 

def show_new_node_drag (ctx: EditorContext?; var from_pin: PinId; var drop_pos: float2&) : bool

Arguments:
  • ctx : EditorContext?

  • from_pin : PinId

  • drop_pos : float2&

1.1.7. Item deletion

  • accept_deleted_link (ctx: EditorContext?) : bool

  • accept_deleted_node (ctx: EditorContext?; delete_dependencies: bool = true) : bool

  • begin_delete (ctx: EditorContext?; blk: block<():void>)

  • clear_pending_deletes (ctx: EditorContext?)

  • enqueue_delete_link (ctx: EditorContext?; id: LinkId) : bool

  • enqueue_delete_node (ctx: EditorContext?; id: NodeId) : bool

  • query_deleted_link (ctx: EditorContext?; var lid: LinkId) : bool

  • query_deleted_node (ctx: EditorContext?; var nid: NodeId) : bool

  • reject_deleted_link (ctx: EditorContext?)

  • reject_deleted_node (ctx: EditorContext?)

accept_deleted_link(ctx: EditorContext? ): bool 

def accept_deleted_link (ctx: EditorContext?) : bool

Arguments:
  • ctx : EditorContext?

accept_deleted_node(ctx: EditorContext?; delete_dependencies: bool = true ): bool 

def accept_deleted_node (ctx: EditorContext?; delete_dependencies: bool = true) : bool

Arguments:
  • ctx : EditorContext?

  • delete_dependencies : bool

begin_delete(ctx: EditorContext?; blk: block<():void> )

def begin_delete (ctx: EditorContext?; blk: block<():void>)

Arguments:
  • ctx : EditorContext?

  • blk : block<void>

clear_pending_deletes(ctx: EditorContext? )

def clear_pending_deletes (ctx: EditorContext?)

Arguments:
  • ctx : EditorContext?

enqueue_delete_link(ctx: EditorContext?; id: LinkId ): bool 

def enqueue_delete_link (ctx: EditorContext?; id: LinkId) : bool

Arguments:
  • ctx : EditorContext?

  • id : LinkId

enqueue_delete_node(ctx: EditorContext?; id: NodeId ): bool 

def enqueue_delete_node (ctx: EditorContext?; id: NodeId) : bool

Arguments:
  • ctx : EditorContext?

  • id : NodeId

query_deleted_link(ctx: EditorContext?; lid: LinkId ): bool 

def query_deleted_link (ctx: EditorContext?; var lid: LinkId) : bool

Arguments:
  • ctx : EditorContext?

  • lid : LinkId

query_deleted_node(ctx: EditorContext?; nid: NodeId ): bool 

def query_deleted_node (ctx: EditorContext?; var nid: NodeId) : bool

Arguments:
  • ctx : EditorContext?

  • nid : NodeId

reject_deleted_link(ctx: EditorContext? )

def reject_deleted_link (ctx: EditorContext?)

Arguments:
  • ctx : EditorContext?

reject_deleted_node(ctx: EditorContext? )

def reject_deleted_node (ctx: EditorContext?)

Arguments:
  • ctx : EditorContext?

1.1.8. Context menus

  • show_background_context_menu (ctx: EditorContext?; var canvas_pos: float2&) : bool

  • show_link_context_menu (ctx: EditorContext?; var lid: LinkId) : bool

  • show_node_context_menu (ctx: EditorContext?; var nid: NodeId) : bool

  • show_pin_context_menu (ctx: EditorContext?; var pid: PinId) : bool

  • with_suspended (blk: block<():void>)

show_background_context_menu(ctx: EditorContext?; canvas_pos: float2& ): bool 

def show_background_context_menu (ctx: EditorContext?; var canvas_pos: float2&) : bool

Arguments:
  • ctx : EditorContext?

  • canvas_pos : float2&

show_link_context_menu(ctx: EditorContext?; lid: LinkId ): bool 

def show_link_context_menu (ctx: EditorContext?; var lid: LinkId) : bool

Arguments:
  • ctx : EditorContext?

  • lid : LinkId

show_node_context_menu(ctx: EditorContext?; nid: NodeId ): bool 

def show_node_context_menu (ctx: EditorContext?; var nid: NodeId) : bool

Arguments:
  • ctx : EditorContext?

  • nid : NodeId

show_pin_context_menu(ctx: EditorContext?; pid: PinId ): bool 

def show_pin_context_menu (ctx: EditorContext?; var pid: PinId) : bool

Arguments:
  • ctx : EditorContext?

  • pid : PinId

with_suspended(blk: block<():void> )

def with_suspended (blk: block<():void>)

Arguments:
  • blk : block<void>

1.1.9. Clipboard & shortcuts

  • accept_copy (ctx: EditorContext?) : bool

  • accept_create_node (ctx: EditorContext?) : bool

  • accept_cut (ctx: EditorContext?) : bool

  • accept_duplicate (ctx: EditorContext?) : bool

  • accept_paste (ctx: EditorContext?) : bool

  • clear_pending_shortcuts (ctx: EditorContext?)

  • enable_shortcuts (ctx: EditorContext?; on: bool) : bool

  • enqueue_shortcut (ctx: EditorContext?; kind: string) : bool

  • with_shortcuts (ctx: EditorContext?; blk: block<():void>)

accept_copy(ctx: EditorContext? ): bool 

def accept_copy (ctx: EditorContext?) : bool

Arguments:
  • ctx : EditorContext?

accept_create_node(ctx: EditorContext? ): bool 

def accept_create_node (ctx: EditorContext?) : bool

Arguments:
  • ctx : EditorContext?

accept_cut(ctx: EditorContext? ): bool 

def accept_cut (ctx: EditorContext?) : bool

Arguments:
  • ctx : EditorContext?

accept_duplicate(ctx: EditorContext? ): bool 

def accept_duplicate (ctx: EditorContext?) : bool

Arguments:
  • ctx : EditorContext?

accept_paste(ctx: EditorContext? ): bool 

def accept_paste (ctx: EditorContext?) : bool

Arguments:
  • ctx : EditorContext?

clear_pending_shortcuts(ctx: EditorContext? )

def clear_pending_shortcuts (ctx: EditorContext?)

Arguments:
  • ctx : EditorContext?

enable_shortcuts(ctx: EditorContext?; on: bool ): bool 

def enable_shortcuts (ctx: EditorContext?; on: bool) : bool

Arguments:
  • ctx : EditorContext?

  • on : bool

enqueue_shortcut(ctx: EditorContext?; kind: string ): bool 

def enqueue_shortcut (ctx: EditorContext?; kind: string) : bool

Arguments:
  • ctx : EditorContext?

  • kind : string

with_shortcuts(ctx: EditorContext?; blk: block<():void> )

def with_shortcuts (ctx: EditorContext?; blk: block<():void>)

Arguments:
  • ctx : EditorContext?

  • blk : block<void>

1.1.10. Styling

  • with_style_color (style_color: StyleColor; color: float4; blk: block<():void>)

  • with_style_var (style_var: StyleVar; value: float2; blk: block<():void>)

  • with_style_var (style_var: StyleVar; value: float4; blk: block<():void>)

  • with_style_var (style_var: StyleVar; value: float; blk: block<():void>)

with_style_color(style_color: StyleColor; color: float4; blk: block<():void> )

def with_style_color (style_color: StyleColor; color: float4; blk: block<():void>)

Arguments:
  • style_color : StyleColor

  • color : float4

  • blk : block<void>

1.1.10.1. with_style_var

with_style_var(style_var: StyleVar; value: float2; blk: block<():void> )

def with_style_var (style_var: StyleVar; value: float2; blk: block<():void>)

Arguments:
  • style_var : StyleVar

  • value : float2

  • blk : block<void>

with_style_var(style_var: StyleVar; value: float4; blk: block<():void> )
with_style_var(style_var: StyleVar; value: float; blk: block<():void> )

1.1.11. Drawing & hints

  • group_hint (id: NodeId; blk: block<(var fg:ImDrawList?;var bg:ImDrawList?):void>) : bool

  • with_node_background_drawlist (id: NodeId; blk: block<(var dl:ImDrawList?):void>)

group_hint(id: NodeId; blk: block<(var fg:ImDrawList?;var bg:ImDrawList?):void> ): bool 

def group_hint (id: NodeId; blk: block<(var fg:ImDrawList?;var bg:ImDrawList?):void>) : bool

Arguments:
  • id : NodeId

  • blk : block<(fg: ImDrawList?;bg: ImDrawList?):void>

with_node_background_drawlist(id: NodeId; blk: block<(var dl:ImDrawList?):void> )

def with_node_background_drawlist (id: NodeId; blk: block<(var dl:ImDrawList?):void>)

Arguments:
  • id : NodeId

  • blk : block<(dl: ImDrawList?):void>

1.1.12. Flow animation

  • flow (ctx: EditorContext?; link_id: LinkId; dir: FlowDirection = imgui_node_editor::FlowDirection.Forward) : bool

flow(ctx: EditorContext?; link_id: LinkId; dir: FlowDirection = imgui_node_editor::FlowDirection.Forward ): bool 

def flow (ctx: EditorContext?; link_id: LinkId; dir: FlowDirection = imgui_node_editor::FlowDirection.Forward) : bool

Arguments:
  • ctx : EditorContext?

  • link_id : LinkId

  • dir : FlowDirection

Previous Next

© Copyright 2026-2026, Gaijin Entertainment.

Built with Sphinx using a theme provided by Read the Docs.