Boost basics
The smallest end-to-end dasImgui v2 program. One window, one slider, one button.
The slider drives a float (VOLUME.value) and the button accumulates a click
counter (BUMP_BTN.click_count). Both pieces of state are auto-generated
daslang globals; nothing is stored inside Dear ImGui.
Source: examples/tutorial/boost_basics.das.
Walkthrough
1options gen2
2
3require imgui
4require imgui_app
5require glfw/glfw_boost
6require opengl/opengl_boost
7require live/glfw_live
8require live/live_api
9require live/live_commands
10require live/live_vars
11require live/opengl_live
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: boost_basics — the smallest dasImgui v2 program.
22//
23// One window. One slider drives a float. One button increments a counter.
24// State lives in daslang globals (@live by default, so values survive reload).
25//
26// STANDALONE: daslang.exe modules/dasImgui/examples/tutorial/boost_basics.das
27// LIVE: daslang-live modules/dasImgui/examples/tutorial/boost_basics.das
28//
29// DRIVE (when running live):
30// curl -X POST -d '{"name":"imgui_snapshot"}' localhost:9090/command
31// curl -X POST -d '{"name":"imgui_set","args":{"target":"BASICS_WIN/VOLUME","value":0.75}}' \
32// localhost:9090/command
33// curl -X POST -d '{"name":"imgui_click","args":{"target":"BASICS_WIN/BUMP_BTN"}}' \
34// localhost:9090/command
35// =============================================================================
36
37[export]
38def init() {
39 live_create_window("dasImgui boost basics", 640, 320)
40 live_imgui_init(live_window)
41 var io & = unsafe(GetIO())
42 io.FontGlobalScale = 1.5
43}
44
45[export]
46def update() {
47 if (!live_begin_frame()) return
48 begin_frame()
49
50 ImGui_ImplOpenGL3_NewFrame()
51 ImGui_ImplGlfw_NewFrame()
52 apply_synth_io_override()
53 NewFrame()
54
55 SetNextWindowSize(ImVec2(560.0, 240.0), ImGuiCond.Always)
56 window(BASICS_WIN, (text = "Boost basics", closable = false,
57 flags = ImGuiWindowFlags.None)) {
58 // Slider — VOLUME state lives in a generated daslang global.
59 VOLUME.bounds = (0.0f, 1.0f)
60 slider_float(VOLUME, (text = "Volume"))
61 text("volume = {VOLUME.value}")
62
63 spacing(BB_SP_1)
64
65 // Button — BUMP_BTN.click_count is updated on every click.
66 if (button(BUMP_BTN, (text = "Bump"))) {
67 print("bump clicked\n")
68 }
69 text("bumps = {BUMP_BTN.click_count}")
70 }
71
72 end_of_frame()
73 Render()
74 var w, h : int
75 live_get_framebuffer_size(w, h)
76 glViewport(0, 0, w, h)
77 glClearColor(0.10f, 0.10f, 0.12f, 1.0f)
78 glClear(GL_COLOR_BUFFER_BIT)
79 ImGui_ImplOpenGL3_RenderDrawData(GetDrawData())
80
81 live_end_frame()
82}
83
84[export]
85def shutdown() {
86 live_imgui_shutdown()
87 live_destroy_window()
88}
89
90[export]
91def main() {
92 init()
93 while (!exit_requested()) {
94 update()
95 }
96 shutdown()
97}
Requires
The require block pulls in:
The C++-bound Dear ImGui surface (
imgui,imgui_app).The GLFW backend + OpenGL renderer + live-reload host glue (
glfw/...,opengl/...,live/...).The dasImgui v2 boost layer:
imgui_live(lifecycle),imgui_boost_runtime(state structs),imgui_boost_v2(macros),imgui_widgets_builtin(the actual widget implementations),imgui_containers_builtin(thewindow(...)block-arg container and its siblings),imgui_visual_aids(the synth-IO override hook used by the recording driver — see Recording APNGs).
Init and shutdown
init() opens a 640x320 GLFW window via live_create_window and
hands its handle to live_imgui_init so the ImGui context, fonts, and GL
backend get wired up. shutdown() reverses the pair in shutdown order.
The frame loop
update() is what runs every frame. The pattern, line by line:
live_begin_frame()— return early if the window is closing.begin_frame()— boost-side per-frame setup (registry, command dispatch).ImGui_ImplOpenGL3_NewFrame/ImGui_ImplGlfw_NewFrame/apply_synth_io_override/NewFrame— the ImGui backend prologue.apply_synth_io_overridelets synthetic mouse/keyboard events from live-commands win against the GLFW backend’s per-frame poll (needed for tutorial recordings).The widget block (see below).
end_of_frame()/Render()— boost-side bookkeeping, then ImGui composes the draw list.glViewport/glClear/ImGui_ImplOpenGL3_RenderDrawData— paint.live_end_frame()— swap buffers, advance live-reload housekeeping.
The window container
The window(NAME, ...) { ... } macro is the boost-layer wrapper around
ImGui’s Begin/End pair:
SetNextWindowSize(ImVec2(560.0, 240.0), ImGuiCond.Always)
window(BASICS_WIN, (text = "Boost basics", closable = false,
flags = ImGuiWindowFlags.None)) {
// ... widgets ...
}
Three things to notice:
The block runs the body once per frame between
BeginandEnd— no manualEnd()to forget.BASICS_WINis a daslang identifier — the macro auto-emits aWindowStateglobal named that, and pushesBASICS_WINonto the boost registry path. Every leaf widget registers underBASICS_WIN/<ident>.Per-call config goes in the named-tuple —
textis the title,closablecontrols whether the X-button shows,flagsare the rawImGuiWindowFlagsbits.
SetNextWindowSize / SetNextWindowPos are the same raw ImGui
calls you’d use without the boost layer — they affect the next
Begin (the one the macro emits) just like before.
Widgets
Two boost macros do the actual work:
VOLUME.bounds = (0.0f, 1.0f)
slider_float(VOLUME, (text = "Volume"))
Text("volume = {VOLUME.value}")
The macro form slider_float(VOLUME, ...) declares a module global
VOLUME : SliderStateFloat the first time it expands. Telemetry
registers it under the path-prefixed name BASICS_WIN/VOLUME (every
widget inside window(BASICS_WIN, ...) inherits the prefix); the
bounds line is plain assignment to the struct field.
if (button(BUMP_BTN, (text = "Bump"))) {
print("bump clicked\n")
}
Text("bumps = {BUMP_BTN.click_count}")
button(BUMP_BTN, ...) returns true on the frame the click registers; the
underlying ButtonState keeps click_count updated for later assertions
(e.g. from imgui_playwright).
Standalone vs live
main() runs the loop directly when invoked as daslang.exe boost_basics.das.
Under daslang-live the host calls init / update / shutdown
itself; main is ignored. The slider and button states preserve across live
reloads because every boost-generated global carries @live by default.
Driving from outside
When run live, the boost layer exposes the standard live-command surface at
localhost:9090. Mutate the slider:
curl -X POST -d '{"name":"imgui_set","args":{"target":"BASICS_WIN/VOLUME","value":0.75}}' \
localhost:9090/command
…and VOLUME.value jumps to 0.75 on the next frame. Note the
BASICS_WIN/ prefix — the window container pushes its identifier
onto the registry path, so external drivers target the
path-qualified name.
Next steps
The next tutorial walks the full common-widget surface — text input, slider, checkbox, combo, color, button — on a single panel.
See also
Full source: examples/tutorial/boost_basics.das
Richer reference: examples/tutorial/visual_aids_tour.das — keeper
reference exercising highlights, mouse trail, narration, and recording.
Next tutorial: Widgets tour
Boost macros — the macro layer.
Builtin widgets — widget reference.