comparison infinite_canvas/dev_ui.c @ 278:8d560f50ed4c

Improve infinite canvas interactions and browser chrome Render Lucide icons directly with Raylib, add searchable icon browsing, robust text editing, entity lifecycle animations, z-order-safe input, semantic themes, and animated editable browser controls. Document rendering, pinning, context, and component extension for future agents. Co-authored-by: Copilot <[email protected]> Copilot-Session: f68442b1-fa8f-46a0-9689-81710613bbd4
author MrJuneJune <me@mrjunejune.com>
date Mon, 17 Aug 2026 22:16:14 -0700
parents b55c22cff335
children 49e9e591c9bb
comparison
equal deleted inserted replaced
277:1d99147f520c 278:8d560f50ed4c
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, 436.0f}; 8 static const Rectangle DEV_PANEL = {18.0f, 18.0f, 264.0f, 478.0f};
9 9
10 static Rectangle Canvas_Dev_UI_Context_Bounds(void) 10 static Rectangle Canvas_Dev_UI_Context_Bounds(void)
11 { 11 {
12 float width = 610.0f; 12 float width = 610.0f;
13 float x = (float)GetScreenWidth() - width - 18.0f; 13 float x = (float)GetScreenWidth() - width - 18.0f;
112 (int)p_snapshot->visible_count, 112 (int)p_snapshot->visible_count,
113 p_snapshot->truncated ? " - output truncated" : ""), 113 p_snapshot->truncated ? " - output truncated" : ""),
114 (Vector2){panel.x + 20.0f, panel.y + 48.0f}, 114 (Vector2){panel.x + 20.0f, panel.y + 48.0f},
115 13.0f, 115 13.0f,
116 0.0f, 116 0.0f,
117 p_snapshot->truncated ? (Color){220, 38, 38, 255} : p_theme->text_muted); 117 p_snapshot->truncated ? p_theme->danger : p_theme->text_muted);
118 118
119 Rectangle close = { 119 Rectangle close = {
120 panel.x + panel.width - 76.0f, 120 panel.x + panel.width - 76.0f,
121 panel.y + 16.0f, 121 panel.y + 16.0f,
122 56.0f, 122 56.0f,
212 Canvas_Dev_UI_Set_Style(font, p_theme); 212 Canvas_Dev_UI_Set_Style(font, p_theme);
213 } 213 }
214 214
215 boolean Canvas_Dev_UI_Contains_Pointer(const Canvas_Dev_UI *p_ui) 215 boolean Canvas_Dev_UI_Contains_Pointer(const Canvas_Dev_UI *p_ui)
216 { 216 {
217 // The expanded dropdown is modal: it draws outside DEV_PANEL and also
218 // consumes outside clicks to close itself.
219 if (p_ui->dropdown_open) return TRUE;
220
217 Vector2 pointer = GetMousePosition(); 221 Vector2 pointer = GetMousePosition();
218 if (CheckCollisionPointRec(pointer, DEV_PANEL)) return TRUE; 222 if (CheckCollisionPointRec(pointer, DEV_PANEL)) return TRUE;
219 if (p_ui->context_open && 223 if (p_ui->context_open &&
220 CheckCollisionPointRec(pointer, Canvas_Dev_UI_Context_Bounds())) { 224 CheckCollisionPointRec(pointer, Canvas_Dev_UI_Context_Bounds())) {
221 return TRUE; 225 return TRUE;
251 (Vector2){34.0f, 61.0f}, 255 (Vector2){34.0f, 61.0f},
252 12.0f, 256 12.0f,
253 0.1f, 257 0.1f,
254 p_theme->text_muted); 258 p_theme->text_muted);
255 259
260 if (p_ui->dropdown_open) GuiLock();
261
256 if (GuiButtonRounded((Rectangle){34.0f, 126.0f, 112.0f, 34.0f}, "Add entity", 0.32f, 10)) { 262 if (GuiButtonRounded((Rectangle){34.0f, 126.0f, 112.0f, 34.0f}, "Add entity", 0.32f, 10)) {
257 Canvas_Scene_Add( 263 Canvas_Scene_Add(
258 p_scene, 264 p_scene,
259 (Canvas_Entity_Type)p_ui->selected_type, 265 (Canvas_Entity_Type)p_ui->selected_type,
260 p_camera->target); 266 p_camera->target);
261 } 267 }
262 if (GuiButtonRounded((Rectangle){154.0f, 126.0f, 112.0f, 34.0f}, "Clear", 0.32f, 10)) { 268 if (GuiButtonRounded((Rectangle){154.0f, 126.0f, 112.0f, 34.0f}, "Clear", 0.32f, 10)) {
263 Canvas_Scene_Clear(p_scene); 269 Canvas_Scene_Fade_Out_All(p_scene);
264 } 270 }
265 if (GuiButtonRounded((Rectangle){34.0f, 168.0f, 72.0f, 34.0f}, "Demo", 0.32f, 10)) { 271 if (GuiButtonRounded((Rectangle){34.0f, 168.0f, 72.0f, 34.0f}, "Demo", 0.32f, 10)) {
266 Canvas_Scene_Add_Demo(p_scene); 272 Canvas_Scene_Add_Demo(p_scene);
267 } 273 }
268 if (GuiButtonRounded((Rectangle){114.0f, 168.0f, 88.0f, 34.0f}, "Reset", 0.32f, 10)) { 274 if (GuiButtonRounded((Rectangle){114.0f, 168.0f, 88.0f, 34.0f}, "Reset", 0.32f, 10)) {
306 10)) { 312 10)) {
307 p_ui->context_open = !p_ui->context_open; 313 p_ui->context_open = !p_ui->context_open;
308 p_ui->context_scroll = 0.0f; 314 p_ui->context_scroll = 0.0f;
309 } 315 }
310 316
311 DrawTextEx(font, TextFormat("%d FPS", GetFPS()), (Vector2){34.0f, 354.0f}, 12.0f, 0.0f, p_theme->text_muted); 317 if (GuiButtonRounded(
312 DrawTextEx(font, TextFormat("%.2fx zoom", p_camera->zoom), (Vector2){104.0f, 354.0f}, 12.0f, 0.0f, p_theme->text_muted); 318 (Rectangle){34.0f, 336.0f, 232.0f, 34.0f},
319 "Lucide icon gallery",
320 0.32f,
321 10)) {
322 Canvas_Scene_Show_Lucide_Gallery(p_scene, p_camera);
323 }
324
325 DrawTextEx(font, TextFormat("%d FPS", GetFPS()), (Vector2){34.0f, 396.0f}, 12.0f, 0.0f, p_theme->text_muted);
326 DrawTextEx(font, TextFormat("%.2fx zoom", p_camera->zoom), (Vector2){104.0f, 396.0f}, 12.0f, 0.0f, p_theme->text_muted);
313 DrawTextEx( 327 DrawTextEx(
314 font, 328 font,
315 TextFormat("%d objects", (int)Dowa_Array_Length(p_scene->p_entities)), 329 TextFormat("%d objects", (int)Dowa_Array_Length(p_scene->p_entities)),
316 (Vector2){196.0f, 354.0f}, 330 (Vector2){196.0f, 396.0f},
317 12.0f, 331 12.0f,
318 0.0f, 332 0.0f,
319 p_theme->text_muted); 333 p_theme->text_muted);
320 DrawTextEx( 334 DrawTextEx(
321 font, 335 font,
322 "Drag objects directly on the canvas", 336 "Drag objects directly on the canvas",
323 (Vector2){34.0f, 400.0f}, 337 (Vector2){34.0f, 442.0f},
324 12.0f, 338 12.0f,
325 0.0f, 339 0.0f,
326 p_theme->text_muted); 340 p_theme->text_muted);
327 341
328 if (p_ui->context_open) { 342 if (p_ui->context_open) {
332 font, 346 font,
333 p_theme); 347 p_theme);
334 } 348 }
335 349
336 // Draw last so the expanded list overlays the other developer controls. 350 // Draw last so the expanded list overlays the other developer controls.
351 if (p_ui->dropdown_open) GuiUnlock();
337 Rectangle dropdown = {34.0f, 84.0f, 232.0f, 34.0f}; 352 Rectangle dropdown = {34.0f, 84.0f, 232.0f, 34.0f};
338 if (GuiDropdownBoxRounded( 353 if (GuiDropdownBoxRounded(
339 dropdown, 354 dropdown,
340 "Rectangle;Circle;Line;Text;Button;Text area;Dropdown;Accordion;Card;Calendar;Switch;Table;Notification;Scrollable area;Image;Web content", 355 "Rectangle;Circle;Line;Text;Button;Text area;Dropdown;Accordion;Card;Calendar;Switch;Table;Notification;Scrollable area;Image;Web content",
341 &p_ui->selected_type, 356 &p_ui->selected_type,