Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@rubenwardy
Last active January 1, 2017 00:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rubenwardy/10074b66bd6e409c72c3ad0f79f5771a to your computer and use it in GitHub Desktop.
Save rubenwardy/10074b66bd6e409c72c3ad0f79f5771a to your computer and use it in GitHub Desktop.
-- Boilerplate to support localized strings if intllib mod is installed.
local S
if minetest.get_modpath("intllib") then
S = intllib.Getter()
else
S = function(s) return s end
end
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 function on_player_receive_fields(player, 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
local should_register_separate_page = not minetest.settings_getbool("sfinv_buttons_use_icon_bar")
if should_register_separate_page then
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)
return on_player_receive_fields(player, fields)
end,
})
else
local old_make_formspec = sfinv.make_formspec
function sfinv.make_formspec(player, context, content, show_inv, size)
size = size or "size[8,8.6]"
local b = "false"
local w, h = string.match(size, "%[([%d.]+)%,([%d.]+)%]")
if not w or not h then
w, h, b = string.match(size, "%[([%d.]+)%,([%d.]+)%;(%s+)%]")
end
w = w + 1
local retval = old_make_formspec(player, context, content, show_inv,
"size[" .. w .. "," .. h .. ";" .. b .."]")
assert(w and h)
w = tonumber(w)
h = tonumber(h)
assert(w > 0 and h > 0)
local x = w - 0.9
local y = 0
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
local button_id = minetest.formspec_escape(button_prefix .. name)
retval = retval .. table.concat({
"image_button[",
x, ",", y, ";",
1, ",", 1, ";",
def.image, ";",
button_id, ";]"}, "")
local tooltip = def.title
if def.tooltip and def.tooltip ~= def.title then
tooltip = tooltip or ""
tooltip = tooltip .. " " .. def.tooltip
end
if tooltip ~= nil then
retval = retval .. "tooltip["..button_id..";"..
minetest.formspec_escape(tooltip).."]"
end
y = y + 1
end
end
return retval
end
local function override_page(def)
local old = def.on_player_receive_fields
def.on_player_receive_fields = function(self, player, context, fields)
if on_player_receive_fields(player, fields) then
return true
end
if old then
return old(self, player, context, fields)
end
end
end
for _, def in pairs(sfinv.pages) do
override_page(def)
end
local old_sfinv_register_page = sfinv.register_page
function sfinv.register_page(name, def)
override_page(def)
return old_sfinv_register_page(name, def)
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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment