From 239ada8e3d6591052ff4cf681bc7e9743f6b7d27 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 6 Feb 2026 18:05:21 +0300 Subject: [PATCH] add cursorLocator argument to gui.set_active_frame --- res/scripts/hud.lua | 5 +++-- src/graphics/ui/GUI.cpp | 22 ++++++++++++++-------- src/graphics/ui/GUI.hpp | 5 ++++- src/logic/scripting/lua/libs/libgui.cpp | 16 +++++++++++++++- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/res/scripts/hud.lua b/res/scripts/hud.lua index 3bdb4d634..365d02e43 100644 --- a/res/scripts/hud.lua +++ b/res/scripts/hud.lua @@ -130,10 +130,11 @@ function on_hud_open() local name = "misc/moon" local frame = gui.create_frame(name, name, {128, 128}) frame:add("") - frame.color = {255, 0, 0, 255} input.add_callback('key:y', function () - gui.set_active_frame(name) + gui.set_active_frame(name, function() + return input.get_mouse_pos() + end) end) end diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp index 1efc1e1f8..6dcb19d90 100644 --- a/src/graphics/ui/GUI.cpp +++ b/src/graphics/ui/GUI.cpp @@ -123,13 +123,18 @@ void GUI::updateTooltip(float delta) { /// @brief Mouse related input and logic handling void GUI::actMouse(Frame& frame, float delta, const CursorState& cursor) { - auto& state = frame.getState(); - float mouseDelta = glm::length(cursor.delta); doubleClicked = false; doubleClickTimer += delta + mouseDelta * 0.1f; - auto hover = frame.getAt(cursor.pos); + auto cursorPos = cursor.pos; + if (cursorLocator) { + cursorPos = cursorLocator(); + if (activeFrame) { + cursorPos.y += activeFrame->getPos().y; + } + } + auto hover = frame.getAt(cursorPos); if (this->hover && this->hover != hover) { this->hover->setMouseEnter(false); } @@ -166,7 +171,7 @@ void GUI::actMouse(Frame& frame, float delta, const CursorState& cursor) { for (auto it = mouseOver.begin(); it != mouseOver.end(); ) { auto mouseOverNode = it->lock(); if (mouseOverNode) { - if (mouseOverNode->isInside(cursor.pos)) { + if (mouseOverNode->isInside(cursorPos)) { ++it; continue; } @@ -179,10 +184,10 @@ void GUI::actMouse(Frame& frame, float delta, const CursorState& cursor) { if (pressed == nullptr && this->hover) { pressed = hover; if (doubleClickTimer < doubleClickDelay) { - pressed->doubleClick(cursor.pos.x, cursor.pos.y); + pressed->doubleClick(cursorPos.x, cursorPos.y); doubleClicked = true; } else { - pressed->click(cursor.pos.x, cursor.pos.y); + pressed->click(cursorPos.x, cursorPos.y); } doubleClickTimer = 0.0f; if (focus && focus != pressed) { @@ -199,7 +204,7 @@ void GUI::actMouse(Frame& frame, float delta, const CursorState& cursor) { focus = nullptr; } } else if (!input.clicked(Mousecode::BUTTON_1) && pressed) { - pressed->mouseRelease(cursor.pos.x, cursor.pos.y); + pressed->mouseRelease(cursorPos.x, cursorPos.y); pressed = nullptr; } @@ -354,7 +359,8 @@ void GUI::addFrame(std::shared_ptr frame) { frames[id] = std::move(frame); } -void GUI::setActiveFrame(const std::string& id) { +void GUI::setActiveFrame(const std::string& id, vec2supplier cursorLocator) { + this->cursorLocator = std::move(cursorLocator); if (id.empty()) { activeFrame = nullptr; return; diff --git a/src/graphics/ui/GUI.hpp b/src/graphics/ui/GUI.hpp index ee3fc1cd5..7d120c9cc 100644 --- a/src/graphics/ui/GUI.hpp +++ b/src/graphics/ui/GUI.hpp @@ -83,6 +83,7 @@ namespace gui { std::queue postRunnables; std::vector> mouseOver; std::unordered_map> frames; + vec2supplier cursorLocator; float tooltipTimer = 0.0f; float doubleClickTimer = 0.0f; @@ -129,7 +130,9 @@ namespace gui { void addFrame(std::shared_ptr frame); - void setActiveFrame(const std::string& id); + void setActiveFrame( + const std::string& id, vec2supplier cursorLocator = nullptr + ); std::shared_ptr getActiveFrame() const; diff --git a/src/logic/scripting/lua/libs/libgui.cpp b/src/logic/scripting/lua/libs/libgui.cpp index 0d6292d7a..60f894bda 100644 --- a/src/logic/scripting/lua/libs/libgui.cpp +++ b/src/logic/scripting/lua/libs/libgui.cpp @@ -1175,8 +1175,22 @@ static int l_set_active_frame(lua::State* L) { return 0; } std::string id = lua::require_string(L, 1); + vec2supplier cursorLocator = nullptr; + if (lua::isfunction(L, 2)) { + auto lambda = lua::create_lambda(L); + cursorLocator = [lambda]() -> glm::vec2 { + auto table = lambda({}); + if (!table.isList()) { + throw std::runtime_error("invalid value returned from locator"); + } + glm::vec2 pos {}; + table.at(0).get(pos.x); + table.at(1).get(pos.y); + return pos; + }; + } auto& gui = engine->getGUI(); - gui.setActiveFrame(id); + gui.setActiveFrame(id, std::move(cursorLocator)); return 0; }