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: examples/tutorial/toggles.das.
Walkthrough
1options gen2
2
3require math
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: toggles — three forms of pick-this-not-that input.
21//
22// checkbox(IDENT, (text = "...")) — single bool, click flips.
23// radio_button(IDENT, (text = "...")) — single bool, circle-rendered.
24// Same ToggleState as checkbox;
25// difference is purely visual.
26// radio_button_int(IDENT, (text = "...", — N call sites SHARE one
27// v_button = N)) RadioIntState. Click writes
28// state.value = v_button — the
29// canonical "pick one of N".
30//
31// All three accept imgui_force_set: checkbox / radio_button take bool, radio_button_int
32// takes int (the v_button to select).
33//
34// STANDALONE: daslang.exe modules/dasImgui/examples/tutorial/toggles.das
35// LIVE: daslang-live modules/dasImgui/examples/tutorial/toggles.das
36//
37// DRIVE (when running live):
38// curl -X POST -d '{"name":"imgui_force_set","args":{"target":"TG_WIN/T_CHECK","value":true}}' \
39// localhost:9090/command
40// curl -X POST -d '{"name":"imgui_force_set","args":{"target":"TG_WIN/T_MODE","value":2}}' \
41// localhost:9090/command
42// =============================================================================
43
44[export]
45def init() {
46 live_create_window("dasImgui toggles tutorial", 760, 560)
47 live_imgui_init(live_window)
48 let io & = unsafe(GetIO())
49 GetStyle().FontScaleMain = 1.4
50}
51
52let MODE_LABELS = fixed_array("Off", "Manual", "Auto")
53
54[export]
55def update() {
56 if (!live_begin_frame()) return
57 begin_frame()
58
59 ImGui_ImplGlfw_NewFrame()
60 apply_synth_io_override()
61 NewFrame()
62
63 SetNextWindowPos(ImVec2(20.0f, 20.0f), ImGuiCond.Always)
64 SetNextWindowSize(ImVec2(720.0f, 520.0f), ImGuiCond.Always)
65 window(TG_WIN, (text = "toggles tutorial", closable = false,
66 flags = ImGuiWindowFlags.None)) {
67
68 text("Three shapes of pick-this-not-that.")
69 text(T_HINT, (text = "checkbox + radio_button share ToggleState. radio_button_int is the grouped form."))
70 separator()
71
72 // ---- Stage 1: checkbox — single bool, square widget ----
73 checkbox(T_CHECK, (text = "Enabled"))
74 text("T_CHECK.value = {T_CHECK.value}")
75 spacing()
76
77 // ---- Stage 2: radio_button (bool form) — circle-rendered checkbox ----
78 radio_button(T_RADIO_BOOL, (text = "Subscribe"))
79 text("T_RADIO_BOOL.value = {T_RADIO_BOOL.value} // same ToggleState as checkbox")
80 spacing()
81
82 // ---- Stage 3: radio_button_int — three sites, ONE shared state ----
83 text("Operation mode:")
84 radio_button_int(T_MODE, (text = "Off", v_button = 0)); same_line(T_SL1)
85 radio_button_int(T_MODE, (text = "Manual", v_button = 1)); same_line(T_SL2)
86 radio_button_int(T_MODE, (text = "Auto", v_button = 2))
87 text("T_MODE.value = {T_MODE.value} ('{MODE_LABELS[clamp(T_MODE.value, 0, 2)]}')")
88 }
89
90 end_of_frame()
91 Render()
92 var w, h : int
93 live_get_framebuffer_size(w, h)
94 glViewport(0, 0, w, h)
95 glClearColor(0.10f, 0.10f, 0.12f, 1.0f)
96 glClear(GL_COLOR_BUFFER_BIT)
97 live_imgui_render()
98
99 live_end_frame()
100}
101
102[export]
103def shutdown() {
104 live_imgui_shutdown()
105 live_destroy_window()
106}
107
108[export]
109def main() {
110 init()
111 while (!exit_requested()) {
112 update()
113 }
114 shutdown()
115}
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).
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.
Caller-owned variants
For sites where the value already lives on an external bool / int (not
a widget state struct), use the edit_* rails — they take a T?
pointer via 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_mode : int = 0
edit_radio_button_int(safe_addr(g_mode), (id = "MODE",
text = "Off", v_button = 0))
See External-pointer editing rail.
See also
Full source: 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.