123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427 |
- panel_lib.panels = {} -- KEY: p_name; VALUE: {{"panel name" = panel}, {"panel name 2" = panel2}, ...}
- local function clone_table() end
- local function add_sub_elem() end
- local function update_sub_elems() end
- Panel = {
- name = "",
- -- player to show the panel to
- player_name = "",
- -- ids of the hud of the player
- hud_id = {},
- -- text values of the huds, to retrieve on :show()
- hud_text = {},
- -- because the panel is composed by a background and a text we need to
- -- define the two HUD to use later
- background_def = {
- hud_elem_type = "image",
- position = { x = 1, y = 0.5 },
- scale = { x = 1, y = 1 },
- alignment = { x = -1, y = 0 },
- offset = {x = 0, y = 0},
- text = "panel_bg.png",
- },
- title_def = {
- hud_elem_type = "text",
- position = {x = 1, y = 0.5},
- alignment = {x = 0, y = 0},
- offset = {x = 0, y = 0},
- size = { x = 1 },
- number = 0xFFFFFF,
- text = ""
- },
- sub_img_elems = {},
- sub_txt_elems = {},
- visible = true
- }
- function Panel:new(name, def)
- local panel = {}
- local metapanel = clone_table(Panel)
- setmetatable(panel, metapanel)
- metapanel.__index = metapanel
- --v------------------ LEGACY UPDATE, to remove in 3.0 -------------------v
- if type(name) == "table" and def == nil then
- minetest.log("warning", "[PANEL_LIB] Panel declaration deprecated. Please put the panel name outside of the def table as it follows -> Panel:new(name, def)")
- def = clone_table(name)
- name = def.name
- end
- if def.is_shown ~= nil then
- minetest.log("warning", "[PANEL_LIB] `is_shown` is deprecated. Use `visible` instead")
- def.visible = def.is_shown
- end
- --^------------------ LEGACY UPDATE, to remove in 3.0 -------------------^
- if not name or type(name) ~= "string" then
- minetest.log("warning", "[PANEL_LIB] Can't create a panel without a proper name, aborting")
- return
- else
- panel.name = name
- end
- if def.position then
- panel.background_def.position = def.position
- panel.title_def.position = def.position
- end
- if def.alignment then
- panel.background_def.alignment = def.alignment
- end
- if def.offset then
- panel.background_def.offset = def.offset
- panel.title_def.offset = def.offset
- end
- if def.bg then
- panel.background_def.text = def.bg
- end
- if def.bg_scale then
- panel.background_def.scale = def.bg_scale
- end
- if def.title then
- panel.title_def.text = def.title
- end
- if def.title_alignment then
- panel.title_def.alignment = def.title_alignment
- end
- if def.title_offset then
- if not def.offset then
- panel.title_def.offset = def.title_offset
- else
- panel.title_def.offset = {x = panel.title_def.offset.x + (def.title_offset.x or 0), y = panel.title_def.offset.y + (def.title_offset.y or 0)}
- end
- end
- if def.title_color then
- panel.title_def.number = def.title_color
- end
- if def.title_size then
- panel.title_def.size = def.title_size
- end
- if def.player then
- panel.player_name = def.player
- end
- if def.visible ~= nil and type(def.visible) == "boolean" then
- panel.visible = def.visible
- end
- panel.hud_text.bg_hud_txt = panel.background_def.text
- panel.hud_text.text_hud_txt = panel.title_def.text
- -- se il pannello non è mostrato di base, svuoto sfondo e titolo
- if panel.visible == false then
- panel.background_def.text = ""
- panel.title_def.text = ""
- end
- local player = minetest.get_player_by_name(def.player)
- -- assegno sfondo e titolo
- panel.hud_id.bg_hud_id = player:hud_add(panel.background_def)
- panel.hud_id.text_hud_id = player:hud_add(panel.title_def)
- -- controllo sottoelementi
- if def.sub_img_elems then
- for subname, HUD_elem in pairs(def.sub_img_elems) do
- add_sub_elem(panel, "image", subname, HUD_elem)
- end
- end
- if def.sub_txt_elems then
- for subname, HUD_elem in pairs(def.sub_txt_elems) do
- add_sub_elem(panel, "text", subname, HUD_elem)
- end
- end
- -- salvo in memoria
- if not panel_lib.panels[def.player] then
- panel_lib.panels[def.player] = {}
- end
- panel_lib.panels[def.player][name] = panel
- return panel
- end
- function Panel:show()
- local player = minetest.get_player_by_name(self.player_name)
- if self.hud_text.bg_hud_txt ~= "" then
- player:hud_change(self.hud_id.bg_hud_id, "text", self.hud_text.bg_hud_txt)
- end
- if self.hud_text.text_hud_txt ~= "" then
- player:hud_change(self.hud_id.text_hud_id, "text", self.hud_text.text_hud_txt)
- end
- --check for custom elements
- for _, name in pairs(self.sub_img_elems) do
- player:hud_change(self.hud_id[name], "text", self.hud_text[name])
- end
- for _, name in pairs(self.sub_txt_elems) do
- player:hud_change(self.hud_id[name], "text", self.hud_text[name])
- end
- self.visible = true
- end
- function Panel:hide()
- if (self.hud_id) then
- local player = minetest.get_player_by_name(self.player_name)
- for k, v in pairs(self.hud_id) do
- player:hud_change(self.hud_id[k], "text", "")
- end
- end
- self.visible = false
- end
- function Panel:update(def, txt_elems, img_elems)
- if def ~= nil then
- local player = minetest.get_player_by_name(self.player_name)
- for k, v in pairs(def) do
- -- aggiorno eventuale posizione, che tratto a parte perché influisce sia su sfondo che titolo,
- -- influenzando anche tutti i sottoelementi del pannello
- if k == "position" then
- self.background_def.position = v
- self.title_def.position = v
- for _, elem in pairs(self.sub_img_elems) do
- local HUD_ID = self.hud_id[elem]
- player:hud_change(HUD_ID, k, v)
- end
- for _, elem in pairs(self.sub_txt_elems) do
- local HUD_ID = self.hud_id[elem]
- player:hud_change(HUD_ID, k, v)
- end
- player:hud_change(self.hud_id.bg_hud_id, k, v)
- player:hud_change(self.hud_id.text_hud_id, k, v)
- -- aggiorno eventuale sfondo
- elseif k == "bg" then
- self.hud_text.bg_hud_txt = v
- self.background_def.text = v
- if self.is_visible then
- player:hud_change(self.hud_id.bg_hud_id, "text", v)
- end
- -- aggiorno eventuali proprietà titolo
- elseif k == "title" or k == "title_color" then
- if k == "title" then
- self.hud_text.text_hud_txt = v
- self.title_def.text = v
- if self.is_visible then
- player:hud_change(self.hud_id.text_hud_id, "text", v)
- end
- else
- self.title_def.number = v
- player:hud_change(self.hud_id.text_hud_id, "number", v)
- end
- else
- error("[PANEL_LIB] Invalid or unsupported element type, check DOCS and spelling")
- return
- end
- end
- end
- if txt_elems ~= nil then
- update_sub_elems(self, txt_elems)
- end
- if img_elems ~= nil then
- update_sub_elems(self, img_elems)
- end
- end
- function Panel:remove()
- panel_lib.panels[self.player_name][self.name] = nil
- local player = minetest.get_player_by_name(self.player_name)
- for k, v in pairs(self.hud_id) do
- player:hud_remove(self.hud_id[k])
- end
- self = nil
- end
- function Panel:is_visible()
- return self.visible
- end
- function Panel:add_sub_elem(type, name, HUD_elem)
- add_sub_elem(self, type, name, HUD_elem)
- end
- function Panel:remove_sub_elem(name)
- self.sub_txt_elems[name] = nil
- self.sub_img_elems[name] = nil
- if self.visible then
- minetest.get_player_by_name(self.player_name):hud_remove(self.hud_id[name])
- end
- self.hud_id[name] = nil
- self.hud_text[name] = nil
- self[name] = nil
- end
- ----------------------------------------------
- -----------------GETTERS----------------------
- ----------------------------------------------
- function panel_lib.get_panel(p_name, panel_name)
- return panel_lib.panels[p_name][panel_name]
- end
- ----------------------------------------------
- ---------------FUNZIONI LOCALI----------------
- ----------------------------------------------
- -- code from => http://lua-users.org/wiki/CopyTable
- function clone_table(orig)
- local orig_type = type(orig)
- local copy
- if orig_type == 'table' then
- copy = {}
- for orig_key, orig_value in pairs(orig) do
- copy[clone_table(orig_key)] = clone_table(orig_value)
- end
- setmetatable(copy, clone_table(getmetatable(orig)))
- else -- number, string, boolean, etc
- copy = orig
- end
- return copy
- end
- function add_sub_elem(panel, type, name, HUD_elem)
- local sub_elems
- local mould
- if type == "text" then
- sub_elems = panel.sub_txt_elems
- mould = panel.title_def
- elseif type == "image" then
- sub_elems = panel.sub_img_elems
- mould = panel.background_def
- else
- error("[PANEL_LIB] type must be either 'text' or 'image'!")
- end
- if panel[name] then
- minetest.log("error", "[PANEL_LIB] Attempt to create a sub element with the same name of another. Aborting")
- return end
- sub_elems[#sub_elems +1] = name
- panel[name] = clone_table(mould)
- for k, v in pairs(HUD_elem) do
- panel[name][k] = v
- end
- -- mantengo la stessa posizione del corpo del panel, costringendo
- -- l'utente a modificare gli offset se vuole spostare gli elementi
- panel[name].position = mould.position
- -- se il pannello ha gli offset personalizzati e il sottoelemento pure, li sommo
- if HUD_elem.offset and (panel.background_def.offset.x ~= 0 or panel.background_def.offset.y ~= 0) then
- panel[name].offset = {x = panel.background_def.offset.x + (HUD_elem.offset.x or 0), y = panel.background_def.offset.y + (HUD_elem.offset.y or 0)}
- end
- -- mostro l'elemento se il pannello era già visibile
- panel[name].text = panel:is_visible() and panel[name].text or ""
- panel.hud_id[name] = minetest.get_player_by_name(panel.player_name):hud_add(panel[name])
- panel.hud_text[name] = HUD_elem.text
- end
- function update_sub_elems(panel, elems)
- local player = minetest.get_player_by_name(panel.player_name)
- for elem, _ in pairs(elems) do
- for k, v in pairs(elems[elem]) do
- if k == "offset" and (panel.background_def.offset.x ~= 0 or panel.background_def.offset.y ~= 0) then
- panel[elem][k] = { x = panel.background_def.offset.x + (v.x or 0), y = panel.background_def.offset.y + (v.y or 0)}
- else
- panel[elem][k] = v
- end
- if k == "text" then
- panel.hud_text[elem] = v
- -- aggiorno il testo solo se visibile
- if panel:is_visible() then
- player:hud_change(panel.hud_id[elem], k, v)
- end
- else
- player:hud_change(panel.hud_id[elem], k, v)
- end
- end
- end
- end
- ----------------------------------------------
- ------------------DEPRECATED------------------
- ----------------------------------------------
- -- to remove in 3.0
- function Panel:is_shown()
- minetest.log("warning", "[PANEL_LIB] `is_shown()` is deprecated. Use `is_visible()` instead")
- return self:is_visible()
- end
|