add cursorLocator argument to gui.set_active_frame

This commit is contained in:
MihailRis 2026-02-06 18:05:21 +03:00
parent 8ee2edef5c
commit 239ada8e3d
4 changed files with 36 additions and 12 deletions

View file

@ -130,10 +130,11 @@ function on_hud_open()
local name = "misc/moon" local name = "misc/moon"
local frame = gui.create_frame(name, name, {128, 128}) local frame = gui.create_frame(name, name, {128, 128})
frame:add("<button>Hello, World</button>") frame:add("<button>Hello, World</button>")
frame.color = {255, 0, 0, 255}
input.add_callback('key:y', function () 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)
end end

View file

@ -123,13 +123,18 @@ void GUI::updateTooltip(float delta) {
/// @brief Mouse related input and logic handling /// @brief Mouse related input and logic handling
void GUI::actMouse(Frame& frame, float delta, const CursorState& cursor) { void GUI::actMouse(Frame& frame, float delta, const CursorState& cursor) {
auto& state = frame.getState();
float mouseDelta = glm::length(cursor.delta); float mouseDelta = glm::length(cursor.delta);
doubleClicked = false; doubleClicked = false;
doubleClickTimer += delta + mouseDelta * 0.1f; 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) { if (this->hover && this->hover != hover) {
this->hover->setMouseEnter(false); 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(); ) { for (auto it = mouseOver.begin(); it != mouseOver.end(); ) {
auto mouseOverNode = it->lock(); auto mouseOverNode = it->lock();
if (mouseOverNode) { if (mouseOverNode) {
if (mouseOverNode->isInside(cursor.pos)) { if (mouseOverNode->isInside(cursorPos)) {
++it; ++it;
continue; continue;
} }
@ -179,10 +184,10 @@ void GUI::actMouse(Frame& frame, float delta, const CursorState& cursor) {
if (pressed == nullptr && this->hover) { if (pressed == nullptr && this->hover) {
pressed = hover; pressed = hover;
if (doubleClickTimer < doubleClickDelay) { if (doubleClickTimer < doubleClickDelay) {
pressed->doubleClick(cursor.pos.x, cursor.pos.y); pressed->doubleClick(cursorPos.x, cursorPos.y);
doubleClicked = true; doubleClicked = true;
} else { } else {
pressed->click(cursor.pos.x, cursor.pos.y); pressed->click(cursorPos.x, cursorPos.y);
} }
doubleClickTimer = 0.0f; doubleClickTimer = 0.0f;
if (focus && focus != pressed) { if (focus && focus != pressed) {
@ -199,7 +204,7 @@ void GUI::actMouse(Frame& frame, float delta, const CursorState& cursor) {
focus = nullptr; focus = nullptr;
} }
} else if (!input.clicked(Mousecode::BUTTON_1) && pressed) { } else if (!input.clicked(Mousecode::BUTTON_1) && pressed) {
pressed->mouseRelease(cursor.pos.x, cursor.pos.y); pressed->mouseRelease(cursorPos.x, cursorPos.y);
pressed = nullptr; pressed = nullptr;
} }
@ -354,7 +359,8 @@ void GUI::addFrame(std::shared_ptr<Frame> frame) {
frames[id] = std::move(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()) { if (id.empty()) {
activeFrame = nullptr; activeFrame = nullptr;
return; return;

View file

@ -83,6 +83,7 @@ namespace gui {
std::queue<runnable> postRunnables; std::queue<runnable> postRunnables;
std::vector<std::weak_ptr<UINode>> mouseOver; std::vector<std::weak_ptr<UINode>> mouseOver;
std::unordered_map<std::string, std::shared_ptr<Frame>> frames; std::unordered_map<std::string, std::shared_ptr<Frame>> frames;
vec2supplier cursorLocator;
float tooltipTimer = 0.0f; float tooltipTimer = 0.0f;
float doubleClickTimer = 0.0f; float doubleClickTimer = 0.0f;
@ -129,7 +130,9 @@ namespace gui {
void addFrame(std::shared_ptr<Frame> frame); void addFrame(std::shared_ptr<Frame> frame);
void setActiveFrame(const std::string& id); void setActiveFrame(
const std::string& id, vec2supplier cursorLocator = nullptr
);
std::shared_ptr<Frame> getActiveFrame() const; std::shared_ptr<Frame> getActiveFrame() const;

View file

@ -1175,8 +1175,22 @@ static int l_set_active_frame(lua::State* L) {
return 0; return 0;
} }
std::string id = lua::require_string(L, 1); 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(); auto& gui = engine->getGUI();
gui.setActiveFrame(id); gui.setActiveFrame(id, std::move(cursorLocator));
return 0; return 0;
} }