ui.lua 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  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. --------------------------------------------------------------------------------
  21. function ui.add(child)
  22. --TODO check child
  23. ui.childlist[child.name] = child
  24. return child.name
  25. end
  26. --------------------------------------------------------------------------------
  27. function ui.delete(child)
  28. if ui.childlist[child.name] == nil then
  29. return false
  30. end
  31. ui.childlist[child.name] = nil
  32. return true
  33. end
  34. --------------------------------------------------------------------------------
  35. function ui.set_default(name)
  36. ui.default = name
  37. end
  38. --------------------------------------------------------------------------------
  39. function ui.find_by_name(name)
  40. return ui.childlist[name]
  41. end
  42. --------------------------------------------------------------------------------
  43. --------------------------------------------------------------------------------
  44. -- Internal functions not to be called from user
  45. --------------------------------------------------------------------------------
  46. --------------------------------------------------------------------------------
  47. local function wordwrap_quickhack(str)
  48. local res = ""
  49. local ar = str:split("\n")
  50. for i = 1, #ar do
  51. local text = ar[i]
  52. -- Hack to add word wrapping.
  53. -- TODO: Add engine support for wrapping in formspecs
  54. while #text > 80 do
  55. if res ~= "" then
  56. res = res .. ","
  57. end
  58. res = res .. core.formspec_escape(string.sub(text, 1, 79))
  59. text = string.sub(text, 80, #text)
  60. end
  61. if res ~= "" then
  62. res = res .. ","
  63. end
  64. res = res .. core.formspec_escape(text)
  65. end
  66. return res
  67. end
  68. --------------------------------------------------------------------------------
  69. function ui.update()
  70. local formspec = ""
  71. -- handle errors
  72. if gamedata ~= nil and gamedata.reconnect_requested then
  73. formspec = wordwrap_quickhack(gamedata.errormessage or "")
  74. formspec = "size[12,5]" ..
  75. "label[0.5,0;" .. fgettext("The server has requested a reconnect:") ..
  76. "]textlist[0.2,0.8;11.5,3.5;;" .. formspec ..
  77. "]button[6,4.6;3,0.5;btn_reconnect_no;" .. fgettext("Main menu") .. "]" ..
  78. "button[3,4.6;3,0.5;btn_reconnect_yes;" .. fgettext("Reconnect") .. "]"
  79. elseif gamedata ~= nil and gamedata.errormessage ~= nil then
  80. formspec = wordwrap_quickhack(gamedata.errormessage)
  81. local error_title
  82. if string.find(gamedata.errormessage, "ModError") then
  83. error_title = fgettext("An error occured in a Lua script, such as a mod:")
  84. else
  85. error_title = fgettext("An error occured:")
  86. end
  87. formspec = "size[12,5]" ..
  88. "label[0.5,0;" .. error_title ..
  89. "]textlist[0.2,0.8;11.5,3.5;;" .. formspec ..
  90. "]button[4.5,4.6;3,0.5;btn_error_confirm;" .. fgettext("Ok") .. "]"
  91. else
  92. local active_toplevel_ui_elements = 0
  93. for key,value in pairs(ui.childlist) do
  94. if (value.type == "toplevel") then
  95. local retval = value:get_formspec()
  96. if retval ~= nil and retval ~= "" then
  97. active_toplevel_ui_elements = active_toplevel_ui_elements +1
  98. formspec = formspec .. retval
  99. end
  100. end
  101. end
  102. -- no need to show addons if there ain't a toplevel element
  103. if (active_toplevel_ui_elements > 0) then
  104. for key,value in pairs(ui.childlist) do
  105. if (value.type == "addon") then
  106. local retval = value:get_formspec()
  107. if retval ~= nil and retval ~= "" then
  108. formspec = formspec .. retval
  109. end
  110. end
  111. end
  112. end
  113. if (active_toplevel_ui_elements > 1) then
  114. core.log("warning", "more than one active ui "..
  115. "element, self most likely isn't intended")
  116. end
  117. if (active_toplevel_ui_elements == 0) then
  118. core.log("warning", "no toplevel ui element "..
  119. "active; switching to default")
  120. ui.childlist[ui.default]:show()
  121. formspec = ui.childlist[ui.default]:get_formspec()
  122. end
  123. end
  124. core.update_formspec(formspec)
  125. end
  126. --------------------------------------------------------------------------------
  127. function ui.handle_buttons(fields)
  128. for key,value in pairs(ui.childlist) do
  129. local retval = value:handle_buttons(fields)
  130. if retval then
  131. ui.update()
  132. return
  133. end
  134. end
  135. end
  136. --------------------------------------------------------------------------------
  137. function ui.handle_events(event)
  138. for key,value in pairs(ui.childlist) do
  139. if value.handle_events ~= nil then
  140. local retval = value:handle_events(event)
  141. if retval then
  142. return retval
  143. end
  144. end
  145. end
  146. end
  147. --------------------------------------------------------------------------------
  148. --------------------------------------------------------------------------------
  149. -- initialize callbacks
  150. --------------------------------------------------------------------------------
  151. --------------------------------------------------------------------------------
  152. core.button_handler = function(fields)
  153. if fields["btn_reconnect_yes"] then
  154. gamedata.reconnect_requested = false
  155. gamedata.errormessage = nil
  156. gamedata.do_reconnect = true
  157. core.start()
  158. return
  159. elseif fields["btn_reconnect_no"] or fields["btn_error_confirm"] then
  160. gamedata.errormessage = nil
  161. gamedata.reconnect_requested = false
  162. ui.update()
  163. return
  164. end
  165. if ui.handle_buttons(fields) then
  166. ui.update()
  167. end
  168. end
  169. --------------------------------------------------------------------------------
  170. core.event_handler = function(event)
  171. if ui.handle_events(event) then
  172. ui.update()
  173. return
  174. end
  175. if event == "Refresh" then
  176. ui.update()
  177. return
  178. end
  179. end