8.19.43. Toggles
The toggle widgets are pick-this-not-that input — three shapes,
one mental model. Click flips state; imgui_force_set writes it from
outside. The three forms differ in glyph and in whether they share
state across call sites:
checkbox(IDENT, (text = "..")) // single bool, square glyph
radio_button(IDENT, (text = "..")) // single bool, circle glyph
radio_button_int(IDENT, (text = "..", // N sites share ONE state;
v_button = N)) // click writes state.value = v_button
Source: modules/dasImgui/examples/tutorial/toggles.das.
8.19.43.1. Walkthrough
1options gen2
2options _comment_hygiene = true
3options gc
4
5require math
6require imgui
7require imgui_app
8require opengl/opengl_boost
9require live/glfw_live
10require live/live_api
11require live/live_commands
12require live/live_vars
13require live_host
14require imgui/imgui_live
15require imgui/imgui_boost_runtime
16require imgui/imgui_boost_v2
17require imgui/imgui_widgets_builtin
18require imgui/imgui_containers_builtin
19require imgui/imgui_visual_aids
20
21// =============================================================================
22// TUTORIAL: toggles — three forms of pick-this-not-that input.
23//
24// checkbox(IDENT, (text = "...")) — single bool, click flips.
25// radio_button(IDENT, (text = "...")) — single bool, circle-rendered.
26// Same ToggleState as checkbox;
27// difference is purely visual.
28// radio_button_int(IDENT, (text = "...", — N call sites SHARE one
29// v_button = N)) RadioIntState. Click writes
30// state.value = v_button — the
31// canonical "pick one of N".
32//
33// All three accept imgui_force_set: checkbox / radio_button take bool, radio_button_int
34// takes int (the v_button to select).
35//
36// STANDALONE: daslang.exe modules/dasImgui/examples/tutorial/toggles.das
37// LIVE: daslang-live modules/dasImgui/examples/tutorial/toggles.das
38//
39// DRIVE (when running live):
40// curl -X POST -d '{"name":"imgui_force_set","args":{"target":"TG_WIN/T_CHECK","value":true}}' \
41// localhost:9090/command
42// curl -X POST -d '{"name":"imgui_force_set","args":{"target":"TG_WIN/T_MODE","value":2}}' \
43// localhost:9090/command
44// =============================================================================
45
46[export]
47def init() {
48 live_create_window("dasImgui toggles tutorial", 760, 560)
49 live_imgui_init(live_window)
50 let io & = unsafe(GetIO())
51 GetStyle().FontScaleMain = 1.4
52}
53
54let MODE_LABELS = fixed_array("Off", "Manual", "Auto")
55
56[export]
57def update() {
58 if (!live_begin_frame()) return
59 begin_frame()
60
61 ImGui_ImplGlfw_NewFrame()
62 apply_synth_io_override()
63 NewFrame()
64
65 SetNextWindowPos(ImVec2(20.0f, 20.0f), ImGuiCond.Always)
66 SetNextWindowSize(ImVec2(720.0f, 520.0f), ImGuiCond.Always)
67 window(TG_WIN, (text = "toggles tutorial", closable = false,
68 flags = ImGuiWindowFlags.None)) {
69
70 text("Three shapes of pick-this-not-that.")
71 text(T_HINT, (text = "checkbox + radio_button share ToggleState. radio_button_int is the grouped form."))
72 separator()
73
74 // ---- Stage 1: checkbox — single bool, square widget ----
75 checkbox(T_CHECK, (text = "Enabled"))
76 text("T_CHECK.value = {T_CHECK.value}")
77 spacing()
78
79 // ---- Stage 2: radio_button (bool form) — circle-rendered checkbox ----
80 radio_button(T_RADIO_BOOL, (text = "Subscribe"))
81 text("T_RADIO_BOOL.value = {T_RADIO_BOOL.value} // same ToggleState as checkbox")
82 spacing()
83
84 // ---- Stage 3: radio_button_int — three sites, ONE shared state ----
85 text("Operation mode:")
86 radio_button_int(T_MODE, (text = "Off", v_button = 0)); same_line(T_SL1)
87 radio_button_int(T_MODE, (text = "Manual", v_button = 1)); same_line(T_SL2)
88 radio_button_int(T_MODE, (text = "Auto", v_button = 2))
89 text("T_MODE.value = {T_MODE.value} ('{MODE_LABELS[clamp(T_MODE.value, 0, 2)]}')")
90 }
91
92 end_of_frame()
93 Render()
94 var w, h : int
95 live_get_framebuffer_size(w, h)
96 glViewport(0, 0, w, h)
97 glClearColor(0.10f, 0.10f, 0.12f, 1.0f)
98 glClear(GL_COLOR_BUFFER_BIT)
99 live_imgui_render()
100
101 live_end_frame()
102}
103
104[export]
105def shutdown() {
106 live_imgui_shutdown()
107 live_destroy_window()
108}
109
110[export]
111def main() {
112 init()
113 while (!exit_requested()) {
114 update()
115 maybe_collect_gc()
116 }
117 shutdown()
118}
8.19.43.1.1. Requires
Already in the baseline boost layer:
imgui/imgui_widgets_builtin—checkbox/radio_button/radio_button_intrails.imgui/imgui_boost_runtime—ToggleState(checkbox + bool radio) andRadioIntState(grouped radio).
8.19.43.1.4. Driving from outside
Same telemetry channel as every other widget — imgui_force_set writes
state.pending_value, consumed next frame:
# checkbox / bool radio — bool value
curl -X POST -d '{"name":"imgui_force_set","args":{"target":"TG_WIN/T_CHECK","value":true}}' \
localhost:9090/command
# grouped radio — int value (the v_button to select)
curl -X POST -d '{"name":"imgui_force_set","args":{"target":"TG_WIN/T_MODE","value":2}}' \
localhost:9090/command
The dispatcher ([widget_dispatch] on ToggleState and
RadioIntState) parses the right JSON shape per state type.
8.19.43.1.5. Caller-owned variants
For sites where the value already lives on an external bool (not a
widget state struct), use the edit_* rails — they take a bool?
pointer via safe_addr (require daslib/safe_addr) and skip the
state-struct allocation:
var g_enabled : bool = false
edit_checkbox(safe_addr(g_enabled), (id = "EN", text = "Enabled"))
var g_subscribed : bool = false
edit_radio_button(safe_addr(g_subscribed), (id = "SUB", text = "Sub"))
Only the bool forms have caller-owned rails: edit_checkbox and
edit_radio_button. There is no edit_radio_button_int — the
grouped one-of-N form needs the shared RadioIntState that carries
the group’s selected value, so declare a RadioIntState ident and use
radio_button_int.
See External-pointer editing rail.
See also
Full source: modules/dasImgui/examples/tutorial/toggles.das
Sibling: Dropdown + select — for one-of-N picks too
large for a radio strip, combo collapses the choices into a
dropdown.
Boost macros — the macro layer.