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
  • Dropdown + select
  • Edit on GitHub

Dropdown + select

Four shapes of pick-one-from-a-list. combo collapses choices into a dropdown popup; selectable stacks them as always-visible rows. combo_getter serves a procedural list from a lambda; selectable_label lets the caller own the selected-flag (so you can wire it through a list_box for single-select):

combo(IDENT, (text = "..", items <- ["A", "B", ...]))                       // dropdown, items array
combo_getter(IDENT, (text = "..", items_count = N,                          // dropdown, procedural list
                     getter = @(idx; var r : string&) : bool { ... }))
selectable(IDENT, (text = ".."))                                            // row, self-toggles
selectable_label(IDENT, text, selected, (flags = ...))                      // row, caller owns 'selected'

Source: examples/tutorial/dropdown_select.das.

Walkthrough

Your browser doesn't support HTML5 video. Download the recording.
  1options gen2
  2
  3require math
  4require strings
  5require imgui
  6require imgui_app
  7require opengl/opengl_boost
  8require live/glfw_live
  9require live/live_api
 10require live/live_commands
 11require live/live_vars
 12require live_host
 13require imgui/imgui_live
 14require imgui/imgui_boost_runtime
 15require imgui/imgui_boost_v2
 16require imgui/imgui_widgets_builtin
 17require imgui/imgui_containers_builtin
 18require imgui/imgui_visual_aids
 19
 20// =============================================================================
 21// TUTORIAL: dropdown_select — four shapes of pick-one-from-a-list.
 22//
 23//   combo(IDENT, (text = "..", items <- ["A", "B", ...]))
 24//     Items-array sugar — pass the strings, get a single-call dropdown.
 25//   combo_getter(IDENT, (text = "..", items_count = N,
 26//                        getter = @(idx; var result : string&) : bool { ... }))
 27//     Procedural list — the callback supplies row text on demand. Use when
 28//     items live in an unusual container (table, generator, large dataset).
 29//   selectable(IDENT, (text = "..", flags = ..., size = ...))
 30//     One row, self-toggles via ToggleState. Stack N to make a list.
 31//   selectable_label(IDENT, text, selected, (flags = ..., size = ...))
 32//     Row whose selected-look is driven by a CALLER-owned bool. Pair with
 33//     list_box (+ external index) when only one row may be active.
 34//
 35// STANDALONE: daslang.exe modules/dasImgui/examples/tutorial/dropdown_select.das
 36// LIVE:       daslang-live modules/dasImgui/examples/tutorial/dropdown_select.das
 37//
 38// DRIVE (when running live):
 39//   curl -X POST -d '{"name":"imgui_force_set","args":{"target":"DS_WIN/D_FRUIT","value":2}}' \
 40//        localhost:9090/command
 41//   curl -X POST -d '{"name":"imgui_force_set","args":{"target":"DS_WIN/D_FONT","value":1}}' \
 42//        localhost:9090/command
 43//   curl -X POST -d '{"name":"imgui_force_set","args":{"target":"DS_WIN/D_SHIRT","value":3}}' \
 44//        localhost:9090/command
 45// =============================================================================
 46
 47let FRUITS : array<string> <- ["Apple", "Banana", "Cherry", "Durian", "Elderberry"]
 48let FONTS  = fixed_array("Serif", "Sans", "Mono", "Cursive")
 49let TAGS   = fixed_array("urgent", "blocked", "review")
 50let SHIRTS = fixed_array("XS", "S", "M", "L", "XL", "XXL")
 51
 52var private D_TAG    : table<int; ToggleState>
 53var private D_SHIRT_ROW : table<int; ClickState>
 54
 55[export]
 56def init() {
 57    live_create_window("dasImgui dropdown_select tutorial", 760, 640)
 58    live_imgui_init(live_window)
 59    let io & = unsafe(GetIO())
 60    GetStyle().FontScaleMain = 1.4
 61}
 62
 63[export]
 64def update() {
 65    if (!live_begin_frame()) return
 66    begin_frame()
 67
 68    ImGui_ImplGlfw_NewFrame()
 69    apply_synth_io_override()
 70    NewFrame()
 71
 72    SetNextWindowPos(ImVec2(20.0f, 20.0f), ImGuiCond.Always)
 73    SetNextWindowSize(ImVec2(720.0f, 600.0f), ImGuiCond.Always)
 74    window(DS_WIN, (text = "dropdown_select tutorial", closable = false,
 75                    flags = ImGuiWindowFlags.None)) {
 76
 77        text("Four shapes of pick-one-from-a-list.")
 78        text(D_HINT, (text = "combo collapses; selectable rows stay open."))
 79        separator()
 80
 81        // ---- Stage 1: combo — items as a string array ----
 82        combo(D_FRUIT, (text = "Fruit", items <- FRUITS))
 83        text("D_FRUIT.value = {D_FRUIT.value} ('{FRUITS[clamp(D_FRUIT.value, 0, length(FRUITS) - 1)]}')")
 84        spacing()
 85
 86        // ---- Stage 2: combo_getter — callback supplies row text on demand ----
 87        combo_getter(D_FONT, (text = "Font", items_count = length(FONTS),
 88            getter = @(idx : int; var result : string&) : bool {
 89                if (idx >= 0 && idx < length(FONTS)) {
 90                    result = FONTS[idx]
 91                    return true
 92                }
 93                return false
 94            }))
 95        text("D_FONT.value = {D_FONT.value} ('{FONTS[clamp(D_FONT.value, 0, length(FONTS) - 1)]}')")
 96        spacing()
 97
 98        // ---- Stage 3: selectable — N rows, each self-toggles independently ----
 99        text("Tags (multi-select - each row toggles its own ToggleState):")
100        for (i in range(length(TAGS))) {
101            selectable(D_TAG[i], (text = TAGS[i]))
102        }
103        text("active tags: {tags_summary()}")
104        spacing()
105
106        // ---- Stage 4: selectable_label inside list_box — single-select ----
107        text("Shirt size (single-select - caller-owned int picks active row):")
108        list_box(D_SHIRT, (text = "size", size = float2(0.0f, 0.0f))) {
109            for (i in range(length(SHIRTS))) {
110                let is_sel = (i == D_SHIRT.value)
111                if (selectable_label(D_SHIRT_ROW[i], SHIRTS[i], is_sel)) {
112                    D_SHIRT.value = i
113                }
114            }
115        }
116        text("D_SHIRT.value = {D_SHIRT.value} ('{SHIRTS[clamp(D_SHIRT.value, 0, length(SHIRTS) - 1)]}')")
117    }
118
119    end_of_frame()
120    Render()
121    var w, h : int
122    live_get_framebuffer_size(w, h)
123    glViewport(0, 0, w, h)
124    glClearColor(0.10f, 0.10f, 0.12f, 1.0f)
125    glClear(GL_COLOR_BUFFER_BIT)
126    live_imgui_render()
127
128    live_end_frame()
129}
130
131def tags_summary() : string {
132    var first = true
133    return build_string() $(var w : StringBuilderWriter) {
134        for (i in range(length(TAGS))) {
135            if (D_TAG[i].value) {
136                if (!first) {
137                    w |> write(", ")
138                }
139                w |> write(TAGS[i])
140                first = false
141            }
142        }
143        if (first) {
144            w |> write("(none)")
145        }
146    }
147}
148
149[export]
150def shutdown() {
151    live_imgui_shutdown()
152    live_destroy_window()
153}
154
155[export]
156def main() {
157    init()
158    while (!exit_requested()) {
159        update()
160    }
161    shutdown()
162}

Requires

Already in the baseline boost layer:

  • imgui/imgui_widgets_builtin — combo / combo_getter / selectable / selectable_label rails.

  • imgui/imgui_containers_builtin — list_box block-arg container.

  • imgui/imgui_boost_runtime — ComboState / ToggleState / ClickState / ListBoxState state structs.

combo — items array

The simplest form. Pass the labels, get a dropdown; state.value is the chosen index.

combo(FRUIT, (text = "Fruit",
              items <- ["Apple", "Banana", "Cherry"]))
// FRUIT.value == 0 / 1 / 2

items is non-copyable (it’s a moved array<string>) — pass it inline with <-, or move from a local. Cap a long popup with popup_max_height_in_items = N to limit the scroller height.

combo_getter — procedural list

When labels don’t live in a flat array<string> (table-backed, generator-driven, computed on the fly), use the getter form. The callback returns one label per idx:

combo_getter(FONT, (text = "Font", items_count = length(FONTS),
    getter = @(idx : int; var result : string&) : bool {
        if (idx >= 0 && idx < length(FONTS)) {
            result = FONTS[idx]
            return true
        }
        return false
    }))

Return false for out-of-range indices — ImGui treats that as an empty row, useful for sparse lists. items_count is the upper bound the dropdown will probe.

selectable — multi-toggle rows

Each selectable owns its own ToggleState — rows toggle independently, which falls out as multi-select naturally:

var private TAG : table<int; ToggleState>
let TAGS = fixed_array("urgent", "blocked", "review")

for (i in range(length(TAGS))) {
    selectable(TAG[i], (text = TAGS[i]))
}
// any subset can be on at once — read TAG[i].value to filter.

The table<int; ToggleState> pattern is required for any indexed call (one IDENT, many rows). The state allocates lazily on first touch of each index.

selectable_label inside list_box — single-select

For one-of-N, switch to selectable_label with a caller-owned selected bool, wrapped in list_box (which adds the bordered frame + scroller). The list_box’s state.value holds the chosen index; the loop tags each row’s selected from it:

var private SHIRT_ROW : table<int; ClickState>
let SHIRTS = fixed_array("XS", "S", "M", "L", "XL", "XXL")

list_box(SHIRT, (text = "size", size = float2(0.0f, 0.0f))) {
    for (i in range(length(SHIRTS))) {
        let is_sel = (i == SHIRT.value)
        if (selectable_label(SHIRT_ROW[i], SHIRTS[i], is_sel)) {
            SHIRT.value = i
        }
    }
}

The ClickState rows carry only edge-trigger info — no per-row toggle persistence. The list_box’s state.value is the single source of truth, so imgui_force_set on the list_box target works the same as a combo.

Driving from outside

# combo / combo_getter — int value (the chosen index)
curl -X POST -d '{"name":"imgui_force_set","args":{"target":"DS_WIN/D_FRUIT","value":2}}' \
     localhost:9090/command
# list_box single-select — int value (the chosen row)
curl -X POST -d '{"name":"imgui_force_set","args":{"target":"DS_WIN/D_SHIRT","value":3}}' \
     localhost:9090/command
# selectable multi-select — bool per row (use the indexed IDENT)
curl -X POST -d '{"name":"imgui_force_set","args":{"target":"DS_WIN/D_TAG[0]","value":true}}' \
     localhost:9090/command

When to use which

  • combo — known list of choices, screen real estate matters. items is a one-liner.

  • combo_getter — list is procedural / huge / sparse. Same UX, callback-driven content.

  • selectable — multi-select. Rows always visible (no popup). Owns its own state per row.

  • selectable_label + list_box — single-select that needs to stay visible (sidebar, settings panel). The framed list_box is the always-visible counterpart to combo’s collapsing popup.

If a strip of 2-5 mutually exclusive options would fit inline, radio_button_int (Toggles) is lighter than a combo or list_box.

See also

Full source: examples/tutorial/dropdown_select.das

Features-side demo: examples/features/inputs_choice.das — combo + list_box in one window for imgui_force_set smoke testing.

Sibling tutorials: Toggles, Selectable hover (hover-only variant of selectable).

Boost macros — the macro layer.

Previous Next

© Copyright 2026-2026, Gaijin Entertainment.

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