Version 1.1.0
[minetest_sfinv_buttons.git] / init.lua
blob3abcf4a439cf63e9bf0a034b046893f45ade40dc
1 local S = minetest.get_translator("sfinv_buttons")
3 local buttons = {}
4 local button_names_sorted = {}
5 local buttons_num = 0
7 local button_prefix = "sfinv_button_"
9 -- Stores selected index in textlist
10 local player_indexes = {}
11 local player_selections = {}
13 sfinv_buttons = {}
15 sfinv_buttons.register_button = function(name, def)
16 buttons[name] = def
17 table.insert(button_names_sorted, name)
18 buttons_num = buttons_num + 1
19 end
21 -- Turns a textlist index to a button name
22 local index_to_button_name = function(index, player)
23 local internal_index = 1
24 for i=1, #button_names_sorted do
25 local name = button_names_sorted[i]
26 local def = buttons[name]
27 if internal_index == index then
28 if def.show == nil or def.show(player) == true then
29 return name
30 end
31 end
32 internal_index = internal_index + 1
33 end
34 return nil
35 end
37 local MAX_ROWS = 9
38 local MAX_COLS = 2
39 local MAX_BUTTONS = MAX_ROWS * MAX_COLS
41 sfinv.register_page("sfinv_buttons:buttons", {
42 title = S("More"),
43 is_in_nav = function(self, player, context)
44 -- Tab is shown only if at least 1 button is visible to player
45 for _, def in pairs(buttons) do
46 if def.show == nil or def.show(player) == true then
47 return true
48 end
49 end
50 return false
51 end,
52 get = function(self, player, context)
53 local f = ""
54 local y = 0
55 local x = 0
56 local w
57 if buttons_num > MAX_ROWS then
58 w = 3
59 else
60 w = 7
61 end
62 if buttons_num > MAX_BUTTONS then
63 f = f .. "textlist[0,0;7.8,8;sfinv_buttons_textlist;"
64 end
65 local buttons_added = 0
66 for i=1, #button_names_sorted do
67 local name = button_names_sorted[i]
68 local def = buttons[name]
69 if def.show == nil or def.show(player) == true then
70 if buttons_num > MAX_BUTTONS then
71 if buttons_added >= 1 then
72 f = f .. ","
73 end
74 f = f .. minetest.formspec_escape(def.title)
75 else
76 if def.image ~= nil then
77 f = f .. "image["..(x+0.1)..","..(y+0.1)..";0.8,0.8;"..def.image.."]"
78 end
79 local button_id = minetest.formspec_escape(button_prefix .. name)
80 f = f .. "button["..
81 (x+1)..","..y..";"..w..",1;"..
82 button_id..";"..
83 minetest.formspec_escape(def.title)..
84 "]"
85 if def.tooltip ~= nil then
86 f = f .. "tooltip["..button_id..";"..
87 minetest.formspec_escape(def.tooltip).."]"
88 end
89 y = y + 1
90 if y >= MAX_ROWS then
91 y = 0
92 x = x + 4
93 end
94 end
95 buttons_added = buttons_added + 1
96 end
97 end
98 if buttons_num > MAX_BUTTONS then
99 local index = player_indexes[player:get_player_name()]
100 if index ~= nil then
101 f = f .. ";" .. index
103 f = f .. "]"
104 f = f .. "button[0,8;8,1;sfinv_buttons_action;"..minetest.formspec_escape(S("Go")).."]"
106 return sfinv.make_formspec(player, context, f)
107 end,
108 on_player_receive_fields = function(self, player, context, fields)
109 local player_name = player:get_player_name()
110 -- TODO: Test support case when some buttons are hidden for player
111 if fields.sfinv_buttons_action then
112 local button = buttons[player_selections[player_name]]
113 if button ~= nil and button.action ~= nil then
114 button.action(player)
116 elseif fields.sfinv_buttons_textlist then
117 local explode = minetest.explode_textlist_event(fields.sfinv_buttons_textlist)
118 if explode.type == "CHG" then
119 player_indexes[player_name] = explode.index
120 player_selections[player_name] = index_to_button_name(explode.index, player)
121 elseif explode.type == "DCL" then
122 local button = buttons[button_names_sorted[explode.index]]
123 if button ~= nil and button.action ~= nil then
124 button.action(player)
127 else
128 for widget_name, _ in pairs(fields) do
129 local id = string.sub(widget_name, string.len(button_prefix) + 1, -1)
130 if buttons[id] ~= nil and buttons[id].action ~= nil then
131 buttons[id].action(player)
135 end,
138 minetest.register_on_joinplayer(function(player)
139 player_indexes[player:get_player_name()] = nil
140 player_selections[player:get_player_name()] = nil
141 end)
143 minetest.register_on_leaveplayer(function(player)
144 player_indexes[player:get_player_name()] = nil
145 player_selections[player:get_player_name()] = nil
146 end)