pane_ui 0.1.0

A RON-driven, hot-reloadable wgpu UI library with spring animations and consistent scaling
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
(
    hot_reload: true,
    headless_accessible: true,
    shader_dirs: ["shaders"],
    style_dirs: ["styles"],
    background: Some("assets/logo.png"),
    default_style: Some("frosted_glass"),
    start_root: "main_menu",
    roots: [

        // ── Main Menu ──────────────────────────────────────────────────────
        (
            name: "main_menu",
            actors: [
    (
    id: "cursor_glow",
    x: 0.0, y: 0.0,
    width: 64.0, height: 64.0,
    gif: Some("assets/test.gif"),         // base gif, always loops
    z_front: true,
    behaviours: [
        ( trigger: Always,      action: FollowCursor(speed: 10.0, trail: 0.1) ),
        ( trigger: OnHoverSelf, action: SwapGif(path: "assets/hover.gif") ),
    ]
)
],
            images: [
                ( id: "test_gif", x: -500.0, y: -100.0, width: 200.0, height: 200.0, path: "assets/test.gif", gif_mode: Some(Loop) ),
            ],
            dividers: [
                ( id: "gif_divider", x: -500.0, y: 105.0, width: 220.0, height: 2.0, style: "plain" ),
            ],
            buttons: [
                ( id: "btn_buttons",     x: -170.0, y: -515.0, width: 340.0, height: 70.0, text: "Buttons",       tooltip: Some("Button styles demo"),        style: "frosted_glass", on_press: SwitchRoot("button_demo")      ),
                ( id: "btn_scroll",      x: -170.0, y: -430.0, width: 340.0, height: 70.0, text: "Scroll List",   tooltip: Some("Scrollable list demo"),      style: "frosted_glass", on_press: SwitchRoot("scroll_demo")      ),
                ( id: "btn_bars",        x: -170.0, y: -345.0, width: 340.0, height: 70.0, text: "Bars",          tooltip: Some("Edge-anchored bars demo"),   style: "frosted_glass", on_press: SwitchRoot("bar_demo")         ),
                ( id: "btn_toggles",     x: -170.0, y: -260.0, width: 340.0, height: 70.0, text: "Toggles",       tooltip: Some("Toggle switch demo"),        style: "frosted_glass", on_press: SwitchRoot("toggle_demo")      ),
                ( id: "btn_sliders",     x: -170.0, y: -175.0, width: 340.0, height: 70.0, text: "Sliders",       tooltip: Some("Slider demo"),               style: "frosted_glass", on_press: SwitchRoot("slider_demo")      ),
                ( id: "btn_textbox",     x: -170.0, y:  -90.0, width: 340.0, height: 70.0, text: "Text Input",    tooltip: Some("Text box demo"),             style: "frosted_glass", on_press: SwitchRoot("textbox_demo")     ),
                ( id: "btn_popout",      x: -170.0, y:   -5.0, width: 340.0, height: 70.0, text: "Popout Panels", tooltip: Some("Animated slide-in panels"),  style: "frosted_glass", on_press: SwitchRoot("popout_demo")      ),
                ( id: "btn_progress",    x: -170.0, y:   80.0, width: 340.0, height: 70.0, text: "Progress Bars", tooltip: Some("Read-only progress bars"),   style: "frosted_glass", on_press: SwitchRoot("progress_demo")    ),
                ( id: "btn_dropdown",    x: -170.0, y:  165.0, width: 340.0, height: 70.0, text: "Dropdowns",     tooltip: Some("Dropdown selector demo"),    style: "frosted_glass", on_press: SwitchRoot("dropdown_demo")    ),
                ( id: "btn_radio",       x: -170.0, y:  250.0, width: 340.0, height: 70.0, text: "Radio Groups",  tooltip: Some("Radio group demo"),          style: "frosted_glass", on_press: SwitchRoot("radio_demo")       ),
                ( id: "btn_scroll_pane", x: -170.0, y:  335.0, width: 340.0, height: 70.0, text: "Scroll Pane",   tooltip: Some("Scrollable container demo"), style: "frosted_glass", on_press: SwitchRoot("scroll_pane_demo") ),
                ( id: "quit",            x: -170.0, y:  425.0, width: 340.0, height: 70.0, text: "Quit",          tooltip: None, nav_default: true,                             style: "plain",         on_press: Quit                           ),
                ( id: "btn_save",        x:  200.0, y:  -60.0, width: 200.0, height: 70.0, text: "Save",          tooltip: Some("Show a save toast"),        style: "frosted_glass", on_press: Toast(message: "Saved!",    duration: 2.0, x: 0.0, y: -460.0, width: 300.0, height: 60.0) ),
                ( id: "btn_delete",      x:  200.0, y:   25.0, width: 200.0, height: 70.0, text: "Delete",        tooltip: Some("Show a delete toast"),      style: "sharp_outline", on_press: Toast(message: "Deleted.",  duration: 2.0, x: 0.0, y: -460.0, width: 300.0, height: 60.0) ),
            ],
        ),

        // ── Button Demo ────────────────────────────────────────────────────
        (
            name: "button_demo",
            labels: [
                ( id: "lbl_fg",  x: -500.0, y: -460.0, text: "frosted_glass", size: 22.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.6)) ),
                ( id: "lbl_ret", x: -130.0, y: -460.0, text: "retro",         size: 22.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.6)) ),
                ( id: "lbl_out", x:  200.0, y: -460.0, text: "sharp_outline", size: 22.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.6)) ),
                ( id: "lbl_pl",  x: -500.0, y:  -10.0, text: "plain",         size: 22.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.6)) ),
                ( id: "lbl_gp",  x: -130.0, y:  -10.0, text: "glass_pill",    size: 22.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.6)) ),
                ( id: "lbl_emb", x:  200.0, y:  -10.0, text: "emboss",        size: 22.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.6)) ),
            ],
            buttons: [
                ( id: "fg1", x: -580.0, y: -420.0, width: 260.0, height: 65.0, text: "Hover Me",    tooltip: Some("Frosted hover"),      style: "frosted_glass", on_press: Print("[frosted] 1") ),
                ( id: "fg2", x: -580.0, y: -340.0, width: 260.0, height: 65.0, text: "Click Me",    tooltip: None,                       style: "frosted_glass", on_press: Print("[frosted] 2") ),
                ( id: "fg3", x: -580.0, y: -260.0, width: 260.0, height: 65.0, text: "Spring!",     tooltip: Some("Watch it bounce"),    style: "frosted_glass", on_press: Print("[frosted] 3") ),
                ( id: "rt1", x: -210.0, y: -420.0, width: 260.0, height: 65.0, text: "PLAYER 1",    tooltip: Some("Insert coin"),        style: "retro",         on_press: Print("[retro] 1")   ),
                ( id: "rt2", x: -210.0, y: -340.0, width: 260.0, height: 65.0, text: "PLAYER 2",    tooltip: None,                       style: "retro",         on_press: Print("[retro] 2")   ),
                ( id: "rt3", x: -210.0, y: -260.0, width: 260.0, height: 65.0, text: "HIGH SCORES", tooltip: Some("Top 10"),             style: "retro",         on_press: Print("[retro] 3")   ),
                ( id: "ot1", x:  160.0, y: -420.0, width: 260.0, height: 65.0, text: "Outline",     tooltip: Some("Clean border"),       style: "sharp_outline", on_press: Print("[outline] 1") ),
                ( id: "ot2", x:  160.0, y: -340.0, width: 260.0, height: 65.0, text: "Minimal",     tooltip: None,                       style: "sharp_outline", on_press: Print("[outline] 2") ),
                ( id: "ot3", x:  160.0, y: -260.0, width: 260.0, height: 65.0, text: "Ghost",       tooltip: Some("Almost invisible"),   style: "sharp_outline", on_press: Print("[outline] 3") ),
                ( id: "pl1", x: -580.0, y:   30.0, width: 260.0, height: 65.0, text: "Plain",       tooltip: Some("Flat solid"),         style: "plain",         on_press: Print("[plain] 1")   ),
                ( id: "pl2", x: -580.0, y:  110.0, width: 260.0, height: 65.0, text: "No Effects",  tooltip: None,                       style: "plain",         on_press: Print("[plain] 2")   ),
                ( id: "pl3", x: -580.0, y:  190.0, width: 260.0, height: 65.0, text: "Clean Look",  tooltip: Some("Simple"),             style: "plain",         on_press: Print("[plain] 3")   ),
                ( id: "gp1", x: -210.0, y:   30.0, width: 260.0, height: 65.0, text: "Glass Pill",  tooltip: Some("Pill shape"),         style: "glass_pill",    on_press: Print("[glass_pill] 1") ),
                ( id: "gp2", x: -210.0, y:  110.0, width: 260.0, height: 65.0, text: "Smooth",      tooltip: None,                       style: "glass_pill",    on_press: Print("[glass_pill] 2") ),
                ( id: "gp3", x: -210.0, y:  190.0, width: 260.0, height: 65.0, text: "Rounded",     tooltip: Some("Hover to see"),       style: "glass_pill",    on_press: Print("[glass_pill] 3") ),
                ( id: "em1", x:  160.0, y:   30.0, width: 260.0, height: 65.0, text: "Emboss",      tooltip: Some("Raised surface"),     style: "emboss",        on_press: Print("[emboss] 1")  ),
                ( id: "em2", x:  160.0, y:  110.0, width: 260.0, height: 65.0, text: "Deep Shadow", tooltip: None,                       style: "emboss",        on_press: Print("[emboss] 2")  ),
                ( id: "em3", x:  160.0, y:  190.0, width: 260.0, height: 65.0, text: "Raised",      tooltip: Some("Notice depth"),       style: "emboss",        on_press: Print("[emboss] 3")  ),
                ( id: "btn_back", x: -170.0, y: 430.0, width: 340.0, height: 70.0, text: "Back", tooltip: None, style: "plain", on_press: SwitchRoot("main_menu") ),
            ],
        ),

        // ── Scroll List Demo ──────────────────────────────────────────────
        (
            name: "scroll_demo",
            buttons: [
                ( id: "sl_back", x: -170.0, y: 430.0, width: 340.0, height: 70.0, text: "Back", tooltip: None, style: "plain", on_press: SwitchRoot("main_menu") ),
            ],
            scroll_lists: [
                (
                    id: "demo_list",
                    x: -170.0, y: -490.0,
                    width: 340.0, height: 880.0,
                    pad_left: 12.0, pad_right: 12.0,
                    pad_top: 12.0, pad_bottom: 12.0,
                    gap: 8.0,
                    style: Some("frosted_glass"),
                    items: [
                        ( id: "item1",  height: 60.0, text: "Item One",      tooltip: None, style: "plain", on_press: Print("[scroll] 1")  ),
                        ( id: "item2",  height: 60.0, text: "Item Two",      tooltip: None, style: "plain", on_press: Print("[scroll] 2")  ),
                        ( id: "item3",  height: 60.0, text: "Item Three",    tooltip: None, style: "plain", on_press: Print("[scroll] 3")  ),
                        ( id: "item4",  height: 60.0, text: "Item Four",     tooltip: None, style: "plain", on_press: Print("[scroll] 4")  ),
                        ( id: "item5",  height: 60.0, text: "Item Five",     tooltip: None, style: "plain", on_press: Print("[scroll] 5")  ),
                        ( id: "item6",  height: 60.0, text: "Item Six",      tooltip: None, style: "plain", on_press: Print("[scroll] 6")  ),
                        ( id: "item7",  height: 60.0, text: "Item Seven",    tooltip: None, style: "plain", on_press: Print("[scroll] 7")  ),
                        ( id: "item8",  height: 60.0, text: "Item Eight",    tooltip: None, style: "plain", on_press: Print("[scroll] 8")  ),
                        ( id: "item9",  height: 60.0, text: "Item Nine",     tooltip: None, style: "plain", on_press: Print("[scroll] 9")  ),
                        ( id: "item10", height: 60.0, text: "Item Ten",      tooltip: None, style: "plain", on_press: Print("[scroll] 10") ),
                        ( id: "item11", height: 60.0, text: "Item Eleven",   tooltip: None, style: "plain", on_press: Print("[scroll] 11") ),
                        ( id: "item12", height: 60.0, text: "Item Twelve",   tooltip: None, style: "plain", on_press: Print("[scroll] 12") ),
                        ( id: "item13", height: 60.0, text: "Item Thirteen", tooltip: None, style: "plain", on_press: Print("[scroll] 13") ),
                        ( id: "item14", height: 60.0, text: "Item Fourteen", tooltip: None, style: "plain", on_press: Print("[scroll] 14") ),
                        ( id: "item15", height: 60.0, text: "Item Fifteen",  tooltip: None, style: "plain", on_press: Print("[scroll] 15") ),
                    ],
                ),
            ],
        ),

        // ── Bar Demo ──────────────────────────────────────────────────────
        (
            name: "bar_demo",
            bars: [
                (
                    id: "top_bar",
                    edge: Top,
                    thickness: 80.0,
                    pad: 10.0,
                    gap: 8.0,
                    style: Some("frosted_glass"),
                    items: [
                        Label(( id: "logo_lbl", text: "pane", size: 32.0, color: Some((r:1.0,g:1.0,b:1.0,a:1.0)) )),
                        Spacer,
                        Button(( id: "bar_back", height: 60.0, text: "Back", tooltip: None, style: "plain", on_press: SwitchRoot("main_menu") )),
                    ],
                ),
                (
                    id: "bottom_bar",
                    edge: Bottom,
                    thickness: 60.0,
                    pad: 8.0,
                    gap: 8.0,
                    style: Some("frosted_glass"),
                    items: [
                        Label(( id: "status_lbl", text: "Status: OK", size: 24.0, color: None )),
                        Spacer,
                        Button(( id: "bb_save",   height: 44.0, text: "Save",   tooltip: Some("Save state"), style: "plain", on_press: Print("[bar] save")   )),
                        Button(( id: "bb_export", height: 44.0, text: "Export", tooltip: Some("Export"),     style: "plain", on_press: Print("[bar] export") )),
                        Label(( id: "ver_lbl", text: "v0.1.0", size: 24.0, color: None )),
                    ],
                ),
                (
                    id: "left_bar",
                    edge: Left,
                    thickness: 80.0,
                    pad: 10.0,
                    gap: 8.0,
                    style: Some("plain"),
                    items: [
                        Button(( id: "nav1", height: 60.0, text: "A", tooltip: Some("Section A"), style: "plain", on_press: Print("[bar] A")     )),
                        Button(( id: "nav2", height: 60.0, text: "B", tooltip: Some("Section B"), style: "plain", on_press: Print("[bar] B")     )),
                        Button(( id: "nav3", height: 60.0, text: "C", tooltip: Some("Section C"), style: "plain", on_press: Print("[bar] C")     )),
                        Spacer,
                        Button(( id: "nav4", height: 60.0, text: "?", tooltip: Some("About"),     style: "plain", on_press: Print("[bar] about") )),
                    ],
                ),
                (
                    id: "right_bar",
                    edge: Right,
                    thickness: 80.0,
                    pad: 10.0,
                    gap: 8.0,
                    style: Some("plain"),
                    items: [
                        Button(( id: "rb1", height: 60.0, text: "1", tooltip: Some("Tool 1"), style: "plain",         on_press: Print("[bar] tool 1") )),
                        Button(( id: "rb2", height: 60.0, text: "2", tooltip: Some("Tool 2"), style: "plain",         on_press: Print("[bar] tool 2") )),
                        Button(( id: "rb3", height: 60.0, text: "3", tooltip: Some("Tool 3"), style: "plain",         on_press: Print("[bar] tool 3") )),
                        Spacer,
                        Button(( id: "rb4", height: 60.0, text: "X", tooltip: Some("Close"),  style: "sharp_outline", on_press: Print("[bar] close")  )),
                    ],
                ),
            ],
        ),

        // ── Toggle Demo ───────────────────────────────────────────────────
        (
            name: "toggle_demo",
            toggles: [
                ( id: "tog_music",      x: -170.0, y: -320.0, width: 340.0, height: 65.0, text: "Music",          tooltip: Some("Toggle background music"), checked: true,  style_off: "sharp_outline", style_on: "plain", on_change: Print ),
                ( id: "tog_sfx",        x: -170.0, y: -240.0, width: 340.0, height: 65.0, text: "Sound Effects",  tooltip: Some("Toggle SFX"),              checked: true,  style_off: "sharp_outline", style_on: "plain", on_change: Print ),
                ( id: "tog_fullscreen", x: -170.0, y: -160.0, width: 340.0, height: 65.0, text: "Fullscreen",     tooltip: Some("Toggle fullscreen mode"),  checked: false, style_off: "sharp_outline", style_on: "plain", on_change: Print ),
                ( id: "tog_vsync",      x: -170.0, y:  -80.0, width: 340.0, height: 65.0, text: "VSync",          tooltip: Some("Toggle vertical sync"),    checked: true,  style_off: "sharp_outline", style_on: "plain", on_change: Print ),
                ( id: "tog_hud",        x: -170.0, y:    0.0, width: 340.0, height: 65.0, text: "Show HUD",       tooltip: Some("Toggle HUD visibility"),   checked: true,  style_off: "sharp_outline", style_on: "plain", on_change: Print ),
                ( id: "tog_hints",      x: -170.0, y:   80.0, width: 340.0, height: 65.0, text: "Show Hints",     tooltip: Some("Toggle gameplay hints"),   checked: false, style_off: "sharp_outline", style_on: "plain", on_change: Print ),
            ],
            buttons: [
                ( id: "tog_back", x: -170.0, y: 430.0, width: 340.0, height: 70.0, text: "Back", tooltip: None, style: "plain", on_press: SwitchRoot("main_menu") ),
            ],
        ),

        // ── Slider Demo ───────────────────────────────────────────────────
        (
            name: "slider_demo",
            labels: [
                ( id: "lbl_vol",    x: -170.0, y: -310.0, text: "Volume",      size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
                ( id: "lbl_bright", x: -170.0, y: -200.0, text: "Brightness",  size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
                ( id: "lbl_speed",  x: -170.0, y:  -90.0, text: "Speed",       size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
                ( id: "lbl_zoom",   x: -170.0, y:   20.0, text: "Zoom",        size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
                ( id: "lbl_sens",   x: -170.0, y:  130.0, text: "Sensitivity", size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
            ],
            sliders: [
                ( id: "vol",    x: -170.0, y: -275.0, width: 340.0, height: 40.0, min: 0.0, max: 1.0, value: 0.75, style_track: "glass_pill",    style_thumb: "glass_pill",    on_change: Custom("volume")      ),
                ( id: "bright", x: -170.0, y: -165.0, width: 340.0, height: 40.0, min: 0.0, max: 1.0, value: 0.5,  style_track: "glass_pill",    style_thumb: "glass_pill",    on_change: Custom("brightness")  ),
                ( id: "speed",  x: -170.0, y:  -55.0, width: 340.0, height: 40.0, min: 0.5, max: 3.0, value: 1.0,  step: Some(0.25), style_track: "plain", style_thumb: "plain", on_change: Custom("speed") ),
                ( id: "zoom",   x: -170.0, y:   55.0, width: 340.0, height: 40.0, min: 1.0, max: 5.0, value: 2.0,  step: Some(0.5),  style_track: "plain", style_thumb: "plain", on_change: Custom("zoom")  ),
                ( id: "sens",   x: -170.0, y:  165.0, width: 340.0, height: 40.0, min: 0.1, max: 2.0, value: 0.8,  style_track: "frosted_glass", style_thumb: "frosted_glass", on_change: Custom("sensitivity") ),
            ],
            buttons: [
                ( id: "sld_back", x: -170.0, y: 430.0, width: 340.0, height: 70.0, text: "Back", tooltip: None, style: "plain", on_press: SwitchRoot("main_menu") ),
            ],
        ),

        // ── Text Box Demo ─────────────────────────────────────────────────
        (
            name: "textbox_demo",
            labels: [
                ( id: "lbl_tb_title", x: -200.0, y: -490.0, text: "Text Input",                                       size: 36.0, color: Some((r:1.0,g:1.0,b:1.0,a:1.0))  ),
                ( id: "lbl_name",     x: -200.0, y: -430.0, text: "Username  (Ctrl+A/C/X/V · shift+arrows · scroll)", size: 20.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.6))  ),
                ( id: "lbl_pass",     x: -200.0, y: -340.0, text: "Password  (masked)",                               size: 20.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.6))  ),
                ( id: "lbl_notes",    x: -200.0, y: -255.0, text: "Notes  (multi-line · Enter=newline · Ctrl+Enter=submit · scroll)", size: 20.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.6)) ),
                ( id: "lbl_code",     x: -200.0, y:   80.0, text: "Invite Code  (max 9 chars)",                       size: 20.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.6))  ),
            ],
            text_boxes: [
                ( id: "tb_username", x: -200.0, y: -400.0, width: 400.0, height: 52.0,
                  hint: "Your username…",
                  style: "plain", style_focus: Some("frosted_glass"),
                  on_change: Custom("username"), on_submit: Custom("username_submit") ),

                ( id: "tb_password", x: -200.0, y: -310.0, width: 400.0, height: 52.0,
                  hint: "Enter password…",
                  password: true,
                  style: "plain", style_focus: Some("frosted_glass"),
                  on_change: None, on_submit: Custom("login") ),

                ( id: "tb_notes", x: -200.0, y: -220.0, width: 400.0, height: 240.0,
                  hint: "Type here…",
                  multiline: true,
                  style: "plain", style_focus: Some("frosted_glass"),
                  on_change: Custom("notes"), on_submit: Custom("notes_submit") ),

                ( id: "tb_code", x: -200.0, y: 110.0, width: 400.0, height: 52.0,
                  hint: "XXXX-XXXX",
                  max_len: Some(9),
                  style: "retro", style_focus: Some("retro"),
                  on_change: Custom("code"), on_submit: Custom("code_submit") ),
            ],
            buttons: [
                ( id: "tb_back", x: -170.0, y: 430.0, width: 340.0, height: 70.0, text: "Back", tooltip: None, style: "plain", on_press: SwitchRoot("main_menu") ),
            ],
        ),

        // ── Popout Demo ───────────────────────────────────────────────────
        (
            name: "popout_demo",
            labels: [
                ( id: "pd_hint", x: -250.0, y: -50.0, text: "Click the arrows to open panels", size: 28.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.7)) ),
            ],
            buttons: [
                ( id: "pd_back", x: -170.0, y: 430.0, width: 340.0, height: 70.0, text: "Back", tooltip: None, style: "plain", on_press: SwitchRoot("main_menu") ),
            ],
            popouts: [
                (
                    id: "left_panel",
                    width: 280.0, height: 500.0,
                    toggle_id: "left_toggle",
                    style: Some("frosted_glass"),
                    edge: Some(Left),
                    items: [
                        Button(( id: "left_toggle", x: 280.0, y: 210.0, width: 48.0, height: 80.0, text: ">", tooltip: Some("Toggle left panel"), style: "plain", on_press: Print("left toggle") )),
                        Button(( id: "lp_btn1", x: 20.0, y:  20.0, width: 240.0, height: 60.0, text: "Left Action 1", tooltip: None, style: "plain", on_press: Print("[popout] left 1") )),
                        Button(( id: "lp_btn2", x: 20.0, y:  95.0, width: 240.0, height: 60.0, text: "Left Action 2", tooltip: None, style: "plain", on_press: Print("[popout] left 2") )),
                        Button(( id: "lp_btn3", x: 20.0, y: 170.0, width: 240.0, height: 60.0, text: "Left Action 3", tooltip: None, style: "plain", on_press: Print("[popout] left 3") )),
                        Button(( id: "lp_btn4", x: 20.0, y: 245.0, width: 240.0, height: 60.0, text: "Left Action 4", tooltip: None, style: "plain", on_press: Print("[popout] left 4") )),
                        Button(( id: "lp_btn5", x: 20.0, y: 320.0, width: 240.0, height: 60.0, text: "Left Action 5", tooltip: None, style: "plain", on_press: Print("[popout] left 5") )),
                    ],
                ),
                (
                    id: "right_panel",
                    width: 280.0, height: 500.0,
                    toggle_id: "right_toggle",
                    style: Some("frosted_glass"),
                    edge: Some(Right),
                    items: [
                        Button(( id: "right_toggle", x: -48.0, y: 210.0, width: 48.0, height: 80.0, text: "<", tooltip: Some("Toggle right panel"), style: "plain",         on_press: Print("right toggle") )),
                        Button(( id: "rp_btn1", x: 20.0, y:  20.0, width: 240.0, height: 60.0, text: "Right Action 1", tooltip: None, style: "sharp_outline", on_press: Print("[popout] right 1") )),
                        Button(( id: "rp_btn2", x: 20.0, y:  95.0, width: 240.0, height: 60.0, text: "Right Action 2", tooltip: None, style: "sharp_outline", on_press: Print("[popout] right 2") )),
                        Button(( id: "rp_btn3", x: 20.0, y: 170.0, width: 240.0, height: 60.0, text: "Right Action 3", tooltip: None, style: "sharp_outline", on_press: Print("[popout] right 3") )),
                        Button(( id: "rp_btn4", x: 20.0, y: 245.0, width: 240.0, height: 60.0, text: "Right Action 4", tooltip: None, style: "sharp_outline", on_press: Print("[popout] right 4") )),
                        Button(( id: "rp_btn5", x: 20.0, y: 320.0, width: 240.0, height: 60.0, text: "Right Action 5", tooltip: None, style: "sharp_outline", on_press: Print("[popout] right 5") )),
                    ],
                ),
            ],
        ),

        // ── Progress Bar Demo ─────────────────────────────────────────────
        (
            name: "progress_demo",
            labels: [
                ( id: "lbl_p1", x: -170.0, y: -340.0, text: "Loading",    size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
                ( id: "lbl_p2", x: -170.0, y: -230.0, text: "Health",     size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
                ( id: "lbl_p3", x: -170.0, y: -120.0, text: "XP",         size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
                ( id: "lbl_p4", x: -170.0, y:  -10.0, text: "Fuel",       size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
                ( id: "lbl_p5", x: -170.0, y:  100.0, text: "Corruption", size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
            ],
            progress_bars: [
                ( id: "pb_loading", x: -170.0, y: -305.0, width: 340.0, height: 36.0, value: 0.72, style_track: "plain",         style_fill: "frosted_glass" ),
                ( id: "pb_health",  x: -170.0, y: -195.0, width: 340.0, height: 36.0, value: 0.55, style_track: "plain",         style_fill: "glass_pill"    ),
                ( id: "pb_xp",      x: -170.0, y:  -85.0, width: 340.0, height: 36.0, value: 0.33, style_track: "sharp_outline", style_fill: "plain"         ),
                ( id: "pb_fuel",    x: -170.0, y:   25.0, width: 340.0, height: 36.0, value: 0.90, style_track: "plain",         style_fill: "emboss"        ),
                ( id: "pb_corrupt", x: -170.0, y:  135.0, width: 340.0, height: 36.0, value: 0.18, style_track: "plain",         style_fill: "retro"         ),
            ],
            buttons: [
                ( id: "pb_back", x: -170.0, y: 430.0, width: 340.0, height: 70.0, text: "Back", tooltip: None, style: "plain", on_press: SwitchRoot("main_menu") ),
            ],
        ),

        // ── Dropdown Demo ─────────────────────────────────────────────────
        (
            name: "dropdown_demo",
            labels: [
                ( id: "lbl_quality",  x: -390.0, y: -370.0, text: "Render Quality", size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
                ( id: "lbl_res",      x: -390.0, y: -260.0, text: "Resolution",     size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
                ( id: "lbl_lang",     x: -390.0, y: -150.0, text: "Language",       size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
                ( id: "lbl_anti",     x:   50.0, y: -370.0, text: "Anti-Aliasing",  size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
                ( id: "lbl_shadow",   x:   50.0, y: -260.0, text: "Shadow Quality", size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
            ],
            dropdowns: [
                ( id: "dd_quality", x: -390.0, y: -335.0, width: 300.0, height: 55.0, options: ["Low", "Medium", "High", "Ultra"],              selected: 2, tooltip: Some("Overall render quality"), on_change: Custom("quality")  ),
                ( id: "dd_res",     x: -390.0, y: -225.0, width: 300.0, height: 55.0, options: ["1280x720", "1920x1080", "2560x1440", "4K"],    selected: 1, tooltip: Some("Display resolution"),     on_change: Custom("res")      ),
                ( id: "dd_lang",    x: -390.0, y: -115.0, width: 300.0, height: 55.0, options: ["English", "French", "German", "Spanish", "Japanese"], selected: 0, tooltip: Some("Interface language"), on_change: Custom("lang") ),
                ( id: "dd_anti",    x:   50.0, y: -335.0, width: 300.0, height: 55.0, options: ["Off", "2x MSAA", "4x MSAA", "8x MSAA", "TAA"], selected: 2, tooltip: Some("Anti-aliasing mode"),    on_change: Custom("anti")     ),
                ( id: "dd_shadow",  x:   50.0, y: -225.0, width: 300.0, height: 55.0, options: ["Off", "Low", "Medium", "High", "Ultra"],        selected: 3, tooltip: Some("Shadow map quality"),    on_change: Custom("shadow")   ),
            ],
            buttons: [
                ( id: "dd_back", x: -170.0, y: 430.0, width: 340.0, height: 70.0, text: "Back", tooltip: None, style: "plain", on_press: SwitchRoot("main_menu") ),
            ],
        ),

        // ── Radio Group Demo ──────────────────────────────────────────────
        (
            name: "radio_demo",
            labels: [
                ( id: "lbl_diff",   x: -390.0, y: -370.0, text: "Difficulty",   size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
                ( id: "lbl_class",  x: -390.0, y: -180.0, text: "Class",        size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
                ( id: "lbl_region", x:   50.0, y: -370.0, text: "Region",       size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
                ( id: "lbl_mode",   x:   50.0, y: -180.0, text: "Game Mode",    size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
            ],
            radio_groups: [
                ( id: "rg_diff",   x: -390.0, y: -335.0, width: 300.0, height: 130.0, options: ["Easy", "Normal", "Hard"],                    selected: 1, gap: 8.0, on_change: Custom("difficulty") ),
                ( id: "rg_class",  x: -390.0, y: -145.0, width: 300.0, height: 170.0, options: ["Warrior", "Mage", "Rogue", "Paladin"],        selected: 0, gap: 8.0, on_change: Custom("class")      ),
                ( id: "rg_region", x:   50.0, y: -335.0, width: 300.0, height: 170.0, options: ["Americas", "Europe", "Asia", "Oceania"],      selected: 0, gap: 8.0, on_change: Custom("region")     ),
                ( id: "rg_mode",   x:   50.0, y: -145.0, width: 300.0, height: 130.0, options: ["Story", "Standard", "Hardcore"],              selected: 1, gap: 8.0, on_change: Custom("mode")       ),
            ],
            buttons: [
                ( id: "rg_back", x: -170.0, y: 430.0, width: 340.0, height: 70.0, text: "Back", tooltip: None, style: "plain", on_press: SwitchRoot("main_menu") ),
            ],
        ),

        // ── Scroll Pane Demo ──────────────────────────────────────────────
        (
            name: "scroll_pane_demo",
            labels: [
                ( id: "lbl_settings", x: -390.0, y: -370.0, text: "Game Settings",       size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
                ( id: "lbl_controls", x: -600.0, y:   300.0, text: "Controls (scroll →)", size: 26.0, color: Some((r:1.0,g:1.0,b:1.0,a:0.8)) ),
            ],
            scroll_panes: [
                (
                    id: "settings_pane",
                    x: -160.0, y: -500.0,
                    width: 320.0, height: 680.0,
                    pad_left: 12.0, pad_right: 12.0,
                    pad_top: 12.0, pad_bottom: 12.0,
                    gap: 10.0,
                    items: [
                        Button(( id: "sp_opt_a",  x: 0.0, y: 0.0, width: 296.0, height: 55.0, text: "Graphics",    style: "frosted_glass", on_press: Print("[pane] graphics")   )),
                        Slider(( id: "sp_vol",    x: 0.0, y: 0.0, width: 296.0, height: 40.0, min: 0.0, max: 1.0, value: 0.8, style_track: "plain", style_thumb: "plain", on_change: Custom("volume") )),
                        Toggle(( id: "sp_vsync",  x: 0.0, y: 0.0, width: 296.0, height: 55.0, text: "VSync",       style_off: "sharp_outline", style_on: "plain", on_change: Print )),
                        Toggle(( id: "sp_hud",    x: 0.0, y: 0.0, width: 296.0, height: 55.0, text: "Show HUD",    style_off: "sharp_outline", style_on: "plain", on_change: Print )),
                        Button(( id: "sp_opt_b",  x: 0.0, y: 0.0, width: 296.0, height: 55.0, text: "Audio",       style: "frosted_glass", on_press: Print("[pane] audio")      )),
                        Slider(( id: "sp_bright", x: 0.0, y: 0.0, width: 296.0, height: 40.0, min: 0.0, max: 1.0, value: 0.6, style_track: "plain", style_thumb: "plain", on_change: Custom("brightness") )),
                        Button(( id: "sp_opt_c",  x: 0.0, y: 0.0, width: 296.0, height: 55.0, text: "Gameplay",    style: "frosted_glass", on_press: Print("[pane] gameplay")   )),
                        Button(( id: "sp_opt_d",  x: 0.0, y: 0.0, width: 296.0, height: 55.0, text: "Accessibility", style: "frosted_glass", on_press: Print("[pane] access")  )),
                        Toggle(( id: "sp_hints",  x: 0.0, y: 0.0, width: 296.0, height: 55.0, text: "Show Hints",  style_off: "sharp_outline", style_on: "plain", on_change: Print )),
                        Button(( id: "sp_opt_e",  x: 0.0, y: 0.0, width: 296.0, height: 55.0, text: "Network",     style: "frosted_glass", on_press: Print("[pane] network")    )),
                        Button(( id: "sp_opt_f",  x: 0.0, y: 0.0, width: 296.0, height: 55.0, text: "Account",     style: "frosted_glass", on_press: Print("[pane] account")    )),
                        Button(( id: "sp_opt_g",  x: 0.0, y: 0.0, width: 296.0, height: 55.0, text: "Reset All",   style: "sharp_outline", on_press: Print("[pane] reset")      )),
                    ],
                ),
                (
                    id: "controls_pane",
                    x: -390.0, y: 250.0,
                    width: 760.0, height: 110.0,
                    pad_left: 10.0, pad_right: 10.0,
                    pad_top: 10.0, pad_bottom: 10.0,
                    gap: 10.0,
                    horizontal: true,
                    items: [
                        Button(( id: "cp_move",   x: 0.0, y: 0.0, width: 140.0, height: 90.0, text: "Move: WASD",      style: "plain",         on_press: Print("[ctrl] move")   )),
                        Button(( id: "cp_jump",   x: 0.0, y: 0.0, width: 140.0, height: 90.0, text: "Jump: Space",     style: "plain",         on_press: Print("[ctrl] jump")   )),
                        Button(( id: "cp_attack", x: 0.0, y: 0.0, width: 140.0, height: 90.0, text: "Attack: LMB",     style: "plain",         on_press: Print("[ctrl] attack") )),
                        Button(( id: "cp_block",  x: 0.0, y: 0.0, width: 140.0, height: 90.0, text: "Block: RMB",      style: "plain",         on_press: Print("[ctrl] block")  )),
                        Button(( id: "cp_dodge",  x: 0.0, y: 0.0, width: 140.0, height: 90.0, text: "Dodge: Shift",    style: "plain",         on_press: Print("[ctrl] dodge")  )),
                        Button(( id: "cp_menu",   x: 0.0, y: 0.0, width: 140.0, height: 90.0, text: "Menu: Escape",    style: "plain",         on_press: Print("[ctrl] menu")   )),
                        Button(( id: "cp_map",    x: 0.0, y: 0.0, width: 140.0, height: 90.0, text: "Map: M",          style: "plain",         on_press: Print("[ctrl] map")    )),
                        Button(( id: "cp_inv",    x: 0.0, y: 0.0, width: 140.0, height: 90.0, text: "Inventory: I",    style: "plain",         on_press: Print("[ctrl] inv")    )),
                        Button(( id: "cp_sprint", x: 0.0, y: 0.0, width: 140.0, height: 90.0, text: "Sprint: Ctrl",    style: "plain",         on_press: Print("[ctrl] sprint") )),
                        Button(( id: "cp_crouch", x: 0.0, y: 0.0, width: 140.0, height: 90.0, text: "Crouch: C",       style: "plain",         on_press: Print("[ctrl] crouch") )),
                        Button(( id: "cp_reset",  x: 0.0, y: 0.0, width: 160.0, height: 90.0, text: "Reset Defaults",  style: "sharp_outline", on_press: Print("[ctrl] reset")  )),
                    ],
                ),
            ],
            buttons: [
                ( id: "sp_back", x: -170.0, y: 430.0, width: 340.0, height: 70.0, text: "Back", tooltip: None, style: "plain", on_press: SwitchRoot("main_menu") ),
            ],
        ),
    ],
)