comparison infinite_canvas/dev_ui.c @ 281:c57149ad216e default tip

Copilot-Session: f68442b1-fa8f-46a0-9689-81710613bbd4
author MrJuneJune <me@mrjunejune.com>
date Tue, 18 Aug 2026 22:18:15 -0700
parents 49e9e591c9bb
children
comparison
equal deleted inserted replaced
280:49e9e591c9bb 281:c57149ad216e
1 #include "infinite_canvas/dev_ui.h" 1 #include "infinite_canvas/dev_ui.h"
2 2
3 #include <math.h> 3 #include <math.h>
4 #include <stdio.h>
4 5
5 #define RAYGUI_IMPLEMENTATION 6 #define RAYGUI_IMPLEMENTATION
6 #include "third_party/raylib/include/raygui.h" 7 #include "third_party/raylib/include/raygui.h"
7 8
8 static const Rectangle DEV_PANEL = {18.0f, 18.0f, 264.0f, 520.0f}; 9 static const Rectangle DEV_PANEL = {18.0f, 18.0f, 264.0f, 650.0f};
9 static const Rectangle DEV_PANEL_COLLAPSED = {18.0f, 18.0f, 44.0f, 44.0f}; 10 static const Rectangle DEV_PANEL_COLLAPSED = {18.0f, 18.0f, 44.0f, 44.0f};
10 11
11 static Rectangle Canvas_Dev_UI_Context_Bounds(void) 12 static Rectangle Canvas_Dev_UI_Context_Bounds(void)
12 { 13 {
13 float width = 610.0f; 14 float width = 610.0f;
209 .selected_type = CANVAS_ENTITY_RECTANGLE, 210 .selected_type = CANVAS_ENTITY_RECTANGLE,
210 .collapsed = FALSE, 211 .collapsed = FALSE,
211 .dropdown_open = FALSE, 212 .dropdown_open = FALSE,
212 .context_open = FALSE, 213 .context_open = FALSE,
213 }; 214 };
215 snprintf(
216 p_ui->snapshot_name,
217 sizeof(p_ui->snapshot_name),
218 "workspace");
219 snprintf(
220 p_ui->snapshot_status,
221 sizeof(p_ui->snapshot_status),
222 "Native snapshots use a versioned .zmap file");
214 Canvas_Dev_UI_Set_Style(font, p_theme); 223 Canvas_Dev_UI_Set_Style(font, p_theme);
224 }
225
226 void Canvas_Dev_UI_Set_Snapshot_Status(
227 Canvas_Dev_UI *p_ui,
228 const char *p_status)
229 {
230 snprintf(
231 p_ui->snapshot_status,
232 sizeof(p_ui->snapshot_status),
233 "%s",
234 p_status ? p_status : "");
215 } 235 }
216 236
217 boolean Canvas_Dev_UI_Contains_Pointer(const Canvas_Dev_UI *p_ui) 237 boolean Canvas_Dev_UI_Contains_Pointer(const Canvas_Dev_UI *p_ui)
218 { 238 {
219 // The expanded dropdown is modal: it draws outside DEV_PANEL and also 239 // The expanded dropdown is modal: it draws outside DEV_PANEL and also
220 // consumes outside clicks to close itself. 240 // consumes outside clicks to close itself.
221 if (p_ui->dropdown_open) return TRUE; 241 if (p_ui->dropdown_open || p_ui->snapshot_name_editing) return TRUE;
222 242
223 Vector2 pointer = GetMousePosition(); 243 Vector2 pointer = GetMousePosition();
224 if (CheckCollisionPointRec( 244 if (CheckCollisionPointRec(
225 pointer, 245 pointer,
226 p_ui->collapsed ? DEV_PANEL_COLLAPSED : DEV_PANEL)) { 246 p_ui->collapsed ? DEV_PANEL_COLLAPSED : DEV_PANEL)) {
231 return TRUE; 251 return TRUE;
232 } 252 }
233 return FALSE; 253 return FALSE;
234 } 254 }
235 255
236 void Canvas_Dev_UI_Draw( 256 boolean Canvas_Dev_UI_Is_Editing(const Canvas_Dev_UI *p_ui)
257 {
258 return p_ui->dropdown_open || p_ui->snapshot_name_editing;
259 }
260
261 Canvas_Dev_UI_Action Canvas_Dev_UI_Draw(
237 Canvas_Dev_UI *p_ui, 262 Canvas_Dev_UI *p_ui,
238 Canvas_Camera *p_camera, 263 Canvas_Camera *p_camera,
239 Canvas_Scene *p_scene, 264 Canvas_Scene *p_scene,
240 Font font, 265 Font font,
241 Canvas_Theme *p_theme) 266 Canvas_Theme *p_theme)
242 { 267 {
268 Canvas_Dev_UI_Action action = CANVAS_DEV_UI_ACTION_NONE;
243 if (p_ui->collapsed) { 269 if (p_ui->collapsed) {
244 Canvas_Theme_Draw_Shadow( 270 Canvas_Theme_Draw_Shadow(
245 p_theme, 271 p_theme,
246 DEV_PANEL_COLLAPSED, 272 DEV_PANEL_COLLAPSED,
247 0.24f, 273 0.24f,
264 ">", 290 ">",
265 0.30f, 291 0.30f,
266 10)) { 292 10)) {
267 p_ui->collapsed = FALSE; 293 p_ui->collapsed = FALSE;
268 } 294 }
269 return; 295 return action;
270 } 296 }
271 297
272 Canvas_Context_Snapshot context = Canvas_Scene_Build_Visible_Context( 298 Canvas_Context_Snapshot context = Canvas_Scene_Build_Visible_Context(
273 p_scene, 299 p_scene,
274 p_camera, 300 p_camera,
297 0.30f, 323 0.30f,
298 10)) { 324 10)) {
299 p_ui->collapsed = TRUE; 325 p_ui->collapsed = TRUE;
300 p_ui->dropdown_open = FALSE; 326 p_ui->dropdown_open = FALSE;
301 p_ui->context_open = FALSE; 327 p_ui->context_open = FALSE;
302 return; 328 return action;
303 } 329 }
304 330
305 if (p_ui->dropdown_open) GuiLock(); 331 if (p_ui->dropdown_open) GuiLock();
306 332
307 if (GuiButtonRounded((Rectangle){34.0f, 126.0f, 112.0f, 34.0f}, "Add entity", 0.32f, 10)) { 333 if (GuiButtonRounded((Rectangle){34.0f, 126.0f, 112.0f, 34.0f}, "Add entity", 0.32f, 10)) {
374 0.32f, 400 0.32f,
375 10)) { 401 10)) {
376 Canvas_Scene_Show_Parking_Lot(p_scene, p_camera); 402 Canvas_Scene_Show_Parking_Lot(p_scene, p_camera);
377 } 403 }
378 404
379 DrawTextEx(font, TextFormat("%d FPS", GetFPS()), (Vector2){34.0f, 438.0f}, 12.0f, 0.0f, p_theme->text_muted); 405 DrawTextEx(
380 DrawTextEx(font, TextFormat("%.2fx zoom", p_camera->zoom), (Vector2){104.0f, 438.0f}, 12.0f, 0.0f, p_theme->text_muted); 406 font,
407 "Named canvas snapshot",
408 (Vector2){34.0f, 424.0f},
409 12.0f,
410 0.0f,
411 p_theme->text_muted);
412 if (GuiTextBox(
413 (Rectangle){34.0f, 444.0f, 232.0f, 34.0f},
414 p_ui->snapshot_name,
415 (int32)sizeof(p_ui->snapshot_name),
416 p_ui->snapshot_name_editing)) {
417 p_ui->snapshot_name_editing = !p_ui->snapshot_name_editing;
418 }
419 if (GuiButtonRounded(
420 (Rectangle){34.0f, 486.0f, 112.0f, 34.0f},
421 "Save",
422 0.32f,
423 10)) {
424 action = CANVAS_DEV_UI_ACTION_SAVE_SNAPSHOT;
425 p_ui->snapshot_name_editing = FALSE;
426 }
427 if (GuiButtonRounded(
428 (Rectangle){154.0f, 486.0f, 112.0f, 34.0f},
429 "Load",
430 0.32f,
431 10)) {
432 action = CANVAS_DEV_UI_ACTION_LOAD_SNAPSHOT;
433 p_ui->snapshot_name_editing = FALSE;
434 }
435 DrawTextEx(
436 font,
437 p_ui->snapshot_status,
438 (Vector2){34.0f, 530.0f},
439 11.0f,
440 0.0f,
441 p_theme->text_muted);
442
443 DrawTextEx(font, TextFormat("%d FPS", GetFPS()), (Vector2){34.0f, 570.0f}, 12.0f, 0.0f, p_theme->text_muted);
444 DrawTextEx(font, TextFormat("%.2fx zoom", p_camera->zoom), (Vector2){104.0f, 570.0f}, 12.0f, 0.0f, p_theme->text_muted);
381 DrawTextEx( 445 DrawTextEx(
382 font, 446 font,
383 TextFormat("%d objects", (int)Dowa_Array_Length(p_scene->p_entities)), 447 TextFormat("%d objects", (int)Dowa_Array_Length(p_scene->p_entities)),
384 (Vector2){196.0f, 438.0f}, 448 (Vector2){196.0f, 570.0f},
385 12.0f, 449 12.0f,
386 0.0f, 450 0.0f,
387 p_theme->text_muted); 451 p_theme->text_muted);
388 DrawTextEx( 452 DrawTextEx(
389 font, 453 font,
390 "Drag objects directly on the canvas", 454 "Drag objects directly on the canvas",
391 (Vector2){34.0f, 484.0f}, 455 (Vector2){34.0f, 616.0f},
392 12.0f, 456 12.0f,
393 0.0f, 457 0.0f,
394 p_theme->text_muted); 458 p_theme->text_muted);
395 459
396 if (p_ui->context_open) { 460 if (p_ui->context_open) {
411 p_ui->dropdown_open, 475 p_ui->dropdown_open,
412 0.32f, 476 0.32f,
413 10)) { 477 10)) {
414 p_ui->dropdown_open = !p_ui->dropdown_open; 478 p_ui->dropdown_open = !p_ui->dropdown_open;
415 } 479 }
416 } 480 return action;
481 }