diff --git a/res/scripts/hud.lua b/res/scripts/hud.lua
index d10d00e1e..8529ef991 100644
--- a/res/scripts/hud.lua
+++ b/res/scripts/hud.lua
@@ -127,11 +127,11 @@ function on_hud_open()
hud.default_hand_controller = update_hand
- local name = "gui/no_icon"
- gui.create_frame(name, {16, 16})
+ local name = "misc/moon"
+ gui.create_frame(name, name, {128, 128})
local document = Document.new(name)
- document.root:add("")
+ document.root:add("")
document.root.color = {255, 0, 0, 255}
end
diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua
index 683f27e8a..8d6ac26c0 100644
--- a/res/scripts/stdlib.lua
+++ b/res/scripts/stdlib.lua
@@ -232,6 +232,7 @@ _GUI_ROOT = Document.new("core:root")
_MENU = _GUI_ROOT.menu
menu = _MENU
gui.root = _GUI_ROOT
+gui.main_frame_id = "core:main"
do
local status, err = pcall(function()
@@ -435,6 +436,7 @@ function __vc_on_hud_open()
if menu.page ~= "" then
if not menu:back() then
menu:reset()
+ gui.set_active_frame("")
end
elseif hud.is_inventory_open() then
hud.close_inventory()
diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp
index 70bb5dae9..4799e9d77 100644
--- a/src/engine/Engine.cpp
+++ b/src/engine/Engine.cpp
@@ -302,10 +302,12 @@ void Engine::startPauseLoop() {
}
void Engine::renderFrame() {
+ if (input->isCursorLocked() != (gui->getActiveFrame() == nullptr)) {
+ input->toggleCursor();
+ }
screen->draw(time.getDelta());
DrawContext ctx(nullptr, *window, nullptr);
- gui->renderFrames(ctx, *assets->getStorage());
gui->draw(ctx, *assets->getStorage());
}
diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp
index d33c67ec6..6f3593610 100644
--- a/src/frontend/hud.cpp
+++ b/src/frontend/hud.cpp
@@ -207,9 +207,6 @@ Hud::Hud(Engine& engine, LevelFrontend& frontend, Player& player)
}
Hud::~Hud() {
- if (input.isCursorLocked()) {
- input.toggleCursor();
- }
// removing all controlled ui
for (auto& element : elements) {
onRemove(element);
@@ -342,9 +339,6 @@ void Hud::update(bool visible) {
if (!gui.isFocusCaught()) {
processInput(visible);
}
- if ((isMenuOpen || inventoryOpen) == input.isCursorLocked()) {
- input.toggleCursor();
- }
if (blockUI) {
voxel* vox = chunks.get(blockPos.x, blockPos.y, blockPos.z);
@@ -395,6 +389,7 @@ void Hud::openInventory(bool playerInventory) {
inventoryView->bind(inventory, &content);
add(HudElement(HudElementMode::INVENTORY, inventoryDocument, inventoryView, false));
}
+ gui.setActiveFrame(GUI::CORE_MAIN);
}
std::shared_ptr Hud::openInventory(
@@ -548,6 +543,7 @@ void Hud::closeInventory() {
}
}
cleanup();
+ gui.setActiveFrame("");
}
void Hud::add(const HudElement& element, const dv::value& argsArray) {
@@ -710,9 +706,11 @@ void Hud::setPause(bool pause) {
if (!pause && menu.hasOpenPage()) {
menu.reset();
+ gui.setActiveFrame("");
}
if (pause && !menu.hasOpenPage()) {
menu.setPage("pause");
+ gui.setActiveFrame(GUI::CORE_MAIN);
}
}
diff --git a/src/frontend/screens/LevelScreen.cpp b/src/frontend/screens/LevelScreen.cpp
index 0dd1894b0..dfeb1dfb4 100644
--- a/src/frontend/screens/LevelScreen.cpp
+++ b/src/frontend/screens/LevelScreen.cpp
@@ -56,6 +56,7 @@ LevelScreen::LevelScreen(
auto& assets = *engine.getAssets();
auto menu = engine.getGUI().getMenu();
menu->reset();
+ gui.setActiveFrame("");
auto player = level->players->get(localPlayer);
assert(player != nullptr);
diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp
index 7677ca9f8..73bf73e2c 100644
--- a/src/graphics/ui/GUI.cpp
+++ b/src/graphics/ui/GUI.cpp
@@ -1,10 +1,10 @@
#include "GUI.hpp"
#include
-#include
#include
#include "assets/Assets.hpp"
+#include "debug/Logger.hpp"
#include "elements/Label.hpp"
#include "elements/Menu.hpp"
#include "elements/Panel.hpp"
@@ -27,13 +27,15 @@
#include
#include
+static debug::Logger logger("gui");
+
using namespace gui;
GUI::GUI(Engine& engine)
: engine(engine),
input(engine.getInput()),
batch2D(std::make_unique(1024)),
- container(std::make_shared(*this, glm::vec2(1000))) {
+ container(std::make_shared(*this, CORE_MAIN, "")) {
container->setId("root");
uicamera =
std::make_unique(glm::vec3(), engine.getWindow().getSize().y);
@@ -64,6 +66,8 @@ GUI::GUI(Engine& engine)
std::dynamic_pointer_cast(container),
nullptr
);
+ addFrame(container);
+ activeFrame = container;
}
GUI::~GUI() = default;
@@ -118,7 +122,9 @@ void GUI::updateTooltip(float delta) {
}
/// @brief Mouse related input and logic handling
-void GUI::actMouse(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);
doubleClicked = false;
doubleClickTimer += delta + mouseDelta * 0.1f;
@@ -158,13 +164,13 @@ void GUI::actMouse(float delta, const CursorState& cursor) {
}
for (auto it = mouseOver.begin(); it != mouseOver.end(); ) {
- auto node = it->lock();
- if (node) {
- if (node->isInside(cursor.pos)) {
+ auto mouseOverNode = it->lock();
+ if (mouseOverNode) {
+ if (mouseOverNode->isInside(cursor.pos)) {
++it;
continue;
}
- node->setMouseOver(false);
+ mouseOverNode->setMouseOver(false);
}
it = mouseOver.erase(it);
}
@@ -233,14 +239,16 @@ void GUI::actFocused() {
void GUI::act(float delta, const glm::uvec2& vp) {
container->setSize(vp);
- container->act(delta);
+ for (auto& pair : frames) {
+ pair.second->act(delta);
+ }
auto prevfocus = focus;
updateTooltip(delta);
const auto& cursor = input.getCursor();
- if (!cursor.locked) {
- actMouse(delta, cursor);
+ if (!cursor.locked && activeFrame) {
+ actMouse(*activeFrame, delta, cursor);
} else {
if (hover) {
hover->setMouseEnter(false);
@@ -263,22 +271,7 @@ void GUI::postAct() {
}
}
-void GUI::renderFrames(const DrawContext& pctx, Assets& assets) {
- auto ctx = pctx.sub(batch2D.get());
-
- auto uishader = assets.get("ui");
- uishader->use();
- uishader->uniformMatrix("u_projview", uicamera->getProjView());
-
- batch2D->begin();
- for (auto& [outputTexture, frame] : frames) {
- frame->updateOutput(assets);
- frame->draw(ctx, assets);
- }
- batch2D->flush();
-}
-
-void GUI::draw(const DrawContext& pctx, const Assets& assets) {
+void GUI::draw(const DrawContext& pctx, Assets& assets) {
auto ctx = pctx.sub(batch2D.get());
auto& viewport = ctx.getViewport();
@@ -300,7 +293,10 @@ void GUI::draw(const DrawContext& pctx, const Assets& assets) {
uishader->uniformMatrix("u_projview", uicamera->getProjView());
batch2D->begin();
- container->draw(ctx, assets);
+ for (auto& [outputTexture, frame] : frames) {
+ frame->updateOutput(assets);
+ frame->draw(ctx, assets);
+ }
if (hover) {
engine.getWindow().setCursor(hover->getCursor());
@@ -354,7 +350,26 @@ void GUI::add(std::shared_ptr node) {
}
void GUI::addFrame(std::shared_ptr frame) {
- frames[frame->getOutputTexture()] = std::move(frame);
+ const auto& id = frame->getFrameId();
+ frames[id] = std::move(frame);
+}
+
+void GUI::setActiveFrame(const std::string& id) {
+ if (id.empty()) {
+ activeFrame = nullptr;
+ return;
+ }
+ const auto& found = frames.find(id);
+ if (found == frames.end()) {
+ logger.error() << "attempted to make non-existing frame '" << id
+ << "' as active";
+ return;
+ }
+ activeFrame = found->second;
+}
+
+std::shared_ptr GUI::getActiveFrame() const {
+ return activeFrame;
}
void GUI::remove(UINode* node) noexcept {
diff --git a/src/graphics/ui/GUI.hpp b/src/graphics/ui/GUI.hpp
index b990d93ab..ee3fc1cd5 100644
--- a/src/graphics/ui/GUI.hpp
+++ b/src/graphics/ui/GUI.hpp
@@ -68,7 +68,7 @@ namespace gui {
Engine& engine;
Input& input;
std::unique_ptr batch2D;
- std::shared_ptr container;
+ std::shared_ptr container;
std::shared_ptr hover;
std::shared_ptr pressed;
std::shared_ptr focus;
@@ -76,6 +76,7 @@ namespace gui {
std::shared_ptr rootDocument;
std::unique_ptr syntaxColorScheme;
std::unordered_map> storage;
+ std::shared_ptr activeFrame;
std::unique_ptr uicamera;
std::shared_ptr