Create a Metatable for UI elements.

master
Nicole Collings 2020-04-11 16:15:41 -07:00
parent f0aee0d952
commit d80fdccde4
8 changed files with 72 additions and 22 deletions

View File

@ -1,10 +1,51 @@
local env = {}
local env = { Gui = {}}
local Gui = env.Gui
setmetatable(env, {__index = _G})
env.Gui = {}
elem_mt = {
__index = function(elem, key)
-- Don't directly access the traits table.
if key == "traits" then return nil end
local function create_gui_table(elem_type, data)
-- Attempt to get a value from the table, e.g. type, key, children, etc.
local val = rawget(elem, key)
-- Attempt to get a value from the metatable, e.g. a function.
if val == nil then val = rawget(getmetatable(elem), key) end
-- Attempt to get a value from the traits array.
if val == nil then val = rawget(rawget(elem, "traits"), key) end
return val
end,
__newindex = function(elem, key, val)
if key == "type" or key == "key" or key == "callbacks" then rawset(elem, key, val) end
rawset(rawget(elem, "traits"), key, val)
end,
get = function(tbl, key)
if type(key) == number then return rawget(tbl, "children")[key] end
for _,v in pairs(rawget(tbl, "children")) do
if v == key then return v end
end
end,
append = function(tbl, elem)
if type(elem) == "function" then elem = zepha.build_ui(elem) end
table.insert(rawget(tbl, "children"), elem)
end,
prepend = function(tbl, elem)
if type(elem) == "function" then elem = zepha.build_ui(elem) end
table.insert(rawget(tbl, "children"), 0, elem)
end,
}
-- create_element
-- Build a GUI Element with the provided constructor data, apply the metatable.
local function create_element(elem_type, data)
local element = {}
element.type = elem_type
element.children = {}
element.callbacks = {}
@ -23,21 +64,31 @@ local function create_gui_table(elem_type, data)
end
end
setmetatable(element, elem_mt)
return element
end
env.Gui.Body = function(data) return create_gui_table("body", data) end
env.Gui.Rect = function(data) return create_gui_table("rect", data) end
env.Gui.Text = function(data) return create_gui_table("text", data) end
env.Gui.Model = function(data) return create_gui_table("model", data) end
env.Gui.Button = function(data) return create_gui_table("button", data) end
env.Gui.InventoryList = function(data) return create_gui_table("inventory_list", data) end
-- register_element
-- Add an element to the Gui namespace.
local function register_element(key)
if type(key) == "table" then
for _,v in pairs(key) do register_element(v) end
return
end
Gui[key] = function(data) return create_element(key, data) end
end
register_element({"Body", "Rect", "Text", "Model", "Button", "InventoryList"})
-- pc
-- Formats a number to be a percent string.
env.pc = function(num)
return tostring(num) .. "%"
end
zepha.create_menu = function(fn)
-- zepha.build_ui
-- Allows you to Build UI Elements with the GUI namespace outside of a callback.
zepha.build_gui = function(fn)
setfenv(fn, env)
return fn()
end

View File

@ -14,7 +14,7 @@ std::shared_ptr<GuiComponent> GameGuiBuilder::createComponent(const SerialGui::E
switch (Util::hash(elem.type.c_str())) {
default: break;
case Util::hash("inventory_list"): {
case Util::hash("InventoryList"): {
c = GuiInventoryList::fromSerialized(elem, defs, bounds, refs);
break;
}

View File

@ -120,22 +120,22 @@ std::shared_ptr<GuiComponent> GuiBuilder::createComponent(const SerialGui::Eleme
switch (Util::hash(elem.type.c_str())) {
default: break;
case Util::hash("body"): {
case Util::hash("Body"): {
auto body = GuiRect::fromSerialized(elem, textures, bounds);
body->setScale(bounds);
c = body;
break;
}
case Util::hash("rect"):
case Util::hash("Rect"):
c = GuiRect::fromSerialized(elem, textures, bounds);
break;
case Util::hash("button"):
case Util::hash("Button"):
c = GuiImageButton::fromSerialized(elem, textures, bounds);
break;
case Util::hash("text"):
case Util::hash("Text"):
c = GuiText::fromSerialized(elem, textures, bounds);
break;
case Util::hash("model"):
case Util::hash("Model"):
c = GuiModel::fromSerialized(elem, textures, models, bounds);
break;
}

View File

@ -1,4 +1,4 @@
local menu = zepha.create_menu(function()
local menu = zepha.build_gui(function()
return Gui.Body {
background = "#214a21",

View File

@ -1,4 +1,4 @@
zepha.set_gui(zepha.create_menu(function()
zepha.set_gui(zepha.build_gui(function()
return Gui.Body {
background = "#124778",

View File

@ -1,4 +1,4 @@
zepha.set_gui(zepha.create_menu(function()
zepha.set_gui(zepha.build_gui(function()
return Gui.Body {
background = "zeus_background",

View File

@ -1,5 +1,3 @@
local friendly = false
zepha.register_entity("zeus:default:bee", {
display = "model",
display_object = "zeus:default:bee",
@ -13,6 +11,7 @@ zepha.register_entity("zeus:default:bee", {
self.object.anims:set_anim("fly"):play()
},
on_update = (self, delta) => {
self.object.pos = self.object.pos +
V(0.03 * math.sin(math.rad(self.object.yaw + 90)), 0, 0.03 * math.cos(math.rad(self.object.yaw + 90)))

View File

@ -1,4 +1,4 @@
local menu = zepha.create_menu(function()
local menu = zepha.build_gui(function()
return Gui.Body {
background = "#0003",