]> git.lizzy.rs Git - minetest.git/blobdiff - src/guiMainMenu.cpp
World creation button and dialog and functionality
[minetest.git] / src / guiMainMenu.cpp
index f557f4dc08eeb0c14fe6bd0a56f97900fa975e73..6d07fe9733c6e6df46556a4da1446d8a242066d6 100644 (file)
@@ -1,6 +1,6 @@
 /*
 Minetest-c55
-Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2010-12 celeron55, Perttu Ahola <celeron55@gmail.com>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,13 +19,52 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "guiMainMenu.h"
 #include "guiKeyChangeMenu.h"
+#include "guiCreateWorld.h"
+#include "guiMessageMenu.h"
 #include "debug.h"
 #include "serialization.h"
 #include <string>
+#include <IGUICheckBox.h>
+#include <IGUIEditBox.h>
+#include <IGUIButton.h>
+#include <IGUIStaticText.h>
+#include <IGUIFont.h>
+#include <IGUIListBox.h>
+// For IGameCallback
+#include "guiPauseMenu.h"
+#include "gettext.h"
+#include "utility.h"
 
+struct CreateWorldDestMainMenu : public CreateWorldDest
+{
+       CreateWorldDestMainMenu(GUIMainMenu *menu):
+               m_menu(menu)
+       {}
+       void accepted(std::wstring name, std::string gameid)
+       {
+               m_menu->createNewWorld(name, gameid);
+       }
+       GUIMainMenu *m_menu;
+};
 
-
-#include "gettext.h"
+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_DAMAGE_CB,
+       GUI_ID_CREATIVE_CB,
+       GUI_ID_JOIN_GAME_BUTTON,
+       GUI_ID_CHANGE_KEYS_BUTTON,
+       GUI_ID_DELETE_WORLD_BUTTON,
+       GUI_ID_CREATE_WORLD_BUTTON,
+       GUI_ID_WORLD_LISTBOX,
+};
 
 GUIMainMenu::GUIMainMenu(gui::IGUIEnvironment* env,
                gui::IGUIElement* parent, s32 id,
@@ -69,67 +108,11 @@ void GUIMainMenu::removeChildren()
 
 void GUIMainMenu::regenerateGui(v2u32 screensize)
 {
-       std::wstring text_name;
-       std::wstring text_address;
-       std::wstring text_port;
-       bool creative_mode;
-       bool enable_damage;
-       bool fancy_trees;
-       bool smooth_lighting;
-       
-       // Client options
-       {
-               gui::IGUIElement *e = getElementFromId(GUI_ID_NAME_INPUT);
-               if(e != NULL)
-                       text_name = e->getText();
-               else
-                       text_name = m_data->name;
-       }
-       {
-               gui::IGUIElement *e = getElementFromId(GUI_ID_ADDRESS_INPUT);
-               if(e != NULL)
-                       text_address = e->getText();
-               else
-                       text_address = m_data->address;
-       }
-       {
-               gui::IGUIElement *e = getElementFromId(GUI_ID_PORT_INPUT);
-               if(e != NULL)
-                       text_port = e->getText();
-               else
-                       text_port = m_data->port;
-       }
-       {
-               gui::IGUIElement *e = getElementFromId(GUI_ID_FANCYTREE_CB);
-               if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
-                       fancy_trees = ((gui::IGUICheckBox*)e)->isChecked();
-               else
-                       fancy_trees = m_data->fancy_trees;
-       }
-       {
-               gui::IGUIElement *e = getElementFromId(GUI_ID_SMOOTH_LIGHTING_CB);
-               if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
-                       smooth_lighting = ((gui::IGUICheckBox*)e)->isChecked();
-               else
-                       smooth_lighting = m_data->smooth_lighting;
-       }
+       /*
+               Read stuff from elements into m_data
+       */
+       readInput(m_data);
        
-       // Server options
-       {
-               gui::IGUIElement *e = getElementFromId(GUI_ID_CREATIVE_CB);
-               if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
-                       creative_mode = ((gui::IGUICheckBox*)e)->isChecked();
-               else
-                       creative_mode = m_data->creative_mode;
-       }
-       {
-               gui::IGUIElement *e = getElementFromId(GUI_ID_DAMAGE_CB);
-               if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
-                       enable_damage = ((gui::IGUICheckBox*)e)->isChecked();
-               else
-                       enable_damage = m_data->enable_damage;
-       }
-
        /*
                Remove stuff
        */
@@ -164,27 +147,38 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
        v2s32 topleft_client(40, 0);
        v2s32 size_client = size - v2s32(40, 0);
        
+       changeCtype("");
+       
+       // Version
+       {
+               core::rect<s32> rect(0, 0, 300, 30);
+               rect += topleft_client + v2s32(-36, 0);
+               Environment->addStaticText(narrow_to_wide(VERSION_STRING).c_str(), 
+                       rect, false, true, this, -1);
+       }
+       // CLIENT
        {
                core::rect<s32> rect(0, 0, 20, 125);
-               rect += topleft_client + v2s32(-15, 60);
+               rect += topleft_client + v2s32(-15, 80);
                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_UPPERLEFT);
        }
-
        // Nickname + password
        {
                core::rect<s32> rect(0, 0, 110, 20);
                rect += topleft_client + v2s32(35, 50+6);
-               Environment->addStaticText(chartowchar_t(gettext("Name/Password")), rect, false, true, this, -1);
+               Environment->addStaticText(wgettext("Name/Password"), 
+                       rect, false, true, this, -1);
        }
+       changeCtype("C");
        {
                core::rect<s32> rect(0, 0, 230, 30);
                rect += topleft_client + v2s32(160, 50);
                gui::IGUIElement *e = 
-               Environment->addEditBox(text_name.c_str(), rect, true, this, GUI_ID_NAME_INPUT);
-               if(text_name == L"")
+               Environment->addEditBox(m_data->name.c_str(), rect, true, this, GUI_ID_NAME_INPUT);
+               if(m_data->name == L"")
                        Environment->setFocus(e);
        }
        {
@@ -193,50 +187,71 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
                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 += topleft_client + v2s32(35, 100+6);
-               Environment->addStaticText(chartowchar_t(gettext("Address/Port")), rect, false, true, this, -1);
+               Environment->addStaticText(wgettext("Address/Port"),
+                       rect, false, true, this, -1);
        }
+       changeCtype("C");
        {
                core::rect<s32> rect(0, 0, 230, 30);
                rect += topleft_client + v2s32(160, 100);
                gui::IGUIElement *e = 
-               Environment->addEditBox(text_address.c_str(), rect, true, this, GUI_ID_ADDRESS_INPUT);
-               if(text_name != L"")
+               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 += topleft_client + v2s32(160+250+20, 125);
                rect += topleft_client + v2s32(size_client.X-60-100, 100);
-               Environment->addEditBox(text_port.c_str(), rect, true, this, GUI_ID_PORT_INPUT);
+               Environment->addEditBox(m_data->port.c_str(), rect, true, this, GUI_ID_PORT_INPUT);
        }
+       changeCtype("");
        {
                core::rect<s32> rect(0, 0, 400, 20);
-               Environment->addStaticText(chartowchar_t(gettext("Leave address blank to start a local server.")), rect, false, true, this, -1);
+               rect += topleft_client + v2s32(160, 100+35);
+               Environment->addStaticText(wgettext("Leave address blank to start a local server."),
+                       rect, false, true, this, -1);
        }
        {
                core::rect<s32> rect(0, 0, 250, 30);
                rect += topleft_client + v2s32(35, 150);
-               Environment->addCheckBox(fancy_trees, rect, this, GUI_ID_FANCYTREE_CB,
-                       chartowchar_t(gettext("Fancy trees"))); 
+               Environment->addCheckBox(m_data->fancy_trees, rect, this, GUI_ID_FANCYTREE_CB,
+                       wgettext("Fancy trees")); 
        }
        {
                core::rect<s32> rect(0, 0, 250, 30);
-               rect += topleft_client + v2s32(35, 150+30);
-               Environment->addCheckBox(smooth_lighting, rect, this, GUI_ID_SMOOTH_LIGHTING_CB,
-                               chartowchar_t(gettext("Smooth Lighting")));
+               rect += topleft_client + v2s32(35, 150+20);
+               Environment->addCheckBox(m_data->smooth_lighting, rect, this, GUI_ID_SMOOTH_LIGHTING_CB,
+                               wgettext("Smooth Lighting"));
+       }
+       {
+               core::rect<s32> rect(0, 0, 250, 30);
+               rect += topleft_client + v2s32(35, 150+40);
+               Environment->addCheckBox(m_data->clouds_3d, rect, this, GUI_ID_3D_CLOUDS_CB,
+                               wgettext("3D Clouds"));
+       }
+       {
+               core::rect<s32> rect(0, 0, 250, 30);
+               rect += topleft_client + v2s32(35, 150+60);
+               Environment->addCheckBox(m_data->opaque_water, rect, this, GUI_ID_OPAQUE_WATER_CB,
+                               wgettext("Opaque water"));
        }
        // Start game button
        {
                core::rect<s32> rect(0, 0, 180, 30);
                //rect += topleft_client + v2s32(size_client.X/2-180/2, 225-30/2);
                rect += topleft_client + v2s32(size_client.X-180-40, 150+25);
-               Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON, chartowchar_t(gettext("Start Game / Connect")));
+               Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON,
+                       wgettext("Start Game / Connect"));
        }
 
        // Key change button
@@ -244,42 +259,66 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
                core::rect<s32> rect(0, 0, 100, 30);
                //rect += topleft_client + v2s32(size_client.X/2-180/2, 225-30/2);
                rect += topleft_client + v2s32(size_client.X-180-40-100-20, 150+25);
-               Environment->addButton(rect, this, GUI_ID_CHANGE_KEYS_BUTTON, chartowchar_t(gettext("Change keys")));
+               Environment->addButton(rect, this, GUI_ID_CHANGE_KEYS_BUTTON,
+                       wgettext("Change keys"));
        }
        /*
                Server section
        */
 
-       v2s32 topleft_server(40, 250);
+       v2s32 topleft_server(40, 290);
        v2s32 size_server = size - v2s32(40, 0);
        
+       // SERVER
        {
                core::rect<s32> rect(0, 0, 20, 125);
-               rect += topleft_server + v2s32(-15, 40);
+               rect += topleft_server + v2s32(-15, 15);
                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_UPPERLEFT);
        }
-
        // Server parameters
        {
                core::rect<s32> rect(0, 0, 250, 30);
-               rect += topleft_server + v2s32(35, 30);
-               Environment->addCheckBox(creative_mode, rect, this, GUI_ID_CREATIVE_CB, chartowchar_t(gettext("Creative Mode")));
+               rect += topleft_server + v2s32(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 += topleft_server + v2s32(35, 60);
-               Environment->addCheckBox(enable_damage, rect, this, GUI_ID_DAMAGE_CB, chartowchar_t(gettext("Enable Damage")));
+               rect += topleft_server + v2s32(20+250+20, 40);
+               Environment->addCheckBox(m_data->enable_damage, rect, this, GUI_ID_DAMAGE_CB,
+                       wgettext("Enable Damage"));
        }
-       // Map delete button
+       // Delete world button
        {
                core::rect<s32> rect(0, 0, 130, 30);
-               //rect += topleft_server + v2s32(size_server.X-40-130, 100+25);
-               rect += topleft_server + v2s32(40, 100+25);
-               Environment->addButton(rect, this, GUI_ID_DELETE_MAP_BUTTON, chartowchar_t(gettext("Delete map")));
+               rect += topleft_server + v2s32(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 += topleft_server + v2s32(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 += topleft_server + v2s32(20, 10);
+               gui::IGUIListBox *e = Environment->addListBox(rect, this,
+                               GUI_ID_WORLD_LISTBOX);
+               e->setDrawBackground(true);
+               for(std::list<std::wstring>::const_iterator i = m_data->worlds.begin();
+                               i != m_data->worlds.end(); i++){
+                       e->addItem(i->c_str());
+               }
+               e->setSelected(m_data->selected_world);
        }
+       changeCtype("C");
 }
 
 void GUIMainMenu::drawMenu()
@@ -295,13 +334,13 @@ void GUIMainMenu::drawMenu()
        video::SColor bgcolor(140,0,0,0);
 
        {
-               core::rect<s32> rect(0, 0, 620, 230);
+               core::rect<s32> rect(0, 0, 620, 270);
                rect += AbsoluteRect.UpperLeftCorner;
                driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
        }
 
        {
-               core::rect<s32> rect(0, 250, 620, 430);
+               core::rect<s32> rect(0, 290, 620, 430);
                rect += AbsoluteRect.UpperLeftCorner;
                driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
        }
@@ -309,49 +348,69 @@ void GUIMainMenu::drawMenu()
        gui::IGUIElement::draw();
 }
 
-void GUIMainMenu::acceptInput()
+void GUIMainMenu::readInput(MainMenuData *dst)
 {
        {
                gui::IGUIElement *e = getElementFromId(GUI_ID_NAME_INPUT);
                if(e != NULL)
-                       m_data->name = e->getText();
+                       dst->name = e->getText();
        }
        {
                gui::IGUIElement *e = getElementFromId(264);
                if(e != NULL)
-                       m_data->password = e->getText();
+                       dst->password = e->getText();
        }
        {
                gui::IGUIElement *e = getElementFromId(GUI_ID_ADDRESS_INPUT);
                if(e != NULL)
-                       m_data->address = e->getText();
+                       dst->address = e->getText();
        }
        {
                gui::IGUIElement *e = getElementFromId(GUI_ID_PORT_INPUT);
                if(e != NULL)
-                       m_data->port = e->getText();
+                       dst->port = e->getText();
        }
        {
                gui::IGUIElement *e = getElementFromId(GUI_ID_CREATIVE_CB);
                if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
-                       m_data->creative_mode = ((gui::IGUICheckBox*)e)->isChecked();
+                       dst->creative_mode = ((gui::IGUICheckBox*)e)->isChecked();
        }
        {
                gui::IGUIElement *e = getElementFromId(GUI_ID_DAMAGE_CB);
                if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
-                       m_data->enable_damage = ((gui::IGUICheckBox*)e)->isChecked();
+                       dst->enable_damage = ((gui::IGUICheckBox*)e)->isChecked();
+       }
+       {
+               gui::IGUIElement *e = getElementFromId(GUI_ID_FANCYTREE_CB);
+               if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
+                       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)
-                       m_data->smooth_lighting = ((gui::IGUICheckBox*)e)->isChecked();
+                       dst->smooth_lighting = ((gui::IGUICheckBox*)e)->isChecked();
        }
        {
-               gui::IGUIElement *e = getElementFromId(GUI_ID_FANCYTREE_CB);
+               gui::IGUIElement *e = getElementFromId(GUI_ID_3D_CLOUDS_CB);
                if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
-                       m_data->fancy_trees = ((gui::IGUICheckBox*)e)->isChecked();
+                       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)
+                       dst->opaque_water = ((gui::IGUICheckBox*)e)->isChecked();
+       }
+
+       {
+               gui::IGUIElement *e = getElementFromId(GUI_ID_WORLD_LISTBOX);
+               if(e != NULL && e->getType() == gui::EGUIET_LIST_BOX)
+                       dst->selected_world = ((gui::IGUIListBox*)e)->getSelected();
+       }
+}
+
+void GUIMainMenu::acceptInput()
+{
+       readInput(m_data);
        m_accepted = true;
 }
 
@@ -389,7 +448,7 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
                {
                        switch(event.GUIEvent.Caller->getID())
                        {
-                       case GUI_ID_JOIN_GAME_BUTTON: // Start game
+                       case GUI_ID_JOIN_GAME_BUTTON:
                                acceptInput();
                                quitMenu();
                                return true;
@@ -398,13 +457,28 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
                                kmenu->drop();
                                return true;
                        }
-                       case GUI_ID_DELETE_MAP_BUTTON: // Delete map
-                               // Don't accept input data, just set deletion request
-                               m_data->delete_map = true;
-                               m_accepted = true;
+                       case GUI_ID_DELETE_WORLD_BUTTON: {
+                               acceptInput();
+                               m_data->delete_world = true;
                                quitMenu();
                                return true;
                        }
+                       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;
+                       }
+                       }
                }
                if(event.GUIEvent.EventType==gui::EGET_EDITBOX_ENTER)
                {
@@ -416,8 +490,29 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
                                return true;
                        }
                }
+               if(event.GUIEvent.EventType==gui::EGET_LISTBOX_SELECTED_AGAIN)
+               {
+                       switch(event.GUIEvent.Caller->getID())
+                       {
+                               case GUI_ID_WORLD_LISTBOX:
+                               acceptInput();
+                               m_data->address = L""; // Force local game
+                               quitMenu();
+                               return true;
+                       }
+               }
        }
 
        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();
+}
+