3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
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.
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.
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.
20 #include "guiMainMenu.h"
21 #include "guiKeyChangeMenu.h"
22 #include "guiCreateWorld.h"
23 #include "guiConfigureWorld.h"
24 #include "guiMessageMenu.h"
25 #include "guiConfirmMenu.h"
27 #include "serialization.h"
29 #include <IGUICheckBox.h>
30 #include <IGUIEditBox.h>
31 #include <IGUIButton.h>
32 #include <IGUIStaticText.h>
34 #include <IGUIListBox.h>
35 #include <IGUITabControl.h>
36 #include <IGUIImage.h>
38 #include "guiPauseMenu.h"
40 #include "tile.h" // getTexturePath
42 #include "util/string.h"
45 #define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))
46 #define LSTRING(x) LSTRING_(x)
47 #define LSTRING_(x) L##x
49 const wchar_t *contrib_core_strs[] = {
50 L"Perttu Ahola (celeron55) <celeron55@gmail.com>",
51 L"Ryan Kwolek (kwolekr) <kwolekr@minetest.net>",
52 L"PilzAdam <pilzadam@minetest.net>",
53 L"Ilya Zhuravlev (thexyz) <xyz@minetest.net>",
54 L"Lisa Milne (darkrose) <lisa@ltmnet.com>",
55 L"Maciej Kasatkin (RealBadAngel) <mk@realbadangel.pl>",
56 L"proller <proler@gmail.com>",
57 L"sfan5 <sfan5@live.de>"
60 const wchar_t *contrib_active_strs[] = {
61 L"kahrl <kahrl@gmx.net>",
62 L"sapier <sapier@gmx.net>",
63 L"Vanessa Ezekowitz (VanessaE) <vanessaezekowitz@gmail.com>",
64 L"Jurgen Doser (doserj) <jurgen.doser@gmail.com>",
65 L"Jeija <jeija@mesecons.net>",
66 L"MirceaKitsune <mirceakitsune@gmail.com>",
68 L"dannydark <the_skeleton_of_a_child@yahoo.co.uk>",
69 L"0gb.us <0gb.us@0gb.us>"
72 const wchar_t *contrib_previous_strs[] = {
73 L"Giuseppe Bilotta (Oblomov) <giuseppe.bilotta@gmail.com>",
74 L"Jonathan Neuschafer <j.neuschaefer@gmx.net>",
75 L"Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net>",
76 L"Constantin Wenger (SpeedProg) <constantin.wenger@googlemail.com>",
77 L"matttpt <matttpt@gmail.com>",
78 L"JacobF <queatz@gmail.com>"
82 struct CreateWorldDestMainMenu : public CreateWorldDest
84 CreateWorldDestMainMenu(GUIMainMenu *menu):
87 void accepted(std::wstring name, std::string gameid)
89 std::string name_narrow = wide_to_narrow(name);
90 if(!string_allowed_blacklist(name_narrow, WORLDNAME_BLACKLISTED_CHARS))
92 wchar_t* text = wgettext("Cannot create world: Name contains invalid characters");
93 m_menu->displayMessageMenu(text);
97 std::vector<WorldSpec> worlds = getAvailableWorlds();
98 for(std::vector<WorldSpec>::iterator i = worlds.begin();
99 i != worlds.end(); i++)
101 if((*i).name == name_narrow)
103 wchar_t* text = wgettext("Cannot create world: A world by this name already exists");
104 m_menu->displayMessageMenu(text);
109 m_menu->createNewWorld(name, gameid);
114 struct ConfirmDestDeleteWorld : public ConfirmDest
116 ConfirmDestDeleteWorld(WorldSpec spec, GUIMainMenu *menu,
117 const std::vector<std::string> &paths):
122 void answer(bool answer)
126 m_menu->deleteWorld(m_paths);
130 std::vector<std::string> m_paths;
135 GUI_ID_QUIT_BUTTON = 101,
137 GUI_ID_ADDRESS_INPUT,
140 GUI_ID_SMOOTH_LIGHTING_CB,
142 GUI_ID_OPAQUE_WATER_CB,
144 GUI_ID_ANISOTROPIC_CB,
148 GUI_ID_PRELOAD_ITEM_VISUALS_CB,
149 GUI_ID_ENABLE_PARTICLES_CB,
150 GUI_ID_LIQUID_FINITE_CB,
154 GUI_ID_JOIN_GAME_BUTTON,
155 GUI_ID_CHANGE_KEYS_BUTTON,
156 GUI_ID_DELETE_WORLD_BUTTON,
157 GUI_ID_CREATE_WORLD_BUTTON,
158 GUI_ID_CONFIGURE_WORLD_BUTTON,
159 GUI_ID_WORLD_LISTBOX,
162 GUI_ID_SERVERLIST_TOGGLE,
163 GUI_ID_SERVERLIST_DELETE,
164 GUI_ID_SERVERLIST_TITLE,
165 GUI_ID_GAME_BUTTON_FIRST = 130,
166 GUI_ID_GAME_BUTTON_MAX = 150,
178 GUIMainMenu::GUIMainMenu(gui::IGUIEnvironment* env,
179 gui::IGUIElement* parent, s32 id,
180 IMenuManager *menumgr,
182 IGameCallback *gamecallback
184 GUIModalMenu(env, parent, id, menumgr),
187 m_gamecallback(gamecallback),
188 m_is_regenerating(false)
192 this->parent = parent;
194 this->menumgr = menumgr;
197 GUIMainMenu::~GUIMainMenu()
202 void GUIMainMenu::removeChildren()
204 const core::list<gui::IGUIElement*> &children = getChildren();
205 core::list<gui::IGUIElement*> children_copy;
206 for(core::list<gui::IGUIElement*>::ConstIterator
207 i = children.begin(); i != children.end(); i++)
209 children_copy.push_back(*i);
211 for(core::list<gui::IGUIElement*>::Iterator
212 i = children_copy.begin();
213 i != children_copy.end(); i++)
219 void GUIMainMenu::regenerateGui(v2u32 screensize)
221 m_is_regenerating = true;
223 Read stuff from elements into m_data
233 Calculate new sizes and positions
236 v2s32 size(screensize.X, screensize.Y);
238 core::rect<s32> rect(
239 screensize.X/2 - size.X/2,
240 screensize.Y/2 - size.Y/2,
241 screensize.X/2 + size.X/2,
242 screensize.Y/2 + size.Y/2
246 recalculateAbsolutePosition(false);
248 //v2s32 size = rect.getSize();
258 core::rect<s32> rect(0, 0, size.X, 40);
260 std::string t = "Minetest " VERSION_STRING;
261 if(m_data->selected_game_name != ""){
263 t += m_data->selected_game_name;
265 Environment->addStaticText(narrow_to_wide(t).c_str(),
266 rect, false, true, this, -1);
269 //v2s32 center(size.X/2, size.Y/2);
270 v2s32 c800(size.X/2-400, size.Y/2-270);
272 m_topleft_client = c800 + v2s32(90, 70+50+30);
273 m_size_client = v2s32(620, 270);
275 m_size_server = v2s32(620, 140);
277 if(m_data->selected_tab == TAB_ADVANCED)
279 m_topleft_client = c800 + v2s32(90, 70+50+30);
280 m_size_client = v2s32(620, 200);
282 m_size_server = v2s32(620, 140);
285 m_topleft_server = m_topleft_client + v2s32(0, m_size_client.Y+20);
289 core::rect<s32> rect(0, 0, m_size_client.X, 30);
290 rect += m_topleft_client + v2s32(0, -30);
291 gui::IGUITabControl *e = Environment->addTabControl(
292 rect, this, true, true, GUI_ID_TAB_CONTROL);
293 wchar_t* text = wgettext("Singleplayer");
296 text = wgettext("Multiplayer");
299 text = wgettext("Advanced");
302 text = wgettext("Settings");
305 text = wgettext("Credits");
309 e->setActiveTab(m_data->selected_tab);
313 if(m_data->selected_tab == TAB_SINGLEPLAYER)
317 core::rect<s32> rect(0, 0, 10, m_size_client.Y);
318 rect += m_topleft_client + v2s32(15, 0);
319 //const wchar_t *text = L"H\nY\nB\nR\nI\nD";
320 const wchar_t *text = L"S\nI\nN\nG\nL\nE\n \nP\nL\nA\nY\nE\nR\n";
321 gui::IGUIStaticText *t =
322 Environment->addStaticText(text, rect, false, true, this, -1);
323 t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
326 // World selection listbox
327 u32 world_sel_h = 160;
328 u32 world_sel_w = 365;
329 //s32 world_sel_x = 50;
330 s32 world_sel_x = m_size_client.X-world_sel_w-30;
331 s32 world_sel_y = 30;
332 u32 world_button_count = 3;
333 u32 world_button_w = (world_sel_w)/world_button_count - bs
334 + bs/(world_button_count-1);
336 core::rect<s32> rect(0, 0, world_sel_w-4, 20);
337 rect += m_topleft_client + v2s32(world_sel_x+4, world_sel_y-20);
338 wchar_t* text = wgettext("Select World:");
339 /*gui::IGUIStaticText *e =*/ Environment->addStaticText(
341 rect, false, true, this, -1);
343 /*e->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);*/
346 core::rect<s32> rect(0, 0, world_sel_w, world_sel_h);
347 rect += m_topleft_client + v2s32(world_sel_x, world_sel_y);
348 gui::IGUIListBox *e = Environment->addListBox(rect, this,
349 GUI_ID_WORLD_LISTBOX);
350 e->setDrawBackground(true);
351 m_world_indices.clear();
352 for(size_t wi = 0; wi < m_data->worlds.size(); wi++){
353 const WorldSpec &spec = m_data->worlds[wi];
354 if(spec.gameid == m_data->selected_game){
355 //e->addItem(narrow_to_wide(spec.name+" ["+spec.gameid+"]").c_str());
356 e->addItem(narrow_to_wide(spec.name).c_str());
357 m_world_indices.push_back(wi);
358 if(m_data->selected_world == (int)wi)
359 e->setSelected(m_world_indices.size()-1);
362 Environment->setFocus(e);
364 // Delete world button
366 core::rect<s32> rect(0, 0, world_button_w, 30);
367 rect += m_topleft_client + v2s32(world_sel_x, world_sel_y+world_sel_h+0);
368 wchar_t* text = wgettext("Delete");
369 Environment->addButton(rect, this, GUI_ID_DELETE_WORLD_BUTTON,
373 // Create world button
375 core::rect<s32> rect(0, 0, world_button_w, 30);
376 rect += m_topleft_client + v2s32(world_sel_x+world_button_w+bs, world_sel_y+world_sel_h+0);
377 wchar_t* text = wgettext("New");
378 Environment->addButton(rect, this, GUI_ID_CREATE_WORLD_BUTTON,
382 // Configure world button
384 core::rect<s32> rect(0, 0, world_button_w, 30);
385 rect += m_topleft_client + v2s32(world_sel_x+(world_button_w+bs)*2,
386 world_sel_y+world_sel_h+0);
387 wchar_t* text = wgettext("Configure");
388 Environment->addButton(rect, this, GUI_ID_CONFIGURE_WORLD_BUTTON,
394 /*core::rect<s32> rect(0, 0, world_button_w, 30);
395 rect += m_topleft_client + v2s32(world_sel_x+(world_button_w+bs)*3,
396 world_sel_y+world_sel_h+0);*/
398 /*core::rect<s32> rect(0, 0, bw, 30);
399 rect += m_topleft_client + v2s32(m_size_client.X-bw-30,
400 m_size_client.Y-30-15);*/
401 core::rect<s32> rect(0, 0, bw, 30);
402 rect += m_topleft_client + v2s32(world_sel_x+world_sel_w-bw,
403 world_sel_y+world_sel_h+30+bs);
404 wchar_t* text = wgettext("Play");
405 Environment->addButton(rect, this,
406 GUI_ID_JOIN_GAME_BUTTON, text);
411 //s32 option_x = 50+world_sel_w+20;
415 core::rect<s32> rect(0, 0, option_w, 30);
416 rect += m_topleft_client + v2s32(option_x, option_y+20*0);
417 wchar_t* text = wgettext("Creative Mode");
418 Environment->addCheckBox(m_data->creative_mode, rect, this,
419 GUI_ID_CREATIVE_CB, text);
423 core::rect<s32> rect(0, 0, option_w, 30);
424 rect += m_topleft_client + v2s32(option_x, option_y+20*1);
425 wchar_t* text = wgettext("Enable Damage");
426 Environment->addCheckBox(m_data->enable_damage, rect, this,
427 GUI_ID_DAMAGE_CB, text);
432 else if(m_data->selected_tab == TAB_MULTIPLAYER)
437 core::rect<s32> rect(0, 0, 10, m_size_client.Y);
438 rect += m_topleft_client + v2s32(15, 0);
439 const wchar_t *text = L"C\nL\nI\nE\nN\nT";
440 gui::IGUIStaticText *t =
441 Environment->addStaticText(text, rect, false, true, this, -1);
442 t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
444 // Nickname + password
446 core::rect<s32> rect(0, 0, 110, 20);
447 wchar_t* text = wgettext("Name/Password");
448 rect += m_topleft_client + v2s32(m_size_client.X-60-100, 10+6);
449 Environment->addStaticText(text,
450 rect, false, true, this, -1);
455 core::rect<s32> rect(0, 0, 120, 30);
456 rect += m_topleft_client + v2s32(m_size_client.X-60-100, 50);
457 gui::IGUIElement *e =
458 Environment->addEditBox(m_data->name.c_str(), rect, true, this, GUI_ID_NAME_INPUT);
459 if(m_data->name == L"")
460 Environment->setFocus(e);
463 core::rect<s32> rect(0, 0, 120, 30);
464 rect += m_topleft_client + v2s32(m_size_client.X-60-100, 90);
465 gui::IGUIEditBox *e =
466 Environment->addEditBox(L"", rect, true, this, 264);
467 e->setPasswordBox(true);
468 if(m_data->name != L"" && m_data->address != L"")
469 Environment->setFocus(e);
475 core::rect<s32> rect(0, 0, 390, 140);
476 rect += m_topleft_client + v2s32(50, 30);
477 gui::IGUIListBox *e = Environment->addListBox(rect, this,
479 e->setDrawBackground(true);
481 if(m_data->selected_serverlist == SERVERLIST_FAVORITES) {
482 m_data->servers = ServerList::getLocal();
484 core::rect<s32> rect(0, 0, 390, 20);
485 rect += m_topleft_client + v2s32(50, 10);
486 Environment->addStaticText(wgettext("Favorites:"),
487 rect, false, true, this, GUI_ID_SERVERLIST_TITLE);
490 m_data->servers = ServerList::getOnline();
492 core::rect<s32> rect(0, 0, 390, 20);
493 rect += m_topleft_client + v2s32(50, 10);
494 Environment->addStaticText(wgettext("Public Server List:"),
495 rect, false, true, this, GUI_ID_SERVERLIST_TITLE);
499 m_data->servers = ServerList::getLocal();
501 core::rect<s32> rect(0, 0, 390, 20);
502 rect += m_topleft_client + v2s32(50, 10);
503 Environment->addStaticText(wgettext("Favorites:"),
504 rect, false, true, this, GUI_ID_SERVERLIST_TITLE);
507 updateGuiServerList();
512 core::rect<s32> rect(0, 0, 110, 20);
513 rect += m_topleft_client + v2s32(50, m_size_client.Y-50-15+6);
514 wchar_t* text = wgettext("Address/Port");
515 Environment->addStaticText(text,
516 rect, false, true, this, -1);
521 core::rect<s32> rect(0, 0, 260, 30);
522 rect += m_topleft_client + v2s32(50, m_size_client.Y-25-15);
523 gui::IGUIElement *e =
524 Environment->addEditBox(m_data->address.c_str(), rect, true,
525 this, GUI_ID_ADDRESS_INPUT);
526 if(m_data->name != L"" && m_data->address == L"")
527 Environment->setFocus(e);
530 core::rect<s32> rect(0, 0, 120, 30);
531 rect += m_topleft_client + v2s32(50+260+10, m_size_client.Y-25-15);
532 Environment->addEditBox(m_data->port.c_str(), rect, true,
533 this, GUI_ID_PORT_INPUT);
537 // Toggle Serverlist (Favorites/Online)
539 core::rect<s32> rect(0, 0, 260, 30);
540 rect += m_topleft_client + v2s32(50,
542 wchar_t* text = wgettext("Show Public");
543 gui::IGUIButton *e = Environment->addButton(rect, this, GUI_ID_SERVERLIST_TOGGLE,
546 e->setIsPushButton(true);
547 if (m_data->selected_serverlist == SERVERLIST_PUBLIC)
549 wchar_t* text = wgettext("Show Favorites");
556 // Delete Local Favorite
558 core::rect<s32> rect(0, 0, 120, 30);
559 rect += m_topleft_client + v2s32(50+260+10, 180);
560 wchar_t* text = wgettext("Delete");
561 gui::IGUIButton *e = Environment->addButton(rect, this, GUI_ID_SERVERLIST_DELETE,
563 if (m_data->selected_serverlist == SERVERLIST_PUBLIC) // Hidden when on public list
564 e->setVisible(false);
570 core::rect<s32> rect(0, 0, 120, 30);
571 rect += m_topleft_client + v2s32(m_size_client.X-130-30,
572 m_size_client.Y-25-15);
573 wchar_t* text = wgettext("Connect");
574 Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON,
580 else if(m_data->selected_tab == TAB_ADVANCED)
585 core::rect<s32> rect(0, 0, 10, m_size_client.Y);
586 rect += m_topleft_client + v2s32(15, 0);
587 const wchar_t *text = L"C\nL\nI\nE\nN\nT";
588 gui::IGUIStaticText *t =
589 Environment->addStaticText(text, rect, false, true, this, -1);
590 t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
592 // Nickname + password
594 core::rect<s32> rect(0, 0, 110, 20);
595 rect += m_topleft_client + v2s32(35+30, 35+6);
596 wchar_t* text = wgettext("Name/Password");
597 Environment->addStaticText(text,
598 rect, false, true, this, -1);
603 core::rect<s32> rect(0, 0, 230, 30);
604 rect += m_topleft_client + v2s32(160+30, 35);
605 gui::IGUIElement *e =
606 Environment->addEditBox(m_data->name.c_str(), rect, true, this, GUI_ID_NAME_INPUT);
607 if(m_data->name == L"")
608 Environment->setFocus(e);
611 core::rect<s32> rect(0, 0, 120, 30);
612 rect += m_topleft_client + v2s32(m_size_client.X-60-100, 35);
613 gui::IGUIEditBox *e =
614 Environment->addEditBox(L"", rect, true, this, 264);
615 e->setPasswordBox(true);
616 if(m_data->name != L"" && m_data->address != L"")
617 Environment->setFocus(e);
623 core::rect<s32> rect(0, 0, 110, 20);
624 rect += m_topleft_client + v2s32(35+30, 75+6);
625 wchar_t* text = wgettext("Address/Port");
626 Environment->addStaticText(text,
627 rect, false, true, this, -1);
632 core::rect<s32> rect(0, 0, 230, 30);
633 rect += m_topleft_client + v2s32(160+30, 75);
634 gui::IGUIElement *e =
635 Environment->addEditBox(m_data->address.c_str(), rect, true,
636 this, GUI_ID_ADDRESS_INPUT);
637 if(m_data->name != L"" && m_data->address == L"")
638 Environment->setFocus(e);
641 core::rect<s32> rect(0, 0, 120, 30);
642 rect += m_topleft_client + v2s32(m_size_client.X-60-100, 75);
643 Environment->addEditBox(m_data->port.c_str(), rect, true,
644 this, GUI_ID_PORT_INPUT);
648 core::rect<s32> rect(0, 0, 400, 20);
649 rect += m_topleft_client + v2s32(160+30, 75+35);
650 wchar_t* text = wgettext("Leave address blank to start a local server.");
651 Environment->addStaticText(text,
652 rect, false, true, this, -1);
657 core::rect<s32> rect(0, 0, 180, 30);
658 rect += m_topleft_client + v2s32(m_size_client.X-180-30,
659 m_size_client.Y-30-20);
660 wchar_t* text = wgettext("Start Game / Connect");
661 Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON,
670 core::rect<s32> rect(0, 0, 10, m_size_server.Y);
671 rect += m_topleft_server + v2s32(15, 0);
672 const wchar_t *text = L"S\nE\nR\nV\nE\nR";
673 gui::IGUIStaticText *t =
674 Environment->addStaticText(text, rect, false, true, this, -1);
675 t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
679 core::rect<s32> rect(0, 0, 250, 30);
680 rect += m_topleft_server + v2s32(30+20+250+20, 20);
681 wchar_t* text = wgettext("Creative Mode");
682 Environment->addCheckBox(m_data->creative_mode, rect, this, GUI_ID_CREATIVE_CB,
687 core::rect<s32> rect(0, 0, 250, 30);
688 rect += m_topleft_server + v2s32(30+20+250+20, 40);
689 wchar_t* text = wgettext("Enable Damage");
690 Environment->addCheckBox(m_data->enable_damage, rect, this, GUI_ID_DAMAGE_CB,
696 core::rect<s32> rect(0, 0, 250, 30);
697 rect += m_topleft_server + v2s32(30+20+250+20, 60);
698 wchar_t* text = wgettext("Public");
699 Environment->addCheckBox(m_data->enable_public, rect, this, GUI_ID_PUBLIC_CB,
704 // Delete world button
706 core::rect<s32> rect(0, 0, 130, 30);
707 rect += m_topleft_server + v2s32(30+20+250+20, 90);
708 wchar_t* text = wgettext("Delete world");
709 Environment->addButton(rect, this, GUI_ID_DELETE_WORLD_BUTTON,
713 // Create world button
715 core::rect<s32> rect(0, 0, 130, 30);
716 rect += m_topleft_server + v2s32(30+20+250+20+140, 90);
717 wchar_t* text = wgettext("Create world");
718 Environment->addButton(rect, this, GUI_ID_CREATE_WORLD_BUTTON,
722 // World selection listbox
724 core::rect<s32> rect(0, 0, 250, 120);
725 rect += m_topleft_server + v2s32(30+20, 10);
726 gui::IGUIListBox *e = Environment->addListBox(rect, this,
727 GUI_ID_WORLD_LISTBOX);
728 e->setDrawBackground(true);
729 m_world_indices.clear();
730 for(size_t wi = 0; wi < m_data->worlds.size(); wi++){
731 const WorldSpec &spec = m_data->worlds[wi];
732 e->addItem(narrow_to_wide(spec.name+" ["+spec.gameid+"]").c_str());
733 m_world_indices.push_back(wi);
735 e->setSelected(m_data->selected_world);
739 else if(m_data->selected_tab == TAB_SETTINGS)
742 core::rect<s32> rect(0, 0, 10, m_size_client.Y);
743 rect += m_topleft_client + v2s32(15, 0);
744 const wchar_t *text = L"S\nE\nT\nT\nI\nN\nG\nS";
745 gui::IGUIStaticText *t =
746 Environment->addStaticText(text, rect, false, true, this, -1);
747 t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
753 core::rect<s32> rect(0, 0, option_w, 30);
754 rect += m_topleft_client + v2s32(option_x, option_y);
755 wchar_t* text = wgettext("Fancy trees");
756 Environment->addCheckBox(m_data->fancy_trees, rect, this,
757 GUI_ID_FANCYTREE_CB, text);
761 core::rect<s32> rect(0, 0, option_w, 30);
762 rect += m_topleft_client + v2s32(option_x, option_y+20);
763 wchar_t* text = wgettext("Smooth Lighting");
764 Environment->addCheckBox(m_data->smooth_lighting, rect, this,
765 GUI_ID_SMOOTH_LIGHTING_CB, text);
769 core::rect<s32> rect(0, 0, option_w, 30);
770 rect += m_topleft_client + v2s32(option_x, option_y+20*2);
771 wchar_t* text = wgettext("3D Clouds");
772 Environment->addCheckBox(m_data->clouds_3d, rect, this,
773 GUI_ID_3D_CLOUDS_CB, text);
777 core::rect<s32> rect(0, 0, option_w, 30);
778 rect += m_topleft_client + v2s32(option_x, option_y+20*3);
779 wchar_t* text = wgettext("Opaque water");
780 Environment->addCheckBox(m_data->opaque_water, rect, this,
781 GUI_ID_OPAQUE_WATER_CB, text);
786 // Anisotropic/mipmap/bi-/trilinear settings
789 core::rect<s32> rect(0, 0, option_w+20, 30);
790 rect += m_topleft_client + v2s32(option_x+175, option_y);
791 wchar_t* text = wgettext("Mip-Mapping");
792 Environment->addCheckBox(m_data->mip_map, rect, this,
793 GUI_ID_MIPMAP_CB, text);
798 core::rect<s32> rect(0, 0, option_w+20, 30);
799 rect += m_topleft_client + v2s32(option_x+175, option_y+20);
800 wchar_t* text = wgettext("Anisotropic Filtering");
801 Environment->addCheckBox(m_data->anisotropic_filter, rect, this,
802 GUI_ID_ANISOTROPIC_CB, text);
807 core::rect<s32> rect(0, 0, option_w+20, 30);
808 rect += m_topleft_client + v2s32(option_x+175, option_y+20*2);
809 wchar_t* text = wgettext("Bi-Linear Filtering");
810 Environment->addCheckBox(m_data->bilinear_filter, rect, this,
811 GUI_ID_BILINEAR_CB, text);
816 core::rect<s32> rect(0, 0, option_w+20, 30);
817 rect += m_topleft_client + v2s32(option_x+175, option_y+20*3);
818 wchar_t* text = wgettext("Tri-Linear Filtering");
819 Environment->addCheckBox(m_data->trilinear_filter, rect, this,
820 GUI_ID_TRILINEAR_CB, text);
824 // shader/on demand image loading/particles settings
826 core::rect<s32> rect(0, 0, option_w+20, 30);
827 rect += m_topleft_client + v2s32(option_x+175*2, option_y);
828 wchar_t* text = wgettext("Shaders");
829 Environment->addCheckBox(m_data->enable_shaders, rect, this,
830 GUI_ID_SHADERS_CB, text);
835 core::rect<s32> rect(0, 0, option_w+20+20, 30);
836 rect += m_topleft_client + v2s32(option_x+175*2, option_y+20);
837 wchar_t* text = wgettext("Preload item visuals");
838 Environment->addCheckBox(m_data->preload_item_visuals, rect, this,
839 GUI_ID_PRELOAD_ITEM_VISUALS_CB, text);
844 core::rect<s32> rect(0, 0, option_w+20+20, 30);
845 rect += m_topleft_client + v2s32(option_x+175*2, option_y+20*2);
846 wchar_t* text = wgettext("Enable Particles");
847 Environment->addCheckBox(m_data->enable_particles, rect, this,
848 GUI_ID_ENABLE_PARTICLES_CB, text);
853 core::rect<s32> rect(0, 0, option_w+20+20, 30);
854 rect += m_topleft_client + v2s32(option_x+175*2, option_y+20*3);
855 wchar_t* text = wgettext("Finite liquid");
856 Environment->addCheckBox(m_data->liquid_finite, rect, this,
857 GUI_ID_LIQUID_FINITE_CB, text);
863 core::rect<s32> rect(0, 0, 120, 30);
864 /*rect += m_topleft_client + v2s32(m_size_client.X-120-30,
865 m_size_client.Y-30-20);*/
866 rect += m_topleft_client + v2s32(option_x, option_y+120);
867 wchar_t* text = wgettext("Change keys");
868 Environment->addButton(rect, this,
869 GUI_ID_CHANGE_KEYS_BUTTON, text);
874 else if(m_data->selected_tab == TAB_CREDITS)
878 core::rect<s32> rect(0, 0, 9, m_size_client.Y);
879 rect += m_topleft_client + v2s32(15, 0);
880 const wchar_t *text = L"C\nR\nE\nD\nI\nT\nS";
881 gui::IGUIStaticText *t =
882 Environment->addStaticText(text, rect, false, true, this, -1);
883 t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
886 core::rect<s32> rect(0, 0, 130, 70);
887 rect += m_topleft_client + v2s32(35, 160);
888 Environment->addStaticText(
889 L"Minetest " LSTRING(VERSION_STRING) L"\nhttp://minetest.net/",
890 rect, false, true, this, -1);
893 video::SColor yellow(255, 255, 255, 0);
894 core::rect<s32> rect(0, 0, 450, 260);
895 rect += m_topleft_client + v2s32(168, 5);
897 irr::gui::IGUIListBox *list = Environment->addListBox(rect, this);
899 list->addItem(L"Core Developers");
900 list->setItemOverrideColor(list->getItemCount() - 1, yellow);
901 for (int i = 0; i != ARRAYLEN(contrib_core_strs); i++)
902 list->addItem(contrib_core_strs[i]);
904 list->addItem(L"Active Contributors");
905 list->setItemOverrideColor(list->getItemCount() - 1, yellow);
906 for (int i = 0; i != ARRAYLEN(contrib_active_strs); i++)
907 list->addItem(contrib_active_strs[i]);
909 list->addItem(L"Previous Contributors");
910 list->setItemOverrideColor(list->getItemCount() - 1, yellow);
911 for (int i = 0; i != ARRAYLEN(contrib_previous_strs); i++)
912 list->addItem(contrib_previous_strs[i]);
917 /* Add game selection buttons */
919 video::IVideoDriver* driver = Environment->getVideoDriver();
920 for(size_t i=0; i<m_data->games.size(); i++){
921 const SubgameSpec *spec = &m_data->games[i];
922 v2s32 p(8 + i*(48+8), screensize.Y - (48+8));
923 core::rect<s32> rect(0, 0, 48, 48);
925 video::ITexture *bgtexture = NULL;
926 if(spec->menuicon_path != "")
927 bgtexture = driver->getTexture(spec->menuicon_path.c_str());
928 gui::IGUIButton *b = Environment->addButton(rect, this,
929 GUI_ID_GAME_BUTTON_FIRST+i, narrow_to_wide(wrap_rows(spec->id, 4)).c_str());
931 b->setImage(bgtexture);
933 b->setDrawBorder(false);
934 b->setUseAlphaChannel(true);
938 m_is_regenerating = false;
941 void GUIMainMenu::drawMenu()
943 gui::IGUISkin* skin = Environment->getSkin();
946 video::IVideoDriver* driver = Environment->getVideoDriver();
948 /* Draw menu background */
950 /*video::SColor bgcolor(140,0,0,0);
951 driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect);*/
953 video::SColor bgcolor(140,0,0,0);
955 if(getTab() == TAB_SINGLEPLAYER)
958 core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y);
959 rect += AbsoluteRect.UpperLeftCorner + m_topleft_client;
960 driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
963 else if(getTab() == TAB_MULTIPLAYER)
966 core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y);
967 rect += AbsoluteRect.UpperLeftCorner + m_topleft_client;
968 driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
971 else if(getTab() == TAB_ADVANCED)
974 core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y);
975 rect += AbsoluteRect.UpperLeftCorner + m_topleft_client;
976 driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
979 core::rect<s32> rect(0, 0, m_size_server.X, m_size_server.Y);
980 rect += AbsoluteRect.UpperLeftCorner + m_topleft_server;
981 driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
984 else if(getTab() == TAB_SETTINGS)
987 core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y);
988 rect += AbsoluteRect.UpperLeftCorner + m_topleft_client;
989 driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
992 else if(getTab() == TAB_CREDITS)
995 core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y);
996 rect += AbsoluteRect.UpperLeftCorner + m_topleft_client;
997 driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
999 video::ITexture *logotexture =
1000 driver->getTexture(getTexturePath("logo.png").c_str());
1003 v2s32 logosize(logotexture->getOriginalSize().Width,
1004 logotexture->getOriginalSize().Height);
1006 core::rect<s32> rect(0,0,logosize.X,logosize.Y);
1007 rect += AbsoluteRect.UpperLeftCorner + m_topleft_client;
1008 rect += v2s32(50, 60);
1009 driver->draw2DImage(logotexture, rect,
1010 core::rect<s32>(core::position2d<s32>(0,0),
1011 core::dimension2di(logotexture->getSize())),
1016 /* Draw UI elements */
1018 gui::IGUIElement::draw();
1021 void GUIMainMenu::readInput(MainMenuData *dst)
1024 gui::IGUIElement *e = getElementFromId(GUI_ID_TAB_CONTROL);
1025 if(e != NULL && e->getType() == gui::EGUIET_TAB_CONTROL)
1026 dst->selected_tab = ((gui::IGUITabControl*)e)->getActiveTab();
1028 if(dst->selected_tab == TAB_SINGLEPLAYER)
1030 dst->simple_singleplayer_mode = true;
1034 dst->simple_singleplayer_mode = false;
1036 gui::IGUIElement *e = getElementFromId(GUI_ID_NAME_INPUT);
1038 dst->name = e->getText();
1041 gui::IGUIElement *e = getElementFromId(264);
1043 dst->password = e->getText();
1046 gui::IGUIElement *e = getElementFromId(GUI_ID_ADDRESS_INPUT);
1048 dst->address = e->getText();
1051 gui::IGUIElement *e = getElementFromId(GUI_ID_PORT_INPUT);
1053 dst->port = e->getText();
1057 gui::IGUIElement *e = getElementFromId(GUI_ID_CREATIVE_CB);
1058 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
1059 dst->creative_mode = ((gui::IGUICheckBox*)e)->isChecked();
1062 gui::IGUIElement *e = getElementFromId(GUI_ID_DAMAGE_CB);
1063 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
1064 dst->enable_damage = ((gui::IGUICheckBox*)e)->isChecked();
1067 gui::IGUIElement *e = getElementFromId(GUI_ID_PUBLIC_CB);
1068 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
1069 dst->enable_public = ((gui::IGUICheckBox*)e)->isChecked();
1072 gui::IGUIElement *e = getElementFromId(GUI_ID_FANCYTREE_CB);
1073 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
1074 dst->fancy_trees = ((gui::IGUICheckBox*)e)->isChecked();
1077 gui::IGUIElement *e = getElementFromId(GUI_ID_SMOOTH_LIGHTING_CB);
1078 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
1079 dst->smooth_lighting = ((gui::IGUICheckBox*)e)->isChecked();
1082 gui::IGUIElement *e = getElementFromId(GUI_ID_3D_CLOUDS_CB);
1083 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
1084 dst->clouds_3d = ((gui::IGUICheckBox*)e)->isChecked();
1087 gui::IGUIElement *e = getElementFromId(GUI_ID_OPAQUE_WATER_CB);
1088 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
1089 dst->opaque_water = ((gui::IGUICheckBox*)e)->isChecked();
1093 gui::IGUIElement *e = getElementFromId(GUI_ID_MIPMAP_CB);
1094 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
1095 dst->mip_map = ((gui::IGUICheckBox*)e)->isChecked();
1099 gui::IGUIElement *e = getElementFromId(GUI_ID_ANISOTROPIC_CB);
1100 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
1101 dst->anisotropic_filter = ((gui::IGUICheckBox*)e)->isChecked();
1105 gui::IGUIElement *e = getElementFromId(GUI_ID_BILINEAR_CB);
1106 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
1107 dst->bilinear_filter = ((gui::IGUICheckBox*)e)->isChecked();
1111 gui::IGUIElement *e = getElementFromId(GUI_ID_TRILINEAR_CB);
1112 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
1113 dst->trilinear_filter = ((gui::IGUICheckBox*)e)->isChecked();
1117 gui::IGUIElement *e = getElementFromId(GUI_ID_SHADERS_CB);
1118 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
1119 dst->enable_shaders = ((gui::IGUICheckBox*)e)->isChecked() ? 2 : 0;
1123 gui::IGUIElement *e = getElementFromId(GUI_ID_PRELOAD_ITEM_VISUALS_CB);
1124 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
1125 dst->preload_item_visuals = ((gui::IGUICheckBox*)e)->isChecked();
1129 gui::IGUIElement *e = getElementFromId(GUI_ID_ENABLE_PARTICLES_CB);
1130 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
1131 dst->enable_particles = ((gui::IGUICheckBox*)e)->isChecked();
1135 gui::IGUIElement *e = getElementFromId(GUI_ID_LIQUID_FINITE_CB);
1136 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
1137 dst->liquid_finite = ((gui::IGUICheckBox*)e)->isChecked();
1141 gui::IGUIElement *e = getElementFromId(GUI_ID_WORLD_LISTBOX);
1142 if(e != NULL && e->getType() == gui::EGUIET_LIST_BOX){
1143 int list_i = ((gui::IGUIListBox*)e)->getSelected();
1145 dst->selected_world = -1;
1147 dst->selected_world = m_world_indices[list_i];
1151 ServerListSpec server =
1152 getServerListSpec(wide_to_narrow(dst->address), wide_to_narrow(dst->port));
1153 dst->servername = server["name"].asString();
1154 dst->serverdescription = server["description"].asString();
1158 void GUIMainMenu::acceptInput()
1164 bool GUIMainMenu::OnEvent(const SEvent& event)
1166 if(event.EventType==EET_KEY_INPUT_EVENT)
1168 if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown)
1170 m_gamecallback->exitToOS();
1174 if(event.KeyInput.Key==KEY_RETURN && event.KeyInput.PressedDown)
1181 if(event.EventType==EET_GUI_EVENT)
1183 if(event.GUIEvent.EventType==gui::EGET_ELEMENT_FOCUS_LOST
1186 if(!canTakeFocus(event.GUIEvent.Element))
1188 dstream<<"GUIMainMenu: Not allowing focus change."
1190 // Returning true disables focus change
1194 if(event.GUIEvent.EventType==gui::EGET_TAB_CHANGED)
1196 if(!m_is_regenerating)
1197 regenerateGui(m_screensize_old);
1200 if(event.GUIEvent.EventType==gui::EGET_LISTBOX_CHANGED && event.GUIEvent.Caller->getID() == GUI_ID_SERVERLIST)
1202 serverListOnSelected();
1205 if(event.GUIEvent.EventType==gui::EGET_BUTTON_CLICKED)
1207 switch(event.GUIEvent.Caller->getID())
1209 case GUI_ID_JOIN_GAME_BUTTON: {
1212 if (getTab() == TAB_MULTIPLAYER && cur.address == L"")
1214 wchar_t* text = wgettext("Address required.");
1215 (new GUIMessageMenu(env, parent, -1, menumgr,
1225 case GUI_ID_CHANGE_KEYS_BUTTON: {
1226 GUIKeyChangeMenu *kmenu = new GUIKeyChangeMenu(env, parent, -1,menumgr);
1230 case GUI_ID_DELETE_WORLD_BUTTON: {
1233 if(cur.selected_world == -1){
1234 wchar_t* text = wgettext("Cannot delete world: Nothing selected");
1235 (new GUIMessageMenu(env, parent, -1, menumgr,
1240 WorldSpec spec = m_data->worlds[cur.selected_world];
1241 // Get files and directories involved
1242 std::vector<std::string> paths;
1243 paths.push_back(spec.path);
1244 fs::GetRecursiveSubPaths(spec.path, paths);
1245 // Launch confirmation dialog
1246 ConfirmDestDeleteWorld *dest = new
1247 ConfirmDestDeleteWorld(spec, this, paths);
1248 wchar_t* text1 = wgettext("Delete world");
1249 wchar_t* text2 = wgettext("Files to be deleted");
1250 std::wstring text = text1;
1252 text += narrow_to_wide(spec.name);
1258 for(u32 i=0; i<paths.size(); i++){
1259 if(i == 3){ text += L"..."; break; }
1260 text += narrow_to_wide(paths[i]) + L"\n";
1262 (new GUIConfirmMenu(env, parent, -1, menumgr, dest,
1263 text.c_str()))->drop();
1267 case GUI_ID_CREATE_WORLD_BUTTON: {
1268 const std::vector<SubgameSpec> &games = m_data->games;
1269 if(games.size() == 0){
1270 wchar_t* text = wgettext("Cannot create world: No games found");
1271 GUIMessageMenu *menu = new GUIMessageMenu(env, parent,
1277 CreateWorldDest *dest = new CreateWorldDestMainMenu(this);
1278 GUICreateWorld *menu = new GUICreateWorld(env, parent, -1,
1279 menumgr, dest, games, m_data->selected_game);
1284 case GUI_ID_CONFIGURE_WORLD_BUTTON: {
1287 if(cur.selected_world == -1)
1289 wchar_t* text = wgettext("Cannot configure world: Nothing selected");
1290 (new GUIMessageMenu(env, parent, -1, menumgr,
1297 WorldSpec wspec = m_data->worlds[cur.selected_world];
1298 GUIConfigureWorld *menu = new GUIConfigureWorld(env, parent,
1299 -1, menumgr, wspec);
1304 case GUI_ID_SERVERLIST_DELETE: {
1305 gui::IGUIListBox *serverlist = (gui::IGUIListBox*)getElementFromId(GUI_ID_SERVERLIST);
1306 s32 selected = ((gui::IGUIListBox*)serverlist)->getSelected();
1307 if (selected == -1) return true;
1308 ServerList::deleteEntry(m_data->servers[selected]);
1309 m_data->servers = ServerList::getLocal();
1310 updateGuiServerList();
1313 serverlist->setSelected(selected);
1314 serverListOnSelected();
1318 case GUI_ID_SERVERLIST_TOGGLE: {
1319 gui::IGUIElement *togglebutton = getElementFromId(GUI_ID_SERVERLIST_TOGGLE);
1320 gui::IGUIElement *deletebutton = getElementFromId(GUI_ID_SERVERLIST_DELETE);
1321 gui::IGUIListBox *serverlist = (gui::IGUIListBox*)getElementFromId(GUI_ID_SERVERLIST);
1322 gui::IGUIElement *title = getElementFromId(GUI_ID_SERVERLIST_TITLE);
1323 if (m_data->selected_serverlist == SERVERLIST_PUBLIC) // switch to favorite list
1325 m_data->servers = ServerList::getLocal();
1326 wchar_t* text1 = wgettext("Show Public");
1327 wchar_t* text2 = wgettext("Favorites:");
1328 togglebutton->setText(text1);
1329 title->setText(text2);
1332 deletebutton->setVisible(true);
1333 updateGuiServerList();
1334 serverlist->setSelected(0);
1335 m_data->selected_serverlist = SERVERLIST_FAVORITES;
1337 else // switch to online list
1339 m_data->servers = ServerList::getOnline();
1340 wchar_t* text1 = wgettext("Show Favorites");
1341 wchar_t* text2 = wgettext("Public Server List:");
1342 togglebutton->setText(text1);
1343 title->setText(text2);
1346 deletebutton->setVisible(false);
1347 updateGuiServerList();
1348 serverlist->setSelected(0);
1349 m_data->selected_serverlist = SERVERLIST_PUBLIC;
1351 serverListOnSelected();
1356 int eid = event.GUIEvent.Caller->getID();
1357 if(eid >= GUI_ID_GAME_BUTTON_FIRST &&
1358 eid <= GUI_ID_GAME_BUTTON_MAX){
1359 m_data->selected_game =
1360 m_data->games[eid - GUI_ID_GAME_BUTTON_FIRST].id;
1361 m_data->selected_game_name =
1362 m_data->games[eid - GUI_ID_GAME_BUTTON_FIRST].name;
1363 regenerateGui(m_screensize_old);
1366 if(event.GUIEvent.EventType==gui::EGET_EDITBOX_ENTER)
1368 switch(event.GUIEvent.Caller->getID())
1370 case GUI_ID_ADDRESS_INPUT: case GUI_ID_PORT_INPUT: case GUI_ID_NAME_INPUT: case 264:
1373 if (getTab() == TAB_MULTIPLAYER && cur.address == L"")
1375 (new GUIMessageMenu(env, parent, -1, menumgr,
1376 wgettext("Address required."))
1385 if(event.GUIEvent.EventType==gui::EGET_LISTBOX_CHANGED)
1389 if(event.GUIEvent.EventType==gui::EGET_LISTBOX_SELECTED_AGAIN)
1391 switch(event.GUIEvent.Caller->getID())
1393 case GUI_ID_WORLD_LISTBOX:
1395 if(getTab() != TAB_SINGLEPLAYER)
1396 m_data->address = L""; // Force local game
1399 case GUI_ID_SERVERLIST:
1400 gui::IGUIListBox *serverlist = (gui::IGUIListBox*)getElementFromId(GUI_ID_SERVERLIST);
1401 if (serverlist->getSelected() > -1)
1411 return Parent ? Parent->OnEvent(event) : false;
1414 void GUIMainMenu::createNewWorld(std::wstring name, std::string gameid)
1419 m_data->create_world_name = name;
1420 m_data->create_world_gameid = gameid;
1424 void GUIMainMenu::deleteWorld(const std::vector<std::string> &paths)
1427 bool did = fs::DeletePaths(paths);
1429 wchar_t* text = wgettext("Failed to delete all world files");
1430 GUIMessageMenu *menu = new GUIMessageMenu(env, parent,
1435 // Quit menu to refresh it
1437 m_data->only_refresh = true;
1441 int GUIMainMenu::getTab()
1443 gui::IGUIElement *e = getElementFromId(GUI_ID_TAB_CONTROL);
1444 if(e != NULL && e->getType() == gui::EGUIET_TAB_CONTROL)
1445 return ((gui::IGUITabControl*)e)->getActiveTab();
1446 return TAB_SINGLEPLAYER; // Default
1449 void GUIMainMenu::displayMessageMenu(std::wstring msg)
1451 (new GUIMessageMenu(env, parent, -1, menumgr, msg))->drop();
1454 void GUIMainMenu::updateGuiServerList()
1456 gui::IGUIListBox *serverlist = (gui::IGUIListBox *)getElementFromId(GUI_ID_SERVERLIST);
1457 serverlist->clear();
1459 for(std::vector<ServerListSpec>::iterator i = m_data->servers.begin();
1460 i != m_data->servers.end(); i++)
1464 if ((*i)["clients"].asString().size())
1465 text += (*i)["clients"].asString();
1466 if ((*i)["clients_max"].asString().size())
1467 text += "/" + (*i)["clients_max"].asString();
1469 if ((*i)["version"].asString().size())
1470 text += (*i)["version"].asString() + " ";
1471 if ((*i)["password"].asString().size())
1473 if ((*i)["creative"].asString().size())
1475 if ((*i)["damage"].asString().size())
1477 if ((*i)["pvp"].asString().size())
1481 if ((*i)["name"] != "" && (*i)["description"] != "")
1482 text += (*i)["name"].asString() + " (" + (*i)["description"].asString() + ")";
1483 else if ((*i)["name"] !="")
1484 text += (*i)["name"].asString();
1486 text += (*i)["address"].asString() + ":" + (*i)["port"].asString();
1488 serverlist->addItem(narrow_to_wide(text).c_str());
1492 void GUIMainMenu::serverListOnSelected()
1494 if (!m_data->servers.empty())
1496 gui::IGUIListBox *serverlist = (gui::IGUIListBox*)getElementFromId(GUI_ID_SERVERLIST);
1497 u16 id = serverlist->getSelected();
1498 //if (id < 0) return; // u16>0!
1499 ((gui::IGUIEditBox*)getElementFromId(GUI_ID_ADDRESS_INPUT))
1500 ->setText(narrow_to_wide(m_data->servers[id]["address"].asString()).c_str());
1501 ((gui::IGUIEditBox*)getElementFromId(GUI_ID_PORT_INPUT))
1502 ->setText(narrow_to_wide(m_data->servers[id]["port"].asString()).c_str());
1506 ServerListSpec GUIMainMenu::getServerListSpec(std::string address, std::string port)
1508 ServerListSpec server;
1509 server["address"] = address;
1510 server["port"] = port;
1511 for(std::vector<ServerListSpec>::iterator i = m_data->servers.begin();
1512 i != m_data->servers.end(); i++)
1514 if ((*i)["address"] == address && (*i)["port"] == port)
1516 server["description"] = (*i)["description"];
1517 server["name"] = (*i)["name"];