Child windows
child brackets BeginChild/EndChild into a block-arg container —
a sub-window that can be sized, bordered, scrolled, and addressed in the
registry hierarchy. The wrapper’s signature:
child(IDENT, (text = "...",
size = float2(w, h),
child_flags = ImGuiChildFlags....,
window_flags = ImGuiWindowFlags....)) {
// body — leaves register under <window>/IDENT
}
Three knobs do most of the work — size, child_flags, window_flags
— and the boost layer captures scroll / scroll_max each frame so a
snapshot reports the current scroll position without polling.
Source: examples/tutorial/child.das.
Walkthrough
The recording drives each of the three children with real synthetic input
and self-verifies. It parks the cursor inside the bordered child A and
wheel-scrolls it, asserting SCROLL_A’s scroll payload actually
moved; toggles the VSync checkbox inside the AutoResizeY child B;
then wheel-scrolls the horizontal child C sideways, asserting
SCROLL_C’s scroll moved. The scroll assertions read the boost
layer’s per-frame scroll telemetry directly — a no-op scroll (cursor
not over the child, wheel not attributed) would abort the recording.
1options gen2
2
3require imgui
4require imgui_app
5require opengl/opengl_boost
6require live/glfw_live
7require live/live_api
8require live/live_commands
9require live/live_vars
10require live_host
11require imgui/imgui_live
12require imgui/imgui_boost_runtime
13require imgui/imgui_boost_v2
14require imgui/imgui_widgets_builtin
15require imgui/imgui_containers_builtin
16require imgui/imgui_visual_aids
17
18var private SCROLL_ROW : table<int; NarrativeState>
19
20// =============================================================================
21// TUTORIAL: child — BeginChild/EndChild sub-windows.
22//
23// child(IDENT, (text = "..", size = float2(w, h),
24// child_flags = ..., window_flags = ...)) { body }
25//
26// child is the workhorse for nesting a scrollable, optionally-bordered region
27// inside another window. Three knobs:
28//
29// 1. size — float2(w, h). (0,0) auto-fits to the available row/column
30// depending on flags. Positive = explicit pixels. Negative = "fill the
31// remainder, minus N pixels".
32//
33// 2. child_flags — ImGui's child-specific bitfield: Border, AlwaysAutoResize,
34// AutoResizeX/Y, FrameStyle, NavFlattened, ResizeX/Y.
35//
36// 3. window_flags — same flags every other window takes. Scrollbar control
37// lives here: HorizontalScrollbar, AlwaysVerticalScrollbar, etc.
38//
39// ChildState observed each frame: scroll (float2 current), scroll_max (float2
40// max). The body's render runs only while BeginChild returned true; scroll is
41// captured INSIDE that gate so a hidden child reports the last-known values.
42//
43// STANDALONE: daslang.exe modules/dasImgui/examples/tutorial/child.das
44// LIVE: daslang-live modules/dasImgui/examples/tutorial/child.das
45// =============================================================================
46
47[export]
48def init() {
49 live_create_window("dasImgui child tutorial", 800, 540)
50 live_imgui_init(live_window)
51 let io & = unsafe(GetIO())
52 GetStyle().FontScaleMain = 1.4
53}
54
55[export]
56def update() {
57 if (!live_begin_frame()) return
58 begin_frame()
59
60 ImGui_ImplGlfw_NewFrame()
61 apply_synth_io_override()
62 NewFrame()
63
64 SetNextWindowPos(ImVec2(20.0f, 20.0f), ImGuiCond.Always)
65 SetNextWindowSize(ImVec2(760.0f, 500.0f), ImGuiCond.Always)
66 window(CHILD_WIN, (text = "child tutorial", closable = false,
67 flags = ImGuiWindowFlags.None)) {
68
69 text("Three child variants - one each for borders, autosize, and h-scroll.")
70 separator()
71
72 // ---- A: bordered, fixed-size, vertical scroll ----
73 text("A) Bordered fixed-size with vertical scroll")
74 child(SCROLL_A, (text = "scroll_a",
75 size = float2(360.0f, 140.0f),
76 child_flags = ImGuiChildFlags.Borders,
77 window_flags = ImGuiWindowFlags.None)) {
78 for (i in range(20)) {
79 text(SCROLL_ROW[i], (text = "row {i} - content overflows the visible region"))
80 }
81 }
82 text("scroll.y = {SCROLL_A.scroll.y} / {SCROLL_A.scroll_max.y}")
83 spacing()
84
85 // ---- B: auto-resize Y, FrameStyle (input-group look) ----
86 text("B) AutoResizeY + FrameStyle - height tracks content")
87 child(AUTO_B, (text = "auto_b",
88 size = float2(360.0f, 0.0f),
89 child_flags = ImGuiChildFlags.AutoResizeY | ImGuiChildFlags.FrameStyle,
90 window_flags = ImGuiWindowFlags.None)) {
91 text("Three rows of input chrome")
92 checkbox(B_VSYNC, (text = "VSync"))
93 slider_int(B_LIMIT, (text = "frame limit"))
94 }
95 // AutoResizeY trims overflow to zero, so scroll = (0,0) and
96 // scroll_max = (0,0). The child's actual size lives in size.y;
97 // print scroll fields directly to show "no overflow".
98 text("AUTO_B.scroll = ({AUTO_B.scroll.x}, {AUTO_B.scroll.y}); scroll_max = ({AUTO_B.scroll_max.x}, {AUTO_B.scroll_max.y})")
99 spacing()
100
101 // ---- C: bordered, horizontal scroll ----
102 text("C) Border + horizontal scroll - wide content")
103 child(SCROLL_C, (text = "scroll_c",
104 size = float2(720.0f, 90.0f),
105 child_flags = ImGuiChildFlags.Borders,
106 window_flags = ImGuiWindowFlags.HorizontalScrollbar)) {
107 // One long line — forces horizontal scroll because no wrap.
108 text(LONG_LINE, (text = "very wide content: lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua ut enim ad minim veniam quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo"))
109 text("(scroll horizontally to read; scroll.x mirrors below)")
110 }
111 text("scroll.x = {SCROLL_C.scroll.x} / {SCROLL_C.scroll_max.x}")
112 }
113
114 end_of_frame()
115 Render()
116 var w, h : int
117 live_get_framebuffer_size(w, h)
118 glViewport(0, 0, w, h)
119 glClearColor(0.10f, 0.10f, 0.12f, 1.0f)
120 glClear(GL_COLOR_BUFFER_BIT)
121 live_imgui_render()
122
123 live_end_frame()
124}
125
126[export]
127def shutdown() {
128 live_imgui_shutdown()
129 live_destroy_window()
130}
131
132[export]
133def main() {
134 init()
135 while (!exit_requested()) {
136 update()
137 }
138 shutdown()
139}
Requires
Already in the baseline boost layer:
imgui/imgui_containers_builtin— defineschild,child_scroll_reenter.imgui/imgui_widgets_builtin—text,checkbox,slider_int.
size — three sizing modes
The size : float2(w, h) argument has three flavors:
Explicit positive —
size = float2(360.0f, 140.0f)— fixed pixel size. The body’s content is clipped to that region and scrollbars appear if it overflows.Zero —
size = float2(0.0f, 0.0f)— auto-fit to the available column/row. Pair withImGuiChildFlags.AutoResizeX/Yto let the body grow to the content extent instead.Negative —
size = float2(-FLT_MIN, 0.0f)— “fill the remaining space minus that many pixels”. Useful for stretchy panes that should fit the parent.
child_flags vs window_flags
ImGuiChildFlags (the third arg) is child-specific:
Border— draw a one-pixel border around the region.AutoResizeX/AutoResizeY— height/width tracks content extent.AlwaysAutoResize— combine both axes and re-measure every frame.FrameStyle— frame-style chrome (like input groups). Implies a background and rounded corners drawn from the active style.NavFlattened— keyboard nav treats the child as part of the parent.
ImGuiWindowFlags (the fourth arg) governs the child’s scrollbar
policy and window-level behavior:
HorizontalScrollbar— enable the bottom scroll track when content overflows horizontally (default = none).AlwaysVerticalScrollbar/AlwaysHorizontalScrollbar— keep the bar visible even when the content fits.NoMove/NoResize/NoBackground— standard window knobs.
The two flag sets compose freely; pick from each based on the child’s chrome and scroll needs.
ChildState — what the snapshot reports
ChildState captures four floats:
var SCROLL_A : ChildState
// After the frame renders:
// SCROLL_A.size : float2 // sticky — what was passed in
// SCROLL_A.scroll : float2 // current scroll (GetScrollX/Y)
// SCROLL_A.scroll_max : float2 // GetScrollMaxX/Y for this content
// SCROLL_A.child_flags / SCROLL_A.window_flags // sticky
Snapshot reports them under <window>/SCROLL_A. Drivers that want to
verify “the user scrolled to row 12” compare scroll.y against a
known threshold. scroll_max is read AFTER the body invoke — it
depends on the content extent, which the body just emitted.
Auto-resize variants
The B child uses AutoResizeY | FrameStyle:
child(AUTO_B, (text = "auto_b",
size = float2(360.0f, 0.0f),
child_flags = ImGuiChildFlags.AutoResizeY | ImGuiChildFlags.FrameStyle,
window_flags = ImGuiWindowFlags.None)) {
text("Three rows of input chrome")
checkbox(B_VSYNC, (text = "VSync"))
slider_int(B_LIMIT, (text = "frame limit"))
}
Size’s Y is 0.0f — required when AutoResizeY is active so ImGui
treats the slot as auto. The height grows to fit the body each frame.
scroll and scroll_max both report (0, 0) for an AutoResize child:
no overflow means no scroll range. ChildState.size is the
caller-provided input — for AutoResizeY it stays at (360.0f, 0.0f),
so it does NOT tell you the rendered height. The wrapper does not
currently expose the auto-computed extent; if you need it, call
GetWindowSize() inside the child body, or place a sentinel widget
at the end and read its bbox bottom from the snapshot.
Horizontal scroll
window_flags.HorizontalScrollbar enables the bottom track:
child(SCROLL_C, (text = "scroll_c",
size = float2(720.0f, 90.0f),
child_flags = ImGuiChildFlags.Border,
window_flags = ImGuiWindowFlags.HorizontalScrollbar)) {
text(LONG_LINE, (text = "very wide content: lorem ipsum..."))
}
Without the flag, overlong single-line text would be clipped. With it,
the user drags the bottom bar and SCROLL_C.scroll.x mirrors the
position.
Standalone vs live
Same convention as the other tutorials.
Driving from outside
External drivers can wheel-scroll the active child by posting an
imgui_mouse_scroll command (the live counterpart to
ImGui_ImplGlfw’s wheel events):
curl -X POST -d '{"name":"imgui_mouse_scroll","args":{"x":0.0,"y":-3.0}}' \
localhost:9090/command
The cursor must be over the child window for ImGui to attribute the
scroll. The recording driver uses this exact channel to nudge
SCROLL_A between narration stages.
See also
Full source: examples/tutorial/child.das
Features-side demo: examples/features/child_scroll_reenter.das — the
child_scroll_reenter helper for nudging an existing child’s scroll
from outside its block.
Sibling: Containers — the umbrella tour of container rails.
Boost macros — the macro layer.