Merge pull request #707 from MihailRis/hover-events

add onmouseover, onmouseout ui events
This commit is contained in:
MihailRis 2025-11-26 00:21:21 +03:00 committed by GitHub
commit 5436b98f3b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 36 additions and 53 deletions

View File

@ -42,6 +42,8 @@ Examples:
- `ondoubleclick` - lua function called when you double click on an element.
- `onfocus` - lua function called when focusing on an element.
- `ondefocus` - lua function called when the element loses focus.
- `onmouseover` - lua function called when the cursor enters an element.
- `onmouseover` - lua function called when the cursor exits an element.
- `tooltip` - tooltip text
- `tooltip-delay` - tooltip show-up delay
- `gravity` - automatic positioning of the element in the container. (Does not work in automatic containers like panel). Values: *top-left, top-center, top-right, center-left, center-center, center-right, bottom-left, bottom-center, bottom-right*.

View File

@ -46,6 +46,8 @@
- `ondoubleclick` - lua функция вызываемая при двойном нажатии на элемент.
- `onfocus` - lua функция вызываемая при фокусировке на элемент.
- `ondefocus` - lua функция вызываемая при потере фокуса элеметом.
- `onmouseover` - lua функция вызываемая при входе курсора в элемент.
- `onmouseover` - lua функция вызываемая при выходе курсора из элемента.
- `tooltip` - текст всплывающей подсказки
- `tooltip-delay` - задержка появления всплывающей подсказки
- `gravity` - автоматическое позиционирование элемента в контейнере. (Не работает в автоматических контейнерах, как panel). Значения: *top-left, top-center, top-right, center-left, center-center, center-right, bottom-left, bottom-center, bottom-right*.

View File

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

View File

@ -19,14 +19,14 @@ SelectBox::SelectBox(
: Button(gui, selected.text, padding, nullptr, glm::vec2(contentWidth, -1)),
options(std::move(options)) {
listenClick([this](GUI& gui) {
listenAction(UIAction::CLICK, [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) {
auto button = std::make_shared<Button>(
gui, option.text, glm::vec4(10.0f), nullptr, glm::vec2(-1.0f)
);
button->listenFocus([this, option](GUI& gui) {
button->listenAction(UIAction::FOCUS, [this, option](GUI& gui) {
setSelected(option);
changeCallbacks.notify(gui, option.value);
});
@ -34,7 +34,7 @@ SelectBox::SelectBox(
}
panel->setZIndex(GUI::CONTEXT_MENU_ZINDEX);
gui.setFocus(panel);
panel->listenDefocus([panel=panel.get()](GUI& gui) {
panel->listenAction(UIAction::DEFOCUS, [panel=panel.get()](GUI& gui) {
gui.remove(panel);
});
gui.add(panel);

View File

@ -11,8 +11,7 @@ using gui::Align;
UINode::UINode(GUI& gui, glm::vec2 size) : gui(gui), size(size) {
}
UINode::~UINode() {
}
UINode::~UINode() = default;
bool UINode::isVisible() const {
if (visible && parent) {
@ -49,7 +48,11 @@ void UINode::setAlign(Align align) {
}
void UINode::setHover(bool flag) {
if (hover == flag) {
return;
}
hover = flag;
actions.notify(flag ? UIAction::MOUSE_OVER : UIAction::MOUSE_OUT, gui);
}
bool UINode::isHover() const {
@ -64,24 +67,8 @@ UINode* UINode::getParent() const {
return parent;
}
void UINode::listenClick(OnAction action) {
actions.listen(UIAction::CLICK, std::move(action));
}
void UINode::listenRightClick(OnAction action) {
actions.listen(UIAction::RIGHT_CLICK, std::move(action));
}
void UINode::listenDoubleClick(OnAction action) {
actions.listen(UIAction::DOUBLE_CLICK, std::move(action));
}
void UINode::listenFocus(OnAction action) {
actions.listen(UIAction::FOCUS, std::move(action));
}
void UINode::listenDefocus(OnAction action) {
actions.listen(UIAction::DEFOCUS, std::move(action));
void UINode::listenAction(UIAction type, OnAction action) {
actions.listen(type, std::move(action));
}
void UINode::click(int, int) {

View File

@ -53,7 +53,13 @@ namespace gui {
};
enum class UIAction {
CLICK, DOUBLE_CLICK, FOCUS, DEFOCUS, RIGHT_CLICK
CLICK,
DOUBLE_CLICK,
FOCUS,
DEFOCUS,
RIGHT_CLICK,
MOUSE_OVER,
MOUSE_OUT
};
using ActionsSet = TaggedCallbacksSet<UIAction, GUI&>;
@ -191,11 +197,7 @@ namespace gui {
/// @brief Get element z-index
int getZIndex() const;
virtual void listenClick(OnAction action);
virtual void listenRightClick(OnAction action);
virtual void listenDoubleClick(OnAction action);
virtual void listenFocus(OnAction action);
virtual void listenDefocus(OnAction action);
void listenAction(UIAction type, OnAction action);
virtual void onFocus();
virtual void doubleClick(int x, int y);

View File

@ -73,16 +73,18 @@ static runnable create_runnable(
return nullptr;
}
static OnAction create_action(
static void register_action(
UINode& node,
const UiXmlReader& reader,
const xml::xmlelement& element,
const std::string& name
const std::string& name,
UIAction action
) {
auto callback = create_runnable(reader, element, name);
if (callback == nullptr) {
return nullptr;
return;
}
return [callback](GUI&) { callback(); };
node.listenAction(action, [callback](GUI&) { callback(); });
}
/// @brief Read basic UINode properties
@ -177,25 +179,13 @@ static void read_uinode(
}
}
if (auto onclick = create_action(reader, element, "onclick")) {
node.listenClick(onclick);
}
if (auto onclick = create_action(reader, element, "onrightclick")) {
node.listenRightClick(onclick);
}
if (auto onfocus = create_action(reader, element, "onfocus")) {
node.listenFocus(onfocus);
}
if (auto ondefocus = create_action(reader, element, "ondefocus")) {
node.listenDefocus(ondefocus);
}
if (auto ondoubleclick = create_action(reader, element, "ondoubleclick")) {
node.listenDoubleClick(ondoubleclick);
}
register_action(node, reader, element, "onclick", UIAction::CLICK);
register_action(node, reader, element, "onrightclick", UIAction::RIGHT_CLICK);
register_action(node, reader, element, "onfocus", UIAction::FOCUS);
register_action(node, reader, element, "ondefocus", UIAction::DEFOCUS);
register_action(node, reader, element, "ondoubleclick", UIAction::DOUBLE_CLICK);
register_action(node, reader, element, "onmouseover", UIAction::MOUSE_OVER);
register_action(node, reader, element, "onmouseout", UIAction::MOUSE_OUT);
}
static void read_container_impl(