diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp index 08485201..55dd8ceb 100644 --- a/src/graphics/ui/GUI.cpp +++ b/src/graphics/ui/GUI.cpp @@ -5,6 +5,7 @@ #include "elements/UINode.hpp" #include "elements/Label.hpp" #include "elements/Menu.hpp" +#include "elements/Panel.hpp" #include "assets/Assets.hpp" #include "frontend/UiDocument.hpp" @@ -23,8 +24,10 @@ using namespace gui; -GUI::GUI() : batch2D(std::make_unique(1024)) { - container = std::make_shared(glm::vec2(1000)); +GUI::GUI() + : batch2D(std::make_unique(1024)), + container(std::make_shared(glm::vec2(1000))) { + container->setId("root"); uicamera = std::make_unique(glm::vec3(), Window::height); uicamera->perspective = false; uicamera->flipped = true; @@ -214,6 +217,14 @@ void GUI::draw(const DrawContext& pctx, const Assets& assets) { auto& viewport = ctx.getViewport(); glm::vec2 wsize = viewport.size(); + auto& page = menu->getCurrent(); + if (page.panel) { + menu->setSize(page.panel->getSize()); + page.panel->refresh(); + if (auto panel = std::dynamic_pointer_cast(page.panel)) { + panel->cropToContent(); + } + } menu->setPos((wsize - menu->getSize()) / 2.0f); uicamera->setFov(wsize.y); diff --git a/src/graphics/ui/elements/Menu.cpp b/src/graphics/ui/elements/Menu.cpp index da827489..d059d693 100644 --- a/src/graphics/ui/elements/Menu.cpp +++ b/src/graphics/ui/elements/Menu.cpp @@ -65,9 +65,10 @@ void Menu::setPage(Page page, bool history) { setSize(current.panel->getSize()); } -void Menu::back() { - if (pageStack.empty()) - return; +bool Menu::back() { + if (pageStack.empty()) { + return false; + } Page page = pageStack.top(); pageStack.pop(); @@ -77,6 +78,7 @@ void Menu::back() { } setPage(page, false); + return true; } void Menu::setPageLoader(PageLoaderFunc loader) { diff --git a/src/graphics/ui/elements/Menu.hpp b/src/graphics/ui/elements/Menu.hpp index 478c985a..e3e134d6 100644 --- a/src/graphics/ui/elements/Menu.hpp +++ b/src/graphics/ui/elements/Menu.hpp @@ -54,7 +54,7 @@ namespace gui { PageLoaderFunc getPageLoader(); /// @brief Set page to previous saved in history - void back(); + bool back(); /// @brief Clear pages history void clearHistory(); diff --git a/src/graphics/ui/elements/Panel.cpp b/src/graphics/ui/elements/Panel.cpp index d76866f0..70446d7d 100644 --- a/src/graphics/ui/elements/Panel.cpp +++ b/src/graphics/ui/elements/Panel.cpp @@ -70,9 +70,6 @@ void Panel::remove(const std::shared_ptr &node) { void Panel::refresh() { UINode::refresh(); - std::stable_sort(nodes.begin(), nodes.end(), [](auto a, auto b) { - return a->getZIndex() < b->getZIndex(); - }); float x = padding.x; float y = padding.y; @@ -80,20 +77,21 @@ void Panel::refresh() { if (orientation == Orientation::vertical) { float maxw = size.x; for (auto& node : nodes) { - glm::vec2 nodesize = node->getSize(); const glm::vec4 margin = node->getMargin(); y += margin.y; float ex = x + margin.x; node->setPos(glm::vec2(ex, y)); - y += nodesize.y + margin.w + interval; - + float width = size.x - padding.x - padding.z - margin.x - margin.z; if (node->isResizing()) { - node->setSize(glm::vec2(width, nodesize.y)); + node->setMaxSize({width, node->getMaxSize().y}); + node->setSize(glm::vec2(width, node->getSize().y)); } node->refresh(); - maxw = fmax(maxw, ex+node->getSize().x+margin.z+padding.z); + glm::vec2 nodeSize = node->getSize(); + y += nodeSize.y + margin.w + interval; + maxw = fmax(maxw, ex+nodeSize.x+margin.z+padding.z); } actualLength = y + padding.w; } else { diff --git a/src/graphics/ui/elements/UINode.cpp b/src/graphics/ui/elements/UINode.cpp index 4ebe8c7a..f6444f41 100644 --- a/src/graphics/ui/elements/UINode.cpp +++ b/src/graphics/ui/elements/UINode.cpp @@ -195,7 +195,8 @@ glm::vec2 UINode::getSize() const { void UINode::setSize(glm::vec2 size) { this->size = glm::vec2( - glm::max(minSize.x, size.x), glm::max(minSize.y, size.y) + glm::max(minSize.x, glm::min(maxSize.x, size.x)), + glm::max(minSize.y, glm::min(maxSize.y, size.y)) ); } @@ -208,6 +209,15 @@ void UINode::setMinSize(glm::vec2 minSize) { setSize(getSize()); } +glm::vec2 UINode::getMaxSize() const { + return maxSize; +} + +void UINode::setMaxSize(glm::vec2 maxSize) { + this->maxSize = maxSize; + setSize(getSize()); +} + void UINode::setColor(glm::vec4 color) { this->color = color; this->hoverColor = color; diff --git a/src/graphics/ui/elements/UINode.hpp b/src/graphics/ui/elements/UINode.hpp index af0ab145..2f62dd27 100644 --- a/src/graphics/ui/elements/UINode.hpp +++ b/src/graphics/ui/elements/UINode.hpp @@ -75,6 +75,8 @@ namespace gui { glm::vec2 size; /// @brief minimal element size glm::vec2 minSize {1.0f}; + /// @brief maximal element size + glm::vec2 maxSize {1e6f}; /// @brief element primary color (background-color or text-color if label) glm::vec4 color {1.0f}; /// @brief element color when mouse is over it @@ -224,6 +226,8 @@ namespace gui { virtual void setSize(glm::vec2 size); virtual glm::vec2 getMinSize() const; virtual void setMinSize(glm::vec2 size); + virtual glm::vec2 getMaxSize() const; + virtual void setMaxSize(glm::vec2 size); /// @brief Called in containers when new element added virtual void refresh() {}; virtual void fullRefresh() { diff --git a/src/graphics/ui/gui_util.cpp b/src/graphics/ui/gui_util.cpp index 04026132..7fd40431 100644 --- a/src/graphics/ui/gui_util.cpp +++ b/src/graphics/ui/gui_util.cpp @@ -31,7 +31,17 @@ void guiutil::alert( const std::wstring& text, const runnable& on_hidden ) { - auto panel = std::make_shared(glm::vec2(500, 300), glm::vec4(4.0f), 4.0f); + auto panel = std::make_shared( + glm::vec2( + glm::min( + static_cast(650), + glm::max(text.length() * 10, static_cast(200)) + ), + 300 + ), + glm::vec4(4.0f), + 4.0f + ); panel->setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f)); auto menuPtr = engine.getGUI()->getMenu(); @@ -40,14 +50,15 @@ void guiutil::alert( menu.removePage(""); if (on_hidden) { on_hidden(); - } else { - menu.back(); + } else if (!menu.back()) { + menu.reset(); } }; auto label = std::make_shared