combine uinode actions callbacks sets & cleanup

This commit is contained in:
MihailRis 2025-11-14 19:50:09 +03:00
parent f9bab5a5cf
commit 95721a6864
5 changed files with 53 additions and 31 deletions

View File

@ -42,7 +42,7 @@ Button::Button(
}
if (action) {
listenAction(action);
listenClick(action);
}
setScrollable(false);

View File

@ -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<Panel>(gui, getSize());
panel->setPos(calcPos() + glm::vec2(0, size.y));
for (const auto& option : this->options) {

View File

@ -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 {

View File

@ -46,7 +46,39 @@ namespace gui {
}
};
using ActionsSet = CallbacksSet<GUI&>;
template<class TagT, typename... Args>
class TaggedCallbacksSet {
public:
using Func = std::function<void(Args...)>;
private:
std::unique_ptr<std::vector<std::pair<TagT, Func>>> callbacks;
public:
void listen(TagT tag, Func&& callback) {
if (callbacks == nullptr) {
callbacks =
std::make_unique<std::vector<std::pair<TagT, Func>>>();
}
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<UIAction, GUI&>;
using StringCallbacksSet = CallbacksSet<GUI&, const std::string&>;
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);

View File

@ -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")) {