示例#1
0
void GUIMainMenu::regenerateGui(v2u32 screensize)
{
	m_is_regenerating = true;
	/*
		Read stuff from elements into m_data
	*/
	readInput(m_data);

	/*
		Remove stuff
	*/
	removeChildren();
	
	/*
		Calculate new sizes and positions
	*/
	
	v2s32 size(screensize.X, screensize.Y);

	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
	);

	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	//v2s32 size = rect.getSize();

	/*
		Add stuff
	*/

	changeCtype("");

	// Version
	//if(m_data->selected_tab != TAB_CREDITS)
	{
		core::rect<s32> rect(0, 0, size.X, 40);
		rect += v2s32(4, 0);
		Environment->addStaticText(narrow_to_wide(
				"Minetest-c55 " VERSION_STRING).c_str(),
				rect, false, true, this, -1);
	}

	//v2s32 center(size.X/2, size.Y/2);
	v2s32 c800(size.X/2-400, size.Y/2-300);
	
	m_topleft_client = c800 + v2s32(90, 70+50+30);
	m_size_client = v2s32(620, 270);

	m_size_server = v2s32(620, 140);

	if(m_data->selected_tab == TAB_ADVANCED)
	{
		m_topleft_client = c800 + v2s32(90, 70+50+30);
		m_size_client = v2s32(620, 200);

		m_size_server = v2s32(620, 140);
	}

	m_topleft_server = m_topleft_client + v2s32(0, m_size_client.Y+20);
	
	// Tabs
#if 1
	{
		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(L"Singleplayer");
		e->addTab(L"Multiplayer");
		e->addTab(L"Advanced");
		e->addTab(L"Settings");
		e->addTab(L"Credits");
		e->setActiveTab(m_data->selected_tab);
	}
#endif
	
	if(m_data->selected_tab == TAB_SINGLEPLAYER)
	{
		// HYBRID
		{
			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"T\nA\nP\nE\n\nA\nN\nD\n\nG\nL\nU\nE";
			gui::IGUIStaticText *t =
			Environment->addStaticText(text, rect, false, false, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
		}
		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);
			Environment->setFocus(e);
		}
		// 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;
			/*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);*/
			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;
		//s32 option_x = 50+world_sel_w+20;
		s32 option_y = 30;
		u32 option_w = 150;
		{
			core::rect<s32> rect(0, 0, option_w, 30);
			rect += m_topleft_client + v2s32(option_x, option_y+20*0);
			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);
			Environment->addCheckBox(m_data->enable_damage, rect, this,
					GUI_ID_DAMAGE_CB, wgettext("Enable Damage"));
		}
		changeCtype("C");
	}
	else if(m_data->selected_tab == TAB_MULTIPLAYER)
	{
		changeCtype("");
		// CLIENT
		{
			core::rect<s32> rect(0, 0, 10, m_size_client.Y);
			rect += m_topleft_client + v2s32(15, 0);
			const wchar_t *text = L"C\nL\nI\nE\nN\nT";
			gui::IGUIStaticText *t =
			Environment->addStaticText(text, rect, false, false, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
		}
		// Nickname + password
		{
			core::rect<s32> rect(0, 0, 110, 20);
			rect += m_topleft_client + v2s32(35+30, 50+6);
			Environment->addStaticText(wgettext("Name/Password"), 
				rect, false, true, this, -1);
		}
		changeCtype("C");
		{
			core::rect<s32> rect(0, 0, 230, 30);
			rect += m_topleft_client + v2s32(160+30, 50);
			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, 50);
			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);
			rect += m_topleft_client + v2s32(35+30, 100+6);
			Environment->addStaticText(wgettext("Address/Port"),
				rect, false, true, this, -1);
		}
		changeCtype("C");
		{
			core::rect<s32> rect(0, 0, 230, 30);
			rect += m_topleft_client + v2s32(160+30, 100);
			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(m_size_client.X-60-100, 100);
			Environment->addEditBox(m_data->port.c_str(), rect, true,
					this, GUI_ID_PORT_INPUT);
		}
		changeCtype("");
		// 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-15);
			Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON,
				wgettext("Start Game / Connect"));
		}
		changeCtype("C");
	}
	else if(m_data->selected_tab == TAB_ADVANCED)
	{
		changeCtype("");
		// CLIENT
		{
			core::rect<s32> rect(0, 0, 10, m_size_client.Y);
			rect += m_topleft_client + v2s32(15, 0);
			const wchar_t *text = L"C\nL\nI\nE\nN\nT";
			gui::IGUIStaticText *t =
			Environment->addStaticText(text, rect, false, false, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
		}
		// Nickname + password
		{
			core::rect<s32> rect(0, 0, 110, 20);
			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);
			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);
			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);
			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);
			rect += m_topleft_client + v2s32(160+30, 75);
			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(m_size_client.X-60-100, 75);
			Environment->addEditBox(m_data->port.c_str(), rect, true,
					this, GUI_ID_PORT_INPUT);
		}
		changeCtype("");
		{
			core::rect<s32> rect(0, 0, 400, 20);
			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);
		}
		// 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
		{
			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";
			gui::IGUIStaticText *t =
			Environment->addStaticText(text, rect, false, false, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
		}
		// Server parameters
		{
			core::rect<s32> rect(0, 0, 250, 30);
			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);
			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"));
		}
		// Delete world button
		{
			core::rect<s32> rect(0, 0, 130, 30);
			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);
			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);
			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);
		}
		changeCtype("C");
	}
	else if(m_data->selected_tab == TAB_SETTINGS)
	{
		{
			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";
			gui::IGUIStaticText *t =
			Environment->addStaticText(text, rect, false, false, this, -1);
			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"));
		}
		// 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");
	}
	else if(m_data->selected_tab == TAB_CREDITS)
	{
		// CREDITS
		{
			core::rect<s32> rect(0, 0, 10, m_size_client.Y);
			rect += m_topleft_client + v2s32(15, 0);
			const wchar_t *text = L"C\nR\nE\nD\nI\nT\nS";
			gui::IGUIStaticText *t =
			Environment->addStaticText(text, rect, false, false, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
		}
		{
			core::rect<s32> rect(0, 0, 620, 250);
			rect += m_topleft_client + v2s32(130+14, 50+35);
			Environment->addStaticText(narrow_to_wide(
			"Minetest-c55 " VERSION_STRING "\n"
			"http://c55.me/minetest/\n"
			"\n"
			"by Perttu Ahola <*****@*****.**>\n"
			"and contributors"
			).c_str(), rect, false, true, this, -1);
		}
	}

	m_is_regenerating = false;
}
示例#2
0
void GUIMainMenu::regenerateGui(v2u32 screensize)
{
	m_is_regenerating = true;
	/*
		Read stuff from elements into m_data
	*/
	readInput(m_data);

	/*
		Remove stuff
	*/
	removeChildren();
	
	/*
		Calculate new sizes and positions
	*/
	
	v2s32 size(screensize.X, screensize.Y);

	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
	);

	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	//v2s32 size = rect.getSize();

	/*
		Add stuff
	*/

	changeCtype("");

	// Version
	{
		core::rect<s32> rect(0, 0, size.X, 40);
		rect += v2s32(4, 0);
		std::string t = "Minetest " VERSION_STRING;
		if(m_data->selected_game_name != "" &&
				m_data->selected_tab == TAB_SINGLEPLAYER){
			t += "/";
			t += m_data->selected_game_name;
		}
		Environment->addStaticText(narrow_to_wide(t).c_str(),
				rect, false, true, this, -1);
	}

	//v2s32 center(size.X/2, size.Y/2);
	v2s32 c800(size.X/2-400, size.Y/2-270);
	
	m_topleft_client = c800 + v2s32(90, 70+50+30);
	m_size_client = v2s32(620, 270);

	m_size_server = v2s32(620, 140);

	if(m_data->selected_tab == TAB_ADVANCED)
	{
		m_topleft_client = c800 + v2s32(90, 70+50+30);
		m_size_client = v2s32(620, 200);

		m_size_server = v2s32(620, 140);
	}

	m_topleft_server = m_topleft_client + v2s32(0, m_size_client.Y+20);
	
	// Tabs
	{
		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);
		wchar_t* text = wgettext("Singleplayer");
		e->addTab(text);
		delete[] text;
		text = wgettext("Multiplayer");
		e->addTab(text);
		delete[] text;
		text = wgettext("Advanced");
		e->addTab(text);
		delete[] text;
		text = wgettext("Settings");
		e->addTab(text);
		delete[] text;
		text = wgettext("Credits");
		e->addTab(text);
		delete[] text;

		e->setActiveTab(m_data->selected_tab);

	}
	
	if(m_data->selected_tab == TAB_SINGLEPLAYER)
	{
		// HYBRID
		{
			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";
			gui::IGUIStaticText *t =
			Environment->addStaticText(text, rect, false, true, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
		}
		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);
			wchar_t* text = wgettext("Select World:");
			/*gui::IGUIStaticText *e =*/ Environment->addStaticText(
					text,
					rect, false, true, this, -1);
			delete[] text;
			/*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);
			m_world_indices.clear();
			for(size_t wi = 0; wi < m_data->worlds.size(); wi++){
				const WorldSpec &spec = m_data->worlds[wi];
				if(spec.gameid == m_data->selected_game){
					//e->addItem(narrow_to_wide(spec.name+" ["+spec.gameid+"]").c_str());
					e->addItem(narrow_to_wide(spec.name).c_str());
					m_world_indices.push_back(wi);
					if(m_data->selected_world == (int)wi)
						e->setSelected(m_world_indices.size()-1);
				}
			}
			Environment->setFocus(e);
		}
		// 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);
			wchar_t* text = wgettext("Delete");
			Environment->addButton(rect, this, GUI_ID_DELETE_WORLD_BUTTON,
				 text);
			delete[] text;
		}
		// 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);
			wchar_t* text = wgettext("New");
			Environment->addButton(rect, this, GUI_ID_CREATE_WORLD_BUTTON,
				 text);
			delete[] text;
		}
		// 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);
			wchar_t* text = wgettext("Configure");
			Environment->addButton(rect, this, GUI_ID_CONFIGURE_WORLD_BUTTON,
				text);
			delete[] text;
		}
		// 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;
			/*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);*/
			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);
			wchar_t* text = wgettext("Play");
			Environment->addButton(rect, this,
					GUI_ID_JOIN_GAME_BUTTON, text);
			delete[] text;
		}
		// Options
		s32 option_x = 50;
		//s32 option_x = 50+world_sel_w+20;
		s32 option_y = 30;
		u32 option_w = 150;
		{
			core::rect<s32> rect(0, 0, option_w, 30);
			rect += m_topleft_client + v2s32(option_x, option_y+20*0);
			wchar_t* text = wgettext("Creative Mode");
			Environment->addCheckBox(m_data->creative_mode, rect, this,
					GUI_ID_CREATIVE_CB, text);
			delete[] text;
		}
		{
			core::rect<s32> rect(0, 0, option_w, 30);
			rect += m_topleft_client + v2s32(option_x, option_y+20*1);
			wchar_t* text = wgettext("Enable Damage");
			Environment->addCheckBox(m_data->enable_damage, rect, this,
					GUI_ID_DAMAGE_CB, text);
			delete[] text;
		}
		changeCtype("C");

		/* Add game selection buttons */
		video::IVideoDriver* driver = Environment->getVideoDriver();
		for(size_t i=0; i<m_data->games.size(); i++){
			const SubgameSpec *spec = &m_data->games[i];
			v2s32 p(8 + i*(48+8), screensize.Y - (48+8));
			core::rect<s32> rect(0, 0, 48, 48);
			rect += p;
			video::ITexture *bgtexture = NULL;
			if(spec->menuicon_path != "")
				bgtexture = driver->getTexture(spec->menuicon_path.c_str());
			gui::IGUIButton *b = Environment->addButton(rect, this,
					GUI_ID_GAME_BUTTON_FIRST+i, narrow_to_wide(wrap_rows(spec->id, 4)).c_str());
			if(bgtexture){
				b->setImage(bgtexture);
				b->setText(L"");
				b->setDrawBorder(false);
				b->setUseAlphaChannel(true);
			}
		}
	}
	else if(m_data->selected_tab == TAB_MULTIPLAYER)
	{
		changeCtype("");
		// CLIENT
		{
			core::rect<s32> rect(0, 0, 10, m_size_client.Y);
			rect += m_topleft_client + v2s32(15, 0);
			const wchar_t *text = L"C\nL\nI\nE\nN\nT";
			gui::IGUIStaticText *t =
			Environment->addStaticText(text, rect, false, true, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
		}
		// Nickname + password
		{
			core::rect<s32> rect(0, 0, 110, 20);
			wchar_t* text = wgettext("Name/Password");
			rect += m_topleft_client + v2s32(m_size_client.X-60-100, 10+6);
			Environment->addStaticText(text,
				rect, false, true, this, -1);
			delete [] text;
		}
		changeCtype("C");
		{
			core::rect<s32> rect(0, 0, 120, 30);
			rect += m_topleft_client + v2s32(m_size_client.X-60-100, 50);
			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);
			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);
					wchar_t* text = wgettext("Favorites:");
					Environment->addStaticText(text,
						rect, false, true, this, GUI_ID_SERVERLIST_TITLE);
					delete[] text;
				}
			} else {
				m_data->servers = ServerList::getOnline();
				{
					core::rect<s32> rect(0, 0, 390, 20);
					rect += m_topleft_client + v2s32(50, 10);
					wchar_t* text = wgettext("Public Server List:");
					Environment->addStaticText(text,
						rect, false, true, this, GUI_ID_SERVERLIST_TITLE);
					delete[] text;
				}
			}
#else
			m_data->servers = ServerList::getLocal();
			{
				core::rect<s32> rect(0, 0, 390, 20);
				rect += m_topleft_client + v2s32(50, 10);
				wchar_t* text = wgettext("Favorites:");
				Environment->addStaticText(text,
					rect, false, true, this, GUI_ID_SERVERLIST_TITLE);
				delete[] text;
			}
#endif
			updateGuiServerList();
			e->setSelected(0);
		}
		// Address + port
		{
			core::rect<s32> rect(0, 0, 110, 20);
			rect += m_topleft_client + v2s32(50, m_size_client.Y-50-15+6);
			wchar_t* text = wgettext("Address/Port");
			Environment->addStaticText(text,
				rect, false, true, this, -1);
			delete [] text;
		}
		changeCtype("C");
		{
			core::rect<s32> rect(0, 0, 260, 30);
			rect += m_topleft_client + v2s32(50, m_size_client.Y-25-15);
			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);
			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);
			wchar_t* text = wgettext("Show Public");
			gui::IGUIButton *e = Environment->addButton(rect, this, GUI_ID_SERVERLIST_TOGGLE,
				text);
			delete[] text;
			e->setIsPushButton(true);
			if (m_data->selected_serverlist == SERVERLIST_PUBLIC)
			{
				wchar_t* text = wgettext("Show Favorites");
				e->setText(text);
				e->setPressed();
				delete[] text;
			}
		}
		#endif
		// Delete Local Favorite
		{
			core::rect<s32> rect(0, 0, 120, 30);
			rect += m_topleft_client + v2s32(50+260+10, 180);
			wchar_t* text = wgettext("Delete");
			gui::IGUIButton *e = Environment->addButton(rect, this, GUI_ID_SERVERLIST_DELETE,
					text);
			if (m_data->selected_serverlist == SERVERLIST_PUBLIC) // Hidden when on public list
				e->setVisible(false);

			delete [] text;
		}
		// 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);
			wchar_t* text = wgettext("Connect");
			Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON,
				text);
			delete[] text;
		}
		changeCtype("C");
	}
	else if(m_data->selected_tab == TAB_ADVANCED)
	{
		changeCtype("");
		// CLIENT
		{
			core::rect<s32> rect(0, 0, 10, m_size_client.Y);
			rect += m_topleft_client + v2s32(15, 0);
			const wchar_t *text = L"C\nL\nI\nE\nN\nT";
			gui::IGUIStaticText *t =
			Environment->addStaticText(text, rect, false, true, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
		}
		// Nickname + password
		{
			core::rect<s32> rect(0, 0, 110, 20);
			rect += m_topleft_client + v2s32(35+30, 35+6);
			wchar_t* text = wgettext("Name/Password");
			Environment->addStaticText(text,
				rect, false, true, this, -1);
			delete [] text;
		}
		changeCtype("C");
		{
			core::rect<s32> rect(0, 0, 230, 30);
			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);
			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);
			rect += m_topleft_client + v2s32(35+30, 75+6);
			wchar_t* text = wgettext("Address/Port");
			Environment->addStaticText(text,
				rect, false, true, this, -1);
			delete[] text;
		}
		changeCtype("C");
		{
			core::rect<s32> rect(0, 0, 230, 30);
			rect += m_topleft_client + v2s32(160+30, 75);
			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(m_size_client.X-60-100, 75);
			Environment->addEditBox(m_data->port.c_str(), rect, true,
					this, GUI_ID_PORT_INPUT);
		}
		changeCtype("");
		{
			core::rect<s32> rect(0, 0, 400, 20);
			rect += m_topleft_client + v2s32(160+30, 75+35);
			wchar_t* text = wgettext("Leave address blank to start a local server.");
			Environment->addStaticText(text,
				rect, false, true, this, -1);
			delete[] text;
		}
		// 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);
			wchar_t* text = wgettext("Start Game / Connect");
			Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON,
				text);
			delete[] text;
		}
		/*
			Server section
		*/
		// SERVER
		{
			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";
			gui::IGUIStaticText *t =
			Environment->addStaticText(text, rect, false, true, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
		}
		// Server parameters
		{
			core::rect<s32> rect(0, 0, 250, 30);
			rect += m_topleft_server + v2s32(30+20+250+20, 20);
			wchar_t* text = wgettext("Creative Mode");
			Environment->addCheckBox(m_data->creative_mode, rect, this, GUI_ID_CREATIVE_CB,
				text);
			delete[] text;
		}
		{
			core::rect<s32> rect(0, 0, 250, 30);
			rect += m_topleft_server + v2s32(30+20+250+20, 40);
			wchar_t* text = wgettext("Enable Damage");
			Environment->addCheckBox(m_data->enable_damage, rect, this, GUI_ID_DAMAGE_CB,
				text);
			delete[] text;
		}
		#if USE_CURL
		{
			core::rect<s32> rect(0, 0, 250, 30);
			rect += m_topleft_server + v2s32(30+20+250+20, 60);
			wchar_t* text = wgettext("Public");
			Environment->addCheckBox(m_data->enable_public, rect, this, GUI_ID_PUBLIC_CB,
				text);
			delete[] text;
		}
		#endif
		// Delete world button
		{
			core::rect<s32> rect(0, 0, 130, 30);
			rect += m_topleft_server + v2s32(30+20+250+20, 90);
			wchar_t* text = wgettext("Delete world");
			Environment->addButton(rect, this, GUI_ID_DELETE_WORLD_BUTTON,
				 text );
			delete[] text;
		}
		// Create world button
		{
			core::rect<s32> rect(0, 0, 130, 30);
			rect += m_topleft_server + v2s32(30+20+250+20+140, 90);
			wchar_t* text = wgettext("Create world");
			Environment->addButton(rect, this, GUI_ID_CREATE_WORLD_BUTTON,
				 text );
			delete[] text;
		}
		// World selection listbox
		{
			core::rect<s32> rect(0, 0, 250, 120);
			rect += m_topleft_server + v2s32(30+20, 10);
			gui::IGUIListBox *e = Environment->addListBox(rect, this,
					GUI_ID_WORLD_LISTBOX);
			e->setDrawBackground(true);
			m_world_indices.clear();
			for(size_t wi = 0; wi < m_data->worlds.size(); wi++){
				const WorldSpec &spec = m_data->worlds[wi];
				e->addItem(narrow_to_wide(spec.name+" ["+spec.gameid+"]").c_str());
				m_world_indices.push_back(wi);
			}
			e->setSelected(m_data->selected_world);
		}
		changeCtype("C");
	}
	else if(m_data->selected_tab == TAB_SETTINGS)
	{
		{
			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";
			gui::IGUIStaticText *t =
			Environment->addStaticText(text, rect, false, true, this, -1);
			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);
			wchar_t* text = wgettext("Fancy trees");
			Environment->addCheckBox(m_data->fancy_trees, rect, this,
					GUI_ID_FANCYTREE_CB, text);
			delete[] text;
		}
		{
			core::rect<s32> rect(0, 0, option_w, 30);
			rect += m_topleft_client + v2s32(option_x, option_y+20);
			wchar_t* text = wgettext("Smooth Lighting");
			Environment->addCheckBox(m_data->smooth_lighting, rect, this,
					GUI_ID_SMOOTH_LIGHTING_CB, text);
			delete[] text;
		}
		{
			core::rect<s32> rect(0, 0, option_w, 30);
			rect += m_topleft_client + v2s32(option_x, option_y+20*2);
			wchar_t* text = wgettext("3D Clouds");
			Environment->addCheckBox(m_data->clouds_3d, rect, this,
					GUI_ID_3D_CLOUDS_CB, text);
			delete[] text;
		}
		{
			core::rect<s32> rect(0, 0, option_w, 30);
			rect += m_topleft_client + v2s32(option_x, option_y+20*3);
			wchar_t* text = wgettext("Opaque water");
			Environment->addCheckBox(m_data->opaque_water, rect, this,
					GUI_ID_OPAQUE_WATER_CB, text);
			delete[] text;
		}


		// 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);
			wchar_t* text = wgettext("Mip-Mapping");
			Environment->addCheckBox(m_data->mip_map, rect, this,
				       GUI_ID_MIPMAP_CB, text);
			delete[] text;
		}

		{
			core::rect<s32> rect(0, 0, option_w+20, 30);
			rect += m_topleft_client + v2s32(option_x+175, option_y+20);
			wchar_t* text = wgettext("Anisotropic Filtering");
			Environment->addCheckBox(m_data->anisotropic_filter, rect, this,
				       GUI_ID_ANISOTROPIC_CB, text);
			delete[] text;
		}

		{
			core::rect<s32> rect(0, 0, option_w+20, 30);
			rect += m_topleft_client + v2s32(option_x+175, option_y+20*2);
			wchar_t* text = wgettext("Bi-Linear Filtering");
			Environment->addCheckBox(m_data->bilinear_filter, rect, this,
				       GUI_ID_BILINEAR_CB, text);
			delete[] text;
		}

		{
			core::rect<s32> rect(0, 0, option_w+20, 30);
			rect += m_topleft_client + v2s32(option_x+175, option_y+20*3);
			wchar_t* text = wgettext("Tri-Linear Filtering");
			Environment->addCheckBox(m_data->trilinear_filter, rect, this,
				       GUI_ID_TRILINEAR_CB, text);
			delete[] text;
		}

		// 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);
			wchar_t* text = wgettext("Shaders");
			Environment->addCheckBox(m_data->enable_shaders, rect, this,
					GUI_ID_SHADERS_CB, text);
			delete[] text;
		}

		{
			core::rect<s32> rect(0, 0, option_w+20+20, 30);
			rect += m_topleft_client + v2s32(option_x+175*2, option_y+20);
			wchar_t* text = wgettext("Preload item visuals");
			Environment->addCheckBox(m_data->preload_item_visuals, rect, this,
					GUI_ID_PRELOAD_ITEM_VISUALS_CB, text);
			delete[] text;
		}

		{
			core::rect<s32> rect(0, 0, option_w+20+20, 30);
			rect += m_topleft_client + v2s32(option_x+175*2, option_y+20*2);
			wchar_t* text = wgettext("Enable Particles");
			Environment->addCheckBox(m_data->enable_particles, rect, this,
					GUI_ID_ENABLE_PARTICLES_CB, text);
			delete[] text;
		}

		{
			core::rect<s32> rect(0, 0, option_w+20+20, 30);
			rect += m_topleft_client + v2s32(option_x+175*2, option_y+20*3);
			wchar_t* text = wgettext("Finite liquid");
			Environment->addCheckBox(m_data->liquid_finite, rect, this,
					GUI_ID_LIQUID_FINITE_CB, text);
			delete[] text;
		}

		// 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);
			wchar_t* text = wgettext("Change keys");
			Environment->addButton(rect, this,
					GUI_ID_CHANGE_KEYS_BUTTON, text);
			delete[] text;
		}
		changeCtype("C");
	}
	else if(m_data->selected_tab == TAB_CREDITS)
	{
		// CREDITS
		{
			core::rect<s32> rect(0, 0, 9, m_size_client.Y);
			rect += m_topleft_client + v2s32(15, 0);
			const wchar_t *text = L"C\nR\nE\nD\nI\nT\nS";
			gui::IGUIStaticText *t =
			Environment->addStaticText(text, rect, false, true, this, -1);
			t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
		}
		{
			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"");
		}
	}

	m_is_regenerating = false;
}