8.18.1.3. Widgets tour
One of every common boost widget on a single panel. The example frames as an audio-settings dialog so each widget reads contextually: a text input for the user name, a slider for volume, a checkbox for mute, a combo for codec quality, a color editor for the accent color, and a button to save.
Source: modules/dasImgui/examples/tutorial/widgets_tour.das.
8.18.1.3.1. Walkthrough
The recording is voiced and self-verifying: each stage speaks a line while a
real gesture fires under it and is asserted — typing into the name field
(committed value checked), dragging VOLUME (value must change), clicking
MUTED (toggle must register), opening the QUALITY combo and picking
High (selection verified), setting TINT from the API (color_edit3’s
picker is mouse-only, so the tour drives it via force_set and verifies the
swatch took), and clicking Save (click must register). A silently broken
stage aborts the recording at teardown instead of shipping.
1options gen2
2options _comment_hygiene = true
3
4require imgui
5require imgui_app
6require opengl/opengl_boost
7require live/glfw_live
8require live/live_api
9require live/live_commands
10require live/live_vars
11require live_host
12require imgui/imgui_live
13require imgui/imgui_boost_runtime
14require imgui/imgui_boost_v2
15require imgui/imgui_widgets_builtin
16require imgui/imgui_containers_builtin
17require imgui/imgui_visual_aids
18
19// =============================================================================
20// TUTORIAL: widgets_tour — one of every common boost widget on a single panel.
21//
22// Frame as an audio-settings dialog so each widget reads contextually:
23// USER_NAME : input_text — who's listening
24// VOLUME : slider_float — master volume
25// MUTED : checkbox — mute toggle
26// QUALITY : combo — codec quality preset
27// TINT : color_edit3 — accent color for the UI
28// SAVE_BTN : button — apply the settings
29//
30// Read alongside :ref:`tutorial_boost_basics` for the frame-loop shape; this
31// tutorial only adds widgets on top of that scaffold.
32//
33// STANDALONE: daslang.exe modules/dasImgui/examples/tutorial/widgets_tour.das
34// LIVE: daslang-live modules/dasImgui/examples/tutorial/widgets_tour.das
35//
36// DRIVE (when running live):
37// curl -X POST -d '{"name":"imgui_force_set","args":{"target":"AUDIO_WIN/USER_NAME","value":"Boris"}}' localhost:9090/command
38// curl -X POST -d '{"name":"imgui_force_set","args":{"target":"AUDIO_WIN/VOLUME","value":0.75}}' localhost:9090/command
39// curl -X POST -d '{"name":"imgui_force_set","args":{"target":"AUDIO_WIN/MUTED","value":true}}' localhost:9090/command
40// curl -X POST -d '{"name":"imgui_force_set","args":{"target":"AUDIO_WIN/QUALITY","value":2}}' localhost:9090/command
41// curl -X POST -d '{"name":"imgui_force_set","args":{"target":"AUDIO_WIN/TINT","value":{"x":0.2,"y":0.8,"z":0.4}}}' localhost:9090/command
42// curl -X POST -d '{"name":"imgui_click","args":{"target":"AUDIO_WIN/SAVE_BTN"}}' localhost:9090/command
43// =============================================================================
44
45[export]
46def init() {
47 live_create_window("dasImgui widgets tour", 1024, 720)
48 live_imgui_init(live_window)
49 let io & = unsafe(GetIO())
50 GetStyle().FontScaleMain = 1.5
51}
52
53[export]
54def update() {
55 if (!live_begin_frame()) return
56 begin_frame()
57
58 ImGui_ImplGlfw_NewFrame()
59 apply_synth_io_override()
60 NewFrame()
61
62 // Sized for content with breathing room on the right + below for narrate
63 // post-its to appear without overlapping the panel.
64 SetNextWindowPos(ImVec2(60.0, 60.0), ImGuiCond.Always)
65 SetNextWindowSize(ImVec2(720.0, 540.0), ImGuiCond.Always)
66 window(AUDIO_WIN, (text = "Audio settings", closable = false,
67 flags = ImGuiWindowFlags.None)) {
68 // Text input — buffer + string-mirror managed by the state struct.
69 input_text(USER_NAME, (text = "Your name"))
70
71 spacing(WT_SP_1)
72
73 // Slider — float state with [0, 1] bounds set per-frame.
74 VOLUME.bounds = (0.0f, 1.0f)
75 slider_float(VOLUME, (text = "Master volume"))
76
77 // Checkbox — bool state, toggles on click.
78 checkbox(MUTED, (text = "Mute"))
79
80 spacing(WT_SP_2)
81
82 // Combo — int state indexing into the items array.
83 combo(QUALITY, (text = "Quality",
84 items <- ["Low", "Medium", "High", "Ultra"]))
85
86 spacing(WT_SP_3)
87
88 // Color editor — three-channel RGB, opens a picker on click.
89 color_edit3(TINT, (text = "Accent color"))
90
91 spacing(WT_SP_4)
92 separator(WT_SEP_1)
93 spacing(WT_SP_5)
94
95 // Button — true on the frame the click registers; click_count accumulates.
96 if (button(SAVE_BTN, (text = "Save settings"))) {
97 print("save clicked: name={USER_NAME.value} vol={VOLUME.value} muted={MUTED.value} q={QUALITY.value}\n")
98 }
99
100 spacing(WT_SP_6)
101 text("saves so far: {SAVE_BTN.click_count}")
102 }
103
104 end_of_frame()
105 Render()
106 var w, h : int
107 live_get_framebuffer_size(w, h)
108 glViewport(0, 0, w, h)
109 glClearColor(0.10f, 0.10f, 0.12f, 1.0f)
110 glClear(GL_COLOR_BUFFER_BIT)
111 live_imgui_render()
112
113 live_end_frame()
114}
115
116[export]
117def shutdown() {
118 live_imgui_shutdown()
119 live_destroy_window()
120}
121
122[export]
123def main() {
124 init()
125 while (!exit_requested()) {
126 update()
127 }
128 shutdown()
129}
8.18.1.3.1.1. Requires
The require block matches Boost basics exactly — backend
(imgui_app / glfw / opengl), live host (live/*), and the v2
boost layer (imgui_live, imgui_boost_runtime, imgui_boost_v2,
imgui_widgets_builtin, imgui_containers_builtin for the
window(...) block container). One extra line pulls in
imgui/imgui_visual_aids so the post-it narrate overlay the driver script
paints into the recording is available at render time.
8.18.1.3.1.2. Init and shutdown
init() opens a 1024x720 GLFW window via live_create_window and hands
the handle to live_imgui_init. It also bumps io.FontGlobalScale to
1.5 so the recorded APNG reads at typical Sphinx HTML widths without
zooming. shutdown() mirrors the pair in reverse order.
8.18.1.3.1.3. The frame loop
update() follows the standard dasImgui v2 shape — see
Boost basics for the line-by-line breakdown. The only addition
is a single call to apply_synth_io_override() between
ImGui_ImplGlfw_NewFrame and NewFrame. The GLFW backend polls real OS
mouse data every focused frame and would otherwise win the IO race against
any synthesized event the driver script posted just before. The override
re-asserts the synth IO so live-driven clicks land at the right widget.
8.18.1.3.1.4. Widgets
All six widgets live inside a single window(AUDIO_WIN, ...) boost
container — same pattern Boost basics introduced, so leaves
register at AUDIO_WIN/<ident>:
window(AUDIO_WIN, (text = "Audio settings", closable = false,
flags = ImGuiWindowFlags.None)) {
input_text(USER_NAME, (text = "Your name"))
slider_float(VOLUME, (text = "Master volume"))
checkbox(MUTED, (text = "Mute"))
combo(QUALITY, (text = "Quality", items <- ["Low", "Medium", "High", "Ultra"]))
color_edit3(TINT, (text = "Accent color"))
if (button(SAVE_BTN, (text = "Save settings"))) { ... }
}
Each boost macro declares the named global the first time it expands and
registers it under the path-prefixed name. The slider’s range comes from a
plain field assignment one line above the macro call:
VOLUME.bounds = (0.0f, 1.0f). The combo’s item list moves into the
named argument with items <- because string arrays are non-copyable.
SAVE_BTN.click_count accumulates across frames — handy for assertions in
a test harness.
8.18.1.3.1.5. Standalone vs live
main() runs the loop directly when invoked as
daslang.exe widgets_tour.das. Under daslang-live the host calls
init / update / shutdown itself; main is ignored. Every state
struct (USER_NAME, VOLUME, MUTED, QUALITY, TINT,
SAVE_BTN) carries @live by default, so live-reloading the source
preserves the widget contents.
8.18.1.3.1.6. Driving from outside
Under daslang-live the boost layer exposes imgui_force_set and
imgui_click over localhost:9090. The top of the source file lists
one curl invocation per widget. Each target is path-qualified:
curl -X POST -d '{"name":"imgui_force_set","args":{"target":"AUDIO_WIN/USER_NAME","value":"Boris"}}' \
localhost:9090/command
For color_edit3, value is a JSON object with x / y / z
fields — from_JV reads float3 from object form, not array form. For
combo, value is the zero-based index into the items array.
8.18.1.3.1.7. Next steps
Layout helpers — splitters, columns, child windows — are next on top of the same widget set. To write your own widget kind on the same rails — a rotary knob, an XY-pad, a meter — see Custom widgets.
See also
Full source: modules/dasImgui/examples/tutorial/widgets_tour.das
Richer reference: modules/dasImgui/examples/features/inputs_*.das — every widget with
every option exercised, against the same boost layer.
Previous tutorial: Boost basics
Next tutorial: Custom widgets
Boost macros — the macro layer.
Builtin widgets — widget reference.