1
0
mirror of https://github.com/moparisthebest/minetest synced 2024-11-07 18:05:08 -05:00
minetest/src/guiMainMenu.cpp

1356 lines
40 KiB
C++
Raw Normal View History

2011-01-23 10:29:15 -05:00
/*
2013-02-24 12:40:43 -05:00
Minetest
2013-02-24 13:38:45 -05:00
Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
2011-01-23 10:29:15 -05:00
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
2011-01-23 10:29:15 -05:00
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
2011-01-23 10:29:15 -05:00
You should have received a copy of the GNU Lesser General Public License along
2011-01-23 10:29:15 -05:00
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "guiMainMenu.h"
#include "guiKeyChangeMenu.h"
#include "guiCreateWorld.h"
Basic support for configuring which mods to load for each world settings.h: added function to return all keys used in settings, and a function to remove a setting mods.{h,cpp}: added class ModConfiguration that represents a subset of the installed mods. server.{h,cpp}: server does not load add-on mods that are disabled in the world.mt file. mods are disabled by a setting of the form "load_mod_<modname> = false". if no load_mod_<modname> = ... setting is found, the mod is loaded anyways for backwards compatibilty. server also complains to errorstream about mods with unstatisfied dependencies and about mods that are not installed. guiConfigureWorld.{h,cpp}: shows a treeview of installed add-on mods and modpacks with little icons in front of their name indicating their status: a checkmark for enabled mods, a cross for disabled mods, a question mark for "new" mods Mods can be enabled/disabled by a checkbox. Mods also show a list of dependencies and reverse dependencies. double-click on a mod in dependency or reverse dependency listbox selects the corresponding mod. Enabling a mod also enables all its dependencies. Disabling a mod also disables all its reverse dependencies. For modpacks, show buttons to enable/disable all mods (recursively, including their dependencies) in it. Button "Save" saves the current settings to the world.mt file and returns to the main menu. Button "Cancel" returns to main menu without saving. basic keyboard controls (if the proper widget has keyboard focus): up/down: scroll through tree of mods left/right: collaps/expand a modpack space: enable/disable the selected mod
2012-12-08 12:10:54 -05:00
#include "guiConfigureWorld.h"
#include "guiMessageMenu.h"
#include "guiConfirmMenu.h"
2011-01-23 10:29:15 -05:00
#include "debug.h"
#include "serialization.h"
#include <string>
2011-10-12 06:53:38 -04:00
#include <IGUICheckBox.h>
#include <IGUIEditBox.h>
#include <IGUIButton.h>
#include <IGUIStaticText.h>
#include <IGUIFont.h>
#include <IGUIListBox.h>
#include <IGUITabControl.h>
2012-03-15 07:59:48 -04:00
#include <IGUIImage.h>
// For IGameCallback
#include "guiPauseMenu.h"
#include "gettext.h"
2012-03-15 07:59:48 -04:00
#include "tile.h" // getTexturePath
2012-03-25 19:19:41 -04:00
#include "filesys.h"
#include "util/string.h"
#include "subgame.h"
#define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))
#define LSTRING(x) LSTRING_(x)
#define LSTRING_(x) L##x
const wchar_t *contrib_core_strs[] = {
L"Perttu Ahola (celeron55) <celeron55@gmail.com>",
L"Ryan Kwolek (kwolekr) <kwolekr@minetest.net>",
L"PilzAdam <pilzadam@minetest.net>",
L"Ilya Zhuravlev (thexyz) <xyz@minetest.net>",
2013-03-29 14:35:35 -04:00
L"Lisa Milne (darkrose) <lisa@ltmnet.com>",
L"Maciej Kasatkin (RealBadAngel) <mk@realbadangel.pl>",
L"proller <proler@gmail.com>"
};
const wchar_t *contrib_active_strs[] = {
L"sfan5 <sfan5@live.de>",
L"sapier <sapier@gmx.net>",
L"Vanessa Ezekowitz (VanessaE) <vanessaezekowitz@gmail.com>",
L"Jurgen Doser (doserj) <jurgen.doser@gmail.com>",
2013-03-29 14:35:35 -04:00
L"Jeija <jeija@mesecons.net>",
L"MirceaKitsune <mirceakitsune@gmail.com>",
L"ShadowNinja",
L"dannydark <the_skeleton_of_a_child@yahoo.co.uk>",
2013-03-29 14:35:35 -04:00
L"0gb.us <0gb.us@0gb.us>"
};
const wchar_t *contrib_previous_strs[] = {
L"kahrl <kahrl@gmx.net>",
L"Giuseppe Bilotta (Oblomov) <giuseppe.bilotta@gmail.com>",
L"Jonathan Neuschafer <j.neuschaefer@gmx.net>",
L"Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net>",
L"Constantin Wenger (SpeedProg) <constantin.wenger@googlemail.com>",
L"matttpt <matttpt@gmail.com>",
L"JacobF <queatz@gmail.com>"
};
struct CreateWorldDestMainMenu : public CreateWorldDest
{
CreateWorldDestMainMenu(GUIMainMenu *menu):
m_menu(menu)
{}
void accepted(std::wstring name, std::string gameid)
{
std::string name_narrow = wide_to_narrow(name);
if(!string_allowed_blacklist(name_narrow, WORLDNAME_BLACKLISTED_CHARS))
{
m_menu->displayMessageMenu(wgettext("Cannot create world: Name contains invalid characters"));
return;
}
std::vector<WorldSpec> worlds = getAvailableWorlds();
for(std::vector<WorldSpec>::iterator i = worlds.begin();
i != worlds.end(); i++)
{
if((*i).name == name_narrow)
{
m_menu->displayMessageMenu(wgettext("Cannot create world: A world by this name already exists"));
return;
}
}
m_menu->createNewWorld(name, gameid);
}
GUIMainMenu *m_menu;
};
struct ConfirmDestDeleteWorld : public ConfirmDest
{
2012-03-25 19:19:41 -04:00
ConfirmDestDeleteWorld(WorldSpec spec, GUIMainMenu *menu,
const std::vector<std::string> &paths):
m_spec(spec),
2012-03-25 19:19:41 -04:00
m_menu(menu),
m_paths(paths)
{}
void answer(bool answer)
{
if(answer == false)
return;
2012-03-25 19:19:41 -04:00
m_menu->deleteWorld(m_paths);
}
WorldSpec m_spec;
GUIMainMenu *m_menu;
2012-03-25 19:19:41 -04:00
std::vector<std::string> m_paths;
};
enum
{
GUI_ID_QUIT_BUTTON = 101,
GUI_ID_NAME_INPUT,
GUI_ID_ADDRESS_INPUT,
GUI_ID_PORT_INPUT,
GUI_ID_FANCYTREE_CB,
GUI_ID_SMOOTH_LIGHTING_CB,
GUI_ID_3D_CLOUDS_CB,
GUI_ID_OPAQUE_WATER_CB,
GUI_ID_MIPMAP_CB,
GUI_ID_ANISOTROPIC_CB,
GUI_ID_BILINEAR_CB,
GUI_ID_TRILINEAR_CB,
GUI_ID_SHADERS_CB,
GUI_ID_PRELOAD_ITEM_VISUALS_CB,
2012-12-31 13:33:36 -05:00
GUI_ID_ENABLE_PARTICLES_CB,
GUI_ID_LIQUID_FINITE_CB,
GUI_ID_DAMAGE_CB,
GUI_ID_CREATIVE_CB,
2013-02-21 17:00:44 -05:00
GUI_ID_PUBLIC_CB,
GUI_ID_JOIN_GAME_BUTTON,
GUI_ID_CHANGE_KEYS_BUTTON,
GUI_ID_DELETE_WORLD_BUTTON,
GUI_ID_CREATE_WORLD_BUTTON,
2012-03-15 07:59:48 -04:00
GUI_ID_CONFIGURE_WORLD_BUTTON,
GUI_ID_WORLD_LISTBOX,
GUI_ID_TAB_CONTROL,
GUI_ID_SERVERLIST,
GUI_ID_SERVERLIST_TOGGLE,
GUI_ID_SERVERLIST_DELETE,
GUI_ID_SERVERLIST_TITLE,
};
enum
{
TAB_SINGLEPLAYER=0,
TAB_MULTIPLAYER,
2012-03-15 07:59:48 -04:00
TAB_ADVANCED,
TAB_SETTINGS,
2012-03-15 07:59:48 -04:00
TAB_CREDITS
};
2011-01-23 10:29:15 -05:00
GUIMainMenu::GUIMainMenu(gui::IGUIEnvironment* env,
gui::IGUIElement* parent, s32 id,
IMenuManager *menumgr,
MainMenuData *data,
IGameCallback *gamecallback
):
GUIModalMenu(env, parent, id, menumgr),
m_data(data),
m_accepted(false),
m_gamecallback(gamecallback),
m_is_regenerating(false)
2011-01-23 10:29:15 -05:00
{
assert(m_data);
this->env = env;
this->parent = parent;
this->id = id;
this->menumgr = menumgr;
2011-01-23 10:29:15 -05:00
}
GUIMainMenu::~GUIMainMenu()
{
removeChildren();
}
void GUIMainMenu::removeChildren()
{
const core::list<gui::IGUIElement*> &children = getChildren();
core::list<gui::IGUIElement*> children_copy;
for(core::list<gui::IGUIElement*>::ConstIterator
i = children.begin(); i != children.end(); i++)
{
children_copy.push_back(*i);
}
for(core::list<gui::IGUIElement*>::Iterator
i = children_copy.begin();
i != children_copy.end(); i++)
{
(*i)->remove();
}
}
void GUIMainMenu::regenerateGui(v2u32 screensize)
{
m_is_regenerating = true;
2012-03-11 15:12:27 -04:00
/*
Read stuff from elements into m_data
*/
readInput(m_data);
2011-01-23 10:29:15 -05:00
/*
Remove stuff
*/
removeChildren();
/*
Calculate new sizes and positions
*/
2012-03-15 07:59:48 -04:00
v2s32 size(screensize.X, screensize.Y);
2011-01-23 10:29:15 -05:00
core::rect<s32> rect(
screensize.X/2 - size.X/2,
screensize.Y/2 - size.Y/2,
screensize.X/2 + size.X/2,
screensize.Y/2 + size.Y/2
2011-01-23 10:29:15 -05:00
);
2011-01-23 10:29:15 -05:00
DesiredRect = rect;
recalculateAbsolutePosition(false);
//v2s32 size = rect.getSize();
2011-01-23 10:29:15 -05:00
/*
Add stuff
*/
2012-03-15 07:59:48 -04:00
changeCtype("");
2012-03-15 07:59:48 -04:00
// Version
{
core::rect<s32> rect(0, 0, size.X, 40);
rect += v2s32(4, 0);
Environment->addStaticText(narrow_to_wide(
2012-12-06 14:01:45 -05:00
"Minetest " VERSION_STRING).c_str(),
2012-03-15 07:59:48 -04:00
rect, false, true, this, -1);
}
//v2s32 center(size.X/2, size.Y/2);
v2s32 c800(size.X/2-400, size.Y/2-270);
2012-03-15 07:59:48 -04:00
m_topleft_client = c800 + v2s32(90, 70+50+30);
m_size_client = v2s32(620, 270);
2012-03-15 07:59:48 -04:00
m_size_server = v2s32(620, 140);
2012-03-15 15:37:43 -04:00
2012-03-15 08:17:05 -04:00
if(m_data->selected_tab == TAB_ADVANCED)
2012-03-15 07:59:48 -04:00
{
2012-03-15 15:37:43 -04:00
m_topleft_client = c800 + v2s32(90, 70+50+30);
m_size_client = v2s32(620, 200);
2012-03-15 07:59:48 -04:00
m_size_server = v2s32(620, 140);
}
2012-03-15 15:37:43 -04:00
m_topleft_server = m_topleft_client + v2s32(0, m_size_client.Y+20);
// Tabs
{
2012-03-15 07:59:48 -04:00
core::rect<s32> rect(0, 0, m_size_client.X, 30);
rect += m_topleft_client + v2s32(0, -30);
gui::IGUITabControl *e = Environment->addTabControl(
rect, this, true, true, GUI_ID_TAB_CONTROL);
e->addTab(wgettext("Singleplayer"));
e->addTab(wgettext("Multiplayer"));
e->addTab(wgettext("Advanced"));
e->addTab(wgettext("Settings"));
e->addTab(wgettext("Credits"));
2012-03-15 08:17:05 -04:00
e->setActiveTab(m_data->selected_tab);
}
2012-03-15 07:59:48 -04:00
2012-03-15 08:17:05 -04:00
if(m_data->selected_tab == TAB_SINGLEPLAYER)
{
2012-03-15 07:59:48 -04:00
// HYBRID
{
2012-03-15 15:37:43 -04:00
core::rect<s32> rect(0, 0, 10, m_size_client.Y);
rect += m_topleft_client + v2s32(15, 0);
//const wchar_t *text = L"H\nY\nB\nR\nI\nD";
const wchar_t *text = L"S\nI\nN\nG\nL\nE\n \nP\nL\nA\nY\nE\nR\n";
2012-03-15 15:37:43 -04:00
gui::IGUIStaticText *t =
2013-02-03 07:19:09 -05:00
Environment->addStaticText(text, rect, false, true, this, -1);
2012-03-15 15:37:43 -04:00
t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
2012-03-15 07:59:48 -04:00
}
u32 bs = 5;
// World selection listbox
u32 world_sel_h = 160;
u32 world_sel_w = 365;
//s32 world_sel_x = 50;
s32 world_sel_x = m_size_client.X-world_sel_w-30;
s32 world_sel_y = 30;
u32 world_button_count = 3;
u32 world_button_w = (world_sel_w)/world_button_count - bs
+ bs/(world_button_count-1);
{
core::rect<s32> rect(0, 0, world_sel_w-4, 20);
rect += m_topleft_client + v2s32(world_sel_x+4, world_sel_y-20);
/*gui::IGUIStaticText *e =*/ Environment->addStaticText(
wgettext("Select World:"),
rect, false, true, this, -1);
/*e->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);*/
}
{
core::rect<s32> rect(0, 0, world_sel_w, world_sel_h);
rect += m_topleft_client + v2s32(world_sel_x, world_sel_y);
gui::IGUIListBox *e = Environment->addListBox(rect, this,
GUI_ID_WORLD_LISTBOX);
e->setDrawBackground(true);
for(std::vector<WorldSpec>::const_iterator i = m_data->worlds.begin();
i != m_data->worlds.end(); i++){
e->addItem(narrow_to_wide(i->name+" ["+i->gameid+"]").c_str());
}
e->setSelected(m_data->selected_world);
2012-03-15 08:17:05 -04:00
Environment->setFocus(e);
2012-03-15 07:59:48 -04:00
}
// Delete world button
{
core::rect<s32> rect(0, 0, world_button_w, 30);
rect += m_topleft_client + v2s32(world_sel_x, world_sel_y+world_sel_h+0);
Environment->addButton(rect, this, GUI_ID_DELETE_WORLD_BUTTON,
wgettext("Delete"));
}
// Create world button
{
core::rect<s32> rect(0, 0, world_button_w, 30);
rect += m_topleft_client + v2s32(world_sel_x+world_button_w+bs, world_sel_y+world_sel_h+0);
Environment->addButton(rect, this, GUI_ID_CREATE_WORLD_BUTTON,
wgettext("New"));
}
// Configure world button
{
core::rect<s32> rect(0, 0, world_button_w, 30);
rect += m_topleft_client + v2s32(world_sel_x+(world_button_w+bs)*2,
world_sel_y+world_sel_h+0);
Environment->addButton(rect, this, GUI_ID_CONFIGURE_WORLD_BUTTON,
wgettext("Configure"));
}
// Start game button
{
/*core::rect<s32> rect(0, 0, world_button_w, 30);
rect += m_topleft_client + v2s32(world_sel_x+(world_button_w+bs)*3,
world_sel_y+world_sel_h+0);*/
u32 bw = 160;
2012-03-15 15:37:43 -04:00
/*core::rect<s32> rect(0, 0, bw, 30);
rect += m_topleft_client + v2s32(m_size_client.X-bw-30,
m_size_client.Y-30-15);*/
2012-03-15 07:59:48 -04:00
core::rect<s32> rect(0, 0, bw, 30);
rect += m_topleft_client + v2s32(world_sel_x+world_sel_w-bw,
world_sel_y+world_sel_h+30+bs);
Environment->addButton(rect, this,
GUI_ID_JOIN_GAME_BUTTON, wgettext("Play"));
}
// Options
s32 option_x = 50;
2012-03-15 15:37:43 -04:00
//s32 option_x = 50+world_sel_w+20;
2012-03-15 07:59:48 -04:00
s32 option_y = 30;
u32 option_w = 150;
2012-03-15 07:59:48 -04:00
{
core::rect<s32> rect(0, 0, option_w, 30);
rect += m_topleft_client + v2s32(option_x, option_y+20*0);
2012-03-15 07:59:48 -04:00
Environment->addCheckBox(m_data->creative_mode, rect, this,
GUI_ID_CREATIVE_CB, wgettext("Creative Mode"));
}
{
core::rect<s32> rect(0, 0, option_w, 30);
rect += m_topleft_client + v2s32(option_x, option_y+20*1);
2012-03-15 07:59:48 -04:00
Environment->addCheckBox(m_data->enable_damage, rect, this,
GUI_ID_DAMAGE_CB, wgettext("Enable Damage"));
}
changeCtype("C");
}
2012-03-15 08:17:05 -04:00
else if(m_data->selected_tab == TAB_MULTIPLAYER)
{
2012-03-15 07:59:48 -04:00
changeCtype("");
// CLIENT
{
2012-03-15 15:37:43 -04:00
core::rect<s32> rect(0, 0, 10, m_size_client.Y);
rect += m_topleft_client + v2s32(15, 0);
2012-03-15 07:59:48 -04:00
const wchar_t *text = L"C\nL\nI\nE\nN\nT";
2012-03-15 15:37:43 -04:00
gui::IGUIStaticText *t =
2013-02-03 07:19:09 -05:00
Environment->addStaticText(text, rect, false, true, this, -1);
2012-03-15 15:37:43 -04:00
t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
2012-03-15 07:59:48 -04:00
}
// Nickname + password
{
core::rect<s32> rect(0, 0, 110, 20);
rect += m_topleft_client + v2s32(m_size_client.X-60-100, 10+6);
2012-03-15 07:59:48 -04:00
Environment->addStaticText(wgettext("Name/Password"),
rect, false, true, this, -1);
}
changeCtype("C");
{
core::rect<s32> rect(0, 0, 120, 30);
rect += m_topleft_client + v2s32(m_size_client.X-60-100, 50);
2012-03-15 07:59:48 -04:00
gui::IGUIElement *e =
Environment->addEditBox(m_data->name.c_str(), rect, true, this, GUI_ID_NAME_INPUT);
if(m_data->name == L"")
Environment->setFocus(e);
}
{
core::rect<s32> rect(0, 0, 120, 30);
rect += m_topleft_client + v2s32(m_size_client.X-60-100, 90);
2012-03-15 07:59:48 -04:00
gui::IGUIEditBox *e =
Environment->addEditBox(L"", rect, true, this, 264);
e->setPasswordBox(true);
if(m_data->name != L"" && m_data->address != L"")
Environment->setFocus(e);
}
changeCtype("");
// Server List
{
core::rect<s32> rect(0, 0, 390, 140);
rect += m_topleft_client + v2s32(50, 30);
gui::IGUIListBox *e = Environment->addListBox(rect, this,
GUI_ID_SERVERLIST);
e->setDrawBackground(true);
#if USE_CURL
if(m_data->selected_serverlist == SERVERLIST_FAVORITES) {
m_data->servers = ServerList::getLocal();
{
core::rect<s32> rect(0, 0, 390, 20);
rect += m_topleft_client + v2s32(50, 10);
Environment->addStaticText(wgettext("Favorites:"),
rect, false, true, this, GUI_ID_SERVERLIST_TITLE);
}
} else {
m_data->servers = ServerList::getOnline();
{
core::rect<s32> rect(0, 0, 390, 20);
rect += m_topleft_client + v2s32(50, 10);
Environment->addStaticText(wgettext("Public Server List:"),
rect, false, true, this, GUI_ID_SERVERLIST_TITLE);
}
}
#else
m_data->servers = ServerList::getLocal();
{
core::rect<s32> rect(0, 0, 390, 20);
rect += m_topleft_client + v2s32(50, 10);
Environment->addStaticText(wgettext("Favorites:"),
rect, false, true, this, GUI_ID_SERVERLIST_TITLE);
}
#endif
updateGuiServerList();
e->setSelected(0);
}
2012-03-15 07:59:48 -04:00
// Address + port
{
core::rect<s32> rect(0, 0, 110, 20);
rect += m_topleft_client + v2s32(50, m_size_client.Y-50-15+6);
2012-03-15 07:59:48 -04:00
Environment->addStaticText(wgettext("Address/Port"),
rect, false, true, this, -1);
}
changeCtype("C");
{
core::rect<s32> rect(0, 0, 260, 30);
rect += m_topleft_client + v2s32(50, m_size_client.Y-25-15);
2012-03-15 07:59:48 -04:00
gui::IGUIElement *e =
Environment->addEditBox(m_data->address.c_str(), rect, true,
this, GUI_ID_ADDRESS_INPUT);
if(m_data->name != L"" && m_data->address == L"")
Environment->setFocus(e);
}
{
core::rect<s32> rect(0, 0, 120, 30);
rect += m_topleft_client + v2s32(50+260+10, m_size_client.Y-25-15);
2012-03-15 07:59:48 -04:00
Environment->addEditBox(m_data->port.c_str(), rect, true,
this, GUI_ID_PORT_INPUT);
}
changeCtype("");
#if USE_CURL
// Toggle Serverlist (Favorites/Online)
{
core::rect<s32> rect(0, 0, 260, 30);
rect += m_topleft_client + v2s32(50,
180);
gui::IGUIButton *e = Environment->addButton(rect, this, GUI_ID_SERVERLIST_TOGGLE,
wgettext("Show Public"));
e->setIsPushButton(true);
if (m_data->selected_serverlist == SERVERLIST_PUBLIC)
{
e->setText(wgettext("Show Favorites"));
e->setPressed();
}
}
#endif
// Delete Local Favorite
{
core::rect<s32> rect(0, 0, 120, 30);
rect += m_topleft_client + v2s32(50+260+10, 180);
gui::IGUIButton *e = Environment->addButton(rect, this, GUI_ID_SERVERLIST_DELETE,
wgettext("Delete"));
if (m_data->selected_serverlist == SERVERLIST_PUBLIC) // Hidden when on public list
e->setVisible(false);
}
2012-03-15 07:59:48 -04:00
// Start game button
{
core::rect<s32> rect(0, 0, 120, 30);
rect += m_topleft_client + v2s32(m_size_client.X-130-30,
m_size_client.Y-25-15);
2012-03-15 07:59:48 -04:00
Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON,
wgettext("Connect"));
2012-03-15 07:59:48 -04:00
}
changeCtype("C");
}
2012-03-15 08:17:05 -04:00
else if(m_data->selected_tab == TAB_ADVANCED)
2011-01-23 10:29:15 -05:00
{
2012-03-15 07:59:48 -04:00
changeCtype("");
// CLIENT
{
2012-03-15 15:37:43 -04:00
core::rect<s32> rect(0, 0, 10, m_size_client.Y);
rect += m_topleft_client + v2s32(15, 0);
2012-03-15 07:59:48 -04:00
const wchar_t *text = L"C\nL\nI\nE\nN\nT";
2012-03-15 15:37:43 -04:00
gui::IGUIStaticText *t =
2013-02-03 07:19:09 -05:00
Environment->addStaticText(text, rect, false, true, this, -1);
2012-03-15 15:37:43 -04:00
t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
2012-03-15 07:59:48 -04:00
}
// Nickname + password
{
core::rect<s32> rect(0, 0, 110, 20);
2012-03-15 15:37:43 -04:00
rect += m_topleft_client + v2s32(35+30, 35+6);
Environment->addStaticText(wgettext("Name/Password"),
rect, false, true, this, -1);
}
changeCtype("C");
{
core::rect<s32> rect(0, 0, 230, 30);
2012-03-15 15:37:43 -04:00
rect += m_topleft_client + v2s32(160+30, 35);
gui::IGUIElement *e =
Environment->addEditBox(m_data->name.c_str(), rect, true, this, GUI_ID_NAME_INPUT);
if(m_data->name == L"")
Environment->setFocus(e);
}
{
core::rect<s32> rect(0, 0, 120, 30);
2012-03-15 15:37:43 -04:00
rect += m_topleft_client + v2s32(m_size_client.X-60-100, 35);
gui::IGUIEditBox *e =
Environment->addEditBox(L"", rect, true, this, 264);
e->setPasswordBox(true);
if(m_data->name != L"" && m_data->address != L"")
Environment->setFocus(e);
}
changeCtype("");
// Address + port
{
core::rect<s32> rect(0, 0, 110, 20);
2012-03-15 15:37:43 -04:00
rect += m_topleft_client + v2s32(35+30, 75+6);
Environment->addStaticText(wgettext("Address/Port"),
rect, false, true, this, -1);
}
changeCtype("C");
{
core::rect<s32> rect(0, 0, 230, 30);
2012-03-15 15:37:43 -04:00
rect += m_topleft_client + v2s32(160+30, 75);
gui::IGUIElement *e =
2012-03-15 07:59:48 -04:00
Environment->addEditBox(m_data->address.c_str(), rect, true,
this, GUI_ID_ADDRESS_INPUT);
if(m_data->name != L"" && m_data->address == L"")
Environment->setFocus(e);
}
{
core::rect<s32> rect(0, 0, 120, 30);
2012-03-15 15:37:43 -04:00
rect += m_topleft_client + v2s32(m_size_client.X-60-100, 75);
2012-03-15 07:59:48 -04:00
Environment->addEditBox(m_data->port.c_str(), rect, true,
this, GUI_ID_PORT_INPUT);
}
changeCtype("");
{
core::rect<s32> rect(0, 0, 400, 20);
2012-03-15 15:37:43 -04:00
rect += m_topleft_client + v2s32(160+30, 75+35);
Environment->addStaticText(wgettext("Leave address blank to start a local server."),
rect, false, true, this, -1);
}
2012-03-15 07:59:48 -04:00
// Start game button
{
core::rect<s32> rect(0, 0, 180, 30);
rect += m_topleft_client + v2s32(m_size_client.X-180-30,
m_size_client.Y-30-20);
Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON,
wgettext("Start Game / Connect"));
}
/*
Server section
*/
// SERVER
{
2012-03-15 15:37:43 -04:00
core::rect<s32> rect(0, 0, 10, m_size_server.Y);
rect += m_topleft_server + v2s32(15, 0);
const wchar_t *text = L"S\nE\nR\nV\nE\nR";
2012-03-15 15:37:43 -04:00
gui::IGUIStaticText *t =
2013-02-03 07:19:09 -05:00
Environment->addStaticText(text, rect, false, true, this, -1);
2012-03-15 15:37:43 -04:00
t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
}
// Server parameters
{
core::rect<s32> rect(0, 0, 250, 30);
2012-03-15 07:59:48 -04:00
rect += m_topleft_server + v2s32(30+20+250+20, 20);
Environment->addCheckBox(m_data->creative_mode, rect, this, GUI_ID_CREATIVE_CB,
wgettext("Creative Mode"));
}
{
core::rect<s32> rect(0, 0, 250, 30);
2012-03-15 07:59:48 -04:00
rect += m_topleft_server + v2s32(30+20+250+20, 40);
Environment->addCheckBox(m_data->enable_damage, rect, this, GUI_ID_DAMAGE_CB,
wgettext("Enable Damage"));
}
2013-02-21 17:00:44 -05:00
#if USE_CURL
{
core::rect<s32> rect(0, 0, 250, 30);
rect += m_topleft_server + v2s32(30+20+250+20, 60);
Environment->addCheckBox(m_data->enable_public, rect, this, GUI_ID_PUBLIC_CB,
wgettext("Public"));
}
#endif
// Delete world button
{
core::rect<s32> rect(0, 0, 130, 30);
2012-03-15 07:59:48 -04:00
rect += m_topleft_server + v2s32(30+20+250+20, 90);
Environment->addButton(rect, this, GUI_ID_DELETE_WORLD_BUTTON,
wgettext("Delete world"));
}
// Create world button
{
core::rect<s32> rect(0, 0, 130, 30);
2012-03-15 07:59:48 -04:00
rect += m_topleft_server + v2s32(30+20+250+20+140, 90);
Environment->addButton(rect, this, GUI_ID_CREATE_WORLD_BUTTON,
wgettext("Create world"));
}
// World selection listbox
{
core::rect<s32> rect(0, 0, 250, 120);
2012-03-15 07:59:48 -04:00
rect += m_topleft_server + v2s32(30+20, 10);
gui::IGUIListBox *e = Environment->addListBox(rect, this,
GUI_ID_WORLD_LISTBOX);
e->setDrawBackground(true);
for(std::vector<WorldSpec>::const_iterator i = m_data->worlds.begin();
i != m_data->worlds.end(); i++){
e->addItem(narrow_to_wide(i->name+" ["+i->gameid+"]").c_str());
}
e->setSelected(m_data->selected_world);
}
2012-03-15 07:59:48 -04:00
changeCtype("C");
}
else if(m_data->selected_tab == TAB_SETTINGS)
{
{
2012-03-15 15:37:43 -04:00
core::rect<s32> rect(0, 0, 10, m_size_client.Y);
rect += m_topleft_client + v2s32(15, 0);
const wchar_t *text = L"S\nE\nT\nT\nI\nN\nG\nS";
2012-03-15 15:37:43 -04:00
gui::IGUIStaticText *t =
2013-02-03 07:19:09 -05:00
Environment->addStaticText(text, rect, false, true, this, -1);
2012-03-15 15:37:43 -04:00
t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
}
s32 option_x = 70;
s32 option_y = 50;
u32 option_w = 150;
{
core::rect<s32> rect(0, 0, option_w, 30);
rect += m_topleft_client + v2s32(option_x, option_y);
Environment->addCheckBox(m_data->fancy_trees, rect, this,
GUI_ID_FANCYTREE_CB, wgettext("Fancy trees"));
}
{
core::rect<s32> rect(0, 0, option_w, 30);
rect += m_topleft_client + v2s32(option_x, option_y+20);
Environment->addCheckBox(m_data->smooth_lighting, rect, this,
GUI_ID_SMOOTH_LIGHTING_CB, wgettext("Smooth Lighting"));
}
{
core::rect<s32> rect(0, 0, option_w, 30);
rect += m_topleft_client + v2s32(option_x, option_y+20*2);
Environment->addCheckBox(m_data->clouds_3d, rect, this,
GUI_ID_3D_CLOUDS_CB, wgettext("3D Clouds"));
}
{
core::rect<s32> rect(0, 0, option_w, 30);
rect += m_topleft_client + v2s32(option_x, option_y+20*3);
Environment->addCheckBox(m_data->opaque_water, rect, this,
GUI_ID_OPAQUE_WATER_CB, wgettext("Opaque water"));
}
// Anisotropic/mipmap/bi-/trilinear settings
{
core::rect<s32> rect(0, 0, option_w+20, 30);
rect += m_topleft_client + v2s32(option_x+175, option_y);
Environment->addCheckBox(m_data->mip_map, rect, this,
GUI_ID_MIPMAP_CB, wgettext("Mip-Mapping"));
}
{
core::rect<s32> rect(0, 0, option_w+20, 30);
rect += m_topleft_client + v2s32(option_x+175, option_y+20);
Environment->addCheckBox(m_data->anisotropic_filter, rect, this,
GUI_ID_ANISOTROPIC_CB, wgettext("Anisotropic Filtering"));
}
{
core::rect<s32> rect(0, 0, option_w+20, 30);
rect += m_topleft_client + v2s32(option_x+175, option_y+20*2);
Environment->addCheckBox(m_data->bilinear_filter, rect, this,
GUI_ID_BILINEAR_CB, wgettext("Bi-Linear Filtering"));
}
{
core::rect<s32> rect(0, 0, option_w+20, 30);
rect += m_topleft_client + v2s32(option_x+175, option_y+20*3);
Environment->addCheckBox(m_data->trilinear_filter, rect, this,
GUI_ID_TRILINEAR_CB, wgettext("Tri-Linear Filtering"));
}
2012-12-31 13:33:36 -05:00
// shader/on demand image loading/particles settings
{
core::rect<s32> rect(0, 0, option_w+20, 30);
rect += m_topleft_client + v2s32(option_x+175*2, option_y);
Environment->addCheckBox(m_data->enable_shaders, rect, this,
GUI_ID_SHADERS_CB, wgettext("Shaders"));
}
{
core::rect<s32> rect(0, 0, option_w+20+20, 30);
rect += m_topleft_client + v2s32(option_x+175*2, option_y+20);
Environment->addCheckBox(m_data->preload_item_visuals, rect, this,
GUI_ID_PRELOAD_ITEM_VISUALS_CB, wgettext("Preload item visuals"));
}
2012-12-31 13:33:36 -05:00
{
core::rect<s32> rect(0, 0, option_w+20+20, 30);
rect += m_topleft_client + v2s32(option_x+175*2, option_y+20*2);
Environment->addCheckBox(m_data->enable_particles, rect, this,
GUI_ID_ENABLE_PARTICLES_CB, wgettext("Enable Particles"));
}
{
core::rect<s32> rect(0, 0, option_w+20+20, 30);
rect += m_topleft_client + v2s32(option_x+175*2, option_y+20*3);
Environment->addCheckBox(m_data->liquid_finite, rect, this,
GUI_ID_LIQUID_FINITE_CB, wgettext("Finite liquid"));
}
// Key change button
{
core::rect<s32> rect(0, 0, 120, 30);
/*rect += m_topleft_client + v2s32(m_size_client.X-120-30,
m_size_client.Y-30-20);*/
rect += m_topleft_client + v2s32(option_x, option_y+120);
Environment->addButton(rect, this,
GUI_ID_CHANGE_KEYS_BUTTON, wgettext("Change keys"));
}
changeCtype("C");
}
2012-03-15 08:17:05 -04:00
else if(m_data->selected_tab == TAB_CREDITS)
2012-03-15 07:59:48 -04:00
{
// CREDITS
{
core::rect<s32> rect(0, 0, 9, m_size_client.Y);
2012-03-15 15:37:43 -04:00
rect += m_topleft_client + v2s32(15, 0);
2012-03-15 07:59:48 -04:00
const wchar_t *text = L"C\nR\nE\nD\nI\nT\nS";
2012-03-15 15:37:43 -04:00
gui::IGUIStaticText *t =
2013-02-03 07:19:09 -05:00
Environment->addStaticText(text, rect, false, true, this, -1);
2012-03-15 15:37:43 -04:00
t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
2012-03-15 07:59:48 -04:00
}
{
core::rect<s32> rect(0, 0, 130, 70);
rect += m_topleft_client + v2s32(35, 160);
Environment->addStaticText(
L"Minetest " LSTRING(VERSION_STRING) L"\nhttp://minetest.net/",
rect, false, true, this, -1);
}
{
video::SColor yellow(255, 255, 255, 0);
core::rect<s32> rect(0, 0, 450, 260);
rect += m_topleft_client + v2s32(168, 5);
irr::gui::IGUIListBox *list = Environment->addListBox(rect, this);
list->addItem(L"Core Developers");
list->setItemOverrideColor(list->getItemCount() - 1, yellow);
for (int i = 0; i != ARRAYLEN(contrib_core_strs); i++)
list->addItem(contrib_core_strs[i]);
list->addItem(L"");
list->addItem(L"Active Contributors");
list->setItemOverrideColor(list->getItemCount() - 1, yellow);
for (int i = 0; i != ARRAYLEN(contrib_active_strs); i++)
list->addItem(contrib_active_strs[i]);
list->addItem(L"");
list->addItem(L"Previous Contributors");
list->setItemOverrideColor(list->getItemCount() - 1, yellow);
for (int i = 0; i != ARRAYLEN(contrib_previous_strs); i++)
list->addItem(contrib_previous_strs[i]);
list->addItem(L"");
2012-03-15 07:59:48 -04:00
}
}
m_is_regenerating = false;
2011-01-23 10:29:15 -05:00
}
void GUIMainMenu::drawMenu()
{
gui::IGUISkin* skin = Environment->getSkin();
if (!skin)
return;
video::IVideoDriver* driver = Environment->getVideoDriver();
/*video::SColor bgcolor(140,0,0,0);
driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect);*/
2011-01-23 10:29:15 -05:00
video::SColor bgcolor(140,0,0,0);
2012-03-15 07:59:48 -04:00
if(getTab() == TAB_SINGLEPLAYER)
{
2012-03-15 07:59:48 -04:00
{
core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y);
rect += AbsoluteRect.UpperLeftCorner + m_topleft_client;
driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
}
}
2012-03-15 07:59:48 -04:00
else if(getTab() == TAB_MULTIPLAYER)
{
{
core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y);
rect += AbsoluteRect.UpperLeftCorner + m_topleft_client;
driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
}
}
else if(getTab() == TAB_ADVANCED)
{
{
core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y);
rect += AbsoluteRect.UpperLeftCorner + m_topleft_client;
driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
}
{
core::rect<s32> rect(0, 0, m_size_server.X, m_size_server.Y);
rect += AbsoluteRect.UpperLeftCorner + m_topleft_server;
driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
}
}
else if(getTab() == TAB_SETTINGS)
{
{
core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y);
rect += AbsoluteRect.UpperLeftCorner + m_topleft_client;
driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
}
}
2012-03-15 07:59:48 -04:00
else if(getTab() == TAB_CREDITS)
{
2012-03-15 07:59:48 -04:00
{
core::rect<s32> rect(0, 0, m_size_client.X, m_size_client.Y);
rect += AbsoluteRect.UpperLeftCorner + m_topleft_client;
driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
}
video::ITexture *logotexture =
driver->getTexture(getTexturePath("logo.png").c_str());
2012-03-15 07:59:48 -04:00
if(logotexture)
{
v2s32 logosize(logotexture->getOriginalSize().Width,
logotexture->getOriginalSize().Height);
2012-03-15 07:59:48 -04:00
core::rect<s32> rect(0,0,logosize.X,logosize.Y);
rect += AbsoluteRect.UpperLeftCorner + m_topleft_client;
rect += v2s32(50, 60);
2012-03-15 07:59:48 -04:00
driver->draw2DImage(logotexture, rect,
core::rect<s32>(core::position2d<s32>(0,0),
core::dimension2di(logotexture->getSize())),
NULL, NULL, true);
}
}
2011-01-23 10:29:15 -05:00
gui::IGUIElement::draw();
}
2012-03-11 15:12:27 -04:00
void GUIMainMenu::readInput(MainMenuData *dst)
2011-01-23 10:29:15 -05:00
{
2012-03-15 08:17:05 -04:00
{
gui::IGUIElement *e = getElementFromId(GUI_ID_TAB_CONTROL);
if(e != NULL && e->getType() == gui::EGUIET_TAB_CONTROL)
dst->selected_tab = ((gui::IGUITabControl*)e)->getActiveTab();
}
if(dst->selected_tab == TAB_SINGLEPLAYER)
2011-01-23 10:29:15 -05:00
{
dst->simple_singleplayer_mode = true;
2011-01-23 10:29:15 -05:00
}
else
{
dst->simple_singleplayer_mode = false;
{
gui::IGUIElement *e = getElementFromId(GUI_ID_NAME_INPUT);
if(e != NULL)
dst->name = e->getText();
}
{
gui::IGUIElement *e = getElementFromId(264);
if(e != NULL)
dst->password = e->getText();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_ADDRESS_INPUT);
if(e != NULL)
dst->address = e->getText();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_PORT_INPUT);
if(e != NULL)
dst->port = e->getText();
}
2011-01-23 10:29:15 -05:00
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_CREATIVE_CB);
2011-01-23 10:29:15 -05:00
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
2012-03-11 15:12:27 -04:00
dst->creative_mode = ((gui::IGUICheckBox*)e)->isChecked();
2011-01-23 10:29:15 -05:00
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_DAMAGE_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
2012-03-11 15:12:27 -04:00
dst->enable_damage = ((gui::IGUICheckBox*)e)->isChecked();
}
2013-02-21 17:00:44 -05:00
{
gui::IGUIElement *e = getElementFromId(GUI_ID_PUBLIC_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
dst->enable_public = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_FANCYTREE_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
2012-03-11 15:12:27 -04:00
dst->fancy_trees = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_SMOOTH_LIGHTING_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
2012-03-11 15:12:27 -04:00
dst->smooth_lighting = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_3D_CLOUDS_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
2012-03-11 15:12:27 -04:00
dst->clouds_3d = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_OPAQUE_WATER_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
2012-03-11 15:12:27 -04:00
dst->opaque_water = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_MIPMAP_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
dst->mip_map = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_ANISOTROPIC_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
dst->anisotropic_filter = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_BILINEAR_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
dst->bilinear_filter = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_TRILINEAR_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
dst->trilinear_filter = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_SHADERS_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
dst->enable_shaders = ((gui::IGUICheckBox*)e)->isChecked() ? 2 : 0;
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_PRELOAD_ITEM_VISUALS_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
dst->preload_item_visuals = ((gui::IGUICheckBox*)e)->isChecked();
}
2012-12-31 13:33:36 -05:00
{
gui::IGUIElement *e = getElementFromId(GUI_ID_ENABLE_PARTICLES_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
dst->enable_particles = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_LIQUID_FINITE_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
dst->liquid_finite = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_WORLD_LISTBOX);
if(e != NULL && e->getType() == gui::EGUIET_LIST_BOX)
2012-03-11 15:12:27 -04:00
dst->selected_world = ((gui::IGUIListBox*)e)->getSelected();
}
{
ServerListSpec server =
getServerListSpec(wide_to_narrow(dst->address), wide_to_narrow(dst->port));
2013-02-21 17:00:44 -05:00
dst->servername = server["name"].asString();
dst->serverdescription = server["description"].asString();
}
2012-03-11 15:12:27 -04:00
}
void GUIMainMenu::acceptInput()
{
readInput(m_data);
2011-01-23 10:29:15 -05:00
m_accepted = true;
}
bool GUIMainMenu::OnEvent(const SEvent& event)
{
if(event.EventType==EET_KEY_INPUT_EVENT)
{
if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown)
{
m_gamecallback->exitToOS();
quitMenu();
return true;
}
if(event.KeyInput.Key==KEY_RETURN && event.KeyInput.PressedDown)
{
acceptInput();
quitMenu();
return true;
}
}
if(event.EventType==EET_GUI_EVENT)
{
if(event.GUIEvent.EventType==gui::EGET_ELEMENT_FOCUS_LOST
&& isVisible())
{
if(!canTakeFocus(event.GUIEvent.Element))
{
dstream<<"GUIMainMenu: Not allowing focus change."
<<std::endl;
// Returning true disables focus change
return true;
}
}
if(event.GUIEvent.EventType==gui::EGET_TAB_CHANGED)
{
if(!m_is_regenerating)
regenerateGui(m_screensize_old);
return true;
}
if(event.GUIEvent.EventType==gui::EGET_LISTBOX_CHANGED && event.GUIEvent.Caller->getID() == GUI_ID_SERVERLIST)
{
serverListOnSelected();
return true;
}
2011-01-23 10:29:15 -05:00
if(event.GUIEvent.EventType==gui::EGET_BUTTON_CLICKED)
{
switch(event.GUIEvent.Caller->getID())
{
2012-03-15 07:59:48 -04:00
case GUI_ID_JOIN_GAME_BUTTON: {
MainMenuData cur;
readInput(&cur);
if (getTab() == TAB_MULTIPLAYER && cur.address == L"")
{
2012-03-15 07:59:48 -04:00
(new GUIMessageMenu(env, parent, -1, menumgr,
wgettext("Address required."))
)->drop();
return true;
}
2011-01-23 10:29:15 -05:00
acceptInput();
quitMenu();
2011-02-07 18:12:55 -05:00
return true;
2012-03-15 07:59:48 -04:00
}
case GUI_ID_CHANGE_KEYS_BUTTON: {
GUIKeyChangeMenu *kmenu = new GUIKeyChangeMenu(env, parent, -1,menumgr);
kmenu->drop();
return true;
}
case GUI_ID_DELETE_WORLD_BUTTON: {
MainMenuData cur;
readInput(&cur);
if(cur.selected_world == -1){
(new GUIMessageMenu(env, parent, -1, menumgr,
wgettext("Cannot delete world: Nothing selected"))
)->drop();
} else {
WorldSpec spec = m_data->worlds[cur.selected_world];
2012-03-25 19:19:41 -04:00
// Get files and directories involved
std::vector<std::string> paths;
paths.push_back(spec.path);
fs::GetRecursiveSubPaths(spec.path, paths);
// Launch confirmation dialog
ConfirmDestDeleteWorld *dest = new
2012-03-25 19:19:41 -04:00
ConfirmDestDeleteWorld(spec, this, paths);
std::wstring text = wgettext("Delete world");
text += L" \"";
text += narrow_to_wide(spec.name);
text += L"\"?\n\n";
text += wgettext("Files to be deleted");
text += L":\n";
for(u32 i=0; i<paths.size(); i++){
if(i == 3){ text += L"..."; break; }
text += narrow_to_wide(paths[i]) + L"\n";
}
(new GUIConfirmMenu(env, parent, -1, menumgr, dest,
2012-03-25 19:19:41 -04:00
text.c_str()))->drop();
}
2011-02-07 18:12:55 -05:00
return true;
2011-01-23 10:29:15 -05:00
}
case GUI_ID_CREATE_WORLD_BUTTON: {
std::vector<SubgameSpec> games = getAvailableGames();
if(games.size() == 0){
GUIMessageMenu *menu = new GUIMessageMenu(env, parent,
-1, menumgr,
wgettext("Cannot create world: No games found"));
menu->drop();
} else {
CreateWorldDest *dest = new CreateWorldDestMainMenu(this);
GUICreateWorld *menu = new GUICreateWorld(env, parent, -1,
menumgr, dest, games);
menu->drop();
}
return true;
}
2012-03-15 07:59:48 -04:00
case GUI_ID_CONFIGURE_WORLD_BUTTON: {
Basic support for configuring which mods to load for each world settings.h: added function to return all keys used in settings, and a function to remove a setting mods.{h,cpp}: added class ModConfiguration that represents a subset of the installed mods. server.{h,cpp}: server does not load add-on mods that are disabled in the world.mt file. mods are disabled by a setting of the form "load_mod_<modname> = false". if no load_mod_<modname> = ... setting is found, the mod is loaded anyways for backwards compatibilty. server also complains to errorstream about mods with unstatisfied dependencies and about mods that are not installed. guiConfigureWorld.{h,cpp}: shows a treeview of installed add-on mods and modpacks with little icons in front of their name indicating their status: a checkmark for enabled mods, a cross for disabled mods, a question mark for "new" mods Mods can be enabled/disabled by a checkbox. Mods also show a list of dependencies and reverse dependencies. double-click on a mod in dependency or reverse dependency listbox selects the corresponding mod. Enabling a mod also enables all its dependencies. Disabling a mod also disables all its reverse dependencies. For modpacks, show buttons to enable/disable all mods (recursively, including their dependencies) in it. Button "Save" saves the current settings to the world.mt file and returns to the main menu. Button "Cancel" returns to main menu without saving. basic keyboard controls (if the proper widget has keyboard focus): up/down: scroll through tree of mods left/right: collaps/expand a modpack space: enable/disable the selected mod
2012-12-08 12:10:54 -05:00
MainMenuData cur;
readInput(&cur);
if(cur.selected_world == -1)
{
(new GUIMessageMenu(env, parent, -1, menumgr,
wgettext("Cannot configure world: Nothing selected"))
)->drop();
}
else
{
WorldSpec wspec = m_data->worlds[cur.selected_world];
GUIConfigureWorld *menu = new GUIConfigureWorld(env, parent,
-1, menumgr, wspec);
menu->drop();
}
return true;
2012-03-15 07:59:48 -04:00
}
case GUI_ID_SERVERLIST_DELETE: {
gui::IGUIListBox *serverlist = (gui::IGUIListBox*)getElementFromId(GUI_ID_SERVERLIST);
s32 selected = ((gui::IGUIListBox*)serverlist)->getSelected();
if (selected == -1) return true;
ServerList::deleteEntry(m_data->servers[selected]);
m_data->servers = ServerList::getLocal();
updateGuiServerList();
if (selected > 0)
selected -= 1;
serverlist->setSelected(selected);
serverListOnSelected();
return true;
}
#if USE_CURL
case GUI_ID_SERVERLIST_TOGGLE: {
gui::IGUIElement *togglebutton = getElementFromId(GUI_ID_SERVERLIST_TOGGLE);
gui::IGUIElement *deletebutton = getElementFromId(GUI_ID_SERVERLIST_DELETE);
gui::IGUIListBox *serverlist = (gui::IGUIListBox*)getElementFromId(GUI_ID_SERVERLIST);
gui::IGUIElement *title = getElementFromId(GUI_ID_SERVERLIST_TITLE);
if (m_data->selected_serverlist == SERVERLIST_PUBLIC) // switch to favorite list
{
m_data->servers = ServerList::getLocal();
togglebutton->setText(wgettext("Show Public"));
title->setText(wgettext("Favorites:"));
deletebutton->setVisible(true);
updateGuiServerList();
serverlist->setSelected(0);
m_data->selected_serverlist = SERVERLIST_FAVORITES;
}
else // switch to online list
{
m_data->servers = ServerList::getOnline();
togglebutton->setText(wgettext("Show Favorites"));
title->setText(wgettext("Public Server List:"));
deletebutton->setVisible(false);
updateGuiServerList();
serverlist->setSelected(0);
m_data->selected_serverlist = SERVERLIST_PUBLIC;
}
serverListOnSelected();
}
#endif
}
2011-01-23 10:29:15 -05:00
}
if(event.GUIEvent.EventType==gui::EGET_EDITBOX_ENTER)
{
switch(event.GUIEvent.Caller->getID())
{
case GUI_ID_ADDRESS_INPUT: case GUI_ID_PORT_INPUT: case GUI_ID_NAME_INPUT: case 264:
MainMenuData cur;
readInput(&cur);
if (getTab() == TAB_MULTIPLAYER && cur.address == L"")
{
(new GUIMessageMenu(env, parent, -1, menumgr,
wgettext("Address required."))
)->drop();
return true;
}
2011-01-23 10:29:15 -05:00
acceptInput();
quitMenu();
2011-02-07 18:12:55 -05:00
return true;
2011-01-23 10:29:15 -05:00
}
}
if(event.GUIEvent.EventType==gui::EGET_LISTBOX_SELECTED_AGAIN)
{
switch(event.GUIEvent.Caller->getID())
{
case GUI_ID_WORLD_LISTBOX:
acceptInput();
if(getTab() != TAB_SINGLEPLAYER)
m_data->address = L""; // Force local game
quitMenu();
return true;
case GUI_ID_SERVERLIST:
gui::IGUIListBox *serverlist = (gui::IGUIListBox*)getElementFromId(GUI_ID_SERVERLIST);
if (serverlist->getSelected() > -1)
{
acceptInput();
quitMenu();
return true;
}
}
}
2011-01-23 10:29:15 -05:00
}
return Parent ? Parent->OnEvent(event) : false;
}
void GUIMainMenu::createNewWorld(std::wstring name, std::string gameid)
{
if(name == L"")
return;
acceptInput();
m_data->create_world_name = name;
m_data->create_world_gameid = gameid;
quitMenu();
}
2012-03-25 19:19:41 -04:00
void GUIMainMenu::deleteWorld(const std::vector<std::string> &paths)
{
2012-03-25 19:19:41 -04:00
// Delete files
bool did = fs::DeletePaths(paths);
if(!did){
GUIMessageMenu *menu = new GUIMessageMenu(env, parent,
-1, menumgr, wgettext("Failed to delete all world files"));
menu->drop();
}
// Quit menu to refresh it
acceptInput();
2012-03-25 19:19:41 -04:00
m_data->only_refresh = true;
quitMenu();
}
int GUIMainMenu::getTab()
{
gui::IGUIElement *e = getElementFromId(GUI_ID_TAB_CONTROL);
if(e != NULL && e->getType() == gui::EGUIET_TAB_CONTROL)
return ((gui::IGUITabControl*)e)->getActiveTab();
2012-03-15 07:59:48 -04:00
return TAB_SINGLEPLAYER; // Default
}
void GUIMainMenu::displayMessageMenu(std::wstring msg)
{
(new GUIMessageMenu(env, parent, -1, menumgr, msg))->drop();
}
void GUIMainMenu::updateGuiServerList()
{
gui::IGUIListBox *serverlist = (gui::IGUIListBox *)getElementFromId(GUI_ID_SERVERLIST);
serverlist->clear();
for(std::vector<ServerListSpec>::iterator i = m_data->servers.begin();
i != m_data->servers.end(); i++)
{
std::string text;
2013-02-21 17:00:44 -05:00
if ((*i)["clients"].asString().size())
text += (*i)["clients"].asString();
if ((*i)["clients_max"].asString().size())
text += "/" + (*i)["clients_max"].asString();
text += " ";
if ((*i)["version"].asString().size())
text += (*i)["version"].asString() + " ";
if ((*i)["password"].asString().size())
text += "*";
if ((*i)["creative"].asString().size())
text += "C";
if ((*i)["damage"].asString().size())
text += "D";
if ((*i)["pvp"].asString().size())
text += "P";
text += " ";
if ((*i)["name"] != "" && (*i)["description"] != "")
text += (*i)["name"].asString() + " (" + (*i)["description"].asString() + ")";
else if ((*i)["name"] !="")
text += (*i)["name"].asString();
else
text += (*i)["address"].asString() + ":" + (*i)["port"].asString();
serverlist->addItem(narrow_to_wide(text).c_str());
}
}
void GUIMainMenu::serverListOnSelected()
{
if (!m_data->servers.empty())
{
gui::IGUIListBox *serverlist = (gui::IGUIListBox*)getElementFromId(GUI_ID_SERVERLIST);
u16 id = serverlist->getSelected();
2013-02-21 17:00:44 -05:00
//if (id < 0) return; // u16>0!
((gui::IGUIEditBox*)getElementFromId(GUI_ID_ADDRESS_INPUT))
2013-02-21 17:00:44 -05:00
->setText(narrow_to_wide(m_data->servers[id]["address"].asString()).c_str());
((gui::IGUIEditBox*)getElementFromId(GUI_ID_PORT_INPUT))
2013-02-21 17:00:44 -05:00
->setText(narrow_to_wide(m_data->servers[id]["port"].asString()).c_str());
}
}
ServerListSpec GUIMainMenu::getServerListSpec(std::string address, std::string port)
{
ServerListSpec server;
2013-02-21 17:00:44 -05:00
server["address"] = address;
server["port"] = port;
for(std::vector<ServerListSpec>::iterator i = m_data->servers.begin();
i != m_data->servers.end(); i++)
{
2013-02-21 17:00:44 -05:00
if ((*i)["address"] == address && (*i)["port"] == port)
{
2013-02-21 17:00:44 -05:00
server["description"] = (*i)["description"];
server["name"] = (*i)["name"];
break;
}
}
return server;
}