.. _stdlib_imgui_boost_runtime: ================================================================ Boost runtime — widget state structs, registry, and dispatcher ================================================================ .. das:module:: imgui_boost_runtime Runtime support layer for the ``[widget]`` / ``[container]`` macros: the per-kind state structs, the per-frame widget registry, the ``imgui_*`` live-command dispatcher, and the AwaitModifiers / Result framing that lets clients drive ImGui from outside the GLFW main thread. Widget state structs mix ``@live`` fields (preserved across hot-reload) and ``@optional`` fields (transient, dropped from JV when zero-valued). Common per-frame ImGui state — ``hex_id``, bbox, hover / active / focus — lives in :ref:`WidgetEntry `, not the per-kind structs, so each state struct stays small. The live-command surface (``imgui_snapshot``, ``imgui_click``, ``imgui_set``, ``imgui_open``, ``imgui_close``, ``imgui_focus``, ``imgui_await``, ``imgui_drag``, ``imgui_type_text``) is the wire-protocol that ``imgui_playwright`` and external test harnesses drive. Commands resolve targets via the registry's path key (e.g. ``MAIN_WIN/SETTINGS_TAB/RPS``) or raw ``0x``; results carry an :ref:`AwaitResult ` whose ``await_*`` modifiers tell the client to wait for quiescence or a specific frame number before reading the response. ++++++++++ Structures ++++++++++ .. _struct-imgui_boost_runtime-ClickState: .. das:attribute:: ClickState :Fields: * **click_count** : int - cumulative across reloads * **pending_click** : bool - queued by imgui_click L2; consumed next frame * **clicked** : bool - true on the frame the button fired .. _struct-imgui_boost_runtime-SliderStateFloat: .. das:attribute:: SliderStateFloat :Fields: * **value** : float - preserved across reload * **bounds** : tuple - (min, max) * **has_pending** : bool - imgui_set L3 sets; render fn consumes * **pending_value** : float - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-SliderStateFloat2: .. das:attribute:: SliderStateFloat2 :Fields: * **value** : float2 - preserved across reload * **bounds** : tuple - (min, max) applied to every component * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : float2 - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-SliderStateFloat3: .. das:attribute:: SliderStateFloat3 :Fields: * **value** : float3 - preserved across reload * **bounds** : tuple - (min, max) applied to every component * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : float3 - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-SliderStateFloat4: .. das:attribute:: SliderStateFloat4 :Fields: * **value** : float4 - preserved across reload * **bounds** : tuple - (min, max) applied to every component * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : float4 - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-SliderStateInt: .. das:attribute:: SliderStateInt :Fields: * **value** : int - preserved across reload * **bounds** : tuple - (min, max) * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : int - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-SliderStateInt2: .. das:attribute:: SliderStateInt2 :Fields: * **value** : int2 - preserved across reload * **bounds** : tuple - (min, max) applied to every component * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : int2 - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-SliderStateInt3: .. das:attribute:: SliderStateInt3 :Fields: * **value** : int3 - preserved across reload * **bounds** : tuple - (min, max) applied to every component * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : int3 - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-SliderStateInt4: .. das:attribute:: SliderStateInt4 :Fields: * **value** : int4 - preserved across reload * **bounds** : tuple - (min, max) applied to every component * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : int4 - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-ToggleState: .. das:attribute:: ToggleState Shared across Checkbox / RadioButton (bool form) / Selectable / MenuItem. `pending_toggle` + `pending_value` let imgui_set steer the next frame's value deterministically; the renderer consumes-then-clears. :Fields: * **value** : bool - current toggle state; preserved across reload * **pending_toggle** : bool - imgui_set L3 sets; consumed next frame * **pending_value** : bool - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-RadioIntState: .. das:attribute:: RadioIntState Backs RadioButton(int form). `value` is the currently-selected button id; the widget def takes the per-call `v_button` and writes value=v_button when the user clicks. `imgui_set {"value":N}` steers the selection. :Fields: * **value** : int - currently-selected button id * **pending_set** : bool - imgui_set queued; consumed next frame * **pending_value** : int - next-frame selection queued by imgui_set * **changed** : bool - true on the frame the selection changed .. _struct-imgui_boost_runtime-DragStateFloat: .. das:attribute:: DragStateFloat :Fields: * **value** : float - preserved across reload * **bounds** : tuple - (min, max); zero-init = unclamped * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : float - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-DragStateFloat2: .. das:attribute:: DragStateFloat2 :Fields: * **value** : float2 - preserved across reload * **bounds** : tuple - (min, max); zero-init = unclamped * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : float2 - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-DragStateFloat3: .. das:attribute:: DragStateFloat3 :Fields: * **value** : float3 - preserved across reload * **bounds** : tuple - (min, max); zero-init = unclamped * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : float3 - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-DragStateFloat4: .. das:attribute:: DragStateFloat4 :Fields: * **value** : float4 - preserved across reload * **bounds** : tuple - (min, max); zero-init = unclamped * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : float4 - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-DragStateInt: .. das:attribute:: DragStateInt :Fields: * **value** : int - preserved across reload * **bounds** : tuple - (min, max); zero-init = unclamped * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : int - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-DragStateInt2: .. das:attribute:: DragStateInt2 :Fields: * **value** : int2 - preserved across reload * **bounds** : tuple - (min, max); zero-init = unclamped * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : int2 - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-DragStateInt3: .. das:attribute:: DragStateInt3 :Fields: * **value** : int3 - preserved across reload * **bounds** : tuple - (min, max); zero-init = unclamped * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : int3 - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-DragStateInt4: .. das:attribute:: DragStateInt4 :Fields: * **value** : int4 - preserved across reload * **bounds** : tuple - (min, max); zero-init = unclamped * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : int4 - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-DragStateRangeFloat: .. das:attribute:: DragStateRangeFloat `value.x` = current_min, `value.y` = current_max. Bounds clamp both. `imgui_set {"value":[lo,hi]}` writes the whole range atomically. :Fields: * **value** : float2 - (current_min, current_max); preserved across reload * **bounds** : tuple - (min, max) clamp applied to both endpoints * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : float2 - next-frame range queued by imgui_set * **changed** : bool - true on the frame the range changed .. _struct-imgui_boost_runtime-DragStateRangeInt: .. das:attribute:: DragStateRangeInt `value.x` = current_min, `value.y` = current_max. :Fields: * **value** : int2 - (current_min, current_max); preserved across reload * **bounds** : tuple - (min, max) clamp applied to both endpoints * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : int2 - next-frame range queued by imgui_set * **changed** : bool - true on the frame the range changed .. _struct-imgui_boost_runtime-InputStateFloat: .. das:attribute:: InputStateFloat :Fields: * **value** : float - preserved across reload * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : float - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-InputStateFloat2: .. das:attribute:: InputStateFloat2 :Fields: * **value** : float2 - preserved across reload * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : float2 - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-InputStateFloat3: .. das:attribute:: InputStateFloat3 :Fields: * **value** : float3 - preserved across reload * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : float3 - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-InputStateFloat4: .. das:attribute:: InputStateFloat4 :Fields: * **value** : float4 - preserved across reload * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : float4 - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-InputStateInt: .. das:attribute:: InputStateInt :Fields: * **value** : int - preserved across reload * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : int - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-InputStateInt2: .. das:attribute:: InputStateInt2 :Fields: * **value** : int2 - preserved across reload * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : int2 - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-InputStateInt3: .. das:attribute:: InputStateInt3 :Fields: * **value** : int3 - preserved across reload * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : int3 - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-InputStateInt4: .. das:attribute:: InputStateInt4 :Fields: * **value** : int4 - preserved across reload * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : int4 - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-InputStateDouble: .. das:attribute:: InputStateDouble :Fields: * **value** : double - preserved across reload * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : double - next-frame value queued by imgui_set * **changed** : bool - true on the frame the widget fired .. _struct-imgui_boost_runtime-ColorState3: .. das:attribute:: ColorState3 :Fields: * **value** : float3 - RGB in [0..1] * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : float3 - next-frame RGB queued by imgui_set * **changed** : bool - true on the frame the color changed .. _struct-imgui_boost_runtime-ColorState4: .. das:attribute:: ColorState4 :Fields: * **value** : float4 - RGBA in [0..1] * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : float4 - next-frame RGBA queued by imgui_set * **changed** : bool - true on the frame the color changed .. _struct-imgui_boost_runtime-ComboState: .. das:attribute:: ComboState :Fields: * **value** : int = -1 - selected index, -1 = none * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : int - next-frame selection queued by imgui_set * **changed** : bool - true on the frame the selection changed * **items_buf** : array - transient zero-separated buffer; rebuilt each frame .. _struct-imgui_boost_runtime-ListBoxState: .. das:attribute:: ListBoxState :Fields: * **value** : int = -1 - selected index, -1 = none * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : int - next-frame selection queued by imgui_set * **changed** : bool - true on the frame the selection changed .. _struct-imgui_boost_runtime-InputTextState: .. das:attribute:: InputTextState :Fields: * **value** : string = "" - current text content (clone of buffer) * **capacity** : int = 256 - working buffer size in bytes (incl. trailing null) * **has_pending** : bool - imgui_set queued; consumed next frame * **pending_value** : string = "" - next-frame text queued by imgui_set * **changed** : bool - true on the frame the text changed * **buffer** : array - working buffer; mirrors `value`, allocated to capacity on first frame / post-reload .. _struct-imgui_boost_runtime-TextShowState: .. das:attribute:: TextShowState Backs the `text_show` display widget (master plan §4.3a). Read-only from the user's perspective — `value` is set either by an initializer at the call site (`text_show(STATUS, value="saved")`) or programmatically (`STATUS.value = compute_status()`). The standard serializer surfaces `value` for telemetry / playwright `expect_value(app, STATUS, "saved")`. Tests can also drive the value externally via `imgui_set` — the dispatcher writes `state.value` directly. :Fields: * **value** : string = "" - displayed text; settable via call-site initializer or imgui_set .. _struct-imgui_boost_runtime-PlotState: .. das:attribute:: PlotState Backs the `plot_lines` / `plot_histogram` display widgets. The plotted values are passed per-frame as a parameter (not stored in state) — same shape as the imgui_test_engine and daslib v1 conventions. State carries last-frame's call args for telemetry: the visible label, the (scale_min, scale_max) range, and the sample count. Read-only — no dispatcher. :Fields: * **title** : string - overlay text * **bounds** : tuple - (scale_min, scale_max) * **samples** : int - length(values) last frame .. _struct-imgui_boost_runtime-NarrativeState: .. das:attribute:: NarrativeState Backs every text-bearing narrative widget — text / text_unformatted / text_wrapped / text_colored / text_disabled / bullet_text / separator_text / set_tooltip / set_item_tooltip. The displayed string is per-call (the call site is the source of truth) and echoed into `value` every frame for telemetry. `expect_value(MSG, "literal")` works uniformly across the family. Read-only — no dispatcher. :Fields: * **value** : string - per-frame echo of call-site `text` arg .. _struct-imgui_boost_runtime-LabelTextState: .. das:attribute:: LabelTextState Backs the `label_text` display widget. ImGui's `LabelText(label, fmt)` displays the label-key on the left and the value-text on the right; both strings are per-call and echoed for telemetry. Read-only — no dispatcher. (Field is `key` not `label` — `label` is reserved in gen2.) :Fields: * **key** : string - per-frame echo of the left-side label string * **value** : string - per-frame echo of the right-side value string .. _struct-imgui_boost_runtime-EmptyMarkerState: .. das:attribute:: EmptyMarkerState Backs the stateless decoration widgets — `separator`, `spacing`, `new_line`, `dummy`, `same_line`, `bullet`. The state global exists only because [widget] auto-emit needs something to instantiate; mirrors GroupState / MenuBarState / TooltipState shape. :Fields: * **_placeholder** : bool - unused; keeps the struct non-empty for [widget] auto-emit .. _struct-imgui_boost_runtime-ImageState: .. das:attribute:: ImageState Backs the `image` display widget. Texture handle is opaque (void?), so telemetry echoes only the actionable per-call args — size, uv rectangle, tint/border colors. Read-only — no dispatcher. :Fields: * **size** : float2 - per-call display size * **uv0** : float2 - upper-left uv * **uv1** : float2 - lower-right uv * **tint_col** : float4 - tint applied to texels * **border_col** : float4 - border color (zero alpha = no border) .. _struct-imgui_boost_runtime-ProgressBarState: .. das:attribute:: ProgressBarState Backs the `progress_bar` display widget. `fraction` is per-frame per-call (the caller drives progress); `overlay` is the optional center-aligned label; `size` is the per-call display size. Read-only — no dispatcher. :Fields: * **fraction** : float - per-frame progress in [0,1]; -1 means indeterminate * **overlay** : string - optional overlay text (e.g. "42/100") * **size** : float2 - per-call display size; (-1, 0) defaults to full-width .. _struct-imgui_boost_runtime-WindowState: .. das:attribute:: WindowState Backs the `window` container. `open` defaults to true so a closable window renders from frame 1; the X-button or `imgui_close` flips it false. `@live` carries that across reload. Everything else is per- frame observed (pos/size/collapsed/scroll) or echoed from per-call args (flags). ImGui persists window pos itself via imgui.ini, so duplicating it as `@live` would only fight that. `imgui_open` / `imgui_close` flow through pending_open/close; the renderer applies them at the top of the next frame. Per-call config (closable, flags) is supplied via the named-tuple at the call site — same convention as `[widget]`. :Fields: * **open** : bool = true - window open state; preserved across reload * **flags** : :ref:`ImGuiWindowFlags ` - per-call ImGuiWindowFlags (echoed for telemetry) * **pos** : float2 - observed window position (top-left, screen coords) * **size** : float2 - observed window size * **collapsed** : bool - observed collapsed state * **scroll** : float2 - (GetScrollX, GetScrollY) of the window * **scroll_max** : float2 - (GetScrollMaxX, GetScrollMaxY) * **pending_open** : bool - imgui_open queued; applied next frame * **pending_close** : bool - imgui_close queued; applied next frame .. _struct-imgui_boost_runtime-ChildState: .. das:attribute:: ChildState Backs the `child` container. All fields are observed (scroll); per- call config (size, child_flags, window_flags) is supplied via the named-tuple at the call site. :Fields: * **size** : float2 - per-call child region size (echoed for telemetry) * **child_flags** : :ref:`ImGuiChildFlags ` - per-call ImGuiChildFlags * **window_flags** : :ref:`ImGuiWindowFlags ` - per-call ImGuiWindowFlags * **scroll** : float2 - (GetScrollX, GetScrollY) * **scroll_max** : float2 - (GetScrollMaxX, GetScrollMaxY) .. _struct-imgui_boost_runtime-GroupState: .. das:attribute:: GroupState Backs the `group` container. Pure layout grouping — no persistent or observable state, but the [container] macro still needs a struct to hang the auto-emitted global on. The `_placeholder` field stays @optional so JV(state) emits `{}` when the group is rendered. :Fields: * **_placeholder** : bool - unused; keeps the struct non-empty for [container] auto-emit .. _struct-imgui_boost_runtime-MenuBarState: .. das:attribute:: MenuBarState Backs the `menu_bar` container. Stateless wrapper. :Fields: * **_placeholder** : bool - unused; keeps the struct non-empty for [container] auto-emit .. _struct-imgui_boost_runtime-MenuState: .. das:attribute:: MenuState Backs the `menu` container — a single drop-down inside a menu bar. `enabled` is per-call; `opened` is per-frame observed. :Fields: * **enabled** : bool - per-call enable flag (echoed for telemetry) * **opened** : bool - observed per-frame: menu is currently expanded .. _struct-imgui_boost_runtime-PopupState: .. das:attribute:: PopupState Shared by `popup` and `popup_modal`. `open` is @live so the user-driven state survives reload. `imgui_open` / `imgui_close` route through pending_open/close; the renderer issues OpenPopup/CloseCurrentPopup on the next frame in response. :Fields: * **open** : bool - popup open state; preserved across reload * **flags** : :ref:`ImGuiWindowFlags ` - per-call ImGuiWindowFlags * **pending_open** : bool - imgui_open queued; OpenPopup fires next frame * **pending_close** : bool - imgui_close queued; CloseCurrentPopup fires next frame .. _struct-imgui_boost_runtime-TabBarState: .. das:attribute:: TabBarState Backs the `tab_bar` container. ImGui drives active-tab selection itself; we just observe. :Fields: * **flags** : :ref:`ImGuiTabBarFlags ` - per-call ImGuiTabBarFlags .. _struct-imgui_boost_runtime-TabItemState: .. das:attribute:: TabItemState Backs the `tab_item` container. `open` defaults to true so a closable tab renders from frame 1; the X-button or `imgui_close` flips it false. `@live` carries that across reload. :Fields: * **open** : bool = true - tab open state; preserved across reload * **flags** : :ref:`ImGuiTabItemFlags ` - per-call ImGuiTabItemFlags * **pending_open** : bool - imgui_open queued; applied next frame * **pending_close** : bool - imgui_close queued; applied next frame .. _struct-imgui_boost_runtime-TooltipState: .. das:attribute:: TooltipState Backs both `tooltip` and `item_tooltip`. Tooltips don't persist — they're a per-frame chrome pop. :Fields: * **_placeholder** : bool - unused; keeps the struct non-empty for [container] auto-emit .. _struct-imgui_boost_runtime-PopupContextItemState: .. das:attribute:: PopupContextItemState Backs `popup_context_item`. Right-click attaches to the previous item and ImGui drives open/close internally; no pending flags needed. :Fields: * **_placeholder** : bool - unused; keeps the struct non-empty for [container] auto-emit .. _struct-imgui_boost_runtime-PopupContextWindowState: .. das:attribute:: PopupContextWindowState Backs `popup_context_window`. Right-click anywhere in the enclosing window opens the popup; ImGui drives open/close internally. :Fields: * **_placeholder** : bool - unused; keeps the struct non-empty for [container] auto-emit .. _struct-imgui_boost_runtime-TextFilterState: .. das:attribute:: TextFilterState Backs `text_filter`. Holds the bound C++ `ImGuiTextFilter` value inline — zero-init is safe (empty `InputBuf`, empty `Filters` `ImVector`, `CountGrep = 0`), so no explicit ctor call is needed. `text_filter` renders the inline InputText editor via the bound `Draw()` method; `passes_filter(state, line)` delegates to the :Fields: * **value** : string - hand-bound `PassFilter(filter, text)` standalone helper. * **filter** : :ref:`ImGuiTextFilter ` - mirrored InputBuf text for snapshot/telemetry .. _struct-imgui_boost_runtime-DragDropSourceState: .. das:attribute:: DragDropSourceState Backs `drag_drop_source`. Drag activation lives entirely in ImGui's internal drag-drop state machine; body runs only on active drag. :Fields: * **_placeholder** : bool - unused; keeps the struct non-empty for [container] auto-emit .. _struct-imgui_boost_runtime-DragDropTargetState: .. das:attribute:: DragDropTargetState Backs `drag_drop_target`. Body runs only when a payload-bearing drag is hovering this target — caller still calls AcceptDragDropPayload inside. :Fields: * **_placeholder** : bool - unused; keeps the struct non-empty for [container] auto-emit .. _struct-imgui_boost_runtime-TreeNodeState: .. das:attribute:: TreeNodeState Backs the `tree_node` container. ImGui owns the open/close state internally; we mirror what's observable so snapshots reflect truth, and the dispatcher routes open/close through SetNextItemOpen. :Fields: * **flags** : :ref:`ImGuiTreeNodeFlags ` - per-call ImGuiTreeNodeFlags * **opened** : bool - observed per-frame: TreeNode returned true * **pending_open** : bool - imgui_open queued; SetNextItemOpen(true) fires next frame * **pending_close** : bool - imgui_close queued; SetNextItemOpen(false) fires next frame .. _struct-imgui_boost_runtime-CollapsingHeaderState: .. das:attribute:: CollapsingHeaderState Backs the `collapsing_header` container. Same shape as TreeNodeState plus a TabItemState-style `@live open` slot for the X-button form (CollapsingHeader(label, bool* p_visible, flags)). `open` defaults to true so a closable section renders from frame 1; the X-button or `imgui_close` flips it false. :Fields: * **open** : bool = true - closable form's p_visible state; preserved across reload * **flags** : :ref:`ImGuiTreeNodeFlags ` - per-call ImGuiTreeNodeFlags * **opened** : bool - observed per-frame: CollapsingHeader returned true * **pending_open** : bool - imgui_open queued; SetNextItemOpen(true) fires next frame * **pending_close** : bool - imgui_close queued; SetNextItemOpen(false) fires next frame .. _struct-imgui_boost_runtime-MainMenuBarState: .. das:attribute:: MainMenuBarState Backs the `main_menu_bar` container — `BeginMainMenuBar()` / `EndMainMenuBar()`. Screen-top, persistent; ImGui owns visibility, we just register the container path. Stateless wrapper. :Fields: * **_placeholder** : bool - unused; keeps the struct non-empty for [container] auto-emit .. _struct-imgui_boost_runtime-WidgetEntry: .. das:attribute:: WidgetEntry Per-frame snapshot of one rendered widget. Common fields populated every frame; per-kind detail is materialized on demand by the serializer lambda stored in `g_serializers[ident]` (parallel table) and pasted into `payload` at imgui_snapshot time. The lambda lives outside the entry because `g_registry` is cleared every frame and we need the serializer (which captures `& state` of the per-widget global) to survive that clear. :Fields: * **kind** : string - widget kind ("button", "slider_float", ...) * **hex_id** : uint - ImGui's GetID() for this widget on this frame * **bbox** : float4 - packed [x0, y0, x1, y1] * **hover** : bool - IsItemHovered() this frame * **active** : bool - IsItemActive() this frame * **focus** : bool - IsItemFocused() this frame * **payload** : :ref:`JsonValue `? - populated by widget_entry_jv from g_serializers .. _struct-imgui_boost_runtime-WidgetMeta: .. das:attribute:: WidgetMeta :Fields: * **module_name** : string - owning module; lets clear_module_widgets drop on reload * **kind** : string - widget kind ("button", "slider_float", ...) * **state_addr_getter** : lambda - resolves the live state-struct address on every invoke (stable for globals; key-checked re-resolution for indexed widgets) — used by finalize lambdas to avoid dangling captures after table rehash/erase * **serializer** : lambda - captured-state serializer; invoked at imgui_snapshot time * **last_seen_frame** : int - last g_frame this path appeared in g_registry; -1 = never rendered .. _struct-imgui_boost_runtime-AwaitModifiers: .. das:attribute:: AwaitModifiers Per-command await knobs. Pulled from `input["await"]` by `with_await`; all fields optional with sensible defaults (5s, no-op). :Fields: * **await_frames** : int = -1 - min frames to advance before considering the command settled; -1 = no frame floor * **await_until** : string = "" - quiescence predicate name (empty = default is_quiescent()) * **timeout_sec** : float = 5f - client-side wait ceiling (seconds) * **fire_and_forget** : bool = false - when true, client skips the await loop entirely .. _struct-imgui_boost_runtime-AwaitArgs: .. das:attribute:: AwaitArgs :Fields: * **until** : string = "quiescent" - quiescence predicate name to poll * **frame** : int = -1 - when >=0, return quiescent once g_frame >= this value .. _struct-imgui_boost_runtime-AwaitResult: .. das:attribute:: AwaitResult :Fields: * **quiescent** : bool = false - true when the requested condition currently holds * **frame** : int = 0 - server's current g_frame * **pending_coroutines** : int = 0 - length(g_coroutines) — in-flight L1 input drivers * **active_id** : uint = 0x0 - GetActiveID() — non-zero when a widget is being interacted with .. _struct-imgui_boost_runtime-DragArgs: .. das:attribute:: DragArgs :Fields: * **target** : string = "" - widget path or 0x... hex_id where the drag starts * **dx** : float = 0f - horizontal pixel delta from start to end * **dy** : float = 0f - vertical pixel delta from start to end * **steps** : int = 4 - interpolation steps (one mouse move per frame) * **button** : int = 0 - ImGuiMouseButton index (0=Left, 1=Right, 2=Middle) .. _struct-imgui_boost_runtime-TypeTextArgs: .. das:attribute:: TypeTextArgs :Fields: * **target** : string = "" - informational target path (chars go to whichever widget holds focus) * **text** : string = "" - ASCII text to push one char at a time * **per_char_frames** : int = 1 - frames between consecutive chars * **total_frames** : int = 0 - when >0, overrides per_char_frames so the typing fits this frame budget ++++++++++++++++++ Per-frame registry ++++++++++++++++++ * :ref:`begin_frame () ` * :ref:`register_widget (module_name: string; bare_ident: string; kind: string; var state_addr_getter: lambda\<():void\>; var serializer: lambda\<():void\>) ` .. _function-imgui_boost_runtime_begin_frame: .. das:function:: begin_frame() Per-frame reset: bumps the frame counter and clears the per-frame registry, ``hex_id``\ →bbox map, and container path. Call before rendering widgets; L1 coroutines advance separately via :ref:`advance_coroutines `. .. _function-imgui_boost_runtime_register_widget_string_string_string_lambda_ls__c_void_gr__lambda_ls__c_void_gr_: .. das:function:: register_widget(module_name: string; bare_ident: string; kind: string; state_addr_getter: lambda<():void>; serializer: lambda<():void>) Module-init registration of a widget into the long-lived ``g_widgets`` table; ``module_name`` lets :ref:`clear_module_widgets ` drop it on reload. ``state_addr_getter`` is invoked on every dispatcher/serializer call to resolve the live state-struct address — stable closure for globals, key-checked re-resolution for indexed widgets. :Arguments: * **module_name** : string * **bare_ident** : string * **kind** : string * **state_addr_getter** : lambda * **serializer** : lambda +++++++++++++ Live commands +++++++++++++ * :ref:`imgui_await (input: JsonValue?) : JsonValue? ` * :ref:`imgui_click (input: JsonValue?) : JsonValue? ` * :ref:`imgui_close (input: JsonValue?) : JsonValue? ` * :ref:`imgui_drag (input: JsonValue?) : JsonValue? ` * :ref:`imgui_focus (input: JsonValue?) : JsonValue? ` * :ref:`imgui_open (input: JsonValue?) : JsonValue? ` * :ref:`imgui_set (input: JsonValue?) : JsonValue? ` * :ref:`imgui_snapshot (input: JsonValue?) : JsonValue? ` * :ref:`imgui_type_text (input: JsonValue?) : JsonValue? ` .. _function-imgui_boost_runtime_imgui_await_JsonValue_q_: .. das:function:: imgui_await(input: JsonValue?) : JsonValue? Live-command: poll quiescence. Returns ``{quiescent, frame, pending_coroutines, active_id}`` — clients drive the wait loop client-side (the server runs on the GLFW thread). :Arguments: * **input** : :ref:`JsonValue `? .. _function-imgui_boost_runtime_imgui_click_JsonValue_q_: .. das:function:: imgui_click(input: JsonValue?) : JsonValue? Live-command: dispatch a ``click`` to the widget named by ``input["target"]``; resolves path or ``0x...`` hex_id. :Arguments: * **input** : :ref:`JsonValue `? .. _function-imgui_boost_runtime_imgui_close_JsonValue_q_: .. das:function:: imgui_close(input: JsonValue?) : JsonValue? Live-command: close the container named by ``input["target"]`` (window/popup/tree_node/collapsing_header/tab_item). :Arguments: * **input** : :ref:`JsonValue `? .. _function-imgui_boost_runtime_imgui_drag_JsonValue_q_: .. das:function:: imgui_drag(input: JsonValue?) : JsonValue? Live-command: spawn an L1 drag coroutine — press at ``target`` bbox center, walk ``(dx,dy)`` over ``steps`` frames, release. :Arguments: * **input** : :ref:`JsonValue `? .. _function-imgui_boost_runtime_imgui_focus_JsonValue_q_: .. das:function:: imgui_focus(input: JsonValue?) : JsonValue? Live-command: force keyboard focus onto ``input["target"]``; the widget's path must have been tagged via :ref:`register_focusable `. :Arguments: * **input** : :ref:`JsonValue `? .. _function-imgui_boost_runtime_imgui_open_JsonValue_q_: .. das:function:: imgui_open(input: JsonValue?) : JsonValue? Live-command: open the container named by ``input["target"]`` (window/popup/tree_node/collapsing_header/tab_item). :Arguments: * **input** : :ref:`JsonValue `? .. _function-imgui_boost_runtime_imgui_set_JsonValue_q_: .. das:function:: imgui_set(input: JsonValue?) : JsonValue? Live-command: steer the next-frame value of ``input["target"]`` to ``input["value"]``. :Arguments: * **input** : :ref:`JsonValue `? .. _function-imgui_boost_runtime_imgui_snapshot_JsonValue_q_: .. das:function:: imgui_snapshot(input: JsonValue?) : JsonValue? Live-command: return ``{frame, globals, io}`` — every registered widget joined with its per-frame entry when rendered. :Arguments: * **input** : :ref:`JsonValue `? .. _function-imgui_boost_runtime_imgui_type_text_JsonValue_q_: .. das:function:: imgui_type_text(input: JsonValue?) : JsonValue? Live-command: spawn an L1 typing coroutine that pushes ``text`` to whichever widget currently holds focus. :Arguments: * **input** : :ref:`JsonValue `? +++++++++++++ Uncategorized +++++++++++++ .. _function-imgui_boost_runtime_JV_TextFilterState: .. das:function:: JV(value: TextFilterState) : JsonValue? def JV (value: TextFilterState) : JsonValue? :Arguments: * **value** : :ref:`TextFilterState ` .. _function-imgui_boost_runtime_serialize_Archive_TextFilterState: .. das:function:: serialize(arch: Archive; value: TextFilterState) def serialize (var arch: Archive; var value: TextFilterState) :Arguments: * **arch** : :ref:`Archive ` * **value** : :ref:`TextFilterState ` .. _function-imgui_boost_runtime_id_to_path_uint: .. das:function:: id_to_path(hid: uint) : string Resolve a raw ImGui ``hex_id`` to its boost path_key, or ``""`` when unmapped. :Arguments: * **hid** : uint .. _function-imgui_boost_runtime_id_to_bbox_uint: .. das:function:: id_to_bbox(hid: uint) : float4 Per-frame ``hex_id`` → bbox lookup; returns ``float4(0)`` when the id didn't render this frame. :Arguments: * **hid** : uint .. _function-imgui_boost_runtime_container_path_push_string: .. das:function:: container_path_push(widget_ident: string) Append ``widget_ident`` to the open-container chain; emitted by the ``[container]`` macro prelude. :Arguments: * **widget_ident** : string .. _function-imgui_boost_runtime_container_path_pop: .. das:function:: container_path_pop() Pop the tail container ident off the open-container chain; idempotent on empty. .. _function-imgui_boost_runtime_widget_path_key_string: .. das:function:: widget_path_key(widget_ident: string) : string Build a leaf widget's registry key: open container chain (``"/"``-joined) + ``widget_ident``; bare ident when unnested. :Arguments: * **widget_ident** : string .. _function-imgui_boost_runtime_container_path_key: .. das:function:: container_path_key() : string Registry/dispatcher key for the currently-open container's own entry. .. _function-imgui_boost_runtime_register_end_of_frame_hook_string_function_ls__c_void_gr_: .. das:function:: register_end_of_frame_hook(name: string; hook: function<():void>) Register a per-frame painter fired by :ref:`end_of_frame `; re-registering the same ``name`` replaces, so live-reload doesn't multiply hooks. :Arguments: * **name** : string * **hook** : function .. _function-imgui_boost_runtime_end_of_frame: .. das:function:: end_of_frame() Per-frame painter drain — invokes every hook registered via :ref:`register_end_of_frame_hook `. Call after rendering all widgets. .. _function-imgui_boost_runtime_register_post_command_hook_string_function_ls_command_c_string;target_c_string_c_void_gr_: .. das:function:: register_post_command_hook(name: string; hook: function<(command:string;target:string):void>) Register a hook fired after every successful ``imgui_*`` command with ``(command_name, resolved_target)``; same name-keyed idempotent semantics as :ref:`register_end_of_frame_hook `. :Arguments: * **name** : string * **hook** : function<(command:string;target:string):void> .. _function-imgui_boost_runtime_advance_coroutines: .. das:function:: advance_coroutines() Step every active L1 input coroutine one frame; finished coroutines drop out. Must run between ``ImGui_ImplGlfw_NewFrame()`` and ``NewFrame()`` so synthetic events aren't clobbered by the GLFW backend. .. _function-imgui_boost_runtime_spawn_coroutine_Coroutine: .. das:function:: spawn_coroutine(c: Coroutine) Schedule an L1 input coroutine (one event per frame); :ref:`advance_coroutines ` drains it. :Arguments: * **c** : :ref:`Coroutine ` .. _function-imgui_boost_runtime_widget_prelude_string: .. das:function:: widget_prelude(widget_ident: string) Top-of-body helper for ``[widget]`` macros: ``PushID(widget_ident)`` and apply any pending :ref:`imgui_focus ` request. :Arguments: * **widget_ident** : string .. _function-imgui_boost_runtime_register_focusable_string: .. das:function:: register_focusable(widget_ident: string) Tag this widget's path as accepting keyboard focus; called from interactive finalize helpers so :ref:`imgui_focus ` accepts the target. :Arguments: * **widget_ident** : string .. _function-imgui_boost_runtime_clear_module_widgets_string: .. das:function:: clear_module_widgets(module_name: string) Drop every widget tagged with this module from the long-lived registries (g_widgets / id_to_path / focusable / pending_focus); called from each module's ``[init]`` so hot-reload re-binds cleanly. :Arguments: * **module_name** : string .. _function-imgui_boost_runtime_widget_registered_string: .. das:function:: widget_registered(path: string) : bool Idempotency probe used by indexed-form wrappers — true when ``path`` is already in ``g_widgets``. :Arguments: * **path** : string .. _function-imgui_boost_runtime_lookup_state_addr_string: .. das:function:: lookup_state_addr(path: string) : void? Resolve a widget's current state-struct address by path — invokes the registered ``state_addr_getter`` so indexed-form widgets reinterpret the live table slot on every call instead of dereferencing a stale capture. Returns null when ``path`` is absent from ``g_widgets`` or the getter reports the slot is gone (erased indexed key). Uses ``?[]`` safe lookup so the finalize lambdas can run from inside an ``imgui_snapshot`` iteration without tripping the locked-table guard (``tab[k]`` is daslang's auto-insert form). :Arguments: * **path** : string .. _function-imgui_boost_runtime_widget_finalize_string_string_WidgetEntry_lambda_ls__c_void_gr__lambda_ls_action_c_string;payload_c_JsonValue_q__c_void_gr_: .. das:function:: widget_finalize(widget_ident: string; kind: string; entry: WidgetEntry; serializer: lambda<():void>; dispatcher: lambda<(action:string;payload:JsonValue?):void>) Bottom-of-body helper for ``[widget]`` macros: capture bbox/hover/active/focus, install the per-widget serializer + dispatcher, and ``PopID``. :Arguments: * **widget_ident** : string * **kind** : string * **entry** : :ref:`WidgetEntry ` * **serializer** : lambda * **dispatcher** : lambda<(action:string;payload: :ref:`JsonValue `?):void> .. _function-imgui_boost_runtime_container_finalize_string_string_WidgetEntry_lambda_ls__c_void_gr__lambda_ls_action_c_string;payload_c_JsonValue_q__c_void_gr_: .. das:function:: container_finalize(widget_ident: string; kind: string; entry: WidgetEntry; serializer: lambda<():void>; dispatcher: lambda<(action:string;payload:JsonValue?):void>) Container counterpart of :ref:`widget_finalize `; install the per-container serializer + dispatcher at the cached container path key. :Arguments: * **widget_ident** : string * **kind** : string * **entry** : :ref:`WidgetEntry ` * **serializer** : lambda * **dispatcher** : lambda<(action:string;payload: :ref:`JsonValue `?):void> .. _function-imgui_boost_runtime_imgui_dock_JsonValue_q_: .. das:function:: imgui_dock(input: JsonValue?) : JsonValue? Live-command: re-dock the dock_window named by ``input["target"]`` into the dock node id supplied in ``input["value"]`` (a ``uint`` from a ``DockBuilder*`` call). Routes through SetNextWindowDockID on the next frame. :Arguments: * **input** : :ref:`JsonValue `? .. _function-imgui_boost_runtime_imgui_undock_JsonValue_q_: .. das:function:: imgui_undock(input: JsonValue?) : JsonValue? Live-command: undock the dock_window named by ``input["target"]``; the window becomes free-floating. Routes through SetNextWindowDockID(0) on the next frame. :Arguments: * **input** : :ref:`JsonValue `? .. _function-imgui_boost_runtime_imgui_dock_reset_JsonValue_q_: .. das:function:: imgui_dock_reset(input: JsonValue?) : JsonValue? Live-command: reset the dockspace named by ``input["target"]`` — clears the DockBuilder node tree and flips ``state.has_initial_layout`` back to false so the user's setup function re-runs on the next frame. :Arguments: * **input** : :ref:`JsonValue `? .. _function-imgui_boost_runtime_imgui_set_window_pos_JsonValue_q_: .. das:function:: imgui_set_window_pos(input: JsonValue?) : JsonValue? Live-command: reposition the dock_window named by ``input["target"]``. ``value`` is a JSON object with required ``x``/``y`` and optional ``w``/``h``. Routes through SetNextWindowPos / SetNextWindowSize on the next frame; useful for placing a window after ``imgui_undock`` (the floating-window default location is implementation-defined) or for scripted layouts. :Arguments: * **input** : :ref:`JsonValue `? .. _function-imgui_boost_runtime_widget_rect_string: .. das:function:: widget_rect(target: string) : tuple Resolve a target string (path or ``0x...`` hex_id) to its last-known bbox ``(x0,y0,x1,y1)``; returns ``(false, float4(0))`` on miss. :Arguments: * **target** : string .. _function-imgui_boost_runtime_active_widget_path: .. das:function:: active_widget_path() : string Path of the currently active/focused boost-wrapped widget, or ``""`` when none. .. _function-imgui_boost_runtime_pending_value_container_finalize_string_string_auto_0x342: .. das:function:: pending_value_container_finalize(widget_ident: string; kind: string; state: auto) : auto Container-side install of the ``pending_value`` dispatcher (``imgui_set``); used by layout containers like ``split_h`` / ``dock_left``. :Arguments: * **widget_ident** : string * **kind** : string * **state** : auto .. _function-imgui_boost_runtime_pending_value_finalize_string_string_auto_0x359: .. das:function:: pending_value_finalize(widget_ident: string; kind: string; state: auto) : auto Generic serializer + ``imgui_set`` dispatcher install for any state struct with ``has_pending``/``pending_value``/``changed``; covers Drag/Slider/Input-numeric/Color/Combo/ListBox. :Arguments: * **widget_ident** : string * **kind** : string * **state** : auto .. _function-imgui_boost_runtime_state_jv_string_type_ls_autoT_const_gr__0x3aa: .. das:function:: state_jv(path: string; t: type) : JsonValue? Safe serializer-side helper for ``[widget]`` finalize lambdas — resolves the live state-struct address at ``path`` and returns ``JV(state)``. Returns ``null`` when the slot is gone (erased indexed key) so the snapshot reports the widget without a payload instead of dereferencing a stale capture. Pair with ``with_state`` on the dispatcher side; together they let custom-widget finalize helpers stay free of ``unsafe`` / ``reinterpret``. :Arguments: * **path** : string * **t** : auto(T) .. _function-imgui_boost_runtime_with_state_string_type_ls_autoT_const_gr__block_ls_var_s_c_T_ref__c_void_gr__0x3b3: .. das:function:: with_state(path: string; t: type; blk: block<(var s:T&):void>) : auto Safe dispatcher-side helper for ``[widget]`` finalize lambdas — resolves the live state-struct address at ``path`` and invokes ``blk`` with a mutable reference to the state. No-op when the slot is gone (erased indexed key). The block body looks like a plain ``state.field = ...`` mutation; the ``unsafe`` / ``reinterpret`` cast is hidden in this helper. :Arguments: * **path** : string * **t** : auto(T) * **blk** : block<(s:T\ &):void> .. _function-imgui_boost_runtime_JV__builtin_Resulttype_ls_autoTT_gr_,type_ls_autoEE_gr_: .. das:function:: JV(r: $Result(type,type)) : JsonValue? Wire format for ``Result``: ``{"ok": bool, "value"|"error": ...}``; the transport contract every ``imgui_*`` handler returns. :Arguments: * **r** : typemacro