floating_window.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #include "raylib.h"
  2. #define RAYGUI_IMPLEMENTATION
  3. #include "../../src/raygui.h"
  4. #include "../../styles/dark/style_dark.h"
  5. static Vector2 window_position = { 10, 10 };
  6. static Vector2 window_size = { 200, 400 };
  7. static bool minimized = false;
  8. static bool moving = false;
  9. static bool resizing = false;
  10. static Vector2 scroll;
  11. static Vector2 window2_position = { 250, 10 };
  12. static Vector2 window2_size = { 200, 400 };
  13. static bool minimized2 = false;
  14. static bool moving2 = false;
  15. static bool resizing2 = false;
  16. static Vector2 scroll2;
  17. void GuiWindowFloating(Vector2 *position, Vector2 *size, bool *minimized, bool *moving, bool *resizing, void (*draw_content)(Vector2, Vector2), Vector2 content_size, Vector2 *scroll, const char* title) {
  18. #if !defined(RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT)
  19. #define RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT 24
  20. #endif
  21. #if !defined(RAYGUI_WINDOW_CLOSEBUTTON_SIZE)
  22. #define RAYGUI_WINDOW_CLOSEBUTTON_SIZE 18
  23. #endif
  24. int close_title_size_delta_half = (RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - RAYGUI_WINDOW_CLOSEBUTTON_SIZE) / 2;
  25. // window movement and resize input and collision check
  26. if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON) && !*moving && !*resizing) {
  27. Vector2 mouse_position = GetMousePosition();
  28. Rectangle title_collision_rect = { position->x, position->y, size->x - (RAYGUI_WINDOW_CLOSEBUTTON_SIZE + close_title_size_delta_half), RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT };
  29. Rectangle resize_collision_rect = { position->x + size->x - 20, position->y + size->y - 20, 20, 20 };
  30. if(CheckCollisionPointRec(mouse_position, title_collision_rect)) {
  31. *moving = true;
  32. } else if(!*minimized && CheckCollisionPointRec(mouse_position, resize_collision_rect)) {
  33. *resizing = true;
  34. }
  35. }
  36. // window movement and resize update
  37. if(*moving) {
  38. Vector2 mouse_delta = GetMouseDelta();
  39. position->x += mouse_delta.x;
  40. position->y += mouse_delta.y;
  41. if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) {
  42. *moving = false;
  43. // clamp window position keep it inside the application area
  44. if(position->x < 0) position->x = 0;
  45. else if(position->x > GetScreenWidth() - size->x) position->x = GetScreenWidth() - size->x;
  46. if(position->y < 0) position->y = 0;
  47. else if(position->y > GetScreenHeight()) position->y = GetScreenHeight() - RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT;
  48. }
  49. } else if(*resizing) {
  50. Vector2 mouse = GetMousePosition();
  51. if (mouse.x > position->x)
  52. size->x = mouse.x - position->x;
  53. if (mouse.y > position->y)
  54. size->y = mouse.y - position->y;
  55. // clamp window size to an arbitrary minimum value and the window size as the maximum
  56. if(size->x < 100) size->x = 100;
  57. else if(size->x > GetScreenWidth()) size->x = GetScreenWidth();
  58. if(size->y < 100) size->y = 100;
  59. else if(size->y > GetScreenHeight()) size->y = GetScreenHeight();
  60. if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) {
  61. *resizing = false;
  62. }
  63. }
  64. // window and content drawing with scissor and scroll area
  65. if(*minimized) {
  66. GuiStatusBar((Rectangle){ position->x, position->y, size->x, RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT }, title);
  67. if (GuiButton((Rectangle){ position->x + size->x - RAYGUI_WINDOW_CLOSEBUTTON_SIZE - close_title_size_delta_half,
  68. position->y + close_title_size_delta_half,
  69. RAYGUI_WINDOW_CLOSEBUTTON_SIZE,
  70. RAYGUI_WINDOW_CLOSEBUTTON_SIZE },
  71. "#120#")) {
  72. *minimized = false;
  73. }
  74. } else {
  75. *minimized = GuiWindowBox((Rectangle) { position->x, position->y, size->x, size->y }, title);
  76. // scissor and draw content within a scroll panel
  77. if(draw_content != NULL) {
  78. Rectangle scissor = { 0 };
  79. GuiScrollPanel((Rectangle) { position->x, position->y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT, size->x, size->y - RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT },
  80. NULL,
  81. (Rectangle) { position->x, position->y, content_size.x, content_size.y },
  82. scroll,
  83. &scissor);
  84. bool require_scissor = size->x < content_size.x || size->y < content_size.y;
  85. if(require_scissor) {
  86. BeginScissorMode(scissor.x, scissor.y, scissor.width, scissor.height);
  87. }
  88. draw_content(*position, *scroll);
  89. if(require_scissor) {
  90. EndScissorMode();
  91. }
  92. }
  93. // draw the resize button/icon
  94. GuiDrawIcon(71, position->x + size->x - 20, position->y + size->y - 20, 1, WHITE);
  95. }
  96. }
  97. static void DrawContent(Vector2 position, Vector2 scroll) {
  98. GuiButton((Rectangle) { position.x + 20 + scroll.x, position.y + 50 + scroll.y, 100, 25 }, "Button 1");
  99. GuiButton((Rectangle) { position.x + 20 + scroll.x, position.y + 100 + scroll.y, 100, 25 }, "Button 2");
  100. GuiButton((Rectangle) { position.x + 20 + scroll.x, position.y + 150 + scroll.y, 100, 25 }, "Button 3");
  101. GuiLabel((Rectangle) { position.x + 20 + scroll.x, position.y + 200 + scroll.y, 250, 25 }, "A Label");
  102. GuiLabel((Rectangle) { position.x + 20 + scroll.x, position.y + 250 + scroll.y, 250, 25 }, "Another Label");
  103. GuiLabel((Rectangle) { position.x + 20 + scroll.x, position.y + 300 + scroll.y, 250, 25 }, "Yet Another Label");
  104. }
  105. int main(void) {
  106. InitWindow(960, 560, "raygui - floating window example");
  107. SetTargetFPS(60);
  108. GuiLoadStyleDark();
  109. while(!WindowShouldClose()) {
  110. BeginDrawing();
  111. ClearBackground(DARKGREEN);
  112. GuiWindowFloating(&window_position, &window_size, &minimized, &moving, &resizing, &DrawContent, (Vector2) { 140, 320 }, &scroll, "Movable & Scalable Window");
  113. GuiWindowFloating(&window2_position, &window2_size, &minimized2, &moving2, &resizing2, &DrawContent, (Vector2) { 140, 320 }, &scroll2, "Another window");
  114. EndDrawing();
  115. }
  116. CloseWindow();
  117. return 0;
  118. }