]> git.lizzy.rs Git - minetest.git/blob - src/guiMainMenu.cpp
Map deletion button
[minetest.git] / src / guiMainMenu.cpp
1 /*
2 Minetest-c55
3 Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "guiMainMenu.h"
21 #include "debug.h"
22 #include "serialization.h"
23 #include <string>
24
25 GUIMainMenu::GUIMainMenu(gui::IGUIEnvironment* env,
26                 gui::IGUIElement* parent, s32 id,
27                 IMenuManager *menumgr,
28                 MainMenuData *data,
29                 IGameCallback *gamecallback
30 ):
31         GUIModalMenu(env, parent, id, menumgr),
32         m_data(data),
33         m_accepted(false),
34         m_gamecallback(gamecallback)
35 {
36         assert(m_data);
37 }
38
39 GUIMainMenu::~GUIMainMenu()
40 {
41         removeChildren();
42 }
43
44 void GUIMainMenu::removeChildren()
45 {
46         const core::list<gui::IGUIElement*> &children = getChildren();
47         core::list<gui::IGUIElement*> children_copy;
48         for(core::list<gui::IGUIElement*>::ConstIterator
49                         i = children.begin(); i != children.end(); i++)
50         {
51                 children_copy.push_back(*i);
52         }
53         for(core::list<gui::IGUIElement*>::Iterator
54                         i = children_copy.begin();
55                         i != children_copy.end(); i++)
56         {
57                 (*i)->remove();
58         }
59 }
60
61 void GUIMainMenu::regenerateGui(v2u32 screensize)
62 {
63         std::wstring text_name;
64         std::wstring text_address;
65         std::wstring text_port;
66         bool creative_mode;
67
68         {
69                 gui::IGUIElement *e = getElementFromId(258);
70                 if(e != NULL)
71                         text_name = e->getText();
72                 else
73                         text_name = m_data->name;
74         }
75         {
76                 gui::IGUIElement *e = getElementFromId(256);
77                 if(e != NULL)
78                         text_address = e->getText();
79                 else
80                         text_address = m_data->address;
81         }
82         {
83                 gui::IGUIElement *e = getElementFromId(257);
84                 if(e != NULL)
85                         text_port = e->getText();
86                 else
87                         text_port = m_data->port;
88         }
89         {
90                 gui::IGUIElement *e = getElementFromId(259);
91                 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
92                         creative_mode = ((gui::IGUICheckBox*)e)->isChecked();
93                 else
94                         creative_mode = m_data->creative_mode;
95         }
96
97         /*
98                 Remove stuff
99         */
100         removeChildren();
101         
102         /*
103                 Calculate new sizes and positions
104         */
105         core::rect<s32> rect(
106                         screensize.X/2 - 580/2,
107                         screensize.Y/2 - 300/2,
108                         screensize.X/2 + 580/2,
109                         screensize.Y/2 + 300/2
110         );
111         
112         DesiredRect = rect;
113         recalculateAbsolutePosition(false);
114
115         v2s32 size = rect.getSize();
116
117         /*
118                 Add stuff
119         */
120
121         // Nickname
122         {
123                 core::rect<s32> rect(0, 0, 100, 20);
124                 rect = rect + v2s32(size.X/2 - 250, size.Y/2 - 100 + 6);
125                 const wchar_t *text = L"Nickname";
126                 Environment->addStaticText(text, rect, false, true, this, -1);
127         }
128         {
129                 core::rect<s32> rect(0, 0, 250, 30);
130                 rect = rect + v2s32(size.X/2 - 130, size.Y/2 - 100);
131                 gui::IGUIElement *e = 
132                 Environment->addEditBox(text_name.c_str(), rect, true, this, 258);
133                 if(text_name == L"")
134                         Environment->setFocus(e);
135         }
136         // Address + port
137         {
138                 core::rect<s32> rect(0, 0, 100, 20);
139                 rect = rect + v2s32(size.X/2 - 250, size.Y/2 - 50 + 6);
140                 const wchar_t *text = L"Address + Port";
141                 Environment->addStaticText(text, rect, false, true, this, -1);
142         }
143         {
144                 core::rect<s32> rect(0, 0, 250, 30);
145                 rect = rect + v2s32(size.X/2 - 130, size.Y/2 - 50);
146                 gui::IGUIElement *e = 
147                 Environment->addEditBox(text_address.c_str(), rect, true, this, 256);
148                 if(text_name != L"")
149                         Environment->setFocus(e);
150         }
151         {
152                 core::rect<s32> rect(0, 0, 100, 30);
153                 rect = rect + v2s32(size.X/2 - 130 + 250 + 20, size.Y/2 - 50);
154                 Environment->addEditBox(text_port.c_str(), rect, true, this, 257);
155         }
156         {
157                 core::rect<s32> rect(0, 0, 400, 20);
158                 rect = rect + v2s32(size.X/2 - 130, size.Y/2 - 50 + 35);
159                 const wchar_t *text = L"Leave address blank to start a local server.";
160                 Environment->addStaticText(text, rect, false, true, this, -1);
161         }
162         // Server parameters
163         {
164                 core::rect<s32> rect(0, 0, 100, 20);
165                 rect = rect + v2s32(size.X/2 - 250, size.Y/2 + 25 + 6);
166                 const wchar_t *text = L"Server params";
167                 Environment->addStaticText(text, rect, false, true, this, -1);
168         }
169         {
170                 core::rect<s32> rect(0, 0, 250, 30);
171                 rect = rect + v2s32(size.X/2 - 130, size.Y/2 + 25);
172                 Environment->addCheckBox(creative_mode, rect, this, 259, L"Creative Mode");
173         }
174         // Start game button
175         {
176                 core::rect<s32> rect(0, 0, 180, 30);
177                 rect = rect + v2s32(size.X/2-180/2, size.Y/2-30/2 + 100);
178                 Environment->addButton(rect, this, 257, L"Start Game / Connect");
179         }
180         // Map delete button
181         {
182                 core::rect<s32> rect(0, 0, 130, 30);
183                 rect = rect + v2s32(size.X/2-130/2+200, size.Y/2-30/2 + 100);
184                 Environment->addButton(rect, this, 260, L"Delete map");
185         }
186 }
187
188 void GUIMainMenu::drawMenu()
189 {
190         gui::IGUISkin* skin = Environment->getSkin();
191         if (!skin)
192                 return;
193         video::IVideoDriver* driver = Environment->getVideoDriver();
194         
195         video::SColor bgcolor(140,0,0,0);
196         driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect);
197
198         gui::IGUIElement::draw();
199 }
200
201 void GUIMainMenu::acceptInput()
202 {
203         {
204                 gui::IGUIElement *e = getElementFromId(258);
205                 if(e != NULL)
206                         m_data->name = e->getText();
207         }
208         {
209                 gui::IGUIElement *e = getElementFromId(256);
210                 if(e != NULL)
211                         m_data->address = e->getText();
212         }
213         {
214                 gui::IGUIElement *e = getElementFromId(257);
215                 if(e != NULL)
216                         m_data->port = e->getText();
217         }
218         {
219                 gui::IGUIElement *e = getElementFromId(259);
220                 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
221                         m_data->creative_mode = ((gui::IGUICheckBox*)e)->isChecked();
222         }
223         
224         m_accepted = true;
225 }
226
227 bool GUIMainMenu::OnEvent(const SEvent& event)
228 {
229         if(event.EventType==EET_KEY_INPUT_EVENT)
230         {
231                 if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown)
232                 {
233                         m_gamecallback->exitToOS();
234                         quitMenu();
235                         return true;
236                 }
237                 if(event.KeyInput.Key==KEY_RETURN && event.KeyInput.PressedDown)
238                 {
239                         acceptInput();
240                         quitMenu();
241                         return true;
242                 }
243         }
244         if(event.EventType==EET_GUI_EVENT)
245         {
246                 if(event.GUIEvent.EventType==gui::EGET_ELEMENT_FOCUS_LOST
247                                 && isVisible())
248                 {
249                         if(!canTakeFocus(event.GUIEvent.Element))
250                         {
251                                 dstream<<"GUIMainMenu: Not allowing focus change."
252                                                 <<std::endl;
253                                 // Returning true disables focus change
254                                 return true;
255                         }
256                 }
257                 if(event.GUIEvent.EventType==gui::EGET_BUTTON_CLICKED)
258                 {
259                         switch(event.GUIEvent.Caller->getID())
260                         {
261                         case 257: // Start game
262                                 acceptInput();
263                                 quitMenu();
264                                 break;
265                         case 260: // Delete map
266                                 // Don't accept input data, just set deletion request
267                                 m_data->delete_map = true;
268                                 m_accepted = true;
269                                 quitMenu();
270                                 break;
271                         }
272                 }
273                 if(event.GUIEvent.EventType==gui::EGET_EDITBOX_ENTER)
274                 {
275                         switch(event.GUIEvent.Caller->getID())
276                         {
277                         case 256: case 257: case 258:
278                                 acceptInput();
279                                 quitMenu();
280                                 break;
281                         }
282                 }
283         }
284
285         return Parent ? Parent->OnEvent(event) : false;
286 }
287