Mercurial
comparison infinite_canvas/dev_ui.c @ 280:49e9e591c9bb
Add persistent dictation, prewarmed WebRTC speech input, Copilot SDK routing, animated conversation lifecycle controls, parking, and architecture coverage.
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Tue, 18 Aug 2026 19:14:53 -0700 |
| parents | 8d560f50ed4c |
| children | c57149ad216e |
comparison
equal
deleted
inserted
replaced
| 279:b3b547563ec7 | 280:49e9e591c9bb |
|---|---|
| 3 #include <math.h> | 3 #include <math.h> |
| 4 | 4 |
| 5 #define RAYGUI_IMPLEMENTATION | 5 #define RAYGUI_IMPLEMENTATION |
| 6 #include "third_party/raylib/include/raygui.h" | 6 #include "third_party/raylib/include/raygui.h" |
| 7 | 7 |
| 8 static const Rectangle DEV_PANEL = {18.0f, 18.0f, 264.0f, 478.0f}; | 8 static const Rectangle DEV_PANEL = {18.0f, 18.0f, 264.0f, 520.0f}; |
| 9 static const Rectangle DEV_PANEL_COLLAPSED = {18.0f, 18.0f, 44.0f, 44.0f}; | |
| 9 | 10 |
| 10 static Rectangle Canvas_Dev_UI_Context_Bounds(void) | 11 static Rectangle Canvas_Dev_UI_Context_Bounds(void) |
| 11 { | 12 { |
| 12 float width = 610.0f; | 13 float width = 610.0f; |
| 13 float x = (float)GetScreenWidth() - width - 18.0f; | 14 float x = (float)GetScreenWidth() - width - 18.0f; |
| 204 Font font, | 205 Font font, |
| 205 const Canvas_Theme *p_theme) | 206 const Canvas_Theme *p_theme) |
| 206 { | 207 { |
| 207 *p_ui = (Canvas_Dev_UI){ | 208 *p_ui = (Canvas_Dev_UI){ |
| 208 .selected_type = CANVAS_ENTITY_RECTANGLE, | 209 .selected_type = CANVAS_ENTITY_RECTANGLE, |
| 210 .collapsed = FALSE, | |
| 209 .dropdown_open = FALSE, | 211 .dropdown_open = FALSE, |
| 210 .context_open = FALSE, | 212 .context_open = FALSE, |
| 211 }; | 213 }; |
| 212 Canvas_Dev_UI_Set_Style(font, p_theme); | 214 Canvas_Dev_UI_Set_Style(font, p_theme); |
| 213 } | 215 } |
| 217 // The expanded dropdown is modal: it draws outside DEV_PANEL and also | 219 // The expanded dropdown is modal: it draws outside DEV_PANEL and also |
| 218 // consumes outside clicks to close itself. | 220 // consumes outside clicks to close itself. |
| 219 if (p_ui->dropdown_open) return TRUE; | 221 if (p_ui->dropdown_open) return TRUE; |
| 220 | 222 |
| 221 Vector2 pointer = GetMousePosition(); | 223 Vector2 pointer = GetMousePosition(); |
| 222 if (CheckCollisionPointRec(pointer, DEV_PANEL)) return TRUE; | 224 if (CheckCollisionPointRec( |
| 225 pointer, | |
| 226 p_ui->collapsed ? DEV_PANEL_COLLAPSED : DEV_PANEL)) { | |
| 227 return TRUE; | |
| 228 } | |
| 223 if (p_ui->context_open && | 229 if (p_ui->context_open && |
| 224 CheckCollisionPointRec(pointer, Canvas_Dev_UI_Context_Bounds())) { | 230 CheckCollisionPointRec(pointer, Canvas_Dev_UI_Context_Bounds())) { |
| 225 return TRUE; | 231 return TRUE; |
| 226 } | 232 } |
| 227 return FALSE; | 233 return FALSE; |
| 232 Canvas_Camera *p_camera, | 238 Canvas_Camera *p_camera, |
| 233 Canvas_Scene *p_scene, | 239 Canvas_Scene *p_scene, |
| 234 Font font, | 240 Font font, |
| 235 Canvas_Theme *p_theme) | 241 Canvas_Theme *p_theme) |
| 236 { | 242 { |
| 243 if (p_ui->collapsed) { | |
| 244 Canvas_Theme_Draw_Shadow( | |
| 245 p_theme, | |
| 246 DEV_PANEL_COLLAPSED, | |
| 247 0.24f, | |
| 248 12, | |
| 249 1.0f, | |
| 250 1.0f); | |
| 251 DrawRectangleRounded( | |
| 252 DEV_PANEL_COLLAPSED, | |
| 253 0.24f, | |
| 254 12, | |
| 255 p_theme->surface); | |
| 256 DrawRectangleRoundedLinesEx( | |
| 257 DEV_PANEL_COLLAPSED, | |
| 258 0.24f, | |
| 259 12, | |
| 260 1.0f, | |
| 261 p_theme->border); | |
| 262 if (GuiButtonRounded( | |
| 263 (Rectangle){24.0f, 24.0f, 32.0f, 32.0f}, | |
| 264 ">", | |
| 265 0.30f, | |
| 266 10)) { | |
| 267 p_ui->collapsed = FALSE; | |
| 268 } | |
| 269 return; | |
| 270 } | |
| 271 | |
| 237 Canvas_Context_Snapshot context = Canvas_Scene_Build_Visible_Context( | 272 Canvas_Context_Snapshot context = Canvas_Scene_Build_Visible_Context( |
| 238 p_scene, | 273 p_scene, |
| 239 p_camera, | 274 p_camera, |
| 240 p_ui->context_buffer, | 275 p_ui->context_buffer, |
| 241 sizeof(p_ui->context_buffer)); | 276 sizeof(p_ui->context_buffer)); |
| 254 "Developer controls", | 289 "Developer controls", |
| 255 (Vector2){34.0f, 61.0f}, | 290 (Vector2){34.0f, 61.0f}, |
| 256 12.0f, | 291 12.0f, |
| 257 0.1f, | 292 0.1f, |
| 258 p_theme->text_muted); | 293 p_theme->text_muted); |
| 294 if (GuiButtonRounded( | |
| 295 (Rectangle){230.0f, 30.0f, 36.0f, 30.0f}, | |
| 296 "<", | |
| 297 0.30f, | |
| 298 10)) { | |
| 299 p_ui->collapsed = TRUE; | |
| 300 p_ui->dropdown_open = FALSE; | |
| 301 p_ui->context_open = FALSE; | |
| 302 return; | |
| 303 } | |
| 259 | 304 |
| 260 if (p_ui->dropdown_open) GuiLock(); | 305 if (p_ui->dropdown_open) GuiLock(); |
| 261 | 306 |
| 262 if (GuiButtonRounded((Rectangle){34.0f, 126.0f, 112.0f, 34.0f}, "Add entity", 0.32f, 10)) { | 307 if (GuiButtonRounded((Rectangle){34.0f, 126.0f, 112.0f, 34.0f}, "Add entity", 0.32f, 10)) { |
| 263 Canvas_Scene_Add( | 308 Canvas_Scene_Add( |
| 320 0.32f, | 365 0.32f, |
| 321 10)) { | 366 10)) { |
| 322 Canvas_Scene_Show_Lucide_Gallery(p_scene, p_camera); | 367 Canvas_Scene_Show_Lucide_Gallery(p_scene, p_camera); |
| 323 } | 368 } |
| 324 | 369 |
| 325 DrawTextEx(font, TextFormat("%d FPS", GetFPS()), (Vector2){34.0f, 396.0f}, 12.0f, 0.0f, p_theme->text_muted); | 370 size_t parked_count = Canvas_Scene_Parked_Conversation_Count(p_scene); |
| 326 DrawTextEx(font, TextFormat("%.2fx zoom", p_camera->zoom), (Vector2){104.0f, 396.0f}, 12.0f, 0.0f, p_theme->text_muted); | 371 if (GuiButtonRounded( |
| 372 (Rectangle){34.0f, 378.0f, 232.0f, 34.0f}, | |
| 373 TextFormat("Parking lot (%d)", (int)parked_count), | |
| 374 0.32f, | |
| 375 10)) { | |
| 376 Canvas_Scene_Show_Parking_Lot(p_scene, p_camera); | |
| 377 } | |
| 378 | |
| 379 DrawTextEx(font, TextFormat("%d FPS", GetFPS()), (Vector2){34.0f, 438.0f}, 12.0f, 0.0f, p_theme->text_muted); | |
| 380 DrawTextEx(font, TextFormat("%.2fx zoom", p_camera->zoom), (Vector2){104.0f, 438.0f}, 12.0f, 0.0f, p_theme->text_muted); | |
| 327 DrawTextEx( | 381 DrawTextEx( |
| 328 font, | 382 font, |
| 329 TextFormat("%d objects", (int)Dowa_Array_Length(p_scene->p_entities)), | 383 TextFormat("%d objects", (int)Dowa_Array_Length(p_scene->p_entities)), |
| 330 (Vector2){196.0f, 396.0f}, | 384 (Vector2){196.0f, 438.0f}, |
| 331 12.0f, | 385 12.0f, |
| 332 0.0f, | 386 0.0f, |
| 333 p_theme->text_muted); | 387 p_theme->text_muted); |
| 334 DrawTextEx( | 388 DrawTextEx( |
| 335 font, | 389 font, |
| 336 "Drag objects directly on the canvas", | 390 "Drag objects directly on the canvas", |
| 337 (Vector2){34.0f, 442.0f}, | 391 (Vector2){34.0f, 484.0f}, |
| 338 12.0f, | 392 12.0f, |
| 339 0.0f, | 393 0.0f, |
| 340 p_theme->text_muted); | 394 p_theme->text_muted); |
| 341 | 395 |
| 342 if (p_ui->context_open) { | 396 if (p_ui->context_open) { |