From 86af6a8b0de5b827c4d65dc87dc2b7ea854f7ffb Mon Sep 17 00:00:00 2001 From: FailCake Date: Wed, 10 Jul 2024 10:13:32 +0200 Subject: [PATCH 1/2] - Add UITab & UITabs support - Add scripting for UITab & UITabs - Remove initialize from ui --- README.md | 2 +- rawrbox.ui/include/rawrbox/ui/container.hpp | 8 +- .../include/rawrbox/ui/elements/button.hpp | 4 +- .../include/rawrbox/ui/elements/console.hpp | 3 +- .../include/rawrbox/ui/elements/frame.hpp | 9 +- .../include/rawrbox/ui/elements/graph.hpp | 6 +- .../include/rawrbox/ui/elements/group.hpp | 2 +- .../include/rawrbox/ui/elements/image.hpp | 6 +- .../include/rawrbox/ui/elements/input.hpp | 6 +- .../include/rawrbox/ui/elements/label.hpp | 8 +- .../rawrbox/ui/elements/progress_bar.hpp | 9 +- .../include/rawrbox/ui/elements/tabs.hpp | 54 ++++++++++ .../rawrbox/ui/elements/virtual_list.hpp | 2 +- rawrbox.ui/include/rawrbox/ui/root.hpp | 4 +- .../include/rawrbox/ui/scripting/plugin.hpp | 4 + .../rawrbox/ui/scripting/wrappers/tab.hpp | 10 ++ .../rawrbox/ui/scripting/wrappers/tabs.hpp | 10 ++ rawrbox.ui/src/container.cpp | 5 +- rawrbox.ui/src/elements/button.cpp | 2 +- rawrbox.ui/src/elements/console.cpp | 15 ++- rawrbox.ui/src/elements/frame.cpp | 4 +- rawrbox.ui/src/elements/graph.cpp | 5 +- rawrbox.ui/src/elements/group.cpp | 2 + rawrbox.ui/src/elements/image.cpp | 5 + rawrbox.ui/src/elements/input.cpp | 4 +- rawrbox.ui/src/elements/label.cpp | 9 +- rawrbox.ui/src/elements/progress_bar.cpp | 7 +- rawrbox.ui/src/elements/tabs.cpp | 100 ++++++++++++++++++ rawrbox.ui/src/scripting/wrappers/tab.cpp | 16 +++ rawrbox.ui/src/scripting/wrappers/tabs.cpp | 19 ++++ rawrbox.ui/src/scripting/wrappers/ui.cpp | 8 ++ samples/008-ui/src/game.cpp | 59 +++++++++-- 32 files changed, 335 insertions(+), 72 deletions(-) create mode 100644 rawrbox.ui/include/rawrbox/ui/elements/tabs.hpp create mode 100644 rawrbox.ui/include/rawrbox/ui/scripting/wrappers/tab.hpp create mode 100644 rawrbox.ui/include/rawrbox/ui/scripting/wrappers/tabs.hpp create mode 100644 rawrbox.ui/src/elements/tabs.cpp create mode 100644 rawrbox.ui/src/scripting/wrappers/tab.cpp create mode 100644 rawrbox.ui/src/scripting/wrappers/tabs.cpp diff --git a/README.md b/README.md index 6da6cf99..0aef8f32 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ This engine started as a C++ training project, with hopes of being applied in up | 001-stencil
| 002-generated-models
| 003-light
| | :-----------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------: | | 004-instancing
| 005-post-process
| 006-decals
| -| 007-particle-system
| 008-ui
| 009-assimp
| +| 007-particle-system
| 008-ui
| 009-assimp
| | 010-bass-audio
| 011-physics-3D
| 012-physics-2D
| | 013-webm
| 014-scripting
| 015-gpu-picking
| diff --git a/rawrbox.ui/include/rawrbox/ui/container.hpp b/rawrbox.ui/include/rawrbox/ui/container.hpp index b27c5707..599b334a 100644 --- a/rawrbox.ui/include/rawrbox/ui/container.hpp +++ b/rawrbox.ui/include/rawrbox/ui/container.hpp @@ -30,14 +30,12 @@ namespace rawrbox { public: virtual ~UIContainer() = default; - UIContainer() = default; + UIContainer(rawrbox::UIRoot* root); UIContainer(const UIContainer&) = default; UIContainer(UIContainer&&) noexcept; UIContainer& operator=(const UIContainer&) = default; UIContainer& operator=(UIContainer&&) = delete; - virtual void initialize(); - // UTILS --- virtual void setPos(const rawrbox::Vector2f& pos); [[nodiscard]] virtual const rawrbox::Vector2f& getPos() const; @@ -73,10 +71,8 @@ namespace rawrbox { template requires(std::derived_from) T* createChild(CallbackArgs&&... args) { - auto elm = std::make_shared(std::forward(args)...); - elm->setRoot(this->_root); + auto elm = std::make_shared(this->_root, std::forward(args)...); elm->setParent(this); - elm->initialize(); auto& childn = this->getChildren(); if (elm->alwaysOnTop()) { diff --git a/rawrbox.ui/include/rawrbox/ui/elements/button.hpp b/rawrbox.ui/include/rawrbox/ui/elements/button.hpp index 0e516b7d..14dadc03 100644 --- a/rawrbox.ui/include/rawrbox/ui/elements/button.hpp +++ b/rawrbox.ui/include/rawrbox/ui/elements/button.hpp @@ -31,7 +31,7 @@ namespace rawrbox { public: rawrbox::Event<> onClick; - UIButton() = default; + UIButton(rawrbox::UIRoot* root); UIButton(const UIButton&) = default; UIButton(UIButton&&) = delete; UIButton& operator=(const UIButton&) = default; @@ -42,8 +42,6 @@ namespace rawrbox { this->_regular = nullptr; } - void initialize() override; - // UTILS ----- virtual void setTextureSize(const rawrbox::Vector2& size); virtual void setTextureColor(const rawrbox::Color& color); diff --git a/rawrbox.ui/include/rawrbox/ui/elements/console.hpp b/rawrbox.ui/include/rawrbox/ui/elements/console.hpp index c578db94..0c66d2d7 100644 --- a/rawrbox.ui/include/rawrbox/ui/elements/console.hpp +++ b/rawrbox.ui/include/rawrbox/ui/elements/console.hpp @@ -48,14 +48,13 @@ namespace rawrbox { virtual void drawText(rawrbox::Stencil& stencil, const std::vector& entries); public: - UIConsole(rawrbox::Console& console); + UIConsole(rawrbox::UIRoot* root, rawrbox::Console& console); UIConsole(const UIConsole&) = delete; UIConsole(UIConsole&&) = delete; UIConsole& operator=(const UIConsole&) = delete; UIConsole& operator=(UIConsole&&) = delete; ~UIConsole() override; - void initialize() override; void draw(rawrbox::Stencil& stencil) override; void afterDraw(rawrbox::Stencil& stencil) override; diff --git a/rawrbox.ui/include/rawrbox/ui/elements/frame.hpp b/rawrbox.ui/include/rawrbox/ui/elements/frame.hpp index ed24e81b..0354af97 100644 --- a/rawrbox.ui/include/rawrbox/ui/elements/frame.hpp +++ b/rawrbox.ui/include/rawrbox/ui/elements/frame.hpp @@ -31,16 +31,15 @@ namespace rawrbox { // ----------------- public: - ~UIFrame() override = default; - UIFrame() = default; + rawrbox::Event<> onClose; + + UIFrame(rawrbox::UIRoot* root); UIFrame(const UIFrame&) = default; UIFrame(UIFrame&&) = delete; UIFrame& operator=(const UIFrame&) = default; UIFrame& operator=(UIFrame&&) = delete; + ~UIFrame() override = default; - rawrbox::Event<> onClose; - - void initialize() override; [[nodiscard]] rawrbox::Vector2f getDrawOffset() const override; // UTILS ----- diff --git a/rawrbox.ui/include/rawrbox/ui/elements/graph.hpp b/rawrbox.ui/include/rawrbox/ui/elements/graph.hpp index a9fe155c..523bec0c 100644 --- a/rawrbox.ui/include/rawrbox/ui/elements/graph.hpp +++ b/rawrbox.ui/include/rawrbox/ui/elements/graph.hpp @@ -90,14 +90,12 @@ namespace rawrbox { std::vector> texts = {}; public: - ~UIGraph() override = default; - UIGraph() = default; + UIGraph(rawrbox::UIRoot* root); UIGraph(const UIGraph&) = default; UIGraph(UIGraph&&) = delete; UIGraph& operator=(const UIGraph&) = default; UIGraph& operator=(UIGraph&&) = delete; - - void initialize() override; + ~UIGraph() override; // CATEGORY -- virtual rawrbox::UIGraphCategory& getCategory(size_t id); diff --git a/rawrbox.ui/include/rawrbox/ui/elements/group.hpp b/rawrbox.ui/include/rawrbox/ui/elements/group.hpp index 71f3a3de..dea6a1d0 100644 --- a/rawrbox.ui/include/rawrbox/ui/elements/group.hpp +++ b/rawrbox.ui/include/rawrbox/ui/elements/group.hpp @@ -8,8 +8,8 @@ namespace rawrbox { float _border = 0.F; public: + UIGroup(rawrbox::UIRoot* root); ~UIGroup() override = default; - UIGroup() = default; UIGroup(const UIGroup&) = default; UIGroup(UIGroup&&) = delete; UIGroup& operator=(const UIGroup&) = default; diff --git a/rawrbox.ui/include/rawrbox/ui/elements/image.hpp b/rawrbox.ui/include/rawrbox/ui/elements/image.hpp index a9bc5318..7d2ce3a9 100644 --- a/rawrbox.ui/include/rawrbox/ui/elements/image.hpp +++ b/rawrbox.ui/include/rawrbox/ui/elements/image.hpp @@ -12,14 +12,12 @@ namespace rawrbox { rawrbox::Color _color = rawrbox::Colors::White(); public: - UIImage() = default; + UIImage(rawrbox::UIRoot* root); UIImage(const UIImage&) = default; UIImage(UIImage&&) = delete; UIImage& operator=(const UIImage&) = default; UIImage& operator=(UIImage&&) = delete; - ~UIImage() override { - this->_texture = nullptr; - } + ~UIImage() override; // UTILS ---- [[nodiscard]] virtual rawrbox::TextureBase* getTexture() const; diff --git a/rawrbox.ui/include/rawrbox/ui/elements/input.hpp b/rawrbox.ui/include/rawrbox/ui/elements/input.hpp index 4bb78f20..49204ce0 100644 --- a/rawrbox.ui/include/rawrbox/ui/elements/input.hpp +++ b/rawrbox.ui/include/rawrbox/ui/elements/input.hpp @@ -49,19 +49,17 @@ namespace rawrbox { void moveCharet(bool forward); // --------------- public: - ~UIInput() override = default; - UIInput() = default; + UIInput(rawrbox::UIRoot* root); UIInput(const UIInput&) = default; UIInput(UIInput&&) = delete; UIInput& operator=(const UIInput&) = default; UIInput& operator=(UIInput&&) = delete; + ~UIInput() override = default; rawrbox::Event onKey; rawrbox::Event<> onTextUpdate; rawrbox::Event<> onEnter; - void initialize() override; - // UTILS ---- virtual void setHints(const std::vector& hints); diff --git a/rawrbox.ui/include/rawrbox/ui/elements/label.hpp b/rawrbox.ui/include/rawrbox/ui/elements/label.hpp index 9f9ecde3..6ad87eec 100644 --- a/rawrbox.ui/include/rawrbox/ui/elements/label.hpp +++ b/rawrbox.ui/include/rawrbox/ui/elements/label.hpp @@ -19,21 +19,17 @@ namespace rawrbox { rawrbox::Vector2f _shadow = {1, 1}; public: - UILabel() = default; + UILabel(rawrbox::UIRoot* root); UILabel(const UILabel&) = default; UILabel(UILabel&&) = delete; UILabel& operator=(const UILabel&) = default; UILabel& operator=(UILabel&&) = delete; - ~UILabel() override { - this->_font = nullptr; - } + ~UILabel() override; // FOCUS HANDLE --- [[nodiscard]] bool hitTest(const rawrbox::Vector2f& point) const override; // ----- - void initialize() override; - // UTILS ---- virtual void setColor(const rawrbox::Color& col); [[nodiscard]] virtual const rawrbox::Color& getColor() const; diff --git a/rawrbox.ui/include/rawrbox/ui/elements/progress_bar.hpp b/rawrbox.ui/include/rawrbox/ui/elements/progress_bar.hpp index 1f909180..5a8b5620 100644 --- a/rawrbox.ui/include/rawrbox/ui/elements/progress_bar.hpp +++ b/rawrbox.ui/include/rawrbox/ui/elements/progress_bar.hpp @@ -22,9 +22,14 @@ namespace rawrbox { public: rawrbox::Event onValueChange; - // UTILS ---- - void initialize() override; + UIProgressBar(rawrbox::UIRoot* root); + UIProgressBar(const UIProgressBar&) = default; + UIProgressBar(UIProgressBar&&) = delete; + UIProgressBar& operator=(const UIProgressBar&) = default; + UIProgressBar& operator=(UIProgressBar&&) = delete; + ~UIProgressBar() override; + // UTILS ---- virtual void showPercent(bool show); [[nodiscard]] virtual bool isPercentVisible() const; diff --git a/rawrbox.ui/include/rawrbox/ui/elements/tabs.hpp b/rawrbox.ui/include/rawrbox/ui/elements/tabs.hpp new file mode 100644 index 00000000..91171a85 --- /dev/null +++ b/rawrbox.ui/include/rawrbox/ui/elements/tabs.hpp @@ -0,0 +1,54 @@ +#pragma once + +#include +#include +#include + +#include + +namespace rawrbox { + struct UITab { + public: + std::string name; + std::string id; + + rawrbox::UIGroup* group = nullptr; + rawrbox::UIButton* button = nullptr; + + UITab(std::string id, std::string name, rawrbox::UIGroup* groupUI) : name(std::move(name)), id(std::move(id)), group(groupUI) {} + }; + + class UITabs : public rawrbox::UIContainer { + + protected: + std::vector _tabs = {}; + + rawrbox::UITab* _activeTab = nullptr; + rawrbox::UIGroup* _buttonGroup = nullptr; + + virtual void generate(); + + public: + UITabs(rawrbox::UIRoot* root, const std::vector& tabs); + UITabs(const UITabs&) = default; + UITabs(UITabs&&) = delete; + UITabs& operator=(const UITabs&) = default; + UITabs& operator=(UITabs&&) = delete; + ~UITabs() override = default; + + void setSize(const rawrbox::Vector2f& size) override; + + // TABS ---- + virtual void setActive(size_t index); + virtual void setEnabled(size_t index, bool enabled); + + [[nodiscard]] virtual float getTabHeight() const; + [[nodiscard]] virtual float getButtonWidth() const; + [[nodiscard]] virtual uint16_t getButtonFontSize() const; + // --------- + + // DRAW ---- + void draw(rawrbox::Stencil& stencil) override; + // ------- + }; +} // namespace rawrbox diff --git a/rawrbox.ui/include/rawrbox/ui/elements/virtual_list.hpp b/rawrbox.ui/include/rawrbox/ui/elements/virtual_list.hpp index 3e0038c1..379bb0e5 100644 --- a/rawrbox.ui/include/rawrbox/ui/elements/virtual_list.hpp +++ b/rawrbox.ui/include/rawrbox/ui/elements/virtual_list.hpp @@ -34,7 +34,7 @@ namespace rawrbox { rawrbox::Color _backgroundColor = rawrbox::Colors::Transparent(); public: - UIVirtualList() = default; + UIVirtualList(rawrbox::UIRoot* root) : rawrbox::UIContainer(root){}; UIVirtualList(const UIVirtualList&) = delete; UIVirtualList(UIVirtualList&&) = delete; UIVirtualList& operator=(const UIVirtualList&) = delete; diff --git a/rawrbox.ui/include/rawrbox/ui/root.hpp b/rawrbox.ui/include/rawrbox/ui/root.hpp index 132e567a..075b4919 100644 --- a/rawrbox.ui/include/rawrbox/ui/root.hpp +++ b/rawrbox.ui/include/rawrbox/ui/root.hpp @@ -48,9 +48,7 @@ namespace rawrbox { template requires(std::derived_from) T* createChild(CallbackArgs&&... args) { - auto elm = std::make_shared(std::forward(args)...); - elm->setRoot(this); - elm->initialize(); + auto elm = std::make_shared(this, std::forward(args)...); auto& childn = this->getChildren(); if (elm->alwaysOnTop()) { diff --git a/rawrbox.ui/include/rawrbox/ui/scripting/plugin.hpp b/rawrbox.ui/include/rawrbox/ui/scripting/plugin.hpp index 67f8adfb..7deb742b 100644 --- a/rawrbox.ui/include/rawrbox/ui/scripting/plugin.hpp +++ b/rawrbox.ui/include/rawrbox/ui/scripting/plugin.hpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include namespace rawrbox { @@ -35,6 +37,8 @@ namespace rawrbox { rawrbox::UIProgressBarWrapper::registerLua(L); rawrbox::UIGraphCatWrapper::registerLua(L); rawrbox::UIGraphWrapper::registerLua(L); + rawrbox::UITabWrapper::registerLua(L); + rawrbox::UITabsWrapper::registerLua(L); // ------ rawrbox::UIWrapper::registerLua(L, _root); diff --git a/rawrbox.ui/include/rawrbox/ui/scripting/wrappers/tab.hpp b/rawrbox.ui/include/rawrbox/ui/scripting/wrappers/tab.hpp new file mode 100644 index 00000000..a6852252 --- /dev/null +++ b/rawrbox.ui/include/rawrbox/ui/scripting/wrappers/tab.hpp @@ -0,0 +1,10 @@ +#pragma once +#include + +namespace rawrbox { + class UITabWrapper { + + public: + static void registerLua(lua_State* L); + }; +} // namespace rawrbox diff --git a/rawrbox.ui/include/rawrbox/ui/scripting/wrappers/tabs.hpp b/rawrbox.ui/include/rawrbox/ui/scripting/wrappers/tabs.hpp new file mode 100644 index 00000000..582277ae --- /dev/null +++ b/rawrbox.ui/include/rawrbox/ui/scripting/wrappers/tabs.hpp @@ -0,0 +1,10 @@ +#pragma once +#include + +namespace rawrbox { + class UITabsWrapper { + + public: + static void registerLua(lua_State* L); + }; +} // namespace rawrbox diff --git a/rawrbox.ui/src/container.cpp b/rawrbox.ui/src/container.cpp index 3ab76d6a..e7015ff8 100644 --- a/rawrbox.ui/src/container.cpp +++ b/rawrbox.ui/src/container.cpp @@ -3,8 +3,11 @@ #include namespace rawrbox { + UIContainer::UIContainer(rawrbox::UIRoot* root) : _root(root) { + if (_root == nullptr) throw rawrbox::Logger::err("UIContainer", "UI root cannot be null!"); + } + UIContainer::UIContainer(rawrbox::UIContainer&& other) noexcept : _parent(other._parent), _children(std::move(other._children)), _alwaysOnTop(other._alwaysOnTop), _aabb(other._aabb) {} - void UIContainer::initialize() {} // UTILS --- rawrbox::Vector2f UIContainer::getDrawOffset() const { return {}; }; diff --git a/rawrbox.ui/src/elements/button.cpp b/rawrbox.ui/src/elements/button.cpp index b0215f37..e5bef577 100644 --- a/rawrbox.ui/src/elements/button.cpp +++ b/rawrbox.ui/src/elements/button.cpp @@ -6,7 +6,7 @@ #include namespace rawrbox { - void UIButton::initialize() { + UIButton::UIButton(rawrbox::UIRoot* root) : rawrbox::UIContainer(root) { this->_overlay = rawrbox::RESOURCES::getFile("assets/textures/ui/overlay/overlay.png")->get(); } diff --git a/rawrbox.ui/src/elements/console.cpp b/rawrbox.ui/src/elements/console.cpp index b2ad02f9..e7489f89 100644 --- a/rawrbox.ui/src/elements/console.cpp +++ b/rawrbox.ui/src/elements/console.cpp @@ -9,14 +9,8 @@ #include namespace rawrbox { - UIConsole::UIConsole(rawrbox::Console& console) : _console(&console) {} - UIConsole::~UIConsole() { - if (this->_console == nullptr) return; - this->_console->onPrint.clear(); - } - - void UIConsole::initialize() { - if (this->_console == nullptr) throw std::runtime_error("[RawrBox-UIConsole] Invalid console reference"); + UIConsole::UIConsole(rawrbox::UIRoot* root, rawrbox::Console& console) : rawrbox::UIContainer(root), _console(&console) { + if (this->_console == nullptr) throw rawrbox::Logger::err("UIConsole", "Invalid console reference"); this->_overlay = rawrbox::RESOURCES::getFile("./assets/textures/ui/overlay/overlay.png")->get(); @@ -112,6 +106,11 @@ namespace rawrbox { this->updateEntries(); } + UIConsole::~UIConsole() { + if (this->_console == nullptr) return; + this->_console->onPrint.clear(); + } + void UIConsole::setVisible(bool visible) { rawrbox::UIContainer::setVisible(visible); if (visible && this->_input != nullptr) { diff --git a/rawrbox.ui/src/elements/frame.cpp b/rawrbox.ui/src/elements/frame.cpp index 3b81cd5c..87a4a1f9 100644 --- a/rawrbox.ui/src/elements/frame.cpp +++ b/rawrbox.ui/src/elements/frame.cpp @@ -6,14 +6,13 @@ #include namespace rawrbox { - void UIFrame::initialize() { + UIFrame::UIFrame(rawrbox::UIRoot* root) : rawrbox::UIContainer(root), _closeButton(this->createChild()) { this->_stripes = rawrbox::RESOURCES::getFile("./assets/textures/ui/stripe.png")->get(); this->_overlay = rawrbox::RESOURCES::getFile("./assets/textures/ui/overlay/overlay.png")->get(); // Build close button --- auto size = this->getSize(); - this->_closeButton = this->createChild(); this->_closeButton->setTexture("./assets/textures/ui/icons/close.png"); this->_closeButton->setSize({30, this->_titleSize - 1}); this->_closeButton->setPos({size.x - 30, -this->_titleSize}); @@ -23,7 +22,6 @@ namespace rawrbox { this->_closeButton->setBorder(false); this->_closeButton->setBackgroundColor(Colors::Transparent()); this->_closeButton->setVisible(this->_closable); - this->_closeButton->initialize(); this->_closeButton->onClick += [this]() { this->onClose(); diff --git a/rawrbox.ui/src/elements/graph.cpp b/rawrbox.ui/src/elements/graph.cpp index 06971ecb..22f87960 100644 --- a/rawrbox.ui/src/elements/graph.cpp +++ b/rawrbox.ui/src/elements/graph.cpp @@ -16,8 +16,9 @@ namespace rawrbox { } // ---------- - void UIGraph::initialize() { - this->_font = rawrbox::DEBUG_FONT_REGULAR; + UIGraph::UIGraph(rawrbox::UIRoot* root) : rawrbox::UIContainer(root), _font(rawrbox::DEBUG_FONT_REGULAR) {} + UIGraph::~UIGraph() { + this->_font = nullptr; } // UTILS ---- diff --git a/rawrbox.ui/src/elements/group.cpp b/rawrbox.ui/src/elements/group.cpp index 4ccc1823..622085fc 100644 --- a/rawrbox.ui/src/elements/group.cpp +++ b/rawrbox.ui/src/elements/group.cpp @@ -2,6 +2,8 @@ #include namespace rawrbox { + UIGroup::UIGroup(rawrbox::UIRoot* root) : rawrbox::UIContainer(root) {} + // UTILS ---- void UIGroup::setBorder(float border) { this->_border = border; } float UIGroup::getBorder() const { return this->_border; } diff --git a/rawrbox.ui/src/elements/image.cpp b/rawrbox.ui/src/elements/image.cpp index 521bb8d2..e8b55ea2 100644 --- a/rawrbox.ui/src/elements/image.cpp +++ b/rawrbox.ui/src/elements/image.cpp @@ -6,6 +6,11 @@ #include namespace rawrbox { + UIImage::UIImage(rawrbox::UIRoot* root) : rawrbox::UIContainer(root) {} + UIImage::~UIImage() { + this->_texture = nullptr; + } + // UTILS ---- rawrbox::TextureBase* UIImage::getTexture() const { return this->_texture; } void UIImage::setTexture(rawrbox::TextureBase* texture) { this->_texture = texture; } diff --git a/rawrbox.ui/src/elements/input.cpp b/rawrbox.ui/src/elements/input.cpp index f5bcf0d2..67a05a16 100644 --- a/rawrbox.ui/src/elements/input.cpp +++ b/rawrbox.ui/src/elements/input.cpp @@ -119,9 +119,7 @@ namespace rawrbox { } // ----- - void UIInput::initialize() { - this->_font = rawrbox::DEBUG_FONT_REGULAR; - + UIInput::UIInput(rawrbox::UIRoot* root) : rawrbox::UIContainer(root), _font(rawrbox::DEBUG_FONT_REGULAR) { this->_charSize = this->_font->getStringSize("W"); this->_textSize.y = this->_charSize.y; } diff --git a/rawrbox.ui/src/elements/label.cpp b/rawrbox.ui/src/elements/label.cpp index 2830722b..7d0aa643 100644 --- a/rawrbox.ui/src/elements/label.cpp +++ b/rawrbox.ui/src/elements/label.cpp @@ -6,14 +6,15 @@ #include namespace rawrbox { + UILabel::UILabel(rawrbox::UIRoot* root) : rawrbox::UIContainer(root), _font(rawrbox::DEBUG_FONT_REGULAR) {} + UILabel::~UILabel() { + this->_font = nullptr; + } + // FOCUS HANDLE --- bool UILabel::hitTest(const rawrbox::Vector2f& /*point*/) const { return false; } // ----- - void UILabel::initialize() { - this->_font = rawrbox::DEBUG_FONT_REGULAR; - } - // UTILS ---- void UILabel::setColor(const rawrbox::Color& col) { this->_color = col; } const rawrbox::Color& UILabel::getColor() const { return this->_color; } diff --git a/rawrbox.ui/src/elements/progress_bar.cpp b/rawrbox.ui/src/elements/progress_bar.cpp index fdec7528..44180b37 100644 --- a/rawrbox.ui/src/elements/progress_bar.cpp +++ b/rawrbox.ui/src/elements/progress_bar.cpp @@ -7,11 +7,16 @@ namespace rawrbox { // UTILS ---- - void UIProgressBar::initialize() { + UIProgressBar::UIProgressBar(rawrbox::UIRoot* root) : rawrbox::UIContainer(root) { this->_overlay = rawrbox::RESOURCES::getFile("./assets/textures/ui/overlay/overlay.png")->get(); this->_bg = rawrbox::RESOURCES::getFile("./assets/textures/ui/background_grid.png")->get(); } + UIProgressBar::~UIProgressBar() { + this->_overlay = nullptr; + this->_bg = nullptr; + } + void UIProgressBar::showPercent(bool show) { this->_percent = show; } bool UIProgressBar::isPercentVisible() const { return this->_percent; } diff --git a/rawrbox.ui/src/elements/tabs.cpp b/rawrbox.ui/src/elements/tabs.cpp new file mode 100644 index 00000000..a0cafc15 --- /dev/null +++ b/rawrbox.ui/src/elements/tabs.cpp @@ -0,0 +1,100 @@ +#include +#include +#include + +namespace rawrbox { + // PRIVATE ---- + void UITabs::generate() { + if (this->_buttonGroup == nullptr) throw rawrbox::Logger::err("UITabs", "Button group is null"); + const auto& size = this->getSize(); + + const float height = this->getTabHeight(); + const float buttonWidth = this->getButtonWidth(); + + // Create the main group --- + this->_buttonGroup->setPos({0, 0}); + this->_buttonGroup->setSize({size.x, height}); + + this->_buttonGroup->removeChildren(); + // ------ + + for (size_t i = 0; i < this->_tabs.size(); i++) { + auto& tab = this->_tabs[i]; + + tab.group->setPos({0, height}); + tab.group->setSize({size.x, size.y - height}); + tab.group->setVisible(false); + + // Generate buttons --- + tab.button = this->_buttonGroup->createChild(); + tab.button->setText(tab.name, this->getButtonFontSize()); + tab.button->setPos({static_cast(i) * (buttonWidth + 2.F), 0}); + tab.button->setSize({buttonWidth, height}); + tab.button->setEnabled(true); + tab.button->setTextColor(rawrbox::Colors::White()); + tab.button->setBorder(false); + tab.button->setBackgroundColor(rawrbox::Color::RGBHex(0x282a2e)); + tab.button->onClick += [this, i]() { + this->setActive(i); + }; + // ------------ + } + } + // ------------- + + UITabs::UITabs(rawrbox::UIRoot* root, const std::vector& tabs) : rawrbox::UIContainer(root), _tabs(tabs), _buttonGroup(this->createChild()) {} + + void UITabs::setSize(const rawrbox::Vector2f& size) { + rawrbox::UIContainer::setSize(size); + this->generate(); + } + + // TABS --- + void UITabs::setActive(size_t index) { + if (index > this->_tabs.size()) throw rawrbox::Logger::err("UITabs", "Invalid index {}", index); + + if (this->_activeTab != nullptr) { + if (this->_activeTab->button != nullptr && this->_activeTab->group != nullptr) { + this->_activeTab->button->setBackgroundColor(Color::RGBHex(0x282a2e)); + this->_activeTab->group->setVisible(false); + } + } + + auto& tab = this->_tabs[index]; + if (tab.button == nullptr) throw rawrbox::Logger::err("UITabs", "Invalid tab button from index {}", index); + if (tab.group == nullptr) throw rawrbox::Logger::err("UITabs", "Invalid tab group from index {}", index); + + tab.button->setBackgroundColor(Color::RGBHex(0x131418)); + tab.group->setVisible(true); + + this->_activeTab = &tab; + } + + void UITabs::setEnabled(size_t index, bool enabled) { + if (index > this->_tabs.size()) throw rawrbox::Logger::err("UITabs", "Invalid index {}", index); + + auto& tab = this->_tabs[index]; + if (tab.button == nullptr) throw rawrbox::Logger::err("UITabs", "Invalid tab button from index {}", index); + if (tab.group == nullptr) throw rawrbox::Logger::err("UITabs", "Invalid tab group from index {}", index); + + tab.button->setEnabled(enabled); + } + + float UITabs::getTabHeight() const { return 20.F; } + float UITabs::getButtonWidth() const { return 70.F; } + + uint16_t UITabs::getButtonFontSize() const { return 11U; } + // ---- + + // DRAW ---- + void UITabs::draw(rawrbox::Stencil& stencil) { + const auto& size = this->getSize(); + const auto height = this->getTabHeight(); + + // Top bar + stencil.drawBox({0, 0}, {size.x, height}, rawrbox::Color::RGBHex(0x202226)); + stencil.drawBox({0, 20}, {size.x, 1}, rawrbox::Color::RGBAHex(0x0000005A)); // line split + // ---- + } + // ------- +} // namespace rawrbox diff --git a/rawrbox.ui/src/scripting/wrappers/tab.cpp b/rawrbox.ui/src/scripting/wrappers/tab.cpp new file mode 100644 index 00000000..3848070e --- /dev/null +++ b/rawrbox.ui/src/scripting/wrappers/tab.cpp @@ -0,0 +1,16 @@ +#include +#include + +namespace rawrbox { + void UITabWrapper::registerLua(lua_State* L) { + luabridge::getGlobalNamespace(L) + .beginClass("UITab") + .addConstructor() + + .addProperty("id", &rawrbox::UITab::id, false) + .addProperty("name", &rawrbox::UITab::name, false) + .addProperty("group", &rawrbox::UITab::group, false) + + .endClass(); + } +} // namespace rawrbox diff --git a/rawrbox.ui/src/scripting/wrappers/tabs.cpp b/rawrbox.ui/src/scripting/wrappers/tabs.cpp new file mode 100644 index 00000000..e8d875b9 --- /dev/null +++ b/rawrbox.ui/src/scripting/wrappers/tabs.cpp @@ -0,0 +1,19 @@ +#include +#include + +namespace rawrbox { + void UITabsWrapper::registerLua(lua_State* L) { + luabridge::getGlobalNamespace(L) + .deriveClass("UITabs") + .addConstructor&)>() + + .addFunction("setActive", &rawrbox::UITabs::setActive) + .addFunction("setEnabled", &rawrbox::UITabs::setEnabled) + + .addFunction("getButtonWidth", &rawrbox::UITabs::getButtonWidth) + .addFunction("getButtonFontSize", &rawrbox::UITabs::getButtonFontSize) + .addFunction("getTabHeight", &rawrbox::UITabs::getTabHeight) + + .endClass(); + } +} // namespace rawrbox diff --git a/rawrbox.ui/src/scripting/wrappers/ui.cpp b/rawrbox.ui/src/scripting/wrappers/ui.cpp index 20d20047..b8c2e0c5 100644 --- a/rawrbox.ui/src/scripting/wrappers/ui.cpp +++ b/rawrbox.ui/src/scripting/wrappers/ui.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -86,6 +87,13 @@ namespace rawrbox { return root->createChild(); }) + .addFunction("createTabs", [root](std::optional parent, const std::vector& tabs) { + if (parent.has_value()) { + return parent.value()->createChild(tabs); + } + + return root->createChild(tabs); + }) .endNamespace(); } } // namespace rawrbox diff --git a/samples/008-ui/src/game.cpp b/samples/008-ui/src/game.cpp index 7def6b0b..2b3cfb4f 100644 --- a/samples/008-ui/src/game.cpp +++ b/samples/008-ui/src/game.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -227,15 +228,14 @@ namespace ui_test { frame->setTitle("Virtual lists"); frame->setSize({400, 250}); frame->setPos({100, 450}); + + // LIST { auto* label = frame->createChild(); label->setPos({5, 3}); label->setText("LIST MODE"); label->sizeToContents(); - } - // LIST - { auto* vlist = frame->createChild>(); vlist->setPos({0, 16}); vlist->setSize({400, 100}); @@ -253,14 +253,13 @@ namespace ui_test { vlist->addItem(fmt::format("Item #{}", i)); } + // GRID { auto* label = frame->createChild(); label->setPos({5, 120}); label->setText("GRID MODE"); label->sizeToContents(); - } - // GRID - { + auto* vlist = frame->createChild>(); vlist->setPos({0, 136}); vlist->setSize({400, 100}); @@ -281,7 +280,7 @@ namespace ui_test { { auto* frame = this->_ROOT_UI->createChild(); - frame->setTitle("graphss"); + frame->setTitle("Graphs"); frame->setSize({400, 200}); frame->setPos({100, 200}); frame->onClose += [this]() { @@ -304,6 +303,52 @@ namespace ui_test { this->_graph->setSmoothing(20); this->_graph->setShowLegend(true); } + + { + auto* frame = this->_ROOT_UI->createChild(); + frame->setTitle("Tabs"); + frame->setSize({300, 250}); + frame->setPos({600, 450}); + + // TAB 1 --- + auto* group1 = frame->createChild(); + auto* label1 = group1->createChild(); + label1->setText("Tab 1"); + label1->sizeToContents(); + // -------- + + // TAB 2 --- + auto* group2 = frame->createChild(); + auto* label2 = group2->createChild(); + label2->setText("Tab 2"); + label2->sizeToContents(); + // -------- + + // TAB 3 --- + auto* group3 = frame->createChild(); + auto* label3 = group3->createChild(); + label3->setText("Tab 3"); + label3->sizeToContents(); + // -------- + + // TAB 4 --- + auto* group4 = frame->createChild(); + auto* label4 = group4->createChild(); + label4->setText("Tab 4"); + label4->sizeToContents(); + // -------- + + std::vector tabs = { + {"tab1", "Tab 1", group1}, + {"tab2", "Tab 2", group2}, + {"tab3", "Tab 3", group3}, + {"tab4", "Tab 4", group4}}; + + auto* tab = frame->createChild(tabs); + tab->setSize({300, 250}); + tab->setActive(0); + tab->setEnabled(2, false); + } // --- this->_ready = true; From d5e12cf81ee33dccd471c05814c13f31898caeec Mon Sep 17 00:00:00 2001 From: FailCake Date: Wed, 10 Jul 2024 10:20:54 +0200 Subject: [PATCH 2/2] Add missing tab height --- rawrbox.ui/src/elements/tabs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rawrbox.ui/src/elements/tabs.cpp b/rawrbox.ui/src/elements/tabs.cpp index a0cafc15..9d0cf289 100644 --- a/rawrbox.ui/src/elements/tabs.cpp +++ b/rawrbox.ui/src/elements/tabs.cpp @@ -93,8 +93,8 @@ namespace rawrbox { // Top bar stencil.drawBox({0, 0}, {size.x, height}, rawrbox::Color::RGBHex(0x202226)); - stencil.drawBox({0, 20}, {size.x, 1}, rawrbox::Color::RGBAHex(0x0000005A)); // line split - // ---- + stencil.drawBox({0, height}, {size.x, 1}, rawrbox::Color::RGBAHex(0x0000005A)); // line split + // ---- } // ------- } // namespace rawrbox