]> git.lizzy.rs Git - dragonfireclient.git/blob - builtin/mainmenu.lua
Public server checkbox
[dragonfireclient.git] / builtin / mainmenu.lua
1 os.setlocale("C", "numeric")
2
3 local scriptpath = engine.get_scriptdir()
4
5 dofile(scriptpath .. DIR_DELIM .. "modmgr.lua")
6 dofile(scriptpath .. DIR_DELIM .. "modstore.lua")
7 dofile(scriptpath .. DIR_DELIM .. "gamemgr.lua")
8
9 local menu = {}
10 local tabbuilder = {}
11 local menubar = {}
12
13 --------------------------------------------------------------------------------
14 function render_favourite(spec)
15         local text = ""
16         
17         if spec.name ~= nil then
18                 text = text .. spec.name:trim()
19                 
20                 if spec.description ~= nil then
21                         --TODO make sure there's no invalid chat in spec.description
22                         text = text .. " (" .. fs_escape_string(spec.description) .. ")"
23                 end
24         else
25                 if spec.address ~= nil then
26                         text = text .. spec.address:trim()
27                 end
28         end
29         
30         local details = ""
31         if spec.password == true then
32                 details = " *"
33         else
34                 details = "  "
35         end
36         
37         if spec.creative then
38                 details = details .. "C"
39         else
40                 details = details .. " "
41         end
42         
43         if spec.damage then
44                 details = details .. "D"
45         else
46                 details = details .. " "
47         end
48         
49         if spec.pvp then
50                 details = details .. "P"
51         else
52                 details = details .. " "
53         end
54         
55         if spec.port ~= nil then
56                 text = text .. ":" .. spec.port:trim()
57         else
58                 text = text .. ":??"
59         end
60         
61         return text
62 end
63
64 --------------------------------------------------------------------------------
65 os.tempfolder = function()
66         local filetocheck = os.tmpname()
67         os.remove(filetocheck)
68         
69         local randname = "MTTempModFolder_" .. math.random(0,10000)
70         if DIR_DELIM == "\\" then
71                 local tempfolder = os.getenv("TEMP")
72                 return tempfolder .. filetocheck
73         else
74                 local backstring = filetocheck:reverse()
75                 return filetocheck:sub(0,filetocheck:len()-backstring:find(DIR_DELIM)+1) ..randname
76         end
77
78 end
79
80 --------------------------------------------------------------------------------
81 function cleanup_path(temppath)
82         
83         local parts = temppath:split("-")
84         temppath = ""   
85         for i=1,#parts,1 do
86                 if temppath ~= "" then
87                         temppath = temppath .. "_"
88                 end
89                 temppath = temppath .. parts[i]
90         end
91         
92         parts = temppath:split(".")
93         temppath = ""   
94         for i=1,#parts,1 do
95                 if temppath ~= "" then
96                         temppath = temppath .. "_"
97                 end
98                 temppath = temppath .. parts[i]
99         end
100         
101         parts = temppath:split("'")
102         temppath = ""   
103         for i=1,#parts,1 do
104                 if temppath ~= "" then
105                         temppath = temppath .. ""
106                 end
107                 temppath = temppath .. parts[i]
108         end
109         
110         parts = temppath:split(" ")
111         temppath = ""   
112         for i=1,#parts,1 do
113                 if temppath ~= "" then
114                         temppath = temppath
115                 end
116                 temppath = temppath .. parts[i]
117         end
118         
119         return temppath
120 end
121
122 function menu.set_texture(identifier,gamedetails)
123         local texture_set = false
124         if menu.texturepack ~= nil and gamedetails ~= nil then
125                 local path = menu.basetexturedir .. 
126                                                 gamedetails.id .. "_menu_" .. identifier .. ".png"
127                 
128                 if engine.set_background(identifier,path) then
129                         texture_set = true
130                 end
131         end
132         
133         if not texture_set and gamedetails ~= nil then
134                 local path = gamedetails.path .. DIR_DELIM .."menu" .. 
135                                                                          DIR_DELIM .. identifier .. ".png"
136                 if engine.set_background(identifier,path) then
137                         texture_set = true
138                 end
139         end
140         
141         if not texture_set then
142                 local path = menu.basetexturedir .. DIR_DELIM .."menu_" .. 
143                                                                                 identifier .. ".png"
144                 if engine.set_background(identifier,path) then
145                         texture_set = true
146                 end
147         end
148         
149         if not texture_set then
150                 local path = menu.defaulttexturedir .. DIR_DELIM .."menu_" .. 
151                                                                                 identifier .. ".png"
152                 engine.set_background(identifier,path)
153         end
154 end
155
156 --------------------------------------------------------------------------------
157 function menu.update_gametype()
158         if (menu.game_last_check == nil or
159                 menu.game_last_check ~= menu.last_game) and
160                 tabbuilder.current_tab == "singleplayer" then
161                 
162                 local gamedetails = menu.lastgame()
163                 engine.set_topleft_text(gamedetails.name)
164                 
165                 --background
166                 local background_set = false
167                 if menu.texturepack ~= nil then
168                         local path_background_texture = menu.basetexturedir .. 
169                                                                                 gamedetails.id .. "_menu_background.png"
170                         
171                         if engine.set_background("background",path_background_texture) then
172                                 background_set = true
173                                 engine.set_clouds(false)
174                         end
175                 end
176                 
177                 if not background_set then
178                         local path_background_texture = gamedetails.path .. DIR_DELIM .."menu" .. 
179                                                                                  DIR_DELIM .. "background.png"
180                         if engine.set_background("background",path_background_texture) then
181                                 background_set = true
182                                 engine.set_clouds(false)
183                         end
184                 end
185                 
186                 if not background_set then
187                         engine.set_clouds(true)
188                 end
189                 
190                 menu.set_texture("overlay",gamedetails)
191                 menu.set_texture("header",gamedetails)
192                 menu.set_texture("footer",gamedetails)
193                 
194                 menu.game_last_check = menu.last_game
195         else
196                 if menu.game_last_check ~= menu.last_game then
197                         menu.game_last_check = menu.last_game
198                         menu.reset_gametype()
199                 end
200         end
201 end
202
203 --------------------------------------------------------------------------------
204 function menu.reset_gametype()
205         menu.game_last_check = nil
206         
207         local path_background_texture = menu.basetexturedir .. "menu_background.png"
208                         
209         if engine.set_background("background",path_background_texture) then
210                 background_set = true
211                 engine.set_clouds(false)
212         else
213                 engine.set_clouds(true)
214         end 
215
216         menu.set_texture("overlay",nil)
217         menu.set_texture("header",nil)
218         menu.set_texture("footer",nil)
219         engine.set_topleft_text("")
220 end
221
222 --------------------------------------------------------------------------------
223 function get_last_folder(text,count)
224         local parts = text:split(DIR_DELIM)
225         
226         if count == nil then
227                 return parts[#parts]
228         end
229         
230         local retval = ""
231         for i=1,count,1 do
232                 retval = retval .. parts[#parts - (count-i)] .. DIR_DELIM
233         end
234         
235         return retval
236 end
237
238 --------------------------------------------------------------------------------
239 function init_globals()
240         --init gamedata
241         gamedata.worldindex = 0
242 end
243
244 --------------------------------------------------------------------------------
245 function identify_filetype(name)
246
247         if name:sub(-3):lower() == "zip" then
248                 return {
249                                 name = name,
250                                 type = "zip"
251                                 }
252         end
253         
254         if name:sub(-6):lower() == "tar.gz" or
255                 name:sub(-3):lower() == "tgz"then
256                 return {
257                                 name = name,
258                                 type = "tgz"
259                                 }
260         end
261         
262         if name:sub(-6):lower() == "tar.bz2" then
263                 return {
264                                 name = name,
265                                 type = "tbz"
266                                 }
267         end
268         
269         if name:sub(-2):lower() == "7z" then
270                 return {
271                                 name = name,
272                                 type = "7z"
273                                 }
274         end
275
276         return {
277                 name = name,
278                 type = "ukn"
279         }
280 end
281
282 --------------------------------------------------------------------------------
283 function update_menu()
284
285         local formspec = "size[12,5.2]"
286         
287         -- handle errors
288         if gamedata.errormessage ~= nil then
289                 formspec = formspec ..
290                         "field[1,2;10,2;;ERROR: " ..
291                         gamedata.errormessage .. 
292                         ";]"..
293                         "button[4.5,4.2;3,0.5;btn_error_confirm;Ok]"
294         else
295                 formspec = formspec .. tabbuilder.gettab()
296         end
297
298         engine.update_formspec(formspec)
299 end
300
301 --------------------------------------------------------------------------------
302 function menu.filtered_game_list()
303         local retval = ""
304
305         local current_game = menu.lastgame()
306         
307         for i=1,#menu.worldlist,1 do
308                 if menu.worldlist[i].gameid == current_game.id then
309                         if retval ~= "" then
310                                 retval = retval ..","
311                         end
312                         
313                         retval = retval .. menu.worldlist[i].name .. 
314                                                 " \\[" .. menu.worldlist[i].gameid .. "\\]"
315                 end
316         end
317         
318         return retval
319 end
320
321 --------------------------------------------------------------------------------
322 function menu.filtered_game_list_raw()
323         local retval =  {}
324
325         local current_game = menu.lastgame()
326         
327         for i=1,#menu.worldlist,1 do
328                 if menu.worldlist[i].gameid == current_game.id then
329                         table.insert(retval,menu.worldlist[i])
330                 end
331         end
332         
333         return retval
334 end
335
336 --------------------------------------------------------------------------------
337 function menu.filtered_index_to_plain(filtered_index)
338
339         local current_game = menu.lastgame()
340         
341         local temp_idx = 0
342         
343         if menu.worldlist == nil then
344                 return -1
345         end
346         
347         for i=1,#menu.worldlist,1 do
348                 if menu.worldlist[i].gameid == current_game.id then
349                         temp_idx = temp_idx +1
350                 end
351                 
352                 if temp_idx == filtered_index then
353                         return i
354                 end
355         end
356         return -1
357 end
358
359 --------------------------------------------------------------------------------
360 function menu.init()
361         --init menu data
362         gamemgr.update_gamelist()
363
364         menu.worldlist = engine.get_worlds()
365         
366         menu.last_world = tonumber(engine.setting_get("main_menu_last_world_idx"))
367         menu.last_game  = tonumber(engine.setting_get("main_menu_last_game_idx"))
368         
369         if type(menu.last_world) ~= "number" then
370                 menu.last_world = 1
371         end
372         
373         if type(menu.last_game) ~= "number" then
374                 menu.last_game = 1
375         end
376
377         if engine.setting_getbool("public_serverlist") then
378                 menu.favorites = engine.get_favorites("online")
379         else
380                 menu.favorites = engine.get_favorites("local")
381         end
382         
383         
384         menu.defaulttexturedir = engine.get_gamepath() .. DIR_DELIM .. ".." ..
385                                                 DIR_DELIM .. "textures" .. DIR_DELIM .. "base" .. 
386                                                 DIR_DELIM .. "pack" .. DIR_DELIM
387         menu.basetexturedir = menu.defaulttexturedir
388         
389         menu.texturepack = engine.setting_get("texture_path")
390         
391         if menu.texturepack ~= nil then
392                 menu.basetexturedir = menu.texturepack .. DIR_DELIM
393         end
394 end
395
396 --------------------------------------------------------------------------------
397 function menu.lastgame()
398         if menu.last_game > 0 and menu.last_game <= #gamemgr.games then
399                 return gamemgr.games[menu.last_game]
400         end
401         
402         if #gamemgr.games >= 1 then
403                 menu.last_game = 1
404                 return gamemgr.games[menu.last_game]
405         end
406         
407         --error case!!
408         return nil
409 end
410
411 --------------------------------------------------------------------------------
412 function menu.lastworld()
413         if menu.last_world ~= nil and 
414                 menu.last_world > 0 and 
415                 menu.last_world <= #menu.worldlist then
416                 return menu.worldlist[menu.last_world]
417         end
418         
419         if #menu.worldlist >= 1 then
420                 menu.last_world = 1
421                 return menu.worldlist[menu.last_world]
422         end
423         
424         --error case!!
425         return nil
426 end
427
428 --------------------------------------------------------------------------------
429 function menu.update_last_game(world_idx)
430         if gamedata.selected_world <= #menu.worldlist then
431                 local world = menu.worldlist[gamedata.selected_world]
432                 
433                 if world == nil then
434                         return
435                 end
436                 
437                 for i=1,#gamemgr.games,1 do             
438                         if gamemgr.games[i].id == world.gameid then
439                                 menu.last_game = i
440                                 engine.setting_set("main_menu_last_game_idx",menu.last_game)
441                                 break
442                         end
443                 end
444         end
445 end
446
447 --------------------------------------------------------------------------------
448 function menubar.handle_buttons(fields)
449         for i=1,#menubar.buttons,1 do
450                 if fields[menubar.buttons[i].btn_name] ~= nil then
451                         menu.last_game = menubar.buttons[i].index
452                         engine.setting_set("main_menu_last_game_idx",menu.last_game)
453                         menu.update_gametype()
454                 end
455         end
456 end
457
458 --------------------------------------------------------------------------------
459 function menubar.refresh()
460         menubar.formspec = "box[-0.3,5.625;12.4,1.3;000000]" ..
461                                            "box[-0.3,5.6;12.4,0.05;FFFFFF]"
462         menubar.buttons = {}
463
464         local button_base = -0.25
465         
466         local maxbuttons = #gamemgr.games
467         
468         if maxbuttons > 10 then
469                 maxbuttons = 10
470         end
471         
472         for i=1,maxbuttons,1 do
473
474                 local btn_name = "menubar_btn_" .. gamemgr.games[i].id
475                 local buttonpos = button_base + (i-1) * 1.245
476                 if gamemgr.games[i].menuicon_path ~= nil and
477                         gamemgr.games[i].menuicon_path ~= "" then
478
479                         menubar.formspec = menubar.formspec ..
480                                 "image_button[" .. buttonpos ..  ",5.7;1.3,1.3;"  ..
481                                 gamemgr.games[i].menuicon_path .. ";" .. btn_name .. ";;true;false]"
482                 else
483                 
484                         local part1 = gamemgr.games[i].id:sub(1,5)
485                         local part2 = gamemgr.games[i].id:sub(6,10)
486                         local part3 = gamemgr.games[i].id:sub(11)
487                         
488                         local text = part1 .. "\n" .. part2
489                         if part3 ~= nil and
490                                 part3 ~= "" then
491                                 text = text .. "\n" .. part3
492                         end
493                         menubar.formspec = menubar.formspec ..
494                                 "image_button[" .. buttonpos ..  ",5.7;1.3,1.3;;" ..btn_name ..
495                                 ";" .. text .. ";true;true]"
496                 end
497                 
498                 local toadd = {
499                         btn_name = btn_name,
500                         index = i,
501                 }
502                 
503                 table.insert(menubar.buttons,toadd)
504         end
505 end
506
507 --------------------------------------------------------------------------------
508 function tabbuilder.dialog_create_world()
509         local mapgens = {"v6", "v7", "indev", "singlenode", "math"}
510
511         local current_mg = engine.setting_get("mg_name")
512
513         local mglist = ""
514         local selindex = 1
515         local i = 1
516         for k,v in pairs(mapgens) do
517                 if current_mg == v then
518                         selindex = i
519                 end
520                 i = i + 1
521                 mglist = mglist .. v .. ","
522         end
523         mglist = mglist:sub(1, -2)
524
525         local retval = 
526                 "label[2,0;World name]"..
527                 "label[2,1;Mapgen]"..
528                 "field[4.5,0.4;6,0.5;te_world_name;;]" ..
529                 "label[2,2;Game]"..
530                 "button[5,4.5;2.6,0.5;world_create_confirm;Create]" ..
531                 "button[7.5,4.5;2.8,0.5;world_create_cancel;Cancel]" ..
532                 "dropdown[4.2,1;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]" ..
533                 "textlist[4.2,1.9;5.8,2.3;games;" ..
534                 gamemgr.gamelist() ..
535                 ";" .. menu.last_game .. ";true]"
536
537         return retval
538 end
539
540 --------------------------------------------------------------------------------
541 function tabbuilder.dialog_delete_world()
542         return  "label[2,2;Delete World \"" .. menu.lastworld().name .. "\"?]"..
543                         "button[3.5,4.2;2.6,0.5;world_delete_confirm;Yes]" ..
544                         "button[6,4.2;2.8,0.5;world_delete_cancel;No]"
545 end
546
547 --------------------------------------------------------------------------------
548 function tabbuilder.gettab()
549         local retval = ""
550         
551         if tabbuilder.show_buttons then
552                 retval = retval .. tabbuilder.tab_header()
553         end
554
555         if tabbuilder.current_tab == "singleplayer" then
556                 retval = retval .. tabbuilder.tab_singleplayer()
557         end
558         
559         if tabbuilder.current_tab == "multiplayer" then
560                 retval = retval .. tabbuilder.tab_multiplayer()
561         end
562
563         if tabbuilder.current_tab == "server" then
564                 retval = retval .. tabbuilder.tab_server()
565         end
566         
567         if tabbuilder.current_tab == "settings" then
568                 retval = retval .. tabbuilder.tab_settings()
569         end
570         
571         if tabbuilder.current_tab == "credits" then
572                 retval = retval .. tabbuilder.tab_credits()
573         end
574         
575         if tabbuilder.current_tab == "dialog_create_world" then
576                 retval = retval .. tabbuilder.dialog_create_world()
577         end
578         
579         if tabbuilder.current_tab == "dialog_delete_world" then
580                 retval = retval .. tabbuilder.dialog_delete_world()
581         end
582         
583         retval = retval .. modmgr.gettab(tabbuilder.current_tab)
584         retval = retval .. gamemgr.gettab(tabbuilder.current_tab)
585         retval = retval .. modstore.gettab(tabbuilder.current_tab)
586
587         return retval
588 end
589
590 --------------------------------------------------------------------------------
591 function tabbuilder.handle_create_world_buttons(fields)
592         
593         if fields["world_create_confirm"] or
594                 fields["key_enter"] then
595                 
596                 local worldname = fields["te_world_name"]
597                 local gameindex = engine.get_textlist_index("games")
598                 
599                 if gameindex > 0 and
600                         worldname ~= "" then
601                         menu.worldlist = engine.get_worlds()
602                         
603                         local found = false
604                         for i=1,#menu.worldlist,1 do
605                                 if menu.worldlist[i].name == worldname then
606                                         found = true
607                                         break
608                                 end
609                         end
610                         
611                         local message = nil
612                         
613                         if not found then
614                                 engine.setting_set("mg_name",fields["dd_mapgen"])
615                                 message = engine.create_world(worldname,gameindex)
616                         else
617                                 message = "A world named \"" .. worldname .. "\" already exists"
618                         end
619                         
620                         if message ~= nil then
621                                 gamedata.errormessage = message
622                         else
623                                 menu.last_game = gameindex
624                                 engine.setting_set("main_menu_last_game_idx",gameindex)
625                                 menu.worldlist = engine.get_worlds()
626                                 
627                                 local worldlist = menu.worldlist
628                                 
629                                 if tabbuilder.current_tab == "singleplayer" then
630                                         worldlist = menu.filtered_game_list_raw()
631                                 end
632                                 
633                                 local index = 0
634                                 
635                                 for i=1,#worldlist,1 do
636                                         if worldlist[i].name == worldname then
637                                                 index = i
638                                                 break
639                                         end
640                                 end
641
642                                 engine.setting_set("main_menu_singleplayer_world_idx", index)
643                                 menu.last_world = index
644                         end
645                 else
646                         gamedata.errormessage = "No worldname given or no game selected"
647                 end
648         end
649         
650         if fields["games"] then
651                 tabbuilder.skipformupdate = true
652                 return
653         end
654         
655         tabbuilder.is_dialog = false
656         tabbuilder.show_buttons = true
657         tabbuilder.current_tab = engine.setting_get("main_menu_tab")
658 end
659
660 --------------------------------------------------------------------------------
661 function tabbuilder.handle_delete_world_buttons(fields)
662         
663         if fields["world_delete_confirm"] then
664                 if menu.last_world > 0 and 
665                         menu.last_world <= #menu.worldlist then
666                         engine.delete_world(menu.last_world)
667                         menu.worldlist = engine.get_worlds()
668                         menu.last_world = 1
669                 end
670         end
671         
672         tabbuilder.is_dialog = false
673         tabbuilder.show_buttons = true
674         tabbuilder.current_tab = engine.setting_get("main_menu_tab")
675 end
676
677 --------------------------------------------------------------------------------
678 function tabbuilder.handle_multiplayer_buttons(fields)
679         
680         if fields["te_name"] ~= nil then
681                 gamedata.playername = fields["te_name"]
682                 engine.setting_set("name", fields["te_name"])
683         end
684         
685         if fields["favourites"] ~= nil then
686                 local event = explode_textlist_event(fields["favourites"])
687                 if event.typ == "DCL" then
688                         --gamedata.address = menu.favorites[event.index].name
689                         if gamedata.address == nil then
690                                 gamedata.address = menu.favorites[event.index].address
691                         end
692                         gamedata.port = menu.favorites[event.index].port
693                         gamedata.playername             = fields["te_name"]
694                         if fields["te_pwd"] ~= nil then
695                                 gamedata.password               = fields["te_pwd"]
696                         end
697                         gamedata.selected_world = 0
698                         
699                         if gamedata.address ~= nil and
700                                 gamedata.port ~= nil then
701                                 
702                                 engine.start()
703                         end
704                 end
705                 
706                 if event.typ == "CHG" then
707                         local address = menu.favorites[event.index].name
708                         if address == nil then
709                                 address = menu.favorites[event.index].address
710                         end
711                         local port = menu.favorites[event.index].port
712                         
713                         if address ~= nil and
714                                 port ~= nil then
715                                 engine.setting_set("address",address)
716                                 engine.setting_set("port",port)
717                         end
718                         
719                         menu.fav_selected = event.index
720                 end
721                 return
722         end
723         
724         if fields["key_up"] ~= nil or
725                 fields["key_down"] ~= nil then
726                 
727                 local fav_idx = engine.get_textlist_index("favourites")
728                 
729                 if fields["key_up"] ~= nil and fav_idx > 1 then
730                         fav_idx = fav_idx -1
731                 else if fields["key_down"] and fav_idx < #menu.favorites then
732                         fav_idx = fav_idx +1
733                 end end
734                 
735                 local address = menu.favorites[fav_idx].name
736                 if address == nil then
737                         address = menu.favorites[fav_idx].address
738                 end
739                 local port = menu.favorites[fav_idx].port
740                 
741                 if address ~= nil and
742                         port ~= nil then
743                         engine.setting_set("address",address)
744                         engine.setting_set("port",port)
745                 end
746                 
747                 menu.fav_selected = fav_idx
748                 return
749         end
750         
751         if fields["cb_public_serverlist"] ~= nil then
752                 engine.setting_setbool("public_serverlist",
753                         tabbuilder.tobool(fields["cb_public_serverlist"]))
754                         
755                 if engine.setting_getbool("public_serverlist") then
756                         menu.favorites = engine.get_favorites("online")
757                 else
758                         menu.favorites = engine.get_favorites("local")
759                 end
760                 
761                 return
762         end
763
764         if fields["btn_delete_favorite"] ~= nil then
765                 local current_favourite = engine.get_textlist_index("favourites")
766                 engine.delete_favorite(current_favourite)
767                 menu.favorites = engine.get_favorites()
768                 
769                 engine.setting_set("address","")
770                 engine.setting_get("port","")
771                 
772                 return
773         end
774
775         if fields["btn_mp_connect"] ~= nil or
776                 fields["key_enter"] then
777                 
778                 gamedata.playername             = fields["te_name"]
779                 gamedata.password               = fields["te_pwd"]
780                 gamedata.address                = fields["te_address"]
781                 gamedata.port                   = fields["te_port"]
782                 gamedata.selected_world = 0
783                 
784                 engine.start()
785                 return
786         end
787 end
788
789 --------------------------------------------------------------------------------
790 function tabbuilder.handle_server_buttons(fields)
791
792         local world_doubleclick = false
793
794         if fields["srv_worlds"] ~= nil then
795                 local event = explode_textlist_event(fields["srv_worlds"])
796                 
797                 if event.typ == "DCL" then
798                         world_doubleclick = true
799                 end
800                 if event.typ == "CHG" then
801                         engine.setting_set("main_menu_last_world_idx",engine.get_textlist_index("srv_worlds"))
802                 end
803         end
804         
805                 if fields["key_up"] then
806                 local oldidx = engine.get_textlist_index("srv_worlds")
807                 
808                 if oldidx > 1 then
809                         local newidx = oldidx -1
810                         engine.setting_set("main_menu_last_world_idx",newidx)
811                 end
812         end
813         
814         if fields["key_down"] then
815                 local oldidx = engine.get_textlist_index("srv_worlds")
816                 
817                 if oldidx < #menu.worldlist then
818                         local newidx = oldidx + 1
819                         engine.setting_set("main_menu_last_world_idx",newidx)
820                 end
821         end
822         
823         if fields["cb_creative_mode"] then
824                 engine.setting_setbool("creative_mode",tabbuilder.tobool(fields["cb_creative_mode"]))
825         end
826         
827         if fields["cb_enable_damage"] then
828                 engine.setting_setbool("enable_damage",tabbuilder.tobool(fields["cb_enable_damage"]))
829         end
830
831         if fields["cb_server_announce"] then
832                 engine.setting_setbool("server_announce",tabbuilder.tobool(fields["cb_server_announce"]))
833         end
834         
835         
836         if fields["start_server"] ~= nil or
837                 world_doubleclick or
838                 fields["key_enter"] then
839                 local selected = engine.get_textlist_index("srv_worlds")
840                 if selected > 0 then
841                         
842                         gamedata.playername             = fields["te_playername"]
843                         gamedata.password               = fields["te_passwd"]
844                         gamedata.port                   = fields["te_serverport"]
845                         gamedata.address                = ""
846                         gamedata.selected_world = selected
847                         
848                         engine.setting_set("main_menu_tab",tabbuilder.current_tab)
849                         engine.setting_set("main_menu_last_world_idx",gamedata.selected_world)
850                         
851                         menu.update_last_game(gamedata.selected_world)
852                         engine.start()
853                 end
854         end
855         
856         if fields["world_create"] ~= nil then
857                 tabbuilder.current_tab = "dialog_create_world"
858                 tabbuilder.is_dialog = true
859                 tabbuilder.show_buttons = false
860         end
861         
862         if fields["world_delete"] ~= nil then
863                 local selected = engine.get_textlist_index("srv_worlds")
864                 if selected > 0 then
865                         menu.last_world = engine.get_textlist_index("srv_worlds")
866                         if menu.lastworld() ~= nil and
867                                 menu.lastworld().name ~= nil and
868                                 menu.lastworld().name ~= "" then
869                                 tabbuilder.current_tab = "dialog_delete_world"
870                                 tabbuilder.is_dialog = true
871                                 tabbuilder.show_buttons = false
872                         else
873                                 menu.last_world = 0
874                         end
875                 end
876         end
877         
878         if fields["world_configure"] ~= nil then
879                 selected = engine.get_textlist_index("srv_worlds")
880                 if selected > 0 then
881                         modmgr.world_config_selected_world = selected
882                         if modmgr.init_worldconfig() then
883                                 tabbuilder.current_tab = "dialog_configure_world"
884                                 tabbuilder.is_dialog = true
885                                 tabbuilder.show_buttons = false
886                         end
887                 end
888         end
889 end
890
891 --------------------------------------------------------------------------------
892 function tabbuilder.tobool(text)
893         if text == "true" then
894                 return true
895         else
896                 return false
897         end
898 end
899
900 --------------------------------------------------------------------------------
901 function tabbuilder.handle_settings_buttons(fields)
902         if fields["cb_fancy_trees"] then
903                 engine.setting_setbool("new_style_leaves",tabbuilder.tobool(fields["cb_fancy_trees"]))
904         end
905                 
906         if fields["cb_smooth_lighting"] then
907                 engine.setting_setbool("smooth_lighting",tabbuilder.tobool(fields["cb_smooth_lighting"]))
908         end
909         if fields["cb_3d_clouds"] then
910                 engine.setting_setbool("enable_3d_clouds",tabbuilder.tobool(fields["cb_3d_clouds"]))
911         end
912         if fields["cb_opaque_water"] then
913                 engine.setting_setbool("opaque_water",tabbuilder.tobool(fields["cb_opaque_water"]))
914         end
915                         
916         if fields["cb_mipmapping"] then
917                 engine.setting_setbool("mip_map",tabbuilder.tobool(fields["cb_mipmapping"]))
918         end
919         if fields["cb_anisotrophic"] then
920                 engine.setting_setbool("anisotropic_filter",tabbuilder.tobool(fields["cb_anisotrophic"]))
921         end
922         if fields["cb_bilinear"] then
923                 engine.setting_setbool("bilinear_filter",tabbuilder.tobool(fields["cb_bilinear"]))
924         end
925         if fields["cb_trilinear"] then
926                 engine.setting_setbool("trilinear_filter",tabbuilder.tobool(fields["cb_trilinear"]))
927         end
928                         
929         if fields["cb_shaders"] then
930                 engine.setting_setbool("enable_shaders",tabbuilder.tobool(fields["cb_shaders"]))
931         end
932         if fields["cb_pre_ivis"] then
933                 engine.setting_setbool("preload_item_visuals",tabbuilder.tobool(fields["cb_pre_ivis"]))
934         end
935         if fields["cb_particles"] then
936                 engine.setting_setbool("enable_particles",tabbuilder.tobool(fields["cb_particles"]))
937         end
938         if fields["cb_finite_liquid"] then
939                 engine.setting_setbool("liquid_finite",tabbuilder.tobool(fields["cb_finite_liquid"]))
940         end
941
942         if fields["btn_change_keys"] ~= nil then
943                 engine.show_keys_menu()
944         end
945 end
946
947 --------------------------------------------------------------------------------
948 function tabbuilder.handle_singleplayer_buttons(fields)
949
950         local world_doubleclick = false
951
952         if fields["sp_worlds"] ~= nil then
953                 local event = explode_textlist_event(fields["sp_worlds"])
954                 
955                 if event.typ == "DCL" then
956                         world_doubleclick = true
957                 end
958                 
959                 if event.typ == "CHG" then
960                         engine.setting_set("main_menu_singleplayer_world_idx",engine.get_textlist_index("sp_worlds"))
961                 end
962         end
963         
964         if fields["key_up"] then
965                 local oldidx = engine.get_textlist_index("sp_worlds")
966                 
967                 if oldidx > 1 then
968                         local newidx = oldidx -1
969                         engine.setting_set("main_menu_singleplayer_world_idx",newidx)
970                 end
971         end
972         
973         if fields["key_down"] then
974                 local oldidx = engine.get_textlist_index("sp_worlds")
975                 
976                 if oldidx < #menu.filtered_game_list_raw() then
977                         local newidx = oldidx + 1
978                         engine.setting_set("main_menu_singleplayer_world_idx",newidx)
979                 end
980         end
981         
982         if fields["cb_creative_mode"] then
983                 engine.setting_setbool("creative_mode",tabbuilder.tobool(fields["cb_creative_mode"]))
984         end
985         
986         if fields["cb_enable_damage"] then
987                 engine.setting_setbool("enable_damage",tabbuilder.tobool(fields["cb_enable_damage"]))
988         end
989
990         if fields["play"] ~= nil or
991                 world_doubleclick or
992                 fields["key_enter"] then
993                 local selected = engine.get_textlist_index("sp_worlds")
994                 if selected > 0 then
995                         gamedata.selected_world = menu.filtered_index_to_plain(selected)
996                         gamedata.singleplayer   = true
997
998                         engine.setting_set("main_menu_tab",tabbuilder.current_tab)
999                         engine.setting_set("main_menu_singleplayer_world_idx",selected)
1000                         
1001                         menu.update_last_game(gamedata.selected_world)
1002                         
1003                         engine.start()
1004                 end
1005         end
1006         
1007         if fields["world_create"] ~= nil then
1008                 tabbuilder.current_tab = "dialog_create_world"
1009                 tabbuilder.is_dialog = true
1010                 tabbuilder.show_buttons = false
1011         end
1012         
1013         if fields["world_delete"] ~= nil then
1014                 local selected = engine.get_textlist_index("sp_worlds")
1015                 if selected > 0 then
1016                         menu.last_world = menu.filtered_index_to_plain(selected)
1017                         if menu.lastworld() ~= nil and
1018                                 menu.lastworld().name ~= nil and
1019                                 menu.lastworld().name ~= "" then
1020                                 tabbuilder.current_tab = "dialog_delete_world"
1021                                 tabbuilder.is_dialog = true
1022                                 tabbuilder.show_buttons = false
1023                         else
1024                                 menu.last_world = 0
1025                         end
1026                 end
1027         end
1028         
1029         if fields["world_configure"] ~= nil then
1030                 selected = engine.get_textlist_index("sp_worlds")
1031                 if selected > 0 then
1032                         modmgr.world_config_selected_world = menu.filtered_index_to_plain(selected)
1033                         if modmgr.init_worldconfig() then
1034                                 tabbuilder.current_tab = "dialog_configure_world"
1035                                 tabbuilder.is_dialog = true
1036                                 tabbuilder.show_buttons = false
1037                         end
1038                 end
1039         end
1040 end
1041
1042 --------------------------------------------------------------------------------
1043 function tabbuilder.tab_header()
1044
1045         if tabbuilder.last_tab_index == nil then
1046                 tabbuilder.last_tab_index = 1
1047         end
1048         
1049         local toadd = ""
1050         
1051         for i=1,#tabbuilder.current_buttons,1 do
1052                 
1053                 if toadd ~= "" then
1054                         toadd = toadd .. ","
1055                 end
1056                 
1057                 toadd = toadd .. tabbuilder.current_buttons[i].caption
1058         end
1059         return "tabheader[-0.3,-0.99;main_tab;" .. toadd ..";" .. tabbuilder.last_tab_index .. ";true;false]"
1060 end
1061
1062 --------------------------------------------------------------------------------
1063 function tabbuilder.handle_tab_buttons(fields)
1064
1065         if fields["main_tab"] then
1066                 local index = tonumber(fields["main_tab"])
1067                 tabbuilder.last_tab_index = index
1068                 tabbuilder.current_tab = tabbuilder.current_buttons[index].name
1069                 
1070                 engine.setting_set("main_menu_tab",tabbuilder.current_tab)
1071         end
1072         
1073         --handle tab changes
1074         if tabbuilder.current_tab ~= tabbuilder.old_tab then
1075                 if tabbuilder.current_tab ~= "singleplayer" then
1076                         menu.reset_gametype()
1077                 end
1078         end
1079         
1080         if tabbuilder.current_tab == "singleplayer" then
1081                 menu.update_gametype()
1082         end
1083         
1084         tabbuilder.old_tab = tabbuilder.current_tab
1085 end
1086
1087 --------------------------------------------------------------------------------
1088 function tabbuilder.init()
1089         tabbuilder.current_tab = engine.setting_get("main_menu_tab")
1090         
1091         if tabbuilder.current_tab == nil or
1092                 tabbuilder.current_tab == "" then
1093                 tabbuilder.current_tab = "singleplayer"
1094                 engine.setting_set("main_menu_tab",tabbuilder.current_tab)
1095         end
1096         
1097         
1098         --initialize tab buttons
1099         tabbuilder.last_tab = nil
1100         tabbuilder.show_buttons = true
1101         
1102         tabbuilder.current_buttons = {}
1103         table.insert(tabbuilder.current_buttons,{name="singleplayer", caption="Singleplayer"})
1104         table.insert(tabbuilder.current_buttons,{name="multiplayer", caption="Client"})
1105         table.insert(tabbuilder.current_buttons,{name="server", caption="Server"})
1106         table.insert(tabbuilder.current_buttons,{name="settings", caption="Settings"})
1107         
1108         if engine.setting_getbool("main_menu_game_mgr") then
1109                 table.insert(tabbuilder.current_buttons,{name="game_mgr", caption="Games"})
1110         end
1111         
1112         if engine.setting_getbool("main_menu_mod_mgr") then
1113                 table.insert(tabbuilder.current_buttons,{name="mod_mgr", caption="Mods"})
1114         end
1115         table.insert(tabbuilder.current_buttons,{name="credits", caption="Credits"})
1116         
1117         
1118         for i=1,#tabbuilder.current_buttons,1 do
1119                 if tabbuilder.current_buttons[i].name == tabbuilder.current_tab then
1120                         tabbuilder.last_tab_index = i
1121                 end
1122         end
1123         
1124         menu.update_gametype()
1125 end
1126
1127 --------------------------------------------------------------------------------
1128 function tabbuilder.tab_multiplayer()
1129
1130         local retval =
1131                 "vertlabel[0,-0.25;CLIENT]" ..
1132                 "label[1,-0.25;Favorites:]"..
1133                 "label[1,4.25;Address/Port]"..
1134                 "label[9,0;Name/Password]" ..
1135                 "field[1.25,5.25;5.5,0.5;te_address;;" ..engine.setting_get("address") .."]" ..
1136                 "field[6.75,5.25;2.25,0.5;te_port;;" ..engine.setting_get("port") .."]" ..
1137                 "button[6.45,3.95;2.25,0.5;btn_delete_favorite;Delete]" ..
1138                 "button[9,4.95;2.5,0.5;btn_mp_connect;Connect]" ..
1139                 "field[9.25,1;2.5,0.5;te_name;;" ..engine.setting_get("name") .."]" ..
1140                 "pwdfield[9.25,1.75;2.5,0.5;te_pwd;]" ..
1141                 "checkbox[1,3.6;cb_public_serverlist;Public Serverlist;" ..
1142                 dump(engine.setting_getbool("public_serverlist")) .. "]" ..
1143                 "textlist[1,0.35;7.5,3.35;favourites;"
1144
1145         if #menu.favorites > 0 then
1146                 retval = retval .. render_favourite(menu.favorites[1])
1147                 
1148                 for i=2,#menu.favorites,1 do
1149                         retval = retval .. "," .. render_favourite(menu.favorites[i])
1150                 end
1151         end
1152         
1153         print("cfav: " .. dump(menu.fav_selected))
1154         if menu.fav_selected ~= nil then
1155                 retval = retval .. ";" .. menu.fav_selected .. "]"
1156         else
1157                 retval = retval .. ";0]"
1158         end
1159
1160         return retval
1161 end
1162
1163 --------------------------------------------------------------------------------
1164 function tabbuilder.tab_server()
1165         local index = engine.setting_get("main_menu_last_world_idx")
1166         
1167         if index == nil then
1168                 index = 0
1169         end
1170         
1171         local retval = 
1172                 "button[4,4.15;2.6,0.5;world_delete;Delete]" ..
1173                 "button[6.5,4.15;2.8,0.5;world_create;New]" ..
1174                 "button[9.2,4.15;2.55,0.5;world_configure;Configure]" ..
1175                 "button[8.5,4.9;3.25,0.5;start_server;Start Game]" ..
1176                 "label[4,-0.25;Select World:]"..
1177                 "vertlabel[0,-0.25;START SERVER]" ..
1178                 "checkbox[0.5,0.25;cb_creative_mode;Creative Mode;" ..
1179                 dump(engine.setting_getbool("creative_mode")) .. "]"..
1180                 "checkbox[0.5,0.7;cb_enable_damage;Enable Damage;" ..
1181                 dump(engine.setting_getbool("enable_damage")) .. "]"..
1182                 "checkbox[0.5,1.15;cb_server_announce;Public;" ..
1183                 dump(engine.setting_getbool("server_announce")) .. "]"..
1184                 "field[0.8,3.2;3,0.5;te_playername;Name;" ..
1185                 engine.setting_get("name") .. "]" ..
1186                 "pwdfield[0.8,4.2;3,0.5;te_passwd;Password]" ..
1187                 "field[0.8,5.2;3,0.5;te_serverport;Server Port;30000]" ..
1188                 "textlist[4,0.25;7.5,3.7;srv_worlds;"
1189         
1190         if #menu.worldlist > 0 then
1191                 retval = retval .. menu.worldlist[1].name .. 
1192                                                 " \\[" .. menu.worldlist[1].gameid .. "\\]"
1193                                 
1194                 for i=2,#menu.worldlist,1 do
1195                         retval = retval .. "," .. menu.worldlist[i].name .. 
1196                                                 " \\[" .. menu.worldlist[i].gameid .. "\\]"
1197                 end
1198         end
1199                                 
1200         retval = retval .. ";" .. index .. "]"
1201                 
1202         return retval
1203 end
1204
1205 --------------------------------------------------------------------------------
1206 function tabbuilder.tab_settings()
1207         return  "vertlabel[0,0;SETTINGS]" ..
1208                         "checkbox[1,0.75;cb_fancy_trees;Fancy trees;"           .. dump(engine.setting_getbool("new_style_leaves"))     .. "]"..
1209                         "checkbox[1,1.25;cb_smooth_lighting;Smooth Lighting;".. dump(engine.setting_getbool("smooth_lighting")) .. "]"..
1210                         "checkbox[1,1.75;cb_3d_clouds;3D Clouds;"                       .. dump(engine.setting_getbool("enable_3d_clouds"))     .. "]"..
1211                         "checkbox[1,2.25;cb_opaque_water;Opaque Water;"                 .. dump(engine.setting_getbool("opaque_water"))         .. "]"..
1212                         
1213                         "checkbox[4,0.75;cb_mipmapping;Mip-Mapping;"            .. dump(engine.setting_getbool("mip_map"))                      .. "]"..
1214                         "checkbox[4,1.25;cb_anisotrophic;Anisotropic Filtering;".. dump(engine.setting_getbool("anisotropic_filter"))   .. "]"..
1215                         "checkbox[4,1.75;cb_bilinear;Bi-Linear Filtering;"      .. dump(engine.setting_getbool("bilinear_filter"))      .. "]"..
1216                         "checkbox[4,2.25;cb_trilinear;Tri-Linear Filtering;"    .. dump(engine.setting_getbool("trilinear_filter"))     .. "]"..
1217                         
1218                         "checkbox[7.5,0.75;cb_shaders;Shaders;"                         .. dump(engine.setting_getbool("enable_shaders"))               .. "]"..
1219                         "checkbox[7.5,1.25;cb_pre_ivis;Preload item visuals;".. dump(engine.setting_getbool("preload_item_visuals"))    .. "]"..
1220                         "checkbox[7.5,1.75;cb_particles;Enable Particles;"      .. dump(engine.setting_getbool("enable_particles"))     .. "]"..
1221                         "checkbox[7.5,2.25;cb_finite_liquid;Finite Liquid;"     .. dump(engine.setting_getbool("liquid_finite"))                .. "]"..
1222                         
1223                         "button[1,3.75;2.25,0.5;btn_change_keys;Change keys]"
1224 end
1225
1226 --------------------------------------------------------------------------------
1227 function tabbuilder.tab_singleplayer()
1228         local index = engine.setting_get("main_menu_singleplayer_world_idx")
1229
1230         if index == nil then
1231                 index = 0
1232         end
1233
1234         return  "button[4,4.15;2.6,0.5;world_delete;Delete]" ..
1235                         "button[6.5,4.15;2.8,0.5;world_create;New]" ..
1236                         "button[9.2,4.15;2.55,0.5;world_configure;Configure]" ..
1237                         "button[8.5,4.95;3.25,0.5;play;Play]" ..
1238                         "label[4,-0.25;Select World:]"..
1239                         "vertlabel[0,-0.25;SINGLE PLAYER]" ..
1240                         "checkbox[0.5,0.25;cb_creative_mode;Creative Mode;" ..
1241                         dump(engine.setting_getbool("creative_mode")) .. "]"..
1242                         "checkbox[0.5,0.7;cb_enable_damage;Enable Damage;" ..
1243                         dump(engine.setting_getbool("enable_damage")) .. "]"..
1244                         "textlist[4,0.25;7.5,3.7;sp_worlds;" ..
1245                         menu.filtered_game_list() ..
1246                         ";" .. index .. "]" ..
1247                         menubar.formspec
1248 end
1249
1250 --------------------------------------------------------------------------------
1251 function tabbuilder.tab_credits()
1252         return  "vertlabel[0,-0.5;CREDITS]" ..
1253                         "label[0.5,3;Minetest " .. engine.get_version() .. "]" ..
1254                         "label[0.5,3.3;http://minetest.net]" .. 
1255                         "image[0.5,1;" .. menu.defaulttexturedir .. "logo.png]" ..
1256                         "textlist[3.5,-0.25;8.5,5.8;list_credits;" ..
1257                         "#FFFF00Core Developers," ..
1258                         "Perttu Ahola (celeron55) <celeron55@gmail.com>,"..
1259                         "Ryan Kwolek (kwolekr) <kwolekr@minetest.net>,"..
1260                         "PilzAdam <pilzadam@minetest.net>," ..
1261                         "IIya Zhuravlev (thexyz) <xyz@minetest.net>,"..
1262                         "Lisa Milne (darkrose) <lisa@ltmnet.com>,"..
1263                         "Maciej Kasatkin (RealBadAngel) <mk@realbadangel.pl>,"..
1264                         "proller <proler@gmail.com>,"..
1265                         "sfan5 <sfan5@live.de>,"..
1266                         "kahrl <kahrl@gmx.net>,"..
1267                         ","..
1268                         "#FFFF00Active Contributors," ..
1269                         "sapier,"..
1270                         "Vanessa Ezekowitz (VanessaE) <vanessaezekowitz@gmail.com>,"..
1271                         "Jurgen Doser (doserj) <jurgen.doser@gmail.com>,"..
1272                         "Jeija <jeija@mesecons.net>,"..
1273                         "MirceaKitsune <mirceakitsune@gmail.com>,"..
1274                         "ShadowNinja,"..
1275                         "dannydark <the_skeleton_of_a_child@yahoo.co.uk>,"..
1276                         "0gb.us <0gb.us@0gb.us>,"..
1277                         "," ..
1278                         "#FFFF00Previous Contributors," ..
1279                         "Guiseppe Bilotta (Oblomov) <guiseppe.bilotta@gmail.com>,"..
1280                         "Jonathan Neuschafer <j.neuschaefer@gmx.net>,"..
1281                         "Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net>,"..
1282                         "Constantin Wenger (SpeedProg) <constantin.wenger@googlemail.com>,"..
1283                         "matttpt <matttpt@gmail.com>,"..
1284                         "JacobF <queatz@gmail.com>,"..
1285                         ";0;true]"
1286 end
1287
1288 --------------------------------------------------------------------------------
1289 function tabbuilder.checkretval(retval)
1290
1291         if retval ~= nil then
1292                 if retval.current_tab ~= nil then
1293                         tabbuilder.current_tab = retval.current_tab
1294                 end
1295                 
1296                 if retval.is_dialog ~= nil then
1297                         tabbuilder.is_dialog = retval.is_dialog
1298                 end
1299                 
1300                 if retval.show_buttons ~= nil then
1301                         tabbuilder.show_buttons = retval.show_buttons
1302                 end
1303                 
1304                 if retval.skipformupdate ~= nil then
1305                         tabbuilder.skipformupdate = retval.skipformupdate
1306                 end
1307         end
1308 end
1309
1310 --------------------------------------------------------------------------------
1311 --------------------------------------------------------------------------------
1312 -- initialize callbacks
1313 --------------------------------------------------------------------------------
1314 --------------------------------------------------------------------------------
1315 engine.button_handler = function(fields)
1316         --print("Buttonhandler: tab: " .. tabbuilder.current_tab .. " fields: " .. dump(fields))
1317         
1318         if fields["btn_error_confirm"] then
1319                 gamedata.errormessage = nil
1320         end
1321         
1322         local retval = modmgr.handle_buttons(tabbuilder.current_tab,fields)
1323         tabbuilder.checkretval(retval)
1324         
1325         retval = gamemgr.handle_buttons(tabbuilder.current_tab,fields)
1326         tabbuilder.checkretval(retval)
1327         
1328         retval = modstore.handle_buttons(tabbuilder.current_tab,fields)
1329         tabbuilder.checkretval(retval)
1330         
1331         if tabbuilder.current_tab == "dialog_create_world" then
1332                 tabbuilder.handle_create_world_buttons(fields)
1333         end
1334         
1335         if tabbuilder.current_tab == "dialog_delete_world" then
1336                 tabbuilder.handle_delete_world_buttons(fields)
1337         end
1338         
1339         if tabbuilder.current_tab == "singleplayer" then
1340                 tabbuilder.handle_singleplayer_buttons(fields)
1341         end
1342         
1343         if tabbuilder.current_tab == "multiplayer" then
1344                 tabbuilder.handle_multiplayer_buttons(fields)
1345         end
1346         
1347         if tabbuilder.current_tab == "settings" then
1348                 tabbuilder.handle_settings_buttons(fields)
1349         end
1350         
1351         if tabbuilder.current_tab == "server" then
1352                 tabbuilder.handle_server_buttons(fields)
1353         end
1354         
1355         --tab buttons
1356         tabbuilder.handle_tab_buttons(fields)
1357         
1358         --menubar buttons
1359         menubar.handle_buttons(fields)
1360         
1361         if not tabbuilder.skipformupdate then
1362                 --update menu
1363                 update_menu()
1364         else
1365                 tabbuilder.skipformupdate = false
1366         end
1367 end
1368
1369 --------------------------------------------------------------------------------
1370 engine.event_handler = function(event)
1371         if event == "MenuQuit" then
1372                 if tabbuilder.is_dialog then
1373                         tabbuilder.is_dialog = false
1374                         tabbuilder.show_buttons = true
1375                         tabbuilder.current_tab = engine.setting_get("main_menu_tab")
1376                         update_menu()
1377                 else
1378                         engine.close()
1379                 end
1380         end
1381 end
1382
1383 --------------------------------------------------------------------------------
1384 --------------------------------------------------------------------------------
1385 -- menu startup
1386 --------------------------------------------------------------------------------
1387 --------------------------------------------------------------------------------
1388 init_globals()
1389 menu.init()
1390 tabbuilder.init()
1391 menubar.refresh()
1392 modstore.init()
1393 update_menu()