From 95721a6864a67972d5fa7cbe41570f984e5b70c7 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 14 Nov 2025 19:50:09 +0300 Subject: [PATCH] combine uinode actions callbacks sets & cleanup --- src/graphics/ui/elements/Button.cpp | 2 +- src/graphics/ui/elements/SelectBox.cpp | 2 +- src/graphics/ui/elements/UINode.cpp | 28 +++++++-------- src/graphics/ui/elements/UINode.hpp | 50 +++++++++++++++++++------- src/graphics/ui/gui_xml.cpp | 2 +- 5 files changed, 53 insertions(+), 31 deletions(-) diff --git a/src/graphics/ui/elements/Button.cpp b/src/graphics/ui/elements/Button.cpp index 59f90b07..2fe6fc6a 100644 --- a/src/graphics/ui/elements/Button.cpp +++ b/src/graphics/ui/elements/Button.cpp @@ -42,7 +42,7 @@ Button::Button( } if (action) { - listenAction(action); + listenClick(action); } setScrollable(false); diff --git a/src/graphics/ui/elements/SelectBox.cpp b/src/graphics/ui/elements/SelectBox.cpp index 7d4d036e..7273294b 100644 --- a/src/graphics/ui/elements/SelectBox.cpp +++ b/src/graphics/ui/elements/SelectBox.cpp @@ -19,7 +19,7 @@ SelectBox::SelectBox( : Button(gui, selected.text, padding, nullptr, glm::vec2(contentWidth, -1)), options(std::move(options)) { - listenAction([this](GUI& gui) { + listenClick([this](GUI& gui) { auto panel = std::make_shared(gui, getSize()); panel->setPos(calcPos() + glm::vec2(0, size.y)); for (const auto& option : this->options) { diff --git a/src/graphics/ui/elements/UINode.cpp b/src/graphics/ui/elements/UINode.cpp index ec49352d..a5d26ffe 100644 --- a/src/graphics/ui/elements/UINode.cpp +++ b/src/graphics/ui/elements/UINode.cpp @@ -64,24 +64,20 @@ UINode* UINode::getParent() const { return parent; } -UINode* UINode::listenAction(const OnAction& action) { - actions.listen(action); - return this; +void UINode::listenClick(OnAction action) { + actions.listen(UIAction::CLICK, std::move(action)); } -UINode* UINode::listenDoubleClick(const OnAction& action) { - doubleClickCallbacks.listen(action); - return this; +void UINode::listenDoubleClick(OnAction action) { + actions.listen(UIAction::DOUBLE_CLICK, std::move(action)); } -UINode* UINode::listenFocus(const OnAction& action) { - focusCallbacks.listen(action); - return this; +void UINode::listenFocus(OnAction action) { + actions.listen(UIAction::FOCUS, std::move(action)); } -UINode* UINode::listenDefocus(const OnAction& action) { - defocusCallbacks.listen(action); - return this; +void UINode::listenDefocus(OnAction action) { + actions.listen(UIAction::DEFOCUS, std::move(action)); } void UINode::click(int, int) { @@ -91,14 +87,14 @@ void UINode::click(int, int) { void UINode::doubleClick(int x, int y) { pressed = true; if (isInside(glm::vec2(x, y))) { - doubleClickCallbacks.notify(gui); + actions.notify(UIAction::DOUBLE_CLICK, gui); } } void UINode::mouseRelease(int x, int y) { pressed = false; if (isInside(glm::vec2(x, y))) { - actions.notify(gui); + actions.notify(UIAction::CLICK, gui); } } @@ -108,12 +104,12 @@ bool UINode::isPressed() const { void UINode::onFocus() { focused = true; - focusCallbacks.notify(gui); + actions.notify(UIAction::FOCUS, gui); } void UINode::defocus() { focused = false; - defocusCallbacks.notify(gui); + actions.notify(UIAction::DEFOCUS, gui); } bool UINode::isFocused() const { diff --git a/src/graphics/ui/elements/UINode.hpp b/src/graphics/ui/elements/UINode.hpp index 273e71bf..4ae76946 100644 --- a/src/graphics/ui/elements/UINode.hpp +++ b/src/graphics/ui/elements/UINode.hpp @@ -46,7 +46,39 @@ namespace gui { } }; - using ActionsSet = CallbacksSet; + template + class TaggedCallbacksSet { + public: + using Func = std::function; + private: + std::unique_ptr>> callbacks; + public: + void listen(TagT tag, Func&& callback) { + if (callbacks == nullptr) { + callbacks = + std::make_unique>>(); + } + callbacks->push_back({tag, std::move(callback)}); + } + + void notify(TagT notifyTag, Args&&... args) { + if (callbacks == nullptr) { + return; + } + for (const auto& [tag, callback] : * callbacks) { + if (tag != notifyTag) { + continue; + } + callback(args...); + } + } + }; + + enum class UIAction { + CLICK, DOUBLE_CLICK, FOCUS, DEFOCUS + }; + + using ActionsSet = TaggedCallbacksSet; using StringCallbacksSet = CallbacksSet; enum class Align { @@ -119,14 +151,8 @@ namespace gui { vec2supplier positionfunc = nullptr; /// @brief size supplier for the element (called on parent element size update) vec2supplier sizefunc = nullptr; - /// @brief 'onclick' callbacks + /// @brief parameterless callbacks ActionsSet actions; - /// @brief 'ondoubleclick' callbacks - ActionsSet doubleClickCallbacks; - /// @brief 'onfocus' callbacks - ActionsSet focusCallbacks; - /// @brief 'ondefocus' callbacks - ActionsSet defocusCallbacks; /// @brief element tooltip text std::wstring tooltip; /// @brief element tooltip delay @@ -187,10 +213,10 @@ namespace gui { /// @brief Get element z-index int getZIndex() const; - virtual UINode* listenAction(const OnAction& action); - virtual UINode* listenDoubleClick(const OnAction& action); - virtual UINode* listenFocus(const OnAction& action); - virtual UINode* listenDefocus(const OnAction& action); + virtual void listenClick(OnAction action); + virtual void listenDoubleClick(OnAction action); + virtual void listenFocus(OnAction action); + virtual void listenDefocus(OnAction action); virtual void onFocus(); virtual void doubleClick(int x, int y); diff --git a/src/graphics/ui/gui_xml.cpp b/src/graphics/ui/gui_xml.cpp index 0ed8461d..73f1937c 100644 --- a/src/graphics/ui/gui_xml.cpp +++ b/src/graphics/ui/gui_xml.cpp @@ -178,7 +178,7 @@ static void read_uinode( } if (auto onclick = create_action(reader, element, "onclick")) { - node.listenAction(onclick); + node.listenClick(onclick); } if (auto onfocus = create_action(reader, element, "onfocus")) {