diff --git a/TODO b/TODO index 22b694e8..cff1482a 100644 --- a/TODO +++ b/TODO @@ -23,8 +23,10 @@ TODO # GUI • DONE: Add a LuaGUI class to handle GUI from Lua -• TODO: Add more GUI elements - ◦ TODO: `InventoryList` +• WIP: Add more GUI elements + ◦ DONE: `InventoryWidget` + ◦ TODO: `CraftingWidget` + ◦ DONE: `Image` # Main menu diff --git a/include/lua/LuaGUI.hpp b/include/lua/LuaGUI.hpp index 1f91600e..f1e15638 100644 --- a/include/lua/LuaGUI.hpp +++ b/include/lua/LuaGUI.hpp @@ -19,11 +19,13 @@ // This class is meant to be used ONLY in Lua class LuaGUI { public: + void addImage(const sol::table &table); void addButton(const sol::table &table); void addInventory(const sol::table &table); void show(); + std::vector images; std::vector buttons; std::vector inventoryLists; }; diff --git a/include/lua/LuaWidgetDef.hpp b/include/lua/LuaWidgetDef.hpp index 0ac98a49..17fe117a 100644 --- a/include/lua/LuaWidgetDef.hpp +++ b/include/lua/LuaWidgetDef.hpp @@ -17,6 +17,7 @@ #include #include +#include namespace LuaWidgetDef { @@ -27,6 +28,11 @@ struct Widget { float y = 0; }; +struct Image : public Widget { + std::string texture; + gk::FloatRect clipRect; +}; + struct Button : public Widget { std::string text; sol::function on_click; diff --git a/include/states/LuaGUIState.hpp b/include/states/LuaGUIState.hpp index 14ac59fb..6fa19d63 100644 --- a/include/states/LuaGUIState.hpp +++ b/include/states/LuaGUIState.hpp @@ -18,8 +18,10 @@ #include #include +#include "CraftingWidget.hpp" #include "LuaGUI.hpp" -#include "Widget.hpp" +#include "InventoryWidget.hpp" +#include "MouseItemWidget.hpp" // FIXME: This class is almost a duplicate of InventoryState class LuaGUIState : public gk::ApplicationState { @@ -38,11 +40,16 @@ class LuaGUIState : public gk::ApplicationState { gk::Shader m_shader; glm::mat4 m_orthoMatrix; + Widget m_mainWidget; + + MouseItemWidget m_mouseItemWidget{&m_mainWidget}; + + std::vector m_craftingWidgets; + std::vector m_inventoryWidgets; std::vector> m_widgets; + std::vector> m_drawables; gk::RectangleShape m_background; - - Widget m_mainWidget; }; #endif // LUAGUISTATE_HPP_ diff --git a/mods/blocks.lua b/mods/blocks.lua index 90cf2dac..e87f36c6 100644 --- a/mods/blocks.lua +++ b/mods/blocks.lua @@ -103,10 +103,12 @@ mod:block { on_block_activated = function(pos, player, world) -- open_workbench(pos, player, world) - -- local data = world:getBlockData(position.x, position.y, position.z) - -- local inventoryState = ApplicationStateStack.getInstance():push(&gk::ApplicationStateStack::getInstance().top()); - -- inventoryState.setupWidget(player.inventory(), data->inventory); - gui = LuaGUI.new() + + local gui = LuaGUI.new() + local pos = { + x = SCREEN_WIDTH / GUI_SCALE / 2.0 - 176 / 2.0, + y = SCREEN_HEIGHT / GUI_SCALE / 2.0 - 166 / 2.0 + } gui:button { name = "btn_hello", @@ -120,7 +122,7 @@ mod:block { gui:inventory { name = "inv_main", - pos = {x = 176 + 7, y = 166 + 83}, + pos = {x = pos.x + 7, y = pos.y + 83}, player = "player", inventory = "main", @@ -131,7 +133,7 @@ mod:block { gui:inventory { name = "inv_hotbar", - pos = {x = 176 + 7, y = 166 + 141}, + pos = {x = pos.x + 7, y = pos.y + 141}, player = "player", inventory = "main", @@ -140,6 +142,22 @@ mod:block { count = 9, } + -- gui:crafting { + -- name = "inv_crafting", + -- pos = {x = 176, y = 166}, + + -- player = "player", + -- inventory = "main", + -- } + + gui:image { + name = "img_background", + pos = pos, + + texture = "texture-workbench", + clip = {x = 0, y = 0, width = 176, height = 166}, + } + gui:show() end, } diff --git a/mods/test.lua b/mods/test.lua index 9c84e85d..5dcf1b95 100644 --- a/mods/test.lua +++ b/mods/test.lua @@ -1,5 +1,9 @@ print("Hello from Lua!") +SCREEN_WIDTH = 1600 +SCREEN_HEIGHT = 1050 +GUI_SCALE = 3 + mod = LuaMod.new("default") dofile("mods/blocks.lua") diff --git a/source/lua/LuaGUI.cpp b/source/lua/LuaGUI.cpp index 6776b83e..861e3ecb 100644 --- a/source/lua/LuaGUI.cpp +++ b/source/lua/LuaGUI.cpp @@ -16,6 +16,29 @@ #include "LuaGUI.hpp" #include "LuaGUIState.hpp" +void LuaGUI::addImage(const sol::table &table) { + // FIXME: Duplicated below + float x = 0, y = 0; + sol::optional pos = table["pos"]; + std::string name = table["name"].get(); + if (pos != sol::nullopt) { + x = pos.value()["x"]; + y = pos.value()["y"]; + } + + gk::FloatRect clipRect; + std::string texture = table["texture"].get(); + sol::optional clipRectTable = table["clip"]; + if (clipRectTable != sol::nullopt) { + clipRect.x = clipRectTable.value()["x"]; + clipRect.y = clipRectTable.value()["y"]; + clipRect.width = clipRectTable.value()["width"]; + clipRect.height = clipRectTable.value()["height"]; + } + + images.emplace_back(LuaWidgetDef::Image{{name, x, y}, texture, clipRect}); +} + void LuaGUI::addButton(const sol::table &table) { // FIXME: Duplicated below float x = 0, y = 0; diff --git a/source/lua/ScriptEngine.cpp b/source/lua/ScriptEngine.cpp index 69639eb3..607ef7a0 100644 --- a/source/lua/ScriptEngine.cpp +++ b/source/lua/ScriptEngine.cpp @@ -61,6 +61,7 @@ void ScriptEngine::initUsertypes() { ); m_lua.new_usertype("LuaGUI", + "image", &LuaGUI::addImage, "button", &LuaGUI::addButton, "inventory", &LuaGUI::addInventory, "show", &LuaGUI::show diff --git a/source/states/LuaGUIState.cpp b/source/states/LuaGUIState.cpp index 41ba19cd..25f1162b 100644 --- a/source/states/LuaGUIState.cpp +++ b/source/states/LuaGUIState.cpp @@ -47,6 +47,11 @@ void LuaGUIState::onEvent(const SDL_Event &event) { for (auto &it : m_widgets) it->onEvent(event); + for (auto &it : m_inventoryWidgets) + it.onMouseEvent(event, m_mouseItemWidget, false); + + m_mouseItemWidget.onEvent(event); + if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE) { gk::Mouse::setCursorGrabbed(true); gk::Mouse::setCursorVisible(false); @@ -76,11 +81,26 @@ void LuaGUIState::draw(gk::RenderTarget &target, gk::RenderStates states) const target.draw(m_background, states); + for (auto &it : m_drawables) + target.draw(*it, states); + for (auto &it : m_widgets) target.draw(*it, states); + + for (auto &it : m_inventoryWidgets) + target.draw(it, states); + + target.draw(m_mouseItemWidget, states); } void LuaGUIState::loadGUI(LuaGUI &gui) { + for (auto &it : gui.images) { + auto *image = new gk::Image(it.texture); + image->setPosition(it.x, it.y); + image->setClipRect(it.clipRect.x, it.clipRect.y, it.clipRect.width, it.clipRect.height); + m_drawables.emplace_back(image); + } + for (auto &it : gui.buttons) { auto *button = new TextButton(&m_mainWidget); button->setPosition(it.x, it.y); @@ -90,10 +110,9 @@ void LuaGUIState::loadGUI(LuaGUI &gui) { } for (auto &it : gui.inventoryLists) { - auto *inventoryWidget = new InventoryWidget(&m_mainWidget); - inventoryWidget->setPosition(it.x, it.y); - inventoryWidget->init(World::getInstance().getPlayer()->inventory(), it.offset, it.size); - m_widgets.emplace_back(inventoryWidget); + auto &inventoryWidget = m_inventoryWidgets.emplace_back(&m_mainWidget); + inventoryWidget.setPosition(it.x, it.y); + inventoryWidget.init(World::getInstance().getPlayer()->inventory(), it.offset, it.size); } }