dasImgui documentation Logo
2.0

Contents

  • dasImgui v2.0
    • 1. Boost macro layer
      • 1.1. Boost macro layer — DSL for declarative widget composition
        • 1.1.1. Function annotations
        • 1.1.2. Classes
      • 1.2. Boost runtime — widget state structs, registry, and dispatcher
        • 1.2.1. Type aliases
        • 1.2.2. Structures
        • 1.2.3. Per-frame registry
        • 1.2.4. Path machinery
        • 1.2.5. Coroutines
        • 1.2.6. Window control
        • 1.2.7. Live commands
        • 1.2.8. Synthetic input
        • 1.2.9. Debug logging
        • 1.2.10. Memory debugging
        • 1.2.11. Snapshot transform
        • 1.2.12. JSON serialization
    • 2. Builtin widgets
      • 2.1. Built-in widgets — inputs, selection, color, plots, output
        • 2.1.1. Call macros
        • 2.1.2. Selection
        • 2.1.3. Focus & scrolling
        • 2.1.4. Logging
        • 2.1.5. Status queries
      • 2.2. Built-in containers — windows, child regions, tabs, menus, popups
        • 2.2.1. Call macros
        • 2.2.2. Windows
        • 2.2.3. Tabs
        • 2.2.4. Popups
      • 2.3. ID stack — push/pop, scoped, hashing
        • 2.3.1. ID stack
      • 2.4. Layout helpers — splits, columns, docking, spacing
        • 2.4.1. Call macros
        • 2.4.2. Columns
        • 2.4.3. Trees
        • 2.4.4. List clipping
      • 2.5. Style helpers — colors, vars, push/pop, themes
        • 2.5.1. Call macros
        • 2.5.2. Push/pop
      • 2.6. Icon set
        • 2.6.1. Transport
        • 2.6.2. Edit
        • 2.6.3. Visualize
        • 2.6.4. Mix
        • 2.6.5. Organize
        • 2.6.6. Synth
        • 2.6.7. Scene tools
        • 2.6.8. Scene objects
        • 2.6.9. Arrange
        • 2.6.10. Editor transport
        • 2.6.11. View
        • 2.6.12. File
        • 2.6.13. General
        • 2.6.14. API
    • 3. Live reload and transport
      • 3.1. Live-reload lifecycle and synthetic-IO bypass driver
        • 3.1.1. Structures
        • 3.1.2. Lifecycle
        • 3.1.3. Synth IO drivers
        • 3.1.4. Event timelines
        • 3.1.5. Status / introspection
      • 3.2. Transport — pluggable lambda-based IPC for imgui commands
        • 3.2.1. Type aliases
        • 3.2.2. Constants
        • 3.2.3. Structures
        • 3.2.4. Transport construction
        • 3.2.5. Send / receive
        • 3.2.6. Awaiting
        • 3.2.7. Raw HTTP
    • 4. Testing toolkit
      • 4.1. Playwright — block-form test harness for daslang-live + dasImgui apps
        • 4.1.1. Constants
        • 4.1.2. Structures
        • 4.1.3. App lifecycle
        • 4.1.4. Locators / queries
        • 4.1.5. Actions
        • 4.1.6. Recording / narration
        • 4.1.7. Content-time gating
        • 4.1.8. Snapshots
        • 4.1.9. Polling / await
        • 4.1.10. Pause control
        • 4.1.11. Transport plumbing
      • 4.2. Visual aids — tutorial-mode overlays, mouse trail, narration, key HUD
        • 4.2.1. Constants
        • 4.2.2. Structures
        • 4.2.3. Highlight overlay
        • 4.2.4. Mouse trail
        • 4.2.5. Narration
        • 4.2.6. HUD
        • 4.2.7. Cursor sprite
        • 4.2.8. Override hooks
        • 4.2.9. Memory debugging
        • 4.2.10. Color utilities
        • 4.2.11. Serve / lifecycle
    • 5. External types
      • 5.1. imgui::ImGuiCol
      • 5.2. imgui::ImGui*Flags
      • 5.3. imgui::ImGuiCond
      • 5.4. imgui::ImVec2 / imgui::ImVec4 / imgui::ImColor
      • 5.5. imgui::ImGuiViewport
      • 5.6. imgui::ImGuiSizeCallbackData
      • 5.7. glfw::GLFWwindow
      • 5.8. imgui::ImGuiTextFilter
  • dasImgui tutorials
    • Boost basics
      • Walkthrough
        • Requires
        • Init and shutdown
        • The frame loop
        • The window container
        • Widgets
        • Standalone vs live
        • Driving from outside
        • Next steps
    • Widgets tour
      • Walkthrough
        • Requires
        • Init and shutdown
        • The frame loop
        • Widgets
        • Standalone vs live
        • Driving from outside
        • Next steps
    • Display widgets
      • Walkthrough
        • Requires
        • progress_bar
        • image
        • Snapshot shape
    • Narrative widgets
      • Walkthrough
        • Requires
        • text vs text_unformatted vs text_wrapped
        • Colored vs disabled
        • Bullets
        • label_text
        • separator_text
        • Snapshot shape
    • Custom widgets
      • Walkthrough
        • Requires
        • The state struct
        • The [widget] annotation
        • The drawlist pattern
        • Reusing pending_value_finalize
        • Standalone vs live
        • Driving from outside
        • Next steps
    • Layout
      • Walkthrough
        • Requires
        • Init and shutdown
        • The frame loop
        • Layout helpers
        • Standalone vs live
        • Driving from outside
        • Scope wrappers
        • Next steps
    • Layout primitives
      • Walkthrough
        • Requires
        • When to reach for each
        • Snapshot shape
    • Docking
      • Walkthrough
        • Requires
        • The flag that lights it up
        • Seeding the layout
        • Variant: dockspace inside a host window
        • The frame loop
        • Standalone vs live
        • Driving from outside
        • Next steps
    • With style
      • Walkthrough
        • Requires
        • Single block, mixed types
        • Nesting
        • Pop balance
        • Standalone vs live
        • Driving from outside
        • Next steps
    • With id
      • Walkthrough
        • Requires
        • The single-render rule
        • with_id scopes
        • Nested chains
        • Per-call id= — stable hash across renames
        • Per-call path= — stable registry path across renames
        • Standalone vs live
        • Driving from outside
        • Next steps
    • With disabled / font / button_repeat
      • Walkthrough
        • Requires
        • Why scope wrappers
        • with_disabled
        • with_button_repeat
        • with_font
        • with_clip_rect
        • Combining wrappers
    • State & telemetry
      • Walkthrough
        • Auto-emit
        • Reading state
        • Dotted flags
        • text_show — the app-driven mirror
        • Standalone vs live
        • Driving from outside
        • Next steps
    • Containers
      • Walkthrough
        • Requires
        • menu_bar / menu / menu_item
        • tab_bar / tab_item
        • popup
        • item_tooltip — hover-gated overlay
        • Standalone vs live
        • Driving from outside
        • Context popups
        • Next steps
    • Child windows
      • Walkthrough
        • Requires
        • size — three sizing modes
        • child_flags vs window_flags
        • ChildState — what the snapshot reports
        • Auto-resize variants
        • Horizontal scroll
        • Standalone vs live
        • Driving from outside
    • Group
      • Walkthrough
        • Requires
        • Two columns via same_line
        • Hit-testing a cluster
        • The (label | value | button) row
        • Why no flags?
        • Standalone vs live
        • Driving from outside
    • Tree node
      • Walkthrough
        • Requires
        • Nesting and path composition
        • Open / close from outside
        • Reading state.opened
        • ImGuiTreeNodeFlags
        • tree_node vs tree_node_ex
        • Standalone vs live
    • Collapsing header
      • Walkthrough
        • Requires
        • Two visibility dimensions
        • The closable form
        • The pending-flag channel
        • DefaultOpen flag
        • Standalone vs live
        • Driving from outside
    • Tab bar
      • Walkthrough
        • Requires
        • Active tab + body gating
        • Switching tabs from outside
        • Closable tabs
        • Sharing open state across two surfaces
        • ImGuiTabBarFlags
        • Standalone vs live
    • Modal popups
      • Walkthrough
        • Requires
        • Confirm dialog (non-closable)
        • Closable settings modal
        • popup vs popup_modal
        • Pending-flag channels
        • Standalone vs live
        • Driving from outside
    • Main menu bar
      • Walkthrough
        • Requires
        • main_menu_bar vs menu_bar
        • menu_item vs menu_label
        • Driving from outside
        • Snapshot shape
    • Popup window
      • Walkthrough
        • Requires
        • Two scopes, one str_id
        • Custom predicates
        • State
        • Standalone vs live
    • Flat tooltips
      • Walkthrough
        • Requires
        • set_item_tooltip vs the container form
        • The HelpMarker pattern
        • Standalone vs live
    • Drag and drop
      • Walkthrough
        • Requires
        • Source side
        • Target side
        • Driving from outside
        • Next steps
    • Live reload
      • Walkthrough
        • The reload boundary
        • @live preservation
        • The frame gate
        • [live_command] — user-defined HTTP endpoints
        • Manual reload hooks
        • Init / shutdown idempotence
        • Standalone vs live
        • Driving from outside
        • Next steps
    • Driving from outside
      • Walkthrough
        • The command surface
        • imgui_snapshot — read the world
        • imgui_force_set — value writes
        • imgui_click — fire a click
        • imgui_open / imgui_close — containers
        • The flow on a single command
        • Standalone vs live
        • Driving from outside (recap)
        • Next steps
    • Visual aids tour
      • Walkthrough
        • Layout
        • Highlight
        • Mouse trail
        • Cursor sprite
        • Narrate
        • Auto-highlight on command
        • Key HUD + focus rect (recording’s keyboard tour)
        • Standalone vs live
        • Driving from outside
    • Narrative + layout primitives
      • What the tour shows
      • Driving the tour
      • Idents matter for recordings
    • External-pointer editing rail
      • What the tour shows
      • safe_addr vs unsafe(addr)
      • Driving the tour
    • Recording tutorial videos
      • The subject
      • The driver
        • Anatomy of a driver
        • The visual-aids stack
        • The driver workflow in shell
        • Stop conditions
        • Replay stability
        • Standalone vs live
        • Driving from outside
        • The end of the curriculum
    • Harness + headless mode
      • Why headless
      • Running tests headless
      • What –headless does internally
      • Default-on lint: HARNESS001
      • Limits under –headless
    • data_table
      • Walkthrough
        • Requires
        • Container shape
        • Body primitives
        • Sortable tables
        • Why the name
        • Standalone vs live
    • file_dialog
      • Walkthrough
        • Requires
        • Public API
        • Modes
        • Navigation and sorting
        • Drivability
        • Standalone vs live
    • Window size constraints
      • Walkthrough
        • Requires
        • The three callback patterns
        • Struct layout
        • Standalone vs live
    • With tab stop
      • Walkthrough
        • Requires
        • Behaviour
        • When to reach for it
        • Standalone vs live
    • Color button hover
      • Walkthrough
        • Requires
        • When to reach for it
        • Click vs hover
        • Standalone vs live
    • Selectable hover
      • Walkthrough
        • Requires
        • When to reach for it
        • Toggle vs hover
        • Standalone vs live
    • Drawlist rail
      • Walkthrough
        • Scope wrappers
        • Primitives
        • Shape extras (v2 additions)
        • Path building
        • Channel splitting
        • Clip rect scope
        • Path-key telemetry
        • Standalone vs live
    • Drag widgets
      • Walkthrough
        • Requires
        • Speed and format
        • Bounds
        • Vector forms
        • Range forms
        • Driving from outside
        • Drag vs slider vs input
        • Caller-owned variant
    • Slider widgets
      • Walkthrough
        • Requires
        • Bounds
        • Format
        • Vector forms
        • Vertical orientation
        • Driving from outside
        • Slider vs drag vs input
        • Caller-owned variant
    • Input numeric widgets
      • Walkthrough
        • Requires
        • Step buttons
        • Format
        • Vector forms
        • Double precision
        • Flags
        • Driving from outside
        • Input vs drag vs slider
        • Caller-owned variant
    • Input text widgets
      • Walkthrough
        • Requires
        • Basic and with_hint
        • Multiline
        • Growable
        • Callback
        • text_filter
        • Indexed-form note
        • Driving from outside
    • Toggles
      • Walkthrough
        • Requires
        • checkbox vs radio_button (bool form)
        • radio_button_int — grouped, mutually exclusive
        • Driving from outside
        • Caller-owned variants
    • Dropdown + select
      • Walkthrough
        • Requires
        • combo — items array
        • combo_getter — procedural list
        • selectable — multi-toggle rows
        • selectable_label inside list_box — single-select
        • Driving from outside
        • When to use which
    • Color
      • Walkthrough
        • Requires
        • edit vs picker
        • color_button — click trigger, caller-owned color
        • Flags
        • Driving from outside
        • Caller-owned variants
    • Buttons
      • Walkthrough
        • Requires
        • button — the workhorse
        • small_button — zero padding
        • arrow_button — directional glyph
        • invisible_button — hit area only
        • image_button — textured trigger
        • tab_item_button — button styled as a tab
        • Driving from outside
        • Caller-owned variant
    • Plot
      • Walkthrough
        • Requires
        • Array form vs lambda form
        • Auto-fit vs explicit bounds
        • Size
        • The overlay arg
        • Driving from outside
    • tree_node_ex + image
      • Walkthrough
        • Requires
        • tree_node_ex vs tree_node (container)
        • image vs image_button
        • Driving from outside
    • Right-click context popups
      • Walkthrough
        • Requires
        • popup_context_item — attached to an item
        • popup_context_window — attached to the window
        • Flags
        • State model — stateless_finalize
    • edit_tab_item
      • Walkthrough
        • Requires
        • Why edit_tab_item over tab_item
        • The id arg
        • The pointer arg
        • Driving from outside
    • Icons
      • Walkthrough
        • Requires
        • icon_button — clickable
        • icon() — draw only
        • Enumerating the set
        • Drawing without a button
    • Wrapping tab bar
      • Walkthrough
        • Requires
        • Selecting a tab by name
        • Why an index, not ImGui’s tab state
        • Standalone vs live
    • Dynamic fonts
      • Walkthrough
        • Requires
        • Behaviour
        • Migration note
        • Standalone vs live
    • Texture references
      • Walkthrough
        • Requires
        • Behaviour
        • Migration note
    • Item flags
      • Walkthrough
        • Requires
        • Behaviour
    • Log capture
      • Walkthrough
        • Requires
        • Behaviour
        • Migration note
  • Internal binding families
    • Render helpers
    • Vertex shading
    • Layout & item sizing
    • Item hit-test & geometry
    • Item assembly (ItemAdd + ButtonBehavior)
    • Behavior-flag buttons
    • Axis layout primitives (splitter & scrollbar)
    • Tree-node behavior
    • Separator & low-level text
    • Combo internals
    • Popups, tooltips & menus
    • ID stack seed & override
    • Focus scope & activation
    • Item flags
    • Logging & capture
dasImgui documentation
  • dasImgui tutorials
  • Modal popups
  • Edit on GitHub

Modal popups

popup_modal is the blocking sibling of popup: ImGui dims the parent window, absorbs every click outside the modal, and routes ESC to the close path. The wrapper’s signature:

popup_modal(IDENT, (text = "title",
                    closable = bool,
                    flags = ImGuiWindowFlags....)) {
    // body — runs only while ImGui has the modal open
}

Lifecycle is identical to popup — OpenPopup + BeginPopupModal + EndPopup, driven by state.pending_open / pending_close. The differences are entirely visual + input-blocking, both handled by ImGui.

closable=true adds an X-button on the title bar wired to state.open. The wrapper feeds &state.open to BeginPopupModal’s p_open parameter, so an X-click sets state.open=false and ImGui closes the modal on the next frame.

Source: examples/tutorial/popup_modal.das.

Walkthrough

Your browser doesn't support HTML5 video. Download the recording.
  1options gen2
  2
  3require imgui
  4require imgui_app
  5require opengl/opengl_boost
  6require live/glfw_live
  7require live/live_api
  8require live/live_commands
  9require live/live_vars
 10require live_host
 11require imgui/imgui_live
 12require imgui/imgui_boost_runtime
 13require imgui/imgui_boost_v2
 14require imgui/imgui_widgets_builtin
 15require imgui/imgui_containers_builtin
 16require imgui/imgui_visual_aids
 17
 18// =============================================================================
 19// TUTORIAL: popup_modal — blocking modal dialog with optional X-button.
 20//
 21//   popup_modal(IDENT, (text = "title", closable = bool,
 22//                       flags = ImGuiWindowFlags....)) { body }
 23//
 24// Lifecycle is identical to popup() — OpenPopup + BeginPopupModal/EndPopup,
 25// driven by state.pending_open / pending_close — but ImGui ALSO:
 26//
 27//   1. Dims the parent window — visual backdrop says "deal with this first".
 28//   2. Blocks input outside the modal — clicks elsewhere are absorbed, not
 29//      passed through. ESC closes the modal (vanilla ImGui behavior).
 30//   3. With closable=true, renders an X-button wired to state.open.
 31//
 32// The boost wrapper threads three control surfaces through state.pending_*:
 33//   - app code        — `MODAL_X.pending_open = true`
 34//   - live commands   — imgui_open / imgui_close
 35//   - close-button    — ImGui flips state.open when X clicked or ESC pressed
 36//
 37// STANDALONE: daslang.exe modules/dasImgui/examples/tutorial/popup_modal.das
 38// LIVE:       daslang-live modules/dasImgui/examples/tutorial/popup_modal.das
 39//
 40// DRIVE (when running live):
 41//   curl -X POST -d '{"name":"imgui_open","args":{"target":"PM_WIN/CONFIRM_MODAL"}}' \
 42//        localhost:9090/command
 43// =============================================================================
 44
 45var private CONFIRM_RESULT : string = "(no answer yet)"
 46
 47[export]
 48def init() {
 49    live_create_window("dasImgui popup_modal tutorial", 720, 480)
 50    live_imgui_init(live_window)
 51    let io & = unsafe(GetIO())
 52    GetStyle().FontScaleMain = 1.4
 53}
 54
 55[export]
 56def update() {
 57    if (!live_begin_frame()) return
 58    begin_frame()
 59
 60    ImGui_ImplGlfw_NewFrame()
 61    apply_synth_io_override()
 62    NewFrame()
 63
 64    SetNextWindowPos(ImVec2(20.0f, 20.0f), ImGuiCond.Always)
 65    SetNextWindowSize(ImVec2(680.0f, 440.0f), ImGuiCond.Always)
 66    window(PM_WIN, (text = "popup_modal tutorial", closable = false,
 67                    flags = ImGuiWindowFlags.None)) {
 68
 69        text("Two modals - a Yes/No confirm and a closable settings dialog.")
 70        separator()
 71
 72        // ---- A: trigger the confirm modal ----
 73        if (button(OPEN_CONFIRM, (text = "Delete file..."))) {
 74            CONFIRM_MODAL.pending_open = true
 75        }
 76        same_line((spacing = 12.0f))
 77        if (button(OPEN_SETTINGS, (text = "Open settings (X-button)"))) {
 78            SETTINGS_MODAL.pending_open = true
 79        }
 80
 81        separator()
 82        text(STATUS_LINE, (text = "Last confirm answer: {CONFIRM_RESULT}"))
 83        text("SETTINGS_MODAL.open (closable) = {SETTINGS_MODAL.open}")
 84
 85        // ---- Modal A: Yes/No confirm ----
 86        // closable=false → no X-button. Yes/No buttons + ESC are the close
 87        // paths (ESC is an ImGui built-in for popups; to disable it the app
 88        // would need to intercept the keystroke before NewFrame()).
 89        popup_modal(CONFIRM_MODAL, (text = "Confirm delete",
 90                                    closable = false,
 91                                    flags = ImGuiWindowFlags.AlwaysAutoResize)) {
 92            text("Are you sure you want to delete the selected file?")
 93            separator()
 94            if (button(CONFIRM_YES, (text = "Yes"))) {
 95                CONFIRM_RESULT = "Yes"
 96                CONFIRM_MODAL.pending_close = true
 97            }
 98            same_line((spacing = 12.0f))
 99            if (button(CONFIRM_NO, (text = "No"))) {
100                CONFIRM_RESULT = "No"
101                CONFIRM_MODAL.pending_close = true
102            }
103        }
104
105        // ---- Modal B: closable settings ----
106        // closable=true → X-button on the title bar wired to state.open.
107        popup_modal(SETTINGS_MODAL, (text = "Settings",
108                                     closable = true,
109                                     flags = ImGuiWindowFlags.AlwaysAutoResize)) {
110            text("Background tasks")
111            separator()
112            checkbox(S_AUTOSAVE, (text = "Auto-save every 5 minutes"))
113            checkbox(S_TELEMETRY, (text = "Send anonymous telemetry"))
114            S_MAX_FPS.bounds = (30, 240)
115            slider_int(S_MAX_FPS, (text = "Max FPS cap"))
116            separator()
117            if (button(S_APPLY, (text = "Apply"))) {
118                SETTINGS_MODAL.pending_close = true
119            }
120        }
121    }
122
123    end_of_frame()
124    Render()
125    var w, h : int
126    live_get_framebuffer_size(w, h)
127    glViewport(0, 0, w, h)
128    glClearColor(0.10f, 0.10f, 0.12f, 1.0f)
129    glClear(GL_COLOR_BUFFER_BIT)
130    live_imgui_render()
131
132    live_end_frame()
133}
134
135[export]
136def shutdown() {
137    live_imgui_shutdown()
138    live_destroy_window()
139}
140
141[export]
142def main() {
143    init()
144    while (!exit_requested()) {
145        update()
146    }
147    shutdown()
148}

Requires

Already in the baseline boost layer:

  • imgui/imgui_containers_builtin — popup_modal plus window.

  • imgui/imgui_widgets_builtin — button, checkbox, slider_int, text.

Confirm dialog (non-closable)

The classic “Yes/No before destructive action”:

popup_modal(CONFIRM_MODAL, (text = "Confirm delete",
                            closable = false,
                            flags = ImGuiWindowFlags.AlwaysAutoResize)) {
    text("Are you sure you want to delete the selected file?")
    separator()
    if (button(CONFIRM_YES, (text = "Yes"))) {
        CONFIRM_RESULT = "Yes"
        CONFIRM_MODAL.pending_close = true
    }
    same_line()
    if (button(CONFIRM_NO, (text = "No"))) {
        CONFIRM_RESULT = "No"
        CONFIRM_MODAL.pending_close = true
    }
}

closable=false means there’s no X-button — but ESC still closes the modal (ImGui’s built-in popup keybinding, unaffected by closable or any ImGuiWindowFlags bit). The body’s Yes/No buttons are the explicit answer paths: both write to CONFIRM_RESULT and set pending_close. To make the modal truly non-dismissable, the app must intercept the ESC key before NewFrame() and avoid issuing any pending_close from app code — outside the scope of this tutorial.

The AlwaysAutoResize flag (passed via flags) sizes the modal to its content — saves the caller from picking width/height by hand.

Closable settings modal

When the user might want to close without “saving”:

popup_modal(SETTINGS_MODAL, (text = "Settings",
                             closable = true,
                             flags = ImGuiWindowFlags.AlwaysAutoResize)) {
    checkbox(S_AUTOSAVE, (text = "Auto-save every 5 minutes"))
    checkbox(S_TELEMETRY, (text = "Send anonymous telemetry"))
    slider_int(S_MAX_FPS, (text = "Max FPS cap"))
    separator()
    if (button(S_APPLY, (text = "Apply"))) {
        SETTINGS_MODAL.pending_close = true
    }
}

closable=true activates the X-button. The wrapper passes &state.open to ImGui as p_open; ImGui flips it false on X-click or ESC, the next frame’s BeginPopupModal returns false, and the wrapper finalizes the close. SETTINGS_MODAL.open mirrors ImGui’s view so the snapshot reports whether the modal is currently up.

popup vs popup_modal

Same machinery, different UX:

  • popup — clicks outside the popup close it (auto-close behavior). Useful for dropdowns, context menus, transient widgets.

  • popup_modal — clicks outside are absorbed. The user MUST resolve the modal before doing anything else. Use for destructive confirms, multi-step wizards, blocking error dialogs.

The two share PopupState exactly — same open / flags / pending_open / pending_close fields. Switching between forms is a one-word edit.

Pending-flag channels

Three control surfaces converge on the same state:

  • App code — MODAL.pending_open = true from a button handler or any event.

  • Live commands — imgui_open / imgui_close against the registered path.

  • Close button / ESC (closable only) — ImGui flips state.open, the next frame’s wrapper applies the close.

The wrapper bridges them: pending_open=true triggers OpenPopup, pending_close=true triggers CloseCurrentPopup inside the active modal body, X-click flips open=false and the wrapper closes on next frame.

Standalone vs live

Same convention as the other tutorials.

Driving from outside

The walkthrough above opens each modal by clicking its trigger button and dismisses it by clicking Yes / No / Apply — every gesture is a real click, self-verified by the modal body appearing or vanishing. The live commands below drive the same lifecycle directly, for remote or scripted control:

curl -X POST -d '{"name":"imgui_open","args":{"target":"PM_WIN/CONFIRM_MODAL"}}' \
     localhost:9090/command
curl -X POST -d '{"name":"imgui_click","args":{"target":"PM_WIN/CONFIRM_MODAL/CONFIRM_YES"}}' \
     localhost:9090/command
curl -X POST -d '{"name":"imgui_close","args":{"target":"PM_WIN/CONFIRM_MODAL"}}' \
     localhost:9090/command

The path for body widgets composes off the modal IDENT — clicks against PM_WIN/CONFIRM_MODAL/CONFIRM_YES resolve correctly only while the modal is open (the body’s widgets aren’t in the registry otherwise).

See also

Full source: examples/tutorial/popup_modal.das

Features-side demo: examples/features/containers_overlay.das — popup + popup_modal + tooltip overlay family showcase.

Sibling: Popup window — manual-trigger popup pattern for shared-str_id under PushID scopes.

Boost macros — the macro layer.

Previous Next

© Copyright 2026-2026, Gaijin Entertainment.

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