void TestUtilities::testWrapRows()
{
	UASSERT(wrap_rows("12345678",4) == "1234\n5678");
	// test that wrap_rows doesn't wrap inside multibyte sequences
	{
		const unsigned char s[] = {
			0x2f, 0x68, 0x6f, 0x6d, 0x65, 0x2f, 0x72, 0x61, 0x70, 0x74, 0x6f,
			0x72, 0x2f, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0x2f,
			0x6d, 0x69, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x62, 0x69,
			0x6e, 0x2f, 0x2e, 0x2e, 0};
		std::string str((char *)s);
		UASSERT(utf8_to_wide(wrap_rows(str, 20)) != L"<invalid UTF-8 string>");
	};
	{
		const unsigned char s[] = {
			0x74, 0x65, 0x73, 0x74, 0x20, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x81,
			0xd1, 0x82, 0x20, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82,
			0x20, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0};
		std::string str((char *)s);
		UASSERT(utf8_to_wide(wrap_rows(str, 8)) != L"<invalid UTF-8 string>");
	}
}
void GUIPauseMenu::regenerateGui(v2u32 screensize)
{
	/*
		Remove stuff
	*/
	removeChildren();
	
	/*
		Calculate new sizes and positions
	*/
	core::rect<s32> rect(
			screensize.X/2 - 580/2,
			screensize.Y/2 - 300/2,
			screensize.X/2 + 580/2,
			screensize.Y/2 + 300/2
	);
	
	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	v2s32 size = rect.getSize();

	/*
		Add stuff
	*/
	const s32 btn_height = 30;
	const s32 btn_gap = 20;
	const s32 btn_num = 4;
	s32 btn_y = size.Y/2-((btn_num*btn_height+(btn_num-1)*btn_gap))/2;
	changeCtype("");
	{
		core::rect<s32> rect(0, 0, 140, btn_height);
		rect = rect + v2s32(size.X/2-140/2, btn_y);
		Environment->addButton(rect, this, 256,
			wgettext("Continue"));
	}
	btn_y += btn_height + btn_gap;
	{
		core::rect<s32> rect(0, 0, 140, btn_height);
		rect = rect + v2s32(size.X/2-140/2, btn_y);
		Environment->addButton(rect, this, 261,
			wgettext("Change Password"));
	}
	btn_y += btn_height + btn_gap;
	{
		core::rect<s32> rect(0, 0, 140, btn_height);
		rect = rect + v2s32(size.X/2-140/2, btn_y);
		Environment->addButton(rect, this, 260,
			wgettext("Disconnect"));
	}
	btn_y += btn_height + btn_gap;
	{
		core::rect<s32> rect(0, 0, 140, btn_height);
		rect = rect + v2s32(size.X/2-140/2, btn_y);
		Environment->addButton(rect, this, 257,
			wgettext("Exit to OS"));
	}

	{
		core::rect<s32> rect(0, 0, 180, 240);
		rect = rect + v2s32(size.X/2 + 90, size.Y/2-rect.getHeight()/2);
		Environment->addStaticText(chartowchar_t(gettext(
		"Default Controls:\n"
		"- WASD: Walk\n"
		"- Mouse left: dig/hit\n"
		"- Mouse right: place/use\n"
		"- Mouse wheel: select item\n"
		"- 0...9: select item\n"
		"- Shift: sneak\n"
		"- R: Toggle viewing all loaded chunks\n"
		"- I: Inventory menu\n"
		"- ESC: This menu\n"
		"- T: Chat\n"
		)), rect, false, true, this, 258);
	}
	{
		core::rect<s32> rect(0, 0, 180, 220);
		rect = rect + v2s32(size.X/2 - 90 - rect.getWidth(), size.Y/2-rect.getHeight()/2);
	
		v2u32 max_texture_size;
		{
			video::IVideoDriver* driver = Environment->getVideoDriver();
			max_texture_size = driver->getMaxTextureSize();
		}

		/*wchar_t text[200];
		swprintf(text, 200,
				L"Minetest-c55\n"
				L"by Perttu Ahola\n"
				L"[email protected]\n\n"
				SWPRINTF_CHARSTRING L"\n"
				L"userdata path = "
				SWPRINTF_CHARSTRING
				,
				BUILD_INFO,
				porting::path_userdata.c_str()
		);*/

		std::ostringstream os;
		os<<"Minetest-delta\n";
		os<<"by Perttu Ahola and contributors\n";
		os<<"[email protected]\n";
		os<<BUILD_INFO<<"\n";
		os<<"ud_path = "<<wrap_rows(porting::path_userdata, 20)<<"\n";
	
		Environment->addStaticText(narrow_to_wide(os.str()).c_str(), rect, false, true, this, 259);
	}
	changeCtype("C");
}
Exemple #3
0
void GUIPauseMenu::regenerateGui(v2u32 screensize)
{
	/*
		Remove stuff
	*/
	removeChildren();
	
	/*
		Calculate new sizes and positions
	*/
	core::rect<s32> rect(
			screensize.X/2 - 580/2,
			screensize.Y/2 - 300/2,
			screensize.X/2 + 580/2,
			screensize.Y/2 + 300/2
	);
	
	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	v2s32 size = rect.getSize();

	/*
		Add stuff
	*/
	const s32 btn_height = 30;
	const s32 btn_gap = 20;
	const s32 btn_num = m_simple_singleplayer_mode ? 4 : 5;
	s32 btn_y = size.Y/2-((btn_num*btn_height+(btn_num-1)*btn_gap))/2;
	{
		core::rect<s32> rect(0, 0, 140, btn_height);
		rect = rect + v2s32(size.X/2-140/2, btn_y);
		wchar_t* text = wgettext("Continue");
		Environment->addButton(rect, this, 256,
			text);
		delete[] text;
	}
	btn_y += btn_height + btn_gap;
	if(!m_simple_singleplayer_mode)
	{
		{
			core::rect<s32> rect(0, 0, 140, btn_height);
			rect = rect + v2s32(size.X/2-140/2, btn_y);
			wchar_t* text = wgettext("Change Password");
			Environment->addButton(rect, this, 261,
				text);
			delete[] text;
		}
		btn_y += btn_height + btn_gap;
	}
	{
		core::rect<s32> rect(0, 0, 140, btn_height);
		rect = rect + v2s32(size.X/2-140/2, btn_y);
		wchar_t* text = wgettext("Sound Volume");
		Environment->addButton(rect, this, 262,
			text);
		delete[] text;
	}
	btn_y += btn_height + btn_gap;
	{
		core::rect<s32> rect(0, 0, 140, btn_height);
		rect = rect + v2s32(size.X/2-140/2, btn_y);
		wchar_t* text = wgettext("Exit to Menu");
		Environment->addButton(rect, this, 260,
			text);
		delete[] text;
	}
	btn_y += btn_height + btn_gap;
	{
		core::rect<s32> rect(0, 0, 140, btn_height);
		rect = rect + v2s32(size.X/2-140/2, btn_y);
		wchar_t* text = wgettext("Exit to OS");
		Environment->addButton(rect, this, 257,
			text);
		delete[] text;
	}

	{
		core::rect<s32> rect(0, 0, 180, 240);
		rect = rect + v2s32(size.X/2 + 90, size.Y/2-rect.getHeight()/2);
		wchar_t* text = wgettext("Default Controls:\n"
				"- WASD: move\n"
				"- Space: jump/climb\n"
				"- Shift: sneak/go down\n"
				"- Q: drop item\n"
				"- I: inventory\n"
				"- Mouse: turn/look\n"
				"- Mouse left: dig/punch\n"
				"- Mouse right: place/use\n"
				"- Mouse wheel: select item\n"
				"- T: chat\n"
				);
		Environment->addStaticText(text, rect, false, true, this, 258);
		delete[] text;

	}
	{
		core::rect<s32> rect(0, 0, 180, 220);
		rect = rect + v2s32(size.X/2 - 90 - rect.getWidth(), size.Y/2-rect.getHeight()/2);
	
		v2u32 max_texture_size;
		{
			video::IVideoDriver* driver = Environment->getVideoDriver();
			max_texture_size = driver->getMaxTextureSize();
		}

		std::ostringstream os;
		os<<"Minetest\n";
		os<<minetest_build_info<<"\n";
		os<<"path_user = "******"\n";
	
		Environment->addStaticText(narrow_to_wide(os.str()).c_str(), rect, false, true, this, 259);
	}
}
Exemple #4
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;
}
void GUIPauseMenu::regenerateGui(v2u32 screensize)
{
	/*
		Remove stuff
	*/
	removeChildren();
	
	/*
		Calculate new sizes and positions
	*/
	core::rect<s32> rect(
			screensize.X/2 - 580/2,
			screensize.Y/2 - 300/2,
			screensize.X/2 + 580/2,
			screensize.Y/2 + 300/2
	);
	
	DesiredRect = rect;
	recalculateAbsolutePosition(false);

	v2s32 size = rect.getSize();

	/*
		Add stuff
	*/
	const s32 btn_height = 30;
	const s32 btn_gap = 20;
	const s32 btn_num = m_simple_singleplayer_mode ? 4 : 5;
	s32 btn_y = size.Y/2-((btn_num*btn_height+(btn_num-1)*btn_gap))/2;
	changeCtype("");
	{
		core::rect<s32> rect(0, 0, 140, btn_height);
		rect = rect + v2s32(size.X/2-140/2, btn_y);
		Environment->addButton(rect, this, 256,
			wgettext("Continue"));
	}
	btn_y += btn_height + btn_gap;
	if(!m_simple_singleplayer_mode)
	{
		{
			core::rect<s32> rect(0, 0, 140, btn_height);
			rect = rect + v2s32(size.X/2-140/2, btn_y);
			Environment->addButton(rect, this, 261,
				wgettext("Change Password"));
		}
		btn_y += btn_height + btn_gap;
	}
	{
		core::rect<s32> rect(0, 0, 140, btn_height);
		rect = rect + v2s32(size.X/2-140/2, btn_y);
		Environment->addButton(rect, this, 262,
			wgettext("Sound Volume"));
	}
	btn_y += btn_height + btn_gap;
	{
		core::rect<s32> rect(0, 0, 140, btn_height);
		rect = rect + v2s32(size.X/2-140/2, btn_y);
		Environment->addButton(rect, this, 260,
			wgettext("Exit to Menu"));
	}
	btn_y += btn_height + btn_gap;
	{
		core::rect<s32> rect(0, 0, 140, btn_height);
		rect = rect + v2s32(size.X/2-140/2, btn_y);
		Environment->addButton(rect, this, 257,
			wgettext("Exit to OS"));
	}

	{
		core::rect<s32> rect(0, 0, 180, 240);
		rect = rect + v2s32(size.X/2 + 90, size.Y/2-rect.getHeight()/2);
		Environment->addStaticText(chartowchar_t(gettext(
		"Default Controls:\n"
		"- WASD: Walk\n"
		"- Mouse left: dig/hit\n"
		"- Mouse right: place/use\n"
		"- Mouse wheel: select item\n"
		"- 0...9: select item\n"
		"- Shift: sneak\n"
		"- R: Toggle viewing all loaded chunks\n"
		"- I: Inventory menu\n"
		"- ESC: This menu\n"
		"- T: Chat\n"
		)), rect, false, true, this, 258);
	}
	{
		core::rect<s32> rect(0, 0, 180, 220);
		rect = rect + v2s32(size.X/2 - 90 - rect.getWidth(), size.Y/2-rect.getHeight()/2);
	
		v2u32 max_texture_size;
		{
			video::IVideoDriver* driver = Environment->getVideoDriver();
			max_texture_size = driver->getMaxTextureSize();
		}

		std::ostringstream os;
		os<<"Minetest\n";
		os<<BUILD_INFO<<"\n";
		os<<"path_user = "******"\n";
	
		Environment->addStaticText(narrow_to_wide(os.str()).c_str(), rect, false, true, this, 259);
	}
	changeCtype("C");
}