lua: gui library (WIP)

This commit is contained in:
MihailRis 2024-02-13 18:16:18 +03:00
parent 302b649634
commit 05589b721e
14 changed files with 262 additions and 25 deletions

View File

@ -1,3 +1,10 @@
<inventory color="#1F1F1FE0" size="400,0">
<inventory color="#1F1F1FE0" size="0,400">
<slots-grid rows="4" count="40" sharefunc="inventory_share_func"/>
<button id="btn"
coord="8,300"
size="140,30"
z-index="1"
onclick="document.btn.text = tostring(time.uptime())">
-----
</button>
</inventory>

View File

@ -1,9 +1,12 @@
function on_open(inv)
print("OPEN", inv)
local Document = require("core:document")
document = Document.new(DOC_NAME)
function on_open(invid)
print("OPEN", invid)
end
function on_close(inv)
print("CLOSE", inv)
function on_close(invid)
print("CLOSE", invid)
end
function inventory_share_func(invid, slotid)

22
res/modules/document.lua Normal file
View File

@ -0,0 +1,22 @@
local Element = {}
function Element.new(docname, name)
return setmetatable({docname=docname, name=name}, {
__index=function(self, k)
return gui.getattr(self.docname, self.name, k)
end,
__newindex=function(self, k, v)
gui.setattr(self.docname, self.name, k, v)
end
})
end
local Document = {}
function Document.new(docname)
return setmetatable({name=docname}, {
__index=function(self, k)
return Element.new(self.name, k)
end
})
end
return Document

View File

@ -91,3 +91,23 @@ end
function pack.is_installed(packid)
return file.isfile(packid..":package.json")
end
vec2_mt = {}
function vec2_mt.__tostring(self)
return "vec2("..self[1]..", "..self[2]..")"
end
vec3_mt = {}
function vec3_mt.__tostring(self)
return "vec3("..self[1]..", "..self[2]..", "..self[3]..")"
end
vec4_mt = {}
function vec4_mt.__tostring(self)
return "vec4("..self[1]..", "..self[2]..", "..self[3]..", "..self[4]..")"
end
color_mt = {}
function color_mt.__tostring(self)
return "rgba("..self[1]..", "..self[2]..", "..self[3]..", "..self[4]..")"
end

View File

@ -30,6 +30,14 @@ const std::shared_ptr<gui::UINode> UiDocument::getRoot() const {
return root;
}
const std::shared_ptr<gui::UINode> UiDocument::get(const std::string& id) const {
auto found = map.find(id);
if (found == map.end()) {
return nullptr;
}
return found->second;
}
const uidocscript& UiDocument::getScript() const {
return script;
}

View File

@ -43,6 +43,7 @@ public:
const std::string& getId() const;
const uinodes_map& getMap() const;
const std::shared_ptr<gui::UINode> getRoot() const;
const std::shared_ptr<gui::UINode> get(const std::string& id) const;
const uidocscript& getScript() const;
int getEnvironment() const;
/* Collect map of all uinodes having identifiers */

View File

@ -110,6 +110,10 @@ void UINode::setCoord(glm::vec2 coord) {
this->coord = coord;
}
glm::vec2 UINode::getCoord() const {
return coord;
}
glm::vec2 UINode::getSize() const {
return size;
}

View File

@ -112,6 +112,7 @@ namespace gui {
/* Calculate screen position of the element */
virtual glm::vec2 calcCoord() const;
virtual void setCoord(glm::vec2 coord);
glm::vec2 getCoord() const;
virtual glm::vec2 getSize() const;
virtual void setSize(glm::vec2 size);
virtual void refresh() {};

View File

@ -1,6 +1,7 @@
#include "LuaState.h"
#include "api_lua.h"
#include "api/api_lua.h"
#include "api/libgui.h"
#include "../../util/stringutil.h"
lua::luaerror::luaerror(const std::string& message) : std::runtime_error(message) {
@ -98,6 +99,7 @@ void lua::LuaState::createFuncs() {
openlib("item", itemlib, 0);
openlib("time", timelib, 0);
openlib("file", filelib, 0);
openlib("gui", guilib, 0);
addfunc("print", l_print);

View File

@ -1,29 +1,29 @@
#ifndef LOGIC_SCRIPTING_API_LUA_H_
#define LOGIC_SCRIPTING_API_LUA_H_
#include "scripting.h"
#include "lua_util.h"
#include "../scripting.h"
#include "../lua_util.h"
#include <glm/glm.hpp>
#include <iostream>
#include "../../files/files.h"
#include "../../physics/Hitbox.h"
#include "../../objects/Player.h"
#include "../../world/Level.h"
#include "../../world/World.h"
#include "../../content/Content.h"
#include "../../voxels/Block.h"
#include "../../voxels/Chunks.h"
#include "../../voxels/voxel.h"
#include "../../items/ItemDef.h"
#include "../../items/ItemStack.h"
#include "../../items/Inventory.h"
#include "../../items/Inventories.h"
#include "../../lighting/Lighting.h"
#include "../../logic/BlocksController.h"
#include "../../window/Window.h"
#include "../../engine.h"
#include "../../../files/files.h"
#include "../../../physics/Hitbox.h"
#include "../../../objects/Player.h"
#include "../../../world/Level.h"
#include "../../../world/World.h"
#include "../../../content/Content.h"
#include "../../../voxels/Block.h"
#include "../../../voxels/Chunks.h"
#include "../../../voxels/voxel.h"
#include "../../../items/ItemDef.h"
#include "../../../items/ItemStack.h"
#include "../../../items/Inventory.h"
#include "../../../items/Inventories.h"
#include "../../../lighting/Lighting.h"
#include "../../../logic/BlocksController.h"
#include "../../../window/Window.h"
#include "../../../engine.h"
/* == file library == */
static int l_file_resolve(lua_State* L) {

View File

@ -0,0 +1,77 @@
#include "libgui.h"
#include <iostream>
#include "../scripting.h"
#include "../lua_util.h"
#include "../../../engine.h"
#include "../../../assets/Assets.h"
#include "../../../frontend/gui/UINode.h"
#include "../../../frontend/gui/controls.h"
#include "../../../frontend/UiDocument.h"
#include "../../../util/stringutil.h"
static gui::UINode* getDocumentNode(lua_State* L, const std::string& name, const std::string& nodeName) {
auto doc = scripting::engine->getAssets()->getLayout(name);
if (doc == nullptr) {
luaL_error(L, "document '%s' not found", name.c_str());
}
auto node = doc->get(nodeName);
if (node == nullptr) {
luaL_error(L, "document '%s' has no element with id '%s'", name.c_str(), nodeName.c_str());
}
return node.get();
}
static bool getattr(lua_State* L, gui::Button* button, const std::string& attr) {
if (button == nullptr)
return false;
if (attr == "text") {
lua_pushstring(L, util::wstr2str_utf8(button->getText()).c_str());
return true;
}
return false;
}
static bool setattr(lua_State* L, gui::Button* button, const std::string& attr) {
if (button == nullptr)
return false;
if (attr == "text") {
button->setText(util::str2wstr_utf8(lua_tostring(L, 4)));
return true;
}
return false;
}
int l_gui_getattr(lua_State* L) {
auto docname = lua_tostring(L, 1);
auto element = lua_tostring(L, 2);
const std::string attr = lua_tostring(L, 3);
auto node = getDocumentNode(L, docname, element);
if (attr == "color") {
return lua::pushcolor_arr(L, node->getColor());
} else if (attr == "coord") {
return lua::pushvec2_arr(L, node->getCoord());
} else if (attr == "size") {
return lua::pushvec2_arr(L, node->getSize());
}
if (getattr(L, dynamic_cast<gui::Button*>(node), attr))
return 1;
return 0;
}
int l_gui_setattr(lua_State* L) {
auto docname = lua_tostring(L, 1);
auto element = lua_tostring(L, 2);
const std::string attr = lua_tostring(L, 3);
auto node = getDocumentNode(L, docname, element);
if (setattr(L, dynamic_cast<gui::Button*>(node), attr))
return 0;
return 0;
}

View File

@ -0,0 +1,15 @@
#ifndef LOGIC_SCRIPTING_API_LIBGUI_H_
#define LOGIC_SCRIPTING_API_LIBGUI_H_
#include <lua.hpp>
extern int l_gui_getattr(lua_State* L);
extern int l_gui_setattr(lua_State* L);
static const luaL_Reg guilib [] = {
{"getattr", l_gui_getattr},
{"setattr", l_gui_setattr},
{NULL, NULL}
};
#endif // LOGIC_SCRIPTING_API_LIBGUI_H_

View File

@ -2,6 +2,8 @@
#define LOGIC_SCRIPTING_LUA_UTIL_H_
#include <lua.hpp>
#include <glm/glm.hpp>
#include "LuaState.h"
namespace lua {
inline int pushivec3(lua_State* L, luaint x, luaint y, luaint z) {
@ -10,6 +12,79 @@ namespace lua {
lua_pushinteger(L, z);
return 3;
}
inline int pushvec3(lua_State* L, glm::vec3 vec) {
lua_pushnumber(L, vec.x);
lua_pushnumber(L, vec.y);
lua_pushnumber(L, vec.z);
return 3;
}
inline int pushvec4(lua_State* L, glm::vec4 vec) {
lua_pushnumber(L, vec.x);
lua_pushnumber(L, vec.y);
lua_pushnumber(L, vec.z);
lua_pushnumber(L, vec.w);
return 4;
}
inline int pushvec2_arr(lua_State* L, glm::vec2 vec) {
lua_createtable(L, 2, 0);
lua_getglobal(L, "vec2_mt");
lua_setmetatable(L, -2);
lua_pushnumber(L, vec.x);
lua_rawseti(L, -2, 1);
lua_pushnumber(L, vec.y);
lua_rawseti(L, -2, 2);
return 1;
}
inline int pushvec3_arr(lua_State* L, glm::vec3 vec) {
lua_createtable(L, 3, 0);
lua_getglobal(L, "vec3_mt");
lua_setmetatable(L, -2);
lua_pushnumber(L, vec.x);
lua_rawseti(L, -2, 1);
lua_pushnumber(L, vec.y);
lua_rawseti(L, -2, 2);
lua_pushnumber(L, vec.z);
lua_rawseti(L, -2, 3);
return 1;
}
inline int pushvec4_arr(lua_State* L, glm::vec4 vec) {
lua_createtable(L, 4, 0);
lua_getglobal(L, "vec4_mt");
lua_setmetatable(L, -2);
lua_pushnumber(L, vec.x);
lua_rawseti(L, -2, 1);
lua_pushnumber(L, vec.y);
lua_rawseti(L, -2, 2);
lua_pushnumber(L, vec.z);
lua_rawseti(L, -2, 3);
lua_pushnumber(L, vec.w);
lua_rawseti(L, -2, 4);
return 1;
}
inline int pushcolor_arr(lua_State* L, glm::vec4 vec) {
lua_createtable(L, 4, 0);
lua_getglobal(L, "color_mt");
lua_setmetatable(L, -2);
lua_pushinteger(L, vec.x*255);
lua_rawseti(L, -2, 1);
lua_pushinteger(L, vec.y*255);
lua_rawseti(L, -2, 2);
lua_pushinteger(L, vec.z*255);
lua_rawseti(L, -2, 3);
lua_pushinteger(L, vec.w*255);
lua_rawseti(L, -2, 4);
return 1;
}
}
#endif // LOGIC_SCRIPTING_LUA_UTIL_H_

View File

@ -16,6 +16,7 @@
#include "../../engine.h"
#include "LuaState.h"
#include "../../util/stringutil.h"
#include "../../util/timeutil.h"
using namespace scripting;
@ -245,6 +246,7 @@ bool scripting::on_item_break_block(Player* player, const ItemDef* item, int x,
}
void scripting::on_ui_open(UiDocument* layout, Inventory* inventory) {
timeutil::ScopeLogTimer log(555);
std::string name = layout->getId()+".open";
if (state->getglobal(name)) {
state->pushinteger(inventory->getId());