ui.lua 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. ui = {}
  18. ui.childlist = {}
  19. ui.default = nil
  20. -- Whether fstk is currently showing its own formspec instead of active ui elements.
  21. ui.overridden = false
  22. --------------------------------------------------------------------------------
  23. function ui.add(child)
  24. --TODO check child
  25. ui.childlist[child.name] = child
  26. return child.name
  27. end
  28. --------------------------------------------------------------------------------
  29. function ui.delete(child)
  30. if ui.childlist[child.name] == nil then
  31. return false
  32. end
  33. ui.childlist[child.name] = nil
  34. return true
  35. end
  36. --------------------------------------------------------------------------------
  37. function ui.set_default(name)
  38. ui.default = name
  39. end
  40. --------------------------------------------------------------------------------
  41. function ui.find_by_name(name)
  42. return ui.childlist[name]
  43. end
  44. --------------------------------------------------------------------------------
  45. --------------------------------------------------------------------------------
  46. -- Internal functions not to be called from user
  47. --------------------------------------------------------------------------------
  48. --------------------------------------------------------------------------------
  49. function ui.update()
  50. ui.overridden = false
  51. local formspec = {}
  52. -- handle errors
  53. if gamedata ~= nil and gamedata.reconnect_requested then
  54. local error_message = core.formspec_escape(
  55. gamedata.errormessage or fgettext("<none available>"))
  56. formspec = {
  57. "size[14,8]",
  58. "real_coordinates[true]",
  59. "set_focus[btn_reconnect_yes;true]",
  60. "box[0.5,1.2;13,5;#000]",
  61. ("textarea[0.5,1.2;13,5;;%s;%s]"):format(
  62. fgettext("The server has requested a reconnect:"), error_message),
  63. "button[2,6.6;4,1;btn_reconnect_yes;" .. fgettext("Reconnect") .. "]",
  64. "button[8,6.6;4,1;btn_reconnect_no;" .. fgettext("Main menu") .. "]"
  65. }
  66. ui.overridden = true
  67. elseif gamedata ~= nil and gamedata.errormessage ~= nil then
  68. local error_message = core.formspec_escape(gamedata.errormessage)
  69. local error_title
  70. if string.find(gamedata.errormessage, "ModError") then
  71. error_title = fgettext("An error occurred in a Lua script:")
  72. else
  73. error_title = fgettext("An error occurred:")
  74. end
  75. formspec = {
  76. "size[14,8]",
  77. "real_coordinates[true]",
  78. "set_focus[btn_error_confirm;true]",
  79. "box[0.5,1.2;13,5;#000]",
  80. ("textarea[0.5,1.2;13,5;;%s;%s]"):format(
  81. error_title, error_message),
  82. "button[5,6.6;4,1;btn_error_confirm;" .. fgettext("OK") .. "]"
  83. }
  84. ui.overridden = true
  85. else
  86. local active_toplevel_ui_elements = 0
  87. for key,value in pairs(ui.childlist) do
  88. if (value.type == "toplevel") then
  89. local retval = value:get_formspec()
  90. if retval ~= nil and retval ~= "" then
  91. active_toplevel_ui_elements = active_toplevel_ui_elements + 1
  92. table.insert(formspec, retval)
  93. end
  94. end
  95. end
  96. -- no need to show addons if there ain't a toplevel element
  97. if (active_toplevel_ui_elements > 0) then
  98. for key,value in pairs(ui.childlist) do
  99. if (value.type == "addon") then
  100. local retval = value:get_formspec()
  101. if retval ~= nil and retval ~= "" then
  102. table.insert(formspec, retval)
  103. end
  104. end
  105. end
  106. end
  107. if (active_toplevel_ui_elements > 1) then
  108. core.log("warning", "more than one active ui "..
  109. "element, self most likely isn't intended")
  110. end
  111. if (active_toplevel_ui_elements == 0) then
  112. core.log("warning", "no toplevel ui element "..
  113. "active; switching to default")
  114. ui.childlist[ui.default]:show()
  115. formspec = {ui.childlist[ui.default]:get_formspec()}
  116. end
  117. end
  118. core.update_formspec(table.concat(formspec))
  119. end
  120. --------------------------------------------------------------------------------
  121. function ui.handle_buttons(fields)
  122. for key,value in pairs(ui.childlist) do
  123. local retval = value:handle_buttons(fields)
  124. if retval then
  125. ui.update()
  126. return
  127. end
  128. end
  129. end
  130. --------------------------------------------------------------------------------
  131. function ui.handle_events(event)
  132. for key,value in pairs(ui.childlist) do
  133. if value.handle_events ~= nil then
  134. local retval = value:handle_events(event)
  135. if retval then
  136. return retval
  137. end
  138. end
  139. end
  140. end
  141. --------------------------------------------------------------------------------
  142. --------------------------------------------------------------------------------
  143. -- initialize callbacks
  144. --------------------------------------------------------------------------------
  145. --------------------------------------------------------------------------------
  146. core.button_handler = function(fields)
  147. if fields["btn_reconnect_yes"] then
  148. gamedata.reconnect_requested = false
  149. gamedata.errormessage = nil
  150. gamedata.do_reconnect = true
  151. core.start()
  152. return
  153. elseif fields["btn_reconnect_no"] or fields["btn_error_confirm"] then
  154. gamedata.errormessage = nil
  155. gamedata.reconnect_requested = false
  156. ui.update()
  157. return
  158. end
  159. if ui.handle_buttons(fields) then
  160. ui.update()
  161. end
  162. end
  163. --------------------------------------------------------------------------------
  164. core.event_handler = function(event)
  165. -- Handle error messages
  166. if ui.overridden then
  167. if event == "MenuQuit" then
  168. gamedata.errormessage = nil
  169. gamedata.reconnect_requested = false
  170. ui.update()
  171. end
  172. return
  173. end
  174. if ui.handle_events(event) then
  175. ui.update()
  176. return
  177. end
  178. if event == "Refresh" then
  179. ui.update()
  180. return
  181. end
  182. end