]> git.lizzy.rs Git - dragonfireclient.git/blob - builtin/fstk/tabview.lua
Add on_object_add callback
[dragonfireclient.git] / builtin / fstk / tabview.lua
1 --Minetest
2 --Copyright (C) 2014 sapier
3 --
4 --This program is free software; you can redistribute it and/or modify
5 --it under the terms of the GNU Lesser General Public License as published by
6 --the Free Software Foundation; either version 2.1 of the License, or
7 --(at your option) any later version.
8 --
9 --This program is distributed in the hope that it will be useful,
10 --but WITHOUT ANY WARRANTY; without even the implied warranty of
11 --MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 --GNU Lesser General Public License for more details.
13 --
14 --You should have received a copy of the GNU Lesser General Public License along
15 --with this program; if not, write to the Free Software Foundation, Inc.,
16 --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18
19 --------------------------------------------------------------------------------
20 -- A tabview implementation                                                   --
21 -- Usage:                                                                     --
22 -- tabview.create: returns initialized tabview raw element                    --
23 -- element.add(tab): add a tab declaration                                    --
24 -- element.handle_buttons()                                                   --
25 -- element.handle_events()                                                    --
26 -- element.getFormspec() returns formspec of tabview                          --
27 --------------------------------------------------------------------------------
28
29 --------------------------------------------------------------------------------
30 local function add_tab(self,tab)
31         assert(tab.size == nil or (type(tab.size) == table and
32                         tab.size.x ~= nil and tab.size.y ~= nil))
33         assert(tab.cbf_formspec ~= nil and type(tab.cbf_formspec) == "function")
34         assert(tab.cbf_button_handler == nil or
35                         type(tab.cbf_button_handler) == "function")
36         assert(tab.cbf_events == nil or type(tab.cbf_events) == "function")
37
38         local newtab = {
39                 name = tab.name,
40                 caption = tab.caption,
41                 button_handler = tab.cbf_button_handler,
42                 event_handler = tab.cbf_events,
43                 get_formspec = tab.cbf_formspec,
44                 tabsize = tab.tabsize,
45                 on_change = tab.on_change,
46                 tabdata = {},
47         }
48
49         self.tablist[#self.tablist + 1] = newtab
50
51         if self.last_tab_index == #self.tablist then
52                 self.current_tab = tab.name
53                 if tab.on_activate ~= nil then
54                         tab.on_activate(nil,tab.name)
55                 end
56         end
57 end
58
59 --------------------------------------------------------------------------------
60 local function get_formspec(self)
61         if self.hidden or (self.parent ~= nil and self.parent.hidden) then
62                 return ""
63         end
64         local tab = self.tablist[self.last_tab_index]
65
66         local content, prepend = tab.get_formspec(self, tab.name, tab.tabdata, tab.tabsize)
67
68         if self.parent == nil and not prepend then
69                 local tsize = tab.tabsize or {width=self.width, height=self.height}
70                 prepend = string.format("size[%f,%f,%s]", tsize.width, tsize.height,
71                                 dump(self.fixed_size))
72         end
73
74         local formspec = (prepend or "") .. self:tab_header() .. content
75         return formspec
76 end
77
78 --------------------------------------------------------------------------------
79 local function handle_buttons(self,fields)
80
81         if self.hidden then
82                 return false
83         end
84
85         if self:handle_tab_buttons(fields) then
86                 return true
87         end
88
89         if self.glb_btn_handler ~= nil and
90                 self.glb_btn_handler(self,fields) then
91                 return true
92         end
93
94         local tab = self.tablist[self.last_tab_index]
95         if tab.button_handler ~= nil then
96                 return tab.button_handler(self, fields, tab.name, tab.tabdata)
97         end
98
99         return false
100 end
101
102 --------------------------------------------------------------------------------
103 local function handle_events(self,event)
104
105         if self.hidden then
106                 return false
107         end
108
109         if self.glb_evt_handler ~= nil and
110                 self.glb_evt_handler(self,event) then
111                 return true
112         end
113
114         local tab = self.tablist[self.last_tab_index]
115         if tab.evt_handler ~= nil then
116                 return tab.evt_handler(self, event, tab.name, tab.tabdata)
117         end
118
119         return false
120 end
121
122
123 --------------------------------------------------------------------------------
124 local function tab_header(self)
125
126         local toadd = ""
127
128         for i=1,#self.tablist,1 do
129
130                 if toadd ~= "" then
131                         toadd = toadd .. ","
132                 end
133
134                 toadd = toadd .. self.tablist[i].caption
135         end
136         return string.format("tabheader[%f,%f;%s;%s;%i;true;false]",
137                         self.header_x, self.header_y, self.name, toadd, self.last_tab_index);
138 end
139
140 --------------------------------------------------------------------------------
141 local function switch_to_tab(self, index)
142         --first call on_change for tab to leave
143         if self.tablist[self.last_tab_index].on_change ~= nil then
144                 self.tablist[self.last_tab_index].on_change("LEAVE",
145                                 self.current_tab, self.tablist[index].name)
146         end
147
148         --update tabview data
149         self.last_tab_index = index
150         local old_tab = self.current_tab
151         self.current_tab = self.tablist[index].name
152
153         if (self.autosave_tab) then
154                 core.settings:set(self.name .. "_LAST",self.current_tab)
155         end
156
157         -- call for tab to enter
158         if self.tablist[index].on_change ~= nil then
159                 self.tablist[index].on_change("ENTER",
160                                 old_tab,self.current_tab)
161         end
162 end
163
164 --------------------------------------------------------------------------------
165 local function handle_tab_buttons(self,fields)
166         --save tab selection to config file
167         if fields[self.name] then
168                 local index = tonumber(fields[self.name])
169                 switch_to_tab(self, index)
170                 return true
171         end
172
173         return false
174 end
175
176 --------------------------------------------------------------------------------
177 local function set_tab_by_name(self, name)
178         for i=1,#self.tablist,1 do
179                 if self.tablist[i].name == name then
180                         switch_to_tab(self, i)
181                         return true
182                 end
183         end
184
185         return false
186 end
187
188 --------------------------------------------------------------------------------
189 local function hide_tabview(self)
190         self.hidden=true
191
192         --call on_change as we're not gonna show self tab any longer
193         if self.tablist[self.last_tab_index].on_change ~= nil then
194                 self.tablist[self.last_tab_index].on_change("LEAVE",
195                                 self.current_tab, nil)
196         end
197 end
198
199 --------------------------------------------------------------------------------
200 local function show_tabview(self)
201         self.hidden=false
202
203         -- call for tab to enter
204         if self.tablist[self.last_tab_index].on_change ~= nil then
205                 self.tablist[self.last_tab_index].on_change("ENTER",
206                                 nil,self.current_tab)
207         end
208 end
209
210 local tabview_metatable = {
211         add                       = add_tab,
212         handle_buttons            = handle_buttons,
213         handle_events             = handle_events,
214         get_formspec              = get_formspec,
215         show                      = show_tabview,
216         hide                      = hide_tabview,
217         delete                    = function(self) ui.delete(self) end,
218         set_parent                = function(self,parent) self.parent = parent end,
219         set_autosave_tab          =
220                         function(self,value) self.autosave_tab = value end,
221         set_tab                   = set_tab_by_name,
222         set_global_button_handler =
223                         function(self,handler) self.glb_btn_handler = handler end,
224         set_global_event_handler =
225                         function(self,handler) self.glb_evt_handler = handler end,
226         set_fixed_size =
227                         function(self,state) self.fixed_size = state end,
228         tab_header = tab_header,
229         handle_tab_buttons = handle_tab_buttons
230 }
231
232 tabview_metatable.__index = tabview_metatable
233
234 --------------------------------------------------------------------------------
235 function tabview_create(name, size, tabheaderpos)
236         local self = {}
237
238         self.name     = name
239         self.type     = "toplevel"
240         self.width    = size.x
241         self.height   = size.y
242         self.header_x = tabheaderpos.x
243         self.header_y = tabheaderpos.y
244
245         setmetatable(self, tabview_metatable)
246
247         self.fixed_size     = true
248         self.hidden         = true
249         self.current_tab    = nil
250         self.last_tab_index = 1
251         self.tablist        = {}
252
253         self.autosave_tab   = false
254
255         ui.add(self)
256         return self
257 end