[LuaGUI] gk::Image support added.

This commit is contained in:
Quentin Bazin 2019-01-07 02:39:39 +01:00
parent b8eac29892
commit 7c7af38097
9 changed files with 97 additions and 15 deletions

6
TODO
View File

@ -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

View File

@ -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<LuaWidgetDef::Image> images;
std::vector<LuaWidgetDef::Button> buttons;
std::vector<LuaWidgetDef::InventoryList> inventoryLists;
};

View File

@ -17,6 +17,7 @@
#include <sol.hpp>
#include <gk/core/IntTypes.hpp>
#include <gk/core/Rect.hpp>
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;

View File

@ -18,8 +18,10 @@
#include <gk/gl/Shader.hpp>
#include <gk/graphics/RectangleShape.hpp>
#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<CraftingWidget> m_craftingWidgets;
std::vector<InventoryWidget> m_inventoryWidgets;
std::vector<std::unique_ptr<Widget>> m_widgets;
std::vector<std::unique_ptr<gk::IDrawable>> m_drawables;
gk::RectangleShape m_background;
Widget m_mainWidget;
};
#endif // LUAGUISTATE_HPP_

View File

@ -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<InventoryState>(&gk::ApplicationStateStack::getInstance().top());
-- inventoryState.setupWidget<WorkbenchWidget>(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,
}

View File

@ -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")

View File

@ -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<sol::table> pos = table["pos"];
std::string name = table["name"].get<std::string>();
if (pos != sol::nullopt) {
x = pos.value()["x"];
y = pos.value()["y"];
}
gk::FloatRect clipRect;
std::string texture = table["texture"].get<std::string>();
sol::optional<sol::table> 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;

View File

@ -61,6 +61,7 @@ void ScriptEngine::initUsertypes() {
);
m_lua.new_usertype<LuaGUI>("LuaGUI",
"image", &LuaGUI::addImage,
"button", &LuaGUI::addButton,
"inventory", &LuaGUI::addInventory,
"show", &LuaGUI::show

View File

@ -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);
}
}