]> git.lizzy.rs Git - minetest.git/blob - src/guiMainMenu.cpp
Add a list of servers to the "Multiplayer" tab
[minetest.git] / src / guiMainMenu.cpp
1 /*
2 Minetest-c55
3 Copyright (C) 2010-12 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "guiMainMenu.h"
21 #include "guiKeyChangeMenu.h"
22 #include "guiCreateWorld.h"
23 #include "guiMessageMenu.h"
24 #include "guiConfirmMenu.h"
25 #include "debug.h"
26 #include "serialization.h"
27 #include <string>
28 #include <IGUICheckBox.h>
29 #include <IGUIEditBox.h>
30 #include <IGUIButton.h>
31 #include <IGUIStaticText.h>
32 #include <IGUIFont.h>
33 #include <IGUIListBox.h>
34 #include <IGUITabControl.h>
35 #include <IGUIImage.h>
36 // For IGameCallback
37 #include "guiPauseMenu.h"
38 #include "gettext.h"
39 #include "tile.h" // getTexturePath
40 #include "filesys.h"
41 #include "util/string.h"
42 #include "subgame.h"
43
44 struct CreateWorldDestMainMenu : public CreateWorldDest
45 {
46         CreateWorldDestMainMenu(GUIMainMenu *menu):
47                 m_menu(menu)
48         {}
49         void accepted(std::wstring name, std::string gameid)
50         {
51                 std::string name_narrow = wide_to_narrow(name);
52                 if(!string_allowed_blacklist(name_narrow, WORLDNAME_BLACKLISTED_CHARS))
53                 {
54                         m_menu->displayMessageMenu(wgettext("Cannot create world: Name contains invalid characters"));
55                         return;
56                 }
57                 std::vector<WorldSpec> worlds = getAvailableWorlds();
58                 for(std::vector<WorldSpec>::iterator i = worlds.begin();
59                     i != worlds.end(); i++)
60                 {
61                         if((*i).name == name_narrow)
62                         {
63                                 m_menu->displayMessageMenu(wgettext("Cannot create world: A world by this name already exists"));
64                                 return;
65                         }
66                 }
67                 m_menu->createNewWorld(name, gameid);
68         }
69         GUIMainMenu *m_menu;
70 };
71
72 struct ConfirmDestDeleteWorld : public ConfirmDest
73 {
74         ConfirmDestDeleteWorld(WorldSpec spec, GUIMainMenu *menu,
75                         const std::vector<std::string> &paths):
76                 m_spec(spec),
77                 m_menu(menu),
78                 m_paths(paths)
79         {}
80         void answer(bool answer)
81         {
82                 if(answer == false)
83                         return;
84                 m_menu->deleteWorld(m_paths);
85         }
86         WorldSpec m_spec;
87         GUIMainMenu *m_menu;
88         std::vector<std::string> m_paths;
89 };
90
91 enum
92 {
93         GUI_ID_QUIT_BUTTON = 101,
94         GUI_ID_NAME_INPUT,
95         GUI_ID_ADDRESS_INPUT,
96         GUI_ID_PORT_INPUT,
97         GUI_ID_FANCYTREE_CB,
98         GUI_ID_SMOOTH_LIGHTING_CB,
99         GUI_ID_3D_CLOUDS_CB,
100         GUI_ID_OPAQUE_WATER_CB,
101         GUI_ID_MIPMAP_CB,
102         GUI_ID_ANISOTROPIC_CB,
103         GUI_ID_BILINEAR_CB,
104         GUI_ID_TRILINEAR_CB,
105         GUI_ID_SHADERS_CB,
106         GUI_ID_PRELOAD_ITEM_VISUALS_CB,
107         GUI_ID_ENABLE_PARTICLES_CB,
108         GUI_ID_DAMAGE_CB,
109         GUI_ID_CREATIVE_CB,
110         GUI_ID_JOIN_GAME_BUTTON,
111         GUI_ID_CHANGE_KEYS_BUTTON,
112         GUI_ID_DELETE_WORLD_BUTTON,
113         GUI_ID_CREATE_WORLD_BUTTON,
114         GUI_ID_CONFIGURE_WORLD_BUTTON,
115         GUI_ID_WORLD_LISTBOX,
116         GUI_ID_TAB_CONTROL,
117         GUI_ID_SERVERLIST,
118         GUI_ID_SERVERLIST_TOGGLE,
119         GUI_ID_SERVERLIST_DELETE,
120 };
121
122 enum
123 {
124         TAB_SINGLEPLAYER=0,
125         TAB_MULTIPLAYER,
126         TAB_ADVANCED,
127         TAB_SETTINGS,
128         TAB_CREDITS
129 };
130
131 GUIMainMenu::GUIMainMenu(gui::IGUIEnvironment* env,
132                 gui::IGUIElement* parent, s32 id,
133                 IMenuManager *menumgr,
134                 MainMenuData *data,
135                 IGameCallback *gamecallback
136 ):
137         GUIModalMenu(env, parent, id, menumgr),
138         m_data(data),
139         m_accepted(false),
140         m_gamecallback(gamecallback),
141         m_is_regenerating(false)
142 {
143         assert(m_data);
144         this->env = env;
145         this->parent = parent;
146         this->id = id;
147         this->menumgr = menumgr;
148 }
149
150 GUIMainMenu::~GUIMainMenu()
151 {
152         removeChildren();
153 }
154
155 void GUIMainMenu::removeChildren()
156 {
157         const core::list<gui::IGUIElement*> &children = getChildren();
158         core::list<gui::IGUIElement*> children_copy;
159         for(core::list<gui::IGUIElement*>::ConstIterator
160                         i = children.begin(); i != children.end(); i++)
161         {
162                 children_copy.push_back(*i);
163         }
164         for(core::list<gui::IGUIElement*>::Iterator
165                         i = children_copy.begin();
166                         i != children_copy.end(); i++)
167         {
168                 (*i)->remove();
169         }
170 }
171
172 void GUIMainMenu::regenerateGui(v2u32 screensize)
173 {
174         m_is_regenerating = true;
175         /*
176                 Read stuff from elements into m_data
177         */
178         readInput(m_data);
179
180         /*
181                 Remove stuff
182         */
183         removeChildren();
184         
185         /*
186                 Calculate new sizes and positions
187         */
188         
189         v2s32 size(screensize.X, screensize.Y);
190
191         core::rect<s32> rect(
192                         screensize.X/2 - size.X/2,
193                         screensize.Y/2 - size.Y/2,
194                         screensize.X/2 + size.X/2,
195                         screensize.Y/2 + size.Y/2
196         );
197
198         DesiredRect = rect;
199         recalculateAbsolutePosition(false);
200
201         //v2s32 size = rect.getSize();
202
203         /*
204                 Add stuff
205         */
206
207         changeCtype("");
208
209         // Version
210         //if(m_data->selected_tab != TAB_CREDITS)
211         {
212                 core::rect<s32> rect(0, 0, size.X, 40);
213                 rect += v2s32(4, 0);
214                 Environment->addStaticText(narrow_to_wide(
215                                 "Minetest " VERSION_STRING).c_str(),
216                                 rect, false, true, this, -1);
217         }
218
219         //v2s32 center(size.X/2, size.Y/2);
220         v2s32 c800(size.X/2-400, size.Y/2-300);
221         
222         m_topleft_client = c800 + v2s32(90, 70+50+30);
223         m_size_client = v2s32(620, 270);
224
225         m_size_server = v2s32(620, 140);
226
227         if(m_data->selected_tab == TAB_ADVANCED)
228         {
229                 m_topleft_client = c800 + v2s32(90, 70+50+30);
230                 m_size_client = v2s32(620, 200);
231
232                 m_size_server = v2s32(620, 140);
233         }
234
235         m_topleft_server = m_topleft_client + v2s32(0, m_size_client.Y+20);
236         
237         // Tabs
238 #if 1
239         {
240                 core::rect<s32> rect(0, 0, m_size_client.X, 30);
241                 rect += m_topleft_client + v2s32(0, -30);
242                 gui::IGUITabControl *e = Environment->addTabControl(
243                                 rect, this, true, true, GUI_ID_TAB_CONTROL);
244                 e->addTab(wgettext("Singleplayer"));
245                 e->addTab(wgettext("Multiplayer"));
246                 e->addTab(wgettext("Advanced"));
247                 e->addTab(wgettext("Settings"));
248                 e->addTab(wgettext("Credits"));
249                 e->setActiveTab(m_data->selected_tab);
250         }
251 #endif
252         
253         if(m_data->selected_tab == TAB_SINGLEPLAYER)
254         {
255                 // HYBRID
256                 {
257                         core::rect<s32> rect(0, 0, 10, m_size_client.Y);
258                         rect += m_topleft_client + v2s32(15, 0);
259                         //const wchar_t *text = L"H\nY\nB\nR\nI\nD";
260                         const wchar_t *text = L"T\nA\nP\nE\n\nA\nN\nD\n\nG\nL\nU\nE";
261                         gui::IGUIStaticText *t =
262                         Environment->addStaticText(text, rect, false, false, this, -1);
263                         t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
264                 }
265                 u32 bs = 5;
266                 // World selection listbox
267                 u32 world_sel_h = 160;
268                 u32 world_sel_w = 365;
269                 //s32 world_sel_x = 50;
270                 s32 world_sel_x = m_size_client.X-world_sel_w-30;
271                 s32 world_sel_y = 30;
272                 u32 world_button_count = 3;
273                 u32 world_button_w = (world_sel_w)/world_button_count - bs
274                                 + bs/(world_button_count-1);
275                 {
276                         core::rect<s32> rect(0, 0, world_sel_w-4, 20);
277                         rect += m_topleft_client + v2s32(world_sel_x+4, world_sel_y-20);
278                         /*gui::IGUIStaticText *e =*/ Environment->addStaticText(
279                                         wgettext("Select World:"), 
280                                         rect, false, true, this, -1);
281                         /*e->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);*/
282                 }
283                 {
284                         core::rect<s32> rect(0, 0, world_sel_w, world_sel_h);
285                         rect += m_topleft_client + v2s32(world_sel_x, world_sel_y);
286                         gui::IGUIListBox *e = Environment->addListBox(rect, this,
287                                         GUI_ID_WORLD_LISTBOX);
288                         e->setDrawBackground(true);
289                         for(std::vector<WorldSpec>::const_iterator i = m_data->worlds.begin();
290                                         i != m_data->worlds.end(); i++){
291                                 e->addItem(narrow_to_wide(i->name+" ["+i->gameid+"]").c_str());
292                         }
293                         e->setSelected(m_data->selected_world);
294                         Environment->setFocus(e);
295                 }
296                 // Delete world button
297                 {
298                         core::rect<s32> rect(0, 0, world_button_w, 30);
299                         rect += m_topleft_client + v2s32(world_sel_x, world_sel_y+world_sel_h+0);
300                         Environment->addButton(rect, this, GUI_ID_DELETE_WORLD_BUTTON,
301                                   wgettext("Delete"));
302                 }
303                 // Create world button
304                 {
305                         core::rect<s32> rect(0, 0, world_button_w, 30);
306                         rect += m_topleft_client + v2s32(world_sel_x+world_button_w+bs, world_sel_y+world_sel_h+0);
307                         Environment->addButton(rect, this, GUI_ID_CREATE_WORLD_BUTTON,
308                                   wgettext("New"));
309                 }
310                 // Configure world button
311                 {
312                         core::rect<s32> rect(0, 0, world_button_w, 30);
313                         rect += m_topleft_client + v2s32(world_sel_x+(world_button_w+bs)*2,
314                                         world_sel_y+world_sel_h+0);
315                         Environment->addButton(rect, this, GUI_ID_CONFIGURE_WORLD_BUTTON,
316                                   wgettext("Configure"));
317                 }
318                 // Start game button
319                 {
320                         /*core::rect<s32> rect(0, 0, world_button_w, 30);
321                         rect += m_topleft_client + v2s32(world_sel_x+(world_button_w+bs)*3,
322                                         world_sel_y+world_sel_h+0);*/
323                         u32 bw = 160;
324                         /*core::rect<s32> rect(0, 0, bw, 30);
325                         rect += m_topleft_client + v2s32(m_size_client.X-bw-30,
326                                         m_size_client.Y-30-15);*/
327                         core::rect<s32> rect(0, 0, bw, 30);
328                         rect += m_topleft_client + v2s32(world_sel_x+world_sel_w-bw,
329                                         world_sel_y+world_sel_h+30+bs);
330                         Environment->addButton(rect, this,
331                                         GUI_ID_JOIN_GAME_BUTTON, wgettext("Play"));
332                 }
333                 // Options
334                 s32 option_x = 50;
335                 //s32 option_x = 50+world_sel_w+20;
336                 s32 option_y = 30;
337                 u32 option_w = 150;
338                 {
339                         core::rect<s32> rect(0, 0, option_w, 30);
340                         rect += m_topleft_client + v2s32(option_x, option_y+20*0);
341                         Environment->addCheckBox(m_data->creative_mode, rect, this,
342                                         GUI_ID_CREATIVE_CB, wgettext("Creative Mode"));
343                 }
344                 {
345                         core::rect<s32> rect(0, 0, option_w, 30);
346                         rect += m_topleft_client + v2s32(option_x, option_y+20*1);
347                         Environment->addCheckBox(m_data->enable_damage, rect, this,
348                                         GUI_ID_DAMAGE_CB, wgettext("Enable Damage"));
349                 }
350                 changeCtype("C");
351         }
352         else if(m_data->selected_tab == TAB_MULTIPLAYER)
353         {
354                 changeCtype("");
355                 // CLIENT
356                 {
357                         core::rect<s32> rect(0, 0, 10, m_size_client.Y);
358                         rect += m_topleft_client + v2s32(15, 0);
359                         const wchar_t *text = L"C\nL\nI\nE\nN\nT";
360                         gui::IGUIStaticText *t =
361                         Environment->addStaticText(text, rect, false, false, this, -1);
362                         t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
363                 }
364                 // Nickname + password
365                 {
366                         core::rect<s32> rect(0, 0, 110, 20);
367                         rect += m_topleft_client + v2s32(m_size_client.X-60-100, 10+6);
368                         Environment->addStaticText(wgettext("Name/Password"), 
369                                 rect, false, true, this, -1);
370                 }
371                 changeCtype("C");
372                 {
373                         core::rect<s32> rect(0, 0, 120, 30);
374                         rect += m_topleft_client + v2s32(m_size_client.X-60-100, 50);
375                         gui::IGUIElement *e = 
376                         Environment->addEditBox(m_data->name.c_str(), rect, true, this, GUI_ID_NAME_INPUT);
377                         if(m_data->name == L"")
378                                 Environment->setFocus(e);
379                 }
380                 {
381                         core::rect<s32> rect(0, 0, 120, 30);
382                         rect += m_topleft_client + v2s32(m_size_client.X-60-100, 90);
383                         gui::IGUIEditBox *e =
384                         Environment->addEditBox(L"", rect, true, this, 264);
385                         e->setPasswordBox(true);
386                         if(m_data->name != L"" && m_data->address != L"")
387                                 Environment->setFocus(e);
388
389                 }
390                 changeCtype("");
391                 // Server List
392                 {
393                         core::rect<s32> rect(0, 0, 390, 160);
394                         rect += m_topleft_client + v2s32(50, 10);
395                         gui::IGUIListBox *e = Environment->addListBox(rect, this,
396                                         GUI_ID_SERVERLIST);
397                         e->setDrawBackground(true);
398                         if (m_data->serverlist_show_available == false)
399                                 m_data->servers = ServerList::getLocal();
400                         updateGuiServerList();
401                         e->setSelected(0);
402                 }
403                 // Address + port
404                 {
405                         core::rect<s32> rect(0, 0, 110, 20);
406                         rect += m_topleft_client + v2s32(50, m_size_client.Y-50-15+6);
407                         Environment->addStaticText(wgettext("Address/Port"),
408                                 rect, false, true, this, -1);
409                 }
410                 changeCtype("C");
411                 {
412                         core::rect<s32> rect(0, 0, 260, 30);
413                         rect += m_topleft_client + v2s32(50, m_size_client.Y-25-15);
414                         gui::IGUIElement *e = 
415                         Environment->addEditBox(m_data->address.c_str(), rect, true,
416                                         this, GUI_ID_ADDRESS_INPUT);
417                         if(m_data->name != L"" && m_data->address == L"")
418                                 Environment->setFocus(e);
419                 }
420                 {
421                         core::rect<s32> rect(0, 0, 120, 30);
422                         rect += m_topleft_client + v2s32(50+260+10, m_size_client.Y-25-15);
423                         Environment->addEditBox(m_data->port.c_str(), rect, true,
424                                         this, GUI_ID_PORT_INPUT);
425                 }
426                 changeCtype("");
427                 #if USE_CURL
428                 // Toggle Serverlist (Favorites/Online)
429                 {
430                         core::rect<s32> rect(0, 0, 260, 30);
431                         rect += m_topleft_client + v2s32(50,
432                                         180);
433                         gui::IGUIButton *e = Environment->addButton(rect, this, GUI_ID_SERVERLIST_TOGGLE,
434                                 wgettext("Show Public"));
435                         e->setIsPushButton(true);
436                         if (m_data->serverlist_show_available)
437                         {
438                                 e->setText(wgettext("Show Favorites"));
439                                 e->setPressed();
440                         }
441                 }
442                 #endif
443                 // Delete Local Favorite
444                 {
445                         core::rect<s32> rect(0, 0, 120, 30);
446                         rect += m_topleft_client + v2s32(50+260+10, 180);
447                         gui::IGUIButton *e = Environment->addButton(rect, this, GUI_ID_SERVERLIST_DELETE,
448                                 wgettext("Delete"));
449                         if (m_data->serverlist_show_available) // Hidden on Show-Online mode
450                                 e->setVisible(false);
451                 }
452                 // Start game button
453                 {
454                         core::rect<s32> rect(0, 0, 120, 30);
455                         rect += m_topleft_client + v2s32(m_size_client.X-130-30,
456                                         m_size_client.Y-25-15);
457                         Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON,
458                                 wgettext("Connect"));
459                 }
460                 changeCtype("C");
461         }
462         else if(m_data->selected_tab == TAB_ADVANCED)
463         {
464                 changeCtype("");
465                 // CLIENT
466                 {
467                         core::rect<s32> rect(0, 0, 10, m_size_client.Y);
468                         rect += m_topleft_client + v2s32(15, 0);
469                         const wchar_t *text = L"C\nL\nI\nE\nN\nT";
470                         gui::IGUIStaticText *t =
471                         Environment->addStaticText(text, rect, false, false, this, -1);
472                         t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
473                 }
474                 // Nickname + password
475                 {
476                         core::rect<s32> rect(0, 0, 110, 20);
477                         rect += m_topleft_client + v2s32(35+30, 35+6);
478                         Environment->addStaticText(wgettext("Name/Password"), 
479                                 rect, false, true, this, -1);
480                 }
481                 changeCtype("C");
482                 {
483                         core::rect<s32> rect(0, 0, 230, 30);
484                         rect += m_topleft_client + v2s32(160+30, 35);
485                         gui::IGUIElement *e = 
486                         Environment->addEditBox(m_data->name.c_str(), rect, true, this, GUI_ID_NAME_INPUT);
487                         if(m_data->name == L"")
488                                 Environment->setFocus(e);
489                 }
490                 {
491                         core::rect<s32> rect(0, 0, 120, 30);
492                         rect += m_topleft_client + v2s32(m_size_client.X-60-100, 35);
493                         gui::IGUIEditBox *e =
494                         Environment->addEditBox(L"", rect, true, this, 264);
495                         e->setPasswordBox(true);
496                         if(m_data->name != L"" && m_data->address != L"")
497                                 Environment->setFocus(e);
498
499                 }
500                 changeCtype("");
501                 // Address + port
502                 {
503                         core::rect<s32> rect(0, 0, 110, 20);
504                         rect += m_topleft_client + v2s32(35+30, 75+6);
505                         Environment->addStaticText(wgettext("Address/Port"),
506                                 rect, false, true, this, -1);
507                 }
508                 changeCtype("C");
509                 {
510                         core::rect<s32> rect(0, 0, 230, 30);
511                         rect += m_topleft_client + v2s32(160+30, 75);
512                         gui::IGUIElement *e = 
513                         Environment->addEditBox(m_data->address.c_str(), rect, true,
514                                         this, GUI_ID_ADDRESS_INPUT);
515                         if(m_data->name != L"" && m_data->address == L"")
516                                 Environment->setFocus(e);
517                 }
518                 {
519                         core::rect<s32> rect(0, 0, 120, 30);
520                         rect += m_topleft_client + v2s32(m_size_client.X-60-100, 75);
521                         Environment->addEditBox(m_data->port.c_str(), rect, true,
522                                         this, GUI_ID_PORT_INPUT);
523                 }
524                 changeCtype("");
525                 {
526                         core::rect<s32> rect(0, 0, 400, 20);
527                         rect += m_topleft_client + v2s32(160+30, 75+35);
528                         Environment->addStaticText(wgettext("Leave address blank to start a local server."),
529                                 rect, false, true, this, -1);
530                 }
531                 // Start game button
532                 {
533                         core::rect<s32> rect(0, 0, 180, 30);
534                         rect += m_topleft_client + v2s32(m_size_client.X-180-30,
535                                         m_size_client.Y-30-20);
536                         Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON,
537                                 wgettext("Start Game / Connect"));
538                 }
539                 /*
540                         Server section
541                 */
542                 // SERVER
543                 {
544                         core::rect<s32> rect(0, 0, 10, m_size_server.Y);
545                         rect += m_topleft_server + v2s32(15, 0);
546                         const wchar_t *text = L"S\nE\nR\nV\nE\nR";
547                         gui::IGUIStaticText *t =
548                         Environment->addStaticText(text, rect, false, false, this, -1);
549                         t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
550                 }
551                 // Server parameters
552                 {
553                         core::rect<s32> rect(0, 0, 250, 30);
554                         rect += m_topleft_server + v2s32(30+20+250+20, 20);
555                         Environment->addCheckBox(m_data->creative_mode, rect, this, GUI_ID_CREATIVE_CB,
556                                 wgettext("Creative Mode"));
557                 }
558                 {
559                         core::rect<s32> rect(0, 0, 250, 30);
560                         rect += m_topleft_server + v2s32(30+20+250+20, 40);
561                         Environment->addCheckBox(m_data->enable_damage, rect, this, GUI_ID_DAMAGE_CB,
562                                 wgettext("Enable Damage"));
563                 }
564                 // Delete world button
565                 {
566                         core::rect<s32> rect(0, 0, 130, 30);
567                         rect += m_topleft_server + v2s32(30+20+250+20, 90);
568                         Environment->addButton(rect, this, GUI_ID_DELETE_WORLD_BUTTON,
569                                   wgettext("Delete world"));
570                 }
571                 // Create world button
572                 {
573                         core::rect<s32> rect(0, 0, 130, 30);
574                         rect += m_topleft_server + v2s32(30+20+250+20+140, 90);
575                         Environment->addButton(rect, this, GUI_ID_CREATE_WORLD_BUTTON,
576                                   wgettext("Create world"));
577                 }
578                 // World selection listbox
579                 {
580                         core::rect<s32> rect(0, 0, 250, 120);
581                         rect += m_topleft_server + v2s32(30+20, 10);
582                         gui::IGUIListBox *e = Environment->addListBox(rect, this,
583                                         GUI_ID_WORLD_LISTBOX);
584                         e->setDrawBackground(true);
585                         for(std::vector<WorldSpec>::const_iterator i = m_data->worlds.begin();
586                                         i != m_data->worlds.end(); i++){
587                                 e->addItem(narrow_to_wide(i->name+" ["+i->gameid+"]").c_str());
588                         }
589                         e->setSelected(m_data->selected_world);
590                 }
591                 changeCtype("C");
592         }
593         else if(m_data->selected_tab == TAB_SETTINGS)
594         {
595                 {
596                         core::rect<s32> rect(0, 0, 10, m_size_client.Y);
597                         rect += m_topleft_client + v2s32(15, 0);
598                         const wchar_t *text = L"S\nE\nT\nT\nI\nN\nG\nS";
599                         gui::IGUIStaticText *t =
600                         Environment->addStaticText(text, rect, false, false, this, -1);
601                         t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
602                 }
603                 s32 option_x = 70;
604                 s32 option_y = 50;
605                 u32 option_w = 150;
606                 {
607                         core::rect<s32> rect(0, 0, option_w, 30);
608                         rect += m_topleft_client + v2s32(option_x, option_y);
609                         Environment->addCheckBox(m_data->fancy_trees, rect, this,
610                                         GUI_ID_FANCYTREE_CB, wgettext("Fancy trees")); 
611                 }
612                 {
613                         core::rect<s32> rect(0, 0, option_w, 30);
614                         rect += m_topleft_client + v2s32(option_x, option_y+20);
615                         Environment->addCheckBox(m_data->smooth_lighting, rect, this,
616                                         GUI_ID_SMOOTH_LIGHTING_CB, wgettext("Smooth Lighting"));
617                 }
618                 {
619                         core::rect<s32> rect(0, 0, option_w, 30);
620                         rect += m_topleft_client + v2s32(option_x, option_y+20*2);
621                         Environment->addCheckBox(m_data->clouds_3d, rect, this,
622                                         GUI_ID_3D_CLOUDS_CB, wgettext("3D Clouds"));
623                 }
624                 {
625                         core::rect<s32> rect(0, 0, option_w, 30);
626                         rect += m_topleft_client + v2s32(option_x, option_y+20*3);
627                         Environment->addCheckBox(m_data->opaque_water, rect, this,
628                                         GUI_ID_OPAQUE_WATER_CB, wgettext("Opaque water"));
629                 }
630
631
632                 // Anisotropic/mipmap/bi-/trilinear settings
633
634                 {
635                         core::rect<s32> rect(0, 0, option_w+20, 30);
636                         rect += m_topleft_client + v2s32(option_x+175, option_y);
637                         Environment->addCheckBox(m_data->mip_map, rect, this,
638                                        GUI_ID_MIPMAP_CB, wgettext("Mip-Mapping"));
639                 }
640
641                 {
642                         core::rect<s32> rect(0, 0, option_w+20, 30);
643                         rect += m_topleft_client + v2s32(option_x+175, option_y+20);
644                         Environment->addCheckBox(m_data->anisotropic_filter, rect, this,
645                                        GUI_ID_ANISOTROPIC_CB, wgettext("Anisotropic Filtering"));
646                 }
647
648                 {
649                         core::rect<s32> rect(0, 0, option_w+20, 30);
650                         rect += m_topleft_client + v2s32(option_x+175, option_y+20*2);
651                         Environment->addCheckBox(m_data->bilinear_filter, rect, this,
652                                        GUI_ID_BILINEAR_CB, wgettext("Bi-Linear Filtering"));
653                 }
654
655                 {
656                         core::rect<s32> rect(0, 0, option_w+20, 30);
657                         rect += m_topleft_client + v2s32(option_x+175, option_y+20*3);
658                         Environment->addCheckBox(m_data->trilinear_filter, rect, this,
659                                        GUI_ID_TRILINEAR_CB, wgettext("Tri-Linear Filtering"));
660                 }
661
662                 // shader/on demand image loading/particles settings
663                 {
664                         core::rect<s32> rect(0, 0, option_w+20, 30);
665                         rect += m_topleft_client + v2s32(option_x+175*2, option_y);
666                         Environment->addCheckBox(m_data->enable_shaders, rect, this,
667                                         GUI_ID_SHADERS_CB, wgettext("Shaders"));
668                 }
669
670                 {
671                         core::rect<s32> rect(0, 0, option_w+20+20, 30);
672                         rect += m_topleft_client + v2s32(option_x+175*2, option_y+20);
673                         Environment->addCheckBox(m_data->preload_item_visuals, rect, this,
674                                         GUI_ID_PRELOAD_ITEM_VISUALS_CB, wgettext("Preload item visuals"));
675                 }
676
677                 {
678                         core::rect<s32> rect(0, 0, option_w+20+20, 30);
679                         rect += m_topleft_client + v2s32(option_x+175*2, option_y+20*2);
680                         Environment->addCheckBox(m_data->enable_particles, rect, this,
681                                         GUI_ID_ENABLE_PARTICLES_CB, wgettext("Enable Particles"));
682                 }
683
684                 // Key change button
685                 {
686                         core::rect<s32> rect(0, 0, 120, 30);
687                         /*rect += m_topleft_client + v2s32(m_size_client.X-120-30,
688                                         m_size_client.Y-30-20);*/
689                         rect += m_topleft_client + v2s32(option_x, option_y+120);
690                         Environment->addButton(rect, this,
691                                         GUI_ID_CHANGE_KEYS_BUTTON, wgettext("Change keys"));
692                 }
693                 changeCtype("C");
694         }
695         else if(m_data->selected_tab == TAB_CREDITS)
696         {
697                 // CREDITS
698                 {
699                         core::rect<s32> rect(0, 0, 10, m_size_client.Y);
700                         rect += m_topleft_client + v2s32(15, 0);
701                         const wchar_t *text = L"C\nR\nE\nD\nI\nT\nS";
702                         gui::IGUIStaticText *t =
703                         Environment->addStaticText(text, rect, false, false, this, -1);
704                         t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
705                 }
706                 {
707                         core::rect<s32> rect(0, 0, 454, 250);
708                         rect += m_topleft_client + v2s32(110, 50+35);
709                         Environment->addStaticText(narrow_to_wide(
710                         "Minetest " VERSION_STRING "\n"
711                         "http://minetest.net/\n"
712                         "\n"
713                         "by Perttu Ahola <celeron55@gmail.com>\n"
714                         "and contributors: PilzAdam, Taoki, tango_, kahrl (kaaaaaahrl?), darkrose, matttpt, erlehmann, SpeedProg, JacobF, teddydestodes, marktraceur, Jonathan Neuschäfer, thexyz, VanessaE, sfan5... and tens of more random people."
715                         ).c_str(), rect, false, true, this, -1);
716                 }
717         }
718
719         m_is_regenerating = false;
720 }
721
722 void GUIMainMenu::drawMenu()
723 {
724         gui::IGUISkin* skin = Environment->getSkin();
725         if (!skin)
726                 return;
727         video::IVideoDriver* driver = Environment->getVideoDriver();
728         
729         /*video::SColor bgcolor(140,0,0,0);
730         driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect);*/
731
732         video::SColor bgcolor(140,0,0,0);
733
734         if(getTab() == TAB_SINGLEPLAYER)
735         {
736                 {
737                         core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y);
738                         rect += AbsoluteRect.UpperLeftCorner + m_topleft_client;
739                         driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
740                 }
741         }
742         else if(getTab() == TAB_MULTIPLAYER)
743         {
744                 {
745                         core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y);
746                         rect += AbsoluteRect.UpperLeftCorner + m_topleft_client;
747                         driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
748                 }
749         }
750         else if(getTab() == TAB_ADVANCED)
751         {
752                 {
753                         core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y);
754                         rect += AbsoluteRect.UpperLeftCorner + m_topleft_client;
755                         driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
756                 }
757                 {
758                         core::rect<s32> rect(0, 0, m_size_server.X, m_size_server.Y);
759                         rect += AbsoluteRect.UpperLeftCorner + m_topleft_server;
760                         driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
761                 }
762         }
763         else if(getTab() == TAB_SETTINGS)
764         {
765                 {
766                         core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y);
767                         rect += AbsoluteRect.UpperLeftCorner + m_topleft_client;
768                         driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
769                 }
770         }
771         else if(getTab() == TAB_CREDITS)
772         {
773                 {
774                         core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y);
775                         rect += AbsoluteRect.UpperLeftCorner + m_topleft_client;
776                         driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
777                 }
778                 video::ITexture *logotexture =
779                                 driver->getTexture(getTexturePath("menulogo.png").c_str());
780                 if(logotexture)
781                 {
782                         v2s32 logosize(logotexture->getOriginalSize().Width,
783                                         logotexture->getOriginalSize().Height);
784                         logosize *= 2;
785                         core::rect<s32> rect(0,0,logosize.X,logosize.Y);
786                         rect += AbsoluteRect.UpperLeftCorner + m_topleft_client;
787                         rect += v2s32(130, 50);
788                         driver->draw2DImage(logotexture, rect,
789                                 core::rect<s32>(core::position2d<s32>(0,0),
790                                 core::dimension2di(logotexture->getSize())),
791                                 NULL, NULL, true);
792                 }
793         }
794
795         gui::IGUIElement::draw();
796 }
797
798 void GUIMainMenu::readInput(MainMenuData *dst)
799 {
800         {
801                 gui::IGUIElement *e = getElementFromId(GUI_ID_TAB_CONTROL);
802                 if(e != NULL && e->getType() == gui::EGUIET_TAB_CONTROL)
803                         dst->selected_tab = ((gui::IGUITabControl*)e)->getActiveTab();
804         }
805         if(dst->selected_tab == TAB_SINGLEPLAYER)
806         {
807                 dst->simple_singleplayer_mode = true;
808         }
809         else
810         {
811                 dst->simple_singleplayer_mode = false;
812                 {
813                         gui::IGUIElement *e = getElementFromId(GUI_ID_NAME_INPUT);
814                         if(e != NULL)
815                                 dst->name = e->getText();
816                 }
817                 {
818                         gui::IGUIElement *e = getElementFromId(264);
819                         if(e != NULL)
820                                 dst->password = e->getText();
821                 }
822                 {
823                         gui::IGUIElement *e = getElementFromId(GUI_ID_ADDRESS_INPUT);
824                         if(e != NULL)
825                                 dst->address = e->getText();
826                 }
827                 {
828                         gui::IGUIElement *e = getElementFromId(GUI_ID_PORT_INPUT);
829                         if(e != NULL)
830                                 dst->port = e->getText();
831                 }
832         }
833         {
834                 gui::IGUIElement *e = getElementFromId(GUI_ID_CREATIVE_CB);
835                 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
836                         dst->creative_mode = ((gui::IGUICheckBox*)e)->isChecked();
837         }
838         {
839                 gui::IGUIElement *e = getElementFromId(GUI_ID_DAMAGE_CB);
840                 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
841                         dst->enable_damage = ((gui::IGUICheckBox*)e)->isChecked();
842         }
843         {
844                 gui::IGUIElement *e = getElementFromId(GUI_ID_FANCYTREE_CB);
845                 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
846                         dst->fancy_trees = ((gui::IGUICheckBox*)e)->isChecked();
847         }
848         {
849                 gui::IGUIElement *e = getElementFromId(GUI_ID_SMOOTH_LIGHTING_CB);
850                 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
851                         dst->smooth_lighting = ((gui::IGUICheckBox*)e)->isChecked();
852         }
853         {
854                 gui::IGUIElement *e = getElementFromId(GUI_ID_3D_CLOUDS_CB);
855                 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
856                         dst->clouds_3d = ((gui::IGUICheckBox*)e)->isChecked();
857         }
858         {
859                 gui::IGUIElement *e = getElementFromId(GUI_ID_OPAQUE_WATER_CB);
860                 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
861                         dst->opaque_water = ((gui::IGUICheckBox*)e)->isChecked();
862         }
863
864         {
865                 gui::IGUIElement *e = getElementFromId(GUI_ID_MIPMAP_CB);
866                 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
867                         dst->mip_map = ((gui::IGUICheckBox*)e)->isChecked();
868         }
869
870         {
871                 gui::IGUIElement *e = getElementFromId(GUI_ID_ANISOTROPIC_CB);
872                 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
873                         dst->anisotropic_filter = ((gui::IGUICheckBox*)e)->isChecked();
874         }
875
876         {
877                 gui::IGUIElement *e = getElementFromId(GUI_ID_BILINEAR_CB);
878                 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
879                         dst->bilinear_filter = ((gui::IGUICheckBox*)e)->isChecked();
880         }
881
882         {
883                 gui::IGUIElement *e = getElementFromId(GUI_ID_TRILINEAR_CB);
884                 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
885                         dst->trilinear_filter = ((gui::IGUICheckBox*)e)->isChecked();
886         }
887
888         {
889                 gui::IGUIElement *e = getElementFromId(GUI_ID_SHADERS_CB);
890                 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
891                         dst->enable_shaders = ((gui::IGUICheckBox*)e)->isChecked() ? 2 : 0;
892         }
893
894         {
895                 gui::IGUIElement *e = getElementFromId(GUI_ID_PRELOAD_ITEM_VISUALS_CB);
896                 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
897                         dst->preload_item_visuals = ((gui::IGUICheckBox*)e)->isChecked();
898         }
899
900         {
901                 gui::IGUIElement *e = getElementFromId(GUI_ID_ENABLE_PARTICLES_CB);
902                 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
903                         dst->enable_particles = ((gui::IGUICheckBox*)e)->isChecked();
904         }
905
906         {
907                 gui::IGUIElement *e = getElementFromId(GUI_ID_WORLD_LISTBOX);
908                 if(e != NULL && e->getType() == gui::EGUIET_LIST_BOX)
909                         dst->selected_world = ((gui::IGUIListBox*)e)->getSelected();
910         }
911         {
912                 ServerListSpec server =
913                 getServerListSpec(wide_to_narrow(dst->address), wide_to_narrow(dst->port));
914                 dst->servername = server.name;
915                 dst->serverdescription = server.description;
916         }
917 }
918
919 void GUIMainMenu::acceptInput()
920 {
921         readInput(m_data);
922         m_accepted = true;
923 }
924
925 bool GUIMainMenu::OnEvent(const SEvent& event)
926 {
927         if(event.EventType==EET_KEY_INPUT_EVENT)
928         {
929                 if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown)
930                 {
931                         m_gamecallback->exitToOS();
932                         quitMenu();
933                         return true;
934                 }
935                 if(event.KeyInput.Key==KEY_RETURN && event.KeyInput.PressedDown)
936                 {
937                         acceptInput();
938                         quitMenu();
939                         return true;
940                 }
941         }
942         if(event.EventType==EET_GUI_EVENT)
943         {
944                 if(event.GUIEvent.EventType==gui::EGET_ELEMENT_FOCUS_LOST
945                                 && isVisible())
946                 {
947                         if(!canTakeFocus(event.GUIEvent.Element))
948                         {
949                                 dstream<<"GUIMainMenu: Not allowing focus change."
950                                                 <<std::endl;
951                                 // Returning true disables focus change
952                                 return true;
953                         }
954                 }
955                 if(event.GUIEvent.EventType==gui::EGET_TAB_CHANGED)
956                 {
957                         if(!m_is_regenerating)
958                                 regenerateGui(m_screensize_old);
959                         return true;
960                 }
961                 if(event.GUIEvent.EventType==gui::EGET_LISTBOX_CHANGED && event.GUIEvent.Caller->getID() == GUI_ID_SERVERLIST)
962                 {
963                         serverListOnSelected();
964                         return true;
965                 }
966                 if(event.GUIEvent.EventType==gui::EGET_BUTTON_CLICKED)
967                 {
968                         switch(event.GUIEvent.Caller->getID())
969                         {
970                         case GUI_ID_JOIN_GAME_BUTTON: {
971                                 MainMenuData cur;
972                                 readInput(&cur);
973                                 if (getTab() == TAB_MULTIPLAYER && cur.address == L"")
974                                 {
975                                         (new GUIMessageMenu(env, parent, -1, menumgr,
976                                                         wgettext("Address required."))
977                                                         )->drop();
978                                         return true;
979                                 }
980                                 acceptInput();
981                                 quitMenu();
982                                 return true;
983                         }
984                         case GUI_ID_CHANGE_KEYS_BUTTON: {
985                                 GUIKeyChangeMenu *kmenu = new GUIKeyChangeMenu(env, parent, -1,menumgr);
986                                 kmenu->drop();
987                                 return true;
988                         }
989                         case GUI_ID_DELETE_WORLD_BUTTON: {
990                                 MainMenuData cur;
991                                 readInput(&cur);
992                                 if(cur.selected_world == -1){
993                                         (new GUIMessageMenu(env, parent, -1, menumgr,
994                                                         wgettext("Cannot delete world: Nothing selected"))
995                                                         )->drop();
996                                 } else {
997                                         WorldSpec spec = m_data->worlds[cur.selected_world];
998                                         // Get files and directories involved
999                                         std::vector<std::string> paths;
1000                                         paths.push_back(spec.path);
1001                                         fs::GetRecursiveSubPaths(spec.path, paths);
1002                                         // Launch confirmation dialog
1003                                         ConfirmDestDeleteWorld *dest = new
1004                                                         ConfirmDestDeleteWorld(spec, this, paths);
1005                                         std::wstring text = wgettext("Delete world");
1006                                         text += L" \"";
1007                                         text += narrow_to_wide(spec.name);
1008                                         text += L"\"?\n\n";
1009                                         text += wgettext("Files to be deleted");
1010                                         text += L":\n";
1011                                         for(u32 i=0; i<paths.size(); i++){
1012                                                 if(i == 3){ text += L"..."; break; }
1013                                                 text += narrow_to_wide(paths[i]) + L"\n";
1014                                         }
1015                                         (new GUIConfirmMenu(env, parent, -1, menumgr, dest,
1016                                                         text.c_str()))->drop();
1017                                 }
1018                                 return true;
1019                         }
1020                         case GUI_ID_CREATE_WORLD_BUTTON: {
1021                                 std::vector<SubgameSpec> games = getAvailableGames();
1022                                 if(games.size() == 0){
1023                                         GUIMessageMenu *menu = new GUIMessageMenu(env, parent,
1024                                                         -1, menumgr,
1025                                                         wgettext("Cannot create world: No games found"));
1026                                         menu->drop();
1027                                 } else {
1028                                         CreateWorldDest *dest = new CreateWorldDestMainMenu(this);
1029                                         GUICreateWorld *menu = new GUICreateWorld(env, parent, -1,
1030                                                         menumgr, dest, games);
1031                                         menu->drop();
1032                                 }
1033                                 return true;
1034                         }
1035                         case GUI_ID_CONFIGURE_WORLD_BUTTON: {
1036                                 GUIMessageMenu *menu = new GUIMessageMenu(env, parent,
1037                                                 -1, menumgr,
1038                                                 wgettext("Nothing here"));
1039                                 menu->drop();
1040                                 return true;
1041                         }
1042                         case GUI_ID_SERVERLIST_DELETE: {
1043                                 gui::IGUIListBox *serverlist = (gui::IGUIListBox*)getElementFromId(GUI_ID_SERVERLIST);
1044                                 u16 selected = ((gui::IGUIListBox*)serverlist)->getSelected();
1045                                 if (selected == -1) return true;
1046                                 ServerList::deleteEntry(m_data->servers[selected]);
1047                                 m_data->servers = ServerList::getLocal();
1048                                 updateGuiServerList();
1049                                 if (selected > 0)
1050                                         selected -= 1;
1051                                 serverlist->setSelected(selected);
1052                                 serverListOnSelected();
1053                                 return true;
1054                         }
1055                         #if USE_CURL
1056                         case GUI_ID_SERVERLIST_TOGGLE: {
1057                                 gui::IGUIElement *togglebutton = getElementFromId(GUI_ID_SERVERLIST_TOGGLE);
1058                                 gui::IGUIElement *deletebutton = getElementFromId(GUI_ID_SERVERLIST_DELETE);
1059                                 gui::IGUIListBox *serverlist = (gui::IGUIListBox*)getElementFromId(GUI_ID_SERVERLIST);
1060                                 if (m_data->serverlist_show_available) // switch to favorite list
1061                                 {
1062                                         m_data->servers = ServerList::getLocal();
1063                                         togglebutton->setText(wgettext("Show Public"));
1064                                         deletebutton->setVisible(true);
1065                                         updateGuiServerList();
1066                                         serverlist->setSelected(0);
1067                                 }
1068                                 else // switch to online list
1069                                 {
1070                                         m_data->servers = ServerList::getOnline();
1071                                         togglebutton->setText(wgettext("Show Favorites"));
1072                                         deletebutton->setVisible(false);
1073                                         updateGuiServerList();
1074                                         serverlist->setSelected(0);
1075                                 }
1076                                 serverListOnSelected();
1077
1078                                 m_data->serverlist_show_available = !m_data->serverlist_show_available;
1079                         }
1080                         #endif
1081                         }
1082                 }
1083                 if(event.GUIEvent.EventType==gui::EGET_EDITBOX_ENTER)
1084                 {
1085                         switch(event.GUIEvent.Caller->getID())
1086                         {
1087                                 case GUI_ID_ADDRESS_INPUT: case GUI_ID_PORT_INPUT: case GUI_ID_NAME_INPUT: case 264:
1088                                 acceptInput();
1089                                 quitMenu();
1090                                 return true;
1091                         }
1092                 }
1093                 if(event.GUIEvent.EventType==gui::EGET_LISTBOX_SELECTED_AGAIN)
1094                 {
1095                         switch(event.GUIEvent.Caller->getID())
1096                         {
1097                         case GUI_ID_WORLD_LISTBOX:
1098                                 acceptInput();
1099                                 if(getTab() != TAB_SINGLEPLAYER)
1100                                         m_data->address = L""; // Force local game
1101                                 quitMenu();
1102                                 return true;
1103                         case GUI_ID_SERVERLIST:
1104                                 gui::IGUIListBox *serverlist = (gui::IGUIListBox*)getElementFromId(GUI_ID_SERVERLIST);
1105                                 if (serverlist->getSelected() > -1)
1106                                 {
1107                                         acceptInput();
1108                                         quitMenu();
1109                                         return true;
1110                                 }
1111                         }
1112                 }
1113         }
1114
1115         return Parent ? Parent->OnEvent(event) : false;
1116 }
1117
1118 void GUIMainMenu::createNewWorld(std::wstring name, std::string gameid)
1119 {
1120         if(name == L"")
1121                 return;
1122         acceptInput();
1123         m_data->create_world_name = name;
1124         m_data->create_world_gameid = gameid;
1125         quitMenu();
1126 }
1127
1128 void GUIMainMenu::deleteWorld(const std::vector<std::string> &paths)
1129 {
1130         // Delete files
1131         bool did = fs::DeletePaths(paths);
1132         if(!did){
1133                 GUIMessageMenu *menu = new GUIMessageMenu(env, parent,
1134                                 -1, menumgr, wgettext("Failed to delete all world files"));
1135                 menu->drop();
1136         }
1137         // Quit menu to refresh it
1138         acceptInput();
1139         m_data->only_refresh = true;
1140         quitMenu();
1141 }
1142         
1143 int GUIMainMenu::getTab()
1144 {
1145         gui::IGUIElement *e = getElementFromId(GUI_ID_TAB_CONTROL);
1146         if(e != NULL && e->getType() == gui::EGUIET_TAB_CONTROL)
1147                 return ((gui::IGUITabControl*)e)->getActiveTab();
1148         return TAB_SINGLEPLAYER; // Default
1149 }
1150
1151 void GUIMainMenu::displayMessageMenu(std::wstring msg)
1152 {
1153         (new GUIMessageMenu(env, parent, -1, menumgr, msg))->drop();
1154 }
1155
1156 void GUIMainMenu::updateGuiServerList()
1157 {
1158         gui::IGUIListBox *serverlist = (gui::IGUIListBox *)getElementFromId(GUI_ID_SERVERLIST);
1159         serverlist->clear();
1160
1161         for(std::vector<ServerListSpec>::iterator i = m_data->servers.begin();
1162                 i != m_data->servers.end(); i++)
1163         {
1164                 std::string text;
1165                 if (i->name != "" && i->description != "")
1166                         text = i->name + " (" + i->description + ")";
1167                 else if (i->name !="")
1168                         text = i->name;
1169                 else
1170                         text = i->address + ":" + i->port;
1171
1172                 serverlist->addItem(narrow_to_wide(text).c_str());
1173         }
1174 }
1175
1176 void GUIMainMenu::serverListOnSelected()
1177 {
1178         if (!m_data->servers.empty())
1179         {
1180                 gui::IGUIListBox *serverlist = (gui::IGUIListBox*)getElementFromId(GUI_ID_SERVERLIST);
1181                 u16 id = serverlist->getSelected();
1182                 if (id < 0) return;
1183                 ((gui::IGUIEditBox*)getElementFromId(GUI_ID_ADDRESS_INPUT))
1184                 ->setText(narrow_to_wide(m_data->servers[id].address).c_str());
1185                 ((gui::IGUIEditBox*)getElementFromId(GUI_ID_PORT_INPUT))
1186                 ->setText(narrow_to_wide(m_data->servers[id].port).c_str());
1187         }
1188 }
1189
1190 ServerListSpec GUIMainMenu::getServerListSpec(std::string address, std::string port)
1191 {
1192         ServerListSpec server;
1193         server.address = address;
1194         server.port = port;
1195         for(std::vector<ServerListSpec>::iterator i = m_data->servers.begin();
1196                 i != m_data->servers.end(); i++)
1197         {
1198                 if (i->address == address && i->port == port)
1199                 {
1200                         server.description = i->description;
1201                         server.name = i->name;
1202                         break;
1203                 }
1204         }
1205         return server;
1206 }