local S = minetest.get_translator("sfinv_buttons") local buttons = {} local button_names_sorted = {} local buttons_num = 0 local button_prefix = "sfinv_button_" -- Stores selected index in textlist local player_indexes = {} local player_selections = {} sfinv_buttons = {} sfinv_buttons.register_button = function(name, def) buttons[name] = def table.insert(button_names_sorted, name) buttons_num = buttons_num + 1 end -- Turns a textlist index to a button name local index_to_button_name = function(index, player) local internal_index = 1 for i=1, #button_names_sorted do local name = button_names_sorted[i] local def = buttons[name] if internal_index == index then if def.show == nil or def.show(player) == true then return name end end internal_index = internal_index + 1 end return nil end local MAX_ROWS = 9 local MAX_COLS = 2 local MAX_BUTTONS = MAX_ROWS * MAX_COLS sfinv.register_page("sfinv_buttons:buttons", { title = S("More"), is_in_nav = function(self, player, context) -- Tab is shown only if at least 1 button is visible to player for _, def in pairs(buttons) do if def.show == nil or def.show(player) == true then return true end end return false end, get = function(self, player, context) local f = "" local y = 0 local x = 0 local w if buttons_num > MAX_ROWS then w = 3 else w = 7 end if buttons_num > MAX_BUTTONS then f = f .. "textlist[0,0;7.8,8;sfinv_buttons_textlist;" end local buttons_added = 0 for i=1, #button_names_sorted do local name = button_names_sorted[i] local def = buttons[name] if def.show == nil or def.show(player) == true then if buttons_num > MAX_BUTTONS then if buttons_added >= 1 then f = f .. "," end f = f .. minetest.formspec_escape(def.title) else if def.image ~= nil then f = f .. "image["..(x+0.1)..","..(y+0.1)..";0.8,0.8;"..def.image.."]" end local button_id = minetest.formspec_escape(button_prefix .. name) f = f .. "button[".. (x+1)..","..y..";"..w..",1;".. button_id..";".. minetest.formspec_escape(def.title).. "]" if def.tooltip ~= nil then f = f .. "tooltip["..button_id..";".. minetest.formspec_escape(def.tooltip).."]" end y = y + 1 if y >= MAX_ROWS then y = 0 x = x + 4 end end buttons_added = buttons_added + 1 end end if buttons_num > MAX_BUTTONS then local index = player_indexes[player:get_player_name()] if index ~= nil then f = f .. ";" .. index end f = f .. "]" f = f .. "button[0,8;8,1;sfinv_buttons_action;"..minetest.formspec_escape(S("Go")).."]" end return sfinv.make_formspec(player, context, f) end, on_player_receive_fields = function(self, player, context, fields) local player_name = player:get_player_name() -- TODO: Test support case when some buttons are hidden for player if fields.sfinv_buttons_action then local button = buttons[player_selections[player_name]] if button ~= nil and button.action ~= nil then button.action(player) end elseif fields.sfinv_buttons_textlist then local explode = minetest.explode_textlist_event(fields.sfinv_buttons_textlist) if explode.type == "CHG" then player_indexes[player_name] = explode.index player_selections[player_name] = index_to_button_name(explode.index, player) elseif explode.type == "DCL" then local button = buttons[button_names_sorted[explode.index]] if button ~= nil and button.action ~= nil then button.action(player) end end else for widget_name, _ in pairs(fields) do local id = string.sub(widget_name, string.len(button_prefix) + 1, -1) if buttons[id] ~= nil and buttons[id].action ~= nil then buttons[id].action(player) end end end end, }) minetest.register_on_joinplayer(function(player) player_indexes[player:get_player_name()] = nil player_selections[player:get_player_name()] = nil end) minetest.register_on_leaveplayer(function(player) player_indexes[player:get_player_name()] = nil player_selections[player:get_player_name()] = nil end)