tabview.lua 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  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. -- A tabview implementation --
  19. -- Usage: --
  20. -- tabview.create: returns initialized tabview raw element --
  21. -- element.add(tab): add a tab declaration --
  22. -- element.handle_buttons() --
  23. -- element.handle_events() --
  24. -- element.getFormspec() returns formspec of tabview --
  25. --------------------------------------------------------------------------------
  26. --------------------------------------------------------------------------------
  27. local function add_tab(self,tab)
  28. assert(tab.size == nil or (type(tab.size) == table and
  29. tab.size.x ~= nil and tab.size.y ~= nil))
  30. assert(tab.cbf_formspec ~= nil and type(tab.cbf_formspec) == "function")
  31. assert(tab.cbf_button_handler == nil or
  32. type(tab.cbf_button_handler) == "function")
  33. assert(tab.cbf_events == nil or type(tab.cbf_events) == "function")
  34. local newtab = {
  35. name = tab.name,
  36. caption = tab.caption,
  37. button_handler = tab.cbf_button_handler,
  38. event_handler = tab.cbf_events,
  39. get_formspec = tab.cbf_formspec,
  40. tabsize = tab.tabsize,
  41. on_change = tab.on_change,
  42. tabdata = {},
  43. }
  44. self.tablist[#self.tablist + 1] = newtab
  45. if self.last_tab_index == #self.tablist then
  46. self.current_tab = tab.name
  47. if tab.on_activate ~= nil then
  48. tab.on_activate(nil,tab.name)
  49. end
  50. end
  51. end
  52. --------------------------------------------------------------------------------
  53. local function get_formspec(self)
  54. local formspec = ""
  55. if not self.hidden and (self.parent == nil or not self.parent.hidden) then
  56. if self.parent == nil then
  57. local tsize = self.tablist[self.last_tab_index].tabsize or
  58. {width=self.width, height=self.height}
  59. formspec = formspec ..
  60. string.format("size[%f,%f,%s]",tsize.width,tsize.height,
  61. dump(self.fixed_size))
  62. end
  63. formspec = formspec .. self:tab_header()
  64. formspec = formspec ..
  65. self.tablist[self.last_tab_index].get_formspec(
  66. self,
  67. self.tablist[self.last_tab_index].name,
  68. self.tablist[self.last_tab_index].tabdata,
  69. self.tablist[self.last_tab_index].tabsize
  70. )
  71. end
  72. return formspec
  73. end
  74. --------------------------------------------------------------------------------
  75. local function handle_buttons(self,fields)
  76. if self.hidden then
  77. return false
  78. end
  79. if self:handle_tab_buttons(fields) then
  80. return true
  81. end
  82. if self.glb_btn_handler ~= nil and
  83. self.glb_btn_handler(self,fields) then
  84. return true
  85. end
  86. if self.tablist[self.last_tab_index].button_handler ~= nil then
  87. return
  88. self.tablist[self.last_tab_index].button_handler(
  89. self,
  90. fields,
  91. self.tablist[self.last_tab_index].name,
  92. self.tablist[self.last_tab_index].tabdata
  93. )
  94. end
  95. return false
  96. end
  97. --------------------------------------------------------------------------------
  98. local function handle_events(self,event)
  99. if self.hidden then
  100. return false
  101. end
  102. if self.glb_evt_handler ~= nil and
  103. self.glb_evt_handler(self,event) then
  104. return true
  105. end
  106. if self.tablist[self.last_tab_index].evt_handler ~= nil then
  107. return
  108. self.tablist[self.last_tab_index].evt_handler(
  109. self,
  110. event,
  111. self.tablist[self.last_tab_index].name,
  112. self.tablist[self.last_tab_index].tabdata
  113. )
  114. end
  115. return false
  116. end
  117. --------------------------------------------------------------------------------
  118. local function tab_header(self)
  119. local toadd = ""
  120. for i=1,#self.tablist,1 do
  121. if toadd ~= "" then
  122. toadd = toadd .. ","
  123. end
  124. toadd = toadd .. self.tablist[i].caption
  125. end
  126. return string.format("tabheader[%f,%f;%s;%s;%i;true;false]",
  127. self.header_x, self.header_y, self.name, toadd, self.last_tab_index);
  128. end
  129. --------------------------------------------------------------------------------
  130. local function switch_to_tab(self, index)
  131. --first call on_change for tab to leave
  132. if self.tablist[self.last_tab_index].on_change ~= nil then
  133. self.tablist[self.last_tab_index].on_change("LEAVE",
  134. self.current_tab, self.tablist[index].name)
  135. end
  136. --update tabview data
  137. self.last_tab_index = index
  138. local old_tab = self.current_tab
  139. self.current_tab = self.tablist[index].name
  140. if (self.autosave_tab) then
  141. core.setting_set(self.name .. "_LAST",self.current_tab)
  142. end
  143. -- call for tab to enter
  144. if self.tablist[index].on_change ~= nil then
  145. self.tablist[index].on_change("ENTER",
  146. old_tab,self.current_tab)
  147. end
  148. end
  149. --------------------------------------------------------------------------------
  150. local function handle_tab_buttons(self,fields)
  151. --save tab selection to config file
  152. if fields[self.name] then
  153. local index = tonumber(fields[self.name])
  154. switch_to_tab(self, index)
  155. return true
  156. end
  157. return false
  158. end
  159. --------------------------------------------------------------------------------
  160. local function set_tab_by_name(self, name)
  161. for i=1,#self.tablist,1 do
  162. if self.tablist[i].name == name then
  163. switch_to_tab(self, i)
  164. return true
  165. end
  166. end
  167. return false
  168. end
  169. --------------------------------------------------------------------------------
  170. local function hide_tabview(self)
  171. self.hidden=true
  172. --call on_change as we're not gonna show self tab any longer
  173. if self.tablist[self.last_tab_index].on_change ~= nil then
  174. self.tablist[self.last_tab_index].on_change("LEAVE",
  175. self.current_tab, nil)
  176. end
  177. end
  178. --------------------------------------------------------------------------------
  179. local function show_tabview(self)
  180. self.hidden=false
  181. -- call for tab to enter
  182. if self.tablist[self.last_tab_index].on_change ~= nil then
  183. self.tablist[self.last_tab_index].on_change("ENTER",
  184. nil,self.current_tab)
  185. end
  186. end
  187. local tabview_metatable = {
  188. add = add_tab,
  189. handle_buttons = handle_buttons,
  190. handle_events = handle_events,
  191. get_formspec = get_formspec,
  192. show = show_tabview,
  193. hide = hide_tabview,
  194. delete = function(self) ui.delete(self) end,
  195. set_parent = function(self,parent) self.parent = parent end,
  196. set_autosave_tab =
  197. function(self,value) self.autosave_tab = value end,
  198. set_tab = set_tab_by_name,
  199. set_global_button_handler =
  200. function(self,handler) self.glb_btn_handler = handler end,
  201. set_global_event_handler =
  202. function(self,handler) self.glb_evt_handler = handler end,
  203. set_fixed_size =
  204. function(self,state) self.fixed_size = state end,
  205. tab_header = tab_header,
  206. handle_tab_buttons = handle_tab_buttons
  207. }
  208. tabview_metatable.__index = tabview_metatable
  209. --------------------------------------------------------------------------------
  210. function tabview_create(name, size, tabheaderpos)
  211. local self = {}
  212. self.name = name
  213. self.type = "toplevel"
  214. self.width = size.x
  215. self.height = size.y
  216. self.header_x = tabheaderpos.x
  217. self.header_y = tabheaderpos.y
  218. setmetatable(self, tabview_metatable)
  219. self.fixed_size = true
  220. self.hidden = true
  221. self.current_tab = nil
  222. self.last_tab_index = 1
  223. self.tablist = {}
  224. self.autosave_tab = false
  225. ui.add(self)
  226. return self
  227. end