#include "ui.h" FloatingWindow createFloatingWindow() { return (FloatingWindow){ .rect = (Rectangle){0.0, 0.0, 100.0, 100.0}, .minimized = false, .moving = false, .resizing = false, .callback = NULL, .contentSize = Vector2Zero(), .scroll = Vector2Zero() }; } void floatingWindowTransformCollisionCheck(FloatingWindow* window) { int closeTitleSizeDeltaHalf = (RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - RAYGUI_WINDOW_CLOSEBUTTON_SIZE) / 2; Vector2 mousePosition = GetMousePosition(); Rectangle titleCollisionRect = (Rectangle){ window->rect.x, window->rect.y, window->rect.width - (RAYGUI_WINDOW_CLOSEBUTTON_SIZE + closeTitleSizeDeltaHalf), RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT }; Rectangle resizeCollisionRect = (Rectangle){ window->rect.x + window->rect.width - 20, window->rect.y + window->rect.height - 20, 20, 20 }; if (CheckCollisionPointRec(mousePosition, titleCollisionRect)) { window->moving = true; } else if (!window->minimized && CheckCollisionPointRec(mousePosition, resizeCollisionRect)) { window->resizing = true; } } void updateFloatingWindowMoving(FloatingWindow* window) { Vector2 mouseDelta = GetMouseDelta(); window->rect.x += mouseDelta.x; window->rect.y += mouseDelta.y; if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) { window->moving = false; // Clamp window position keep it inside the application area. if (window->rect.x < 0) { window->rect.x = 0; } else if (window->rect.x > GetScreenWidth() - window->rect.width) { window->rect.x = GetScreenWidth() - window->rect.width; } if (window->rect.y < 0) { window->rect.y = 0; } else if (window->rect.y > GetScreenHeight()) { window->rect.y = GetScreenHeight() - RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT; } } } void updateFloatingWindowResizing(FloatingWindow* window) { Vector2 mousePosition = GetMousePosition(); if (mousePosition.x > window->rect.x) { window->rect.width = mousePosition.x - window->rect.x; } if (mousePosition.y > window->rect.y) { window->rect.height = mousePosition.y - window->rect.y; } // Clamp window size to an arbitrary minimum value and the window size as // the maximum. if (window->rect.width < 100) { window->rect.width = 100; } else if (window->rect.width > GetScreenWidth()) { window->rect.width = GetScreenWidth(); } if (window->rect.height < 100) { window->rect.height = 100; } else if (window->rect.height > GetScreenHeight()) { window->rect.height = GetScreenHeight(); } if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) { window->resizing = false; } } void updateFloatingWindowMinimized(FloatingWindow* window, const char* title) { int closeTitleSizeDeltaHalf = (RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - RAYGUI_WINDOW_CLOSEBUTTON_SIZE) / 2; GuiStatusBar( (Rectangle){window->rect.x, window->rect.y, window->rect.width, RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT}, title); if (GuiButton( (Rectangle){window->rect.x + window->rect.width - RAYGUI_WINDOW_CLOSEBUTTON_SIZE - closeTitleSizeDeltaHalf, window->rect.y + closeTitleSizeDeltaHalf, RAYGUI_WINDOW_CLOSEBUTTON_SIZE, RAYGUI_WINDOW_CLOSEBUTTON_SIZE}, "#120#")) { window->minimized = false; } } void updateFloatingWindowNotMinimized(FloatingWindow* window, const char* title) { window->minimized = GuiWindowBox( (Rectangle){window->rect.x, window->rect.y, window->rect.width, window->rect.height}, title); // Scissor and draw content within a scroll panel. if (window->callback != NULL) { Rectangle scissor; GuiScrollPanel( (Rectangle){ window->rect.x, window->rect.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT, window->rect.width, window->rect.height - RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT}, NULL, (Rectangle){ window->rect.x, window->rect.y, window->contentSize.x, window->contentSize.y}, &window->scroll, &scissor); bool requireScissor = window->rect.width < window->contentSize.x || window->rect.height < window->contentSize.x; if (requireScissor) { BeginScissorMode(scissor.x, scissor.y, scissor.width, scissor.height); } window->callback((Vector2){window->rect.x, window->rect.y}, window->scroll); if (requireScissor) { EndScissorMode(); } } // Draw the resize button/icon. GuiDrawIcon(71, window->rect.x + window->rect.width - 20, window->rect.y + window->rect.height - 20, 1, GREEN); } void updateFloatingWindow(FloatingWindow* window, const char* title) { // Window movement and resize input and collision check. if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) && !window->moving && !window->resizing) { floatingWindowTransformCollisionCheck(window); } // Window movement and resize update. if (window->moving) { updateFloatingWindowMoving(window); } else if (window->resizing) { updateFloatingWindowResizing(window); } // window and content drawing with scissor and scroll area if(window->minimized) { updateFloatingWindowMinimized(window, title); } else { updateFloatingWindowNotMinimized(window, title); } }