3 Copyright (C) 2010-11 celeron55, Perttu Ahola <celeron55@gmail.com>
4 Copyright (C) 2011 Ciaran Gultnieks <ciaran@ciarang.com>
5 Copyright (C) 2011 teddydestodes <derkomtur@schattengang.net>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "guiKeyChangeMenu.h"
24 #include "serialization.h"
29 GUIKeyChangeMenu::GUIKeyChangeMenu(gui::IGUIEnvironment* env,
30 gui::IGUIElement* parent, s32 id, IMenuManager *menumgr) :
31 GUIModalMenu(env, parent, id, menumgr)
37 GUIKeyChangeMenu::~GUIKeyChangeMenu()
42 void GUIKeyChangeMenu::removeChildren()
44 const core::list<gui::IGUIElement*> &children = getChildren();
45 core::list<gui::IGUIElement*> children_copy;
46 for (core::list<gui::IGUIElement*>::ConstIterator i = children.begin(); i
47 != children.end(); i++)
49 children_copy.push_back(*i);
51 for (core::list<gui::IGUIElement*>::Iterator i = children_copy.begin(); i
52 != children_copy.end(); i++)
58 void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
66 Calculate new sizes and positions
71 core::rect < s32 > rect(screensize.X / 2 - size.X / 2,
72 screensize.Y / 2 - size.Y / 2, screensize.X / 2 + size.X / 2,
73 screensize.Y / 2 + size.Y / 2);
76 recalculateAbsolutePosition(false);
81 core::rect < s32 > rect(0, 0, 125, 20);
82 rect += topleft + v2s32(25, 3);
83 const wchar_t *text = L"KEYBINDINGS";
84 //gui::IGUIStaticText *t =
85 Environment->addStaticText(text, rect, false, true, this, -1);
86 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
92 core::rect < s32 > rect(0, 0, 100, 20);
93 rect += topleft + v2s32(offset.X, offset.Y);
94 const wchar_t *text = L"Forward";
95 Environment->addStaticText(text, rect, false, true, this, -1);
96 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
100 core::rect < s32 > rect(0, 0, 100, 30);
101 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
102 this->forward = Environment->addButton(rect, this,
103 GUI_ID_KEY_FORWARD_BUTTON,
104 narrow_to_wide(KeyNames[key_forward]).c_str());
107 offset += v2s32(0, 25);
109 core::rect < s32 > rect(0, 0, 100, 20);
110 rect += topleft + v2s32(offset.X, offset.Y);
111 const wchar_t *text = L"Backward";
112 Environment->addStaticText(text, rect, false, true, this, -1);
113 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
117 core::rect < s32 > rect(0, 0, 100, 30);
118 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
119 this->backward = Environment->addButton(rect, this,
120 GUI_ID_KEY_BACKWARD_BUTTON,
121 narrow_to_wide(KeyNames[key_backward]).c_str());
123 offset += v2s32(0, 25);
125 core::rect < s32 > rect(0, 0, 100, 20);
126 rect += topleft + v2s32(offset.X, offset.Y);
127 const wchar_t *text = L"Left";
128 Environment->addStaticText(text, rect, false, true, this, -1);
129 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
133 core::rect < s32 > rect(0, 0, 100, 30);
134 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
135 this->left = Environment->addButton(rect, this, GUI_ID_KEY_LEFT_BUTTON,
136 narrow_to_wide(KeyNames[key_left]).c_str());
138 offset += v2s32(0, 25);
140 core::rect < s32 > rect(0, 0, 100, 20);
141 rect += topleft + v2s32(offset.X, offset.Y);
142 const wchar_t *text = L"Right";
143 Environment->addStaticText(text, rect, false, true, this, -1);
144 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
148 core::rect < s32 > rect(0, 0, 100, 30);
149 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
150 this->right = Environment->addButton(rect, this,
151 GUI_ID_KEY_RIGHT_BUTTON,
152 narrow_to_wide(KeyNames[key_right]).c_str());
154 offset += v2s32(0, 25);
156 core::rect < s32 > rect(0, 0, 100, 20);
157 rect += topleft + v2s32(offset.X, offset.Y);
158 const wchar_t *text = L"Use";
159 Environment->addStaticText(text, rect, false, true, this, -1);
160 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
164 core::rect < s32 > rect(0, 0, 100, 30);
165 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
166 this->use = Environment->addButton(rect, this, GUI_ID_KEY_USE_BUTTON,
167 narrow_to_wide(KeyNames[key_use]).c_str());
169 offset += v2s32(0, 25);
171 core::rect < s32 > rect(0, 0, 100, 20);
172 rect += topleft + v2s32(offset.X, offset.Y);
173 const wchar_t *text = L"Sneak";
174 Environment->addStaticText(text, rect, false, true, this, -1);
175 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
179 core::rect < s32 > rect(0, 0, 100, 30);
180 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
181 this->sneak = Environment->addButton(rect, this,
182 GUI_ID_KEY_SNEAK_BUTTON,
183 narrow_to_wide(KeyNames[key_sneak]).c_str());
185 offset += v2s32(0, 25);
187 core::rect < s32 > rect(0, 0, 100, 20);
188 rect += topleft + v2s32(offset.X, offset.Y);
189 const wchar_t *text = L"Jump";
190 Environment->addStaticText(text, rect, false, true, this, -1);
191 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
195 core::rect < s32 > rect(0, 0, 100, 30);
196 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
197 this->jump = Environment->addButton(rect, this, GUI_ID_KEY_JUMP_BUTTON,
198 narrow_to_wide(KeyNames[key_jump]).c_str());
201 offset += v2s32(0, 25);
203 core::rect < s32 > rect(0, 0, 100, 20);
204 rect += topleft + v2s32(offset.X, offset.Y);
205 const wchar_t *text = L"Inventory";
206 Environment->addStaticText(text, rect, false, true, this, -1);
207 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
211 core::rect < s32 > rect(0, 0, 100, 30);
212 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
213 this->inventory = Environment->addButton(rect, this,
214 GUI_ID_KEY_INVENTORY_BUTTON,
215 narrow_to_wide(KeyNames[key_inventory]).c_str());
217 offset += v2s32(0, 25);
219 core::rect < s32 > rect(0, 0, 100, 20);
220 rect += topleft + v2s32(offset.X, offset.Y);
221 const wchar_t *text = L"Chat";
222 Environment->addStaticText(text, rect, false, true, this, -1);
223 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
227 core::rect < s32 > rect(0, 0, 100, 30);
228 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
229 this->chat = Environment->addButton(rect, this, GUI_ID_KEY_CHAT_BUTTON,
230 narrow_to_wide(KeyNames[key_chat]).c_str());
234 offset = v2s32(250, 40);
236 core::rect < s32 > rect(0, 0, 100, 20);
237 rect += topleft + v2s32(offset.X, offset.Y);
238 const wchar_t *text = L"Toggle fly";
239 Environment->addStaticText(text, rect, false, true, this, -1);
240 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
244 core::rect < s32 > rect(0, 0, 100, 30);
245 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
246 this->fly = Environment->addButton(rect, this, GUI_ID_KEY_FLY_BUTTON,
247 narrow_to_wide(KeyNames[key_fly]).c_str());
249 offset += v2s32(0, 25);
251 core::rect < s32 > rect(0, 0, 100, 20);
252 rect += topleft + v2s32(offset.X, offset.Y);
253 const wchar_t *text = L"Toggle fast";
254 Environment->addStaticText(text, rect, false, true, this, -1);
255 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
259 core::rect < s32 > rect(0, 0, 100, 30);
260 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
261 this->fast = Environment->addButton(rect, this, GUI_ID_KEY_FAST_BUTTON,
262 narrow_to_wide(KeyNames[key_fast]).c_str());
264 offset += v2s32(0, 25);
266 core::rect < s32 > rect(0, 0, 100, 20);
267 rect += topleft + v2s32(offset.X, offset.Y);
268 const wchar_t *text = L"Range select";
269 Environment->addStaticText(text, rect, false, true, this, -1);
270 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
274 core::rect < s32 > rect(0, 0, 100, 30);
275 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
276 this->range = Environment->addButton(rect, this,
277 GUI_ID_KEY_RANGE_BUTTON,
278 narrow_to_wide(KeyNames[key_range]).c_str());
281 offset += v2s32(0, 25);
283 core::rect < s32 > rect(0, 0, 100, 20);
284 rect += topleft + v2s32(offset.X, offset.Y);
285 const wchar_t *text = L"Print stacks";
286 Environment->addStaticText(text, rect, false, true, this, -1);
287 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
291 core::rect < s32 > rect(0, 0, 100, 30);
292 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
293 this->dump = Environment->addButton(rect, this, GUI_ID_KEY_DUMP_BUTTON,
294 narrow_to_wide(KeyNames[key_dump]).c_str());
297 core::rect < s32 > rect(0, 0, 100, 30);
298 rect += topleft + v2s32(size.X - 100 - 20, size.Y - 40);
299 Environment->addButton(rect, this, GUI_ID_BACK_BUTTON, L"Save");
302 core::rect < s32 > rect(0, 0, 100, 30);
303 rect += topleft + v2s32(size.X - 100 - 20 - 100 - 20, size.Y - 40);
304 Environment->addButton(rect, this, GUI_ID_ABORT_BUTTON, L"Cancel");
308 void GUIKeyChangeMenu::drawMenu()
310 gui::IGUISkin* skin = Environment->getSkin();
313 video::IVideoDriver* driver = Environment->getVideoDriver();
315 video::SColor bgcolor(140, 0, 0, 0);
318 core::rect < s32 > rect(0, 0, 620, 620);
319 rect += AbsoluteRect.UpperLeftCorner;
320 driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
323 gui::IGUIElement::draw();
326 bool GUIKeyChangeMenu::acceptInput()
328 g_settings.set("keymap_forward", keycode_to_keyname(key_forward));
329 g_settings.set("keymap_backward", keycode_to_keyname(key_backward));
330 g_settings.set("keymap_left", keycode_to_keyname(key_left));
331 g_settings.set("keymap_right", keycode_to_keyname(key_right));
332 g_settings.set("keymap_jump", keycode_to_keyname(key_jump));
333 g_settings.set("keymap_sneak", keycode_to_keyname(key_sneak));
334 g_settings.set("keymap_inventory", keycode_to_keyname(key_inventory));
335 g_settings.set("keymap_chat", keycode_to_keyname(key_chat));
336 g_settings.set("keymap_rangeselect", keycode_to_keyname(key_range));
337 g_settings.set("keymap_freemove", keycode_to_keyname(key_fly));
338 g_settings.set("keymap_fastmove", keycode_to_keyname(key_fast));
339 g_settings.set("keymap_special1", keycode_to_keyname(key_use));
340 g_settings.set("keymap_print_debug_stacks", keycode_to_keyname(key_dump));
341 //clearKeyCache(); Y U NO SCOPE?!
344 void GUIKeyChangeMenu::init_keys()
346 key_forward = getKeySetting("keymap_forward");
347 key_backward = getKeySetting("keymap_backward");
348 key_left = getKeySetting("keymap_left");
349 key_right = getKeySetting("keymap_right");
350 key_jump = getKeySetting("keymap_jump");
351 key_sneak = getKeySetting("keymap_sneak");
352 key_inventory = getKeySetting("keymap_inventory");
353 key_chat = getKeySetting("keymap_chat");
354 key_range = getKeySetting("keymap_rangeselect");
355 key_fly = getKeySetting("keymap_freemove");
356 key_fast = getKeySetting("keymap_fastmove");
357 key_use = getKeySetting("keymap_special1");
358 key_dump = getKeySetting("keymap_print_debug_stacks");
361 bool GUIKeyChangeMenu::resetMenu()
367 case GUI_ID_KEY_FORWARD_BUTTON:
368 this->forward->setText(
369 narrow_to_wide(KeyNames[key_forward]).c_str());
371 case GUI_ID_KEY_BACKWARD_BUTTON:
372 this->backward->setText(
373 narrow_to_wide(KeyNames[key_backward]).c_str());
375 case GUI_ID_KEY_LEFT_BUTTON:
376 this->left->setText(narrow_to_wide(KeyNames[key_left]).c_str());
378 case GUI_ID_KEY_RIGHT_BUTTON:
379 this->right->setText(narrow_to_wide(KeyNames[key_right]).c_str());
381 case GUI_ID_KEY_JUMP_BUTTON:
382 this->jump->setText(narrow_to_wide(KeyNames[key_jump]).c_str());
384 case GUI_ID_KEY_SNEAK_BUTTON:
385 this->sneak->setText(narrow_to_wide(KeyNames[key_sneak]).c_str());
387 case GUI_ID_KEY_INVENTORY_BUTTON:
388 this->inventory->setText(
389 narrow_to_wide(KeyNames[key_inventory]).c_str());
391 case GUI_ID_KEY_CHAT_BUTTON:
392 this->chat->setText(narrow_to_wide(KeyNames[key_chat]).c_str());
394 case GUI_ID_KEY_RANGE_BUTTON:
395 this->range->setText(narrow_to_wide(KeyNames[key_range]).c_str());
397 case GUI_ID_KEY_FLY_BUTTON:
398 this->fly->setText(narrow_to_wide(KeyNames[key_fly]).c_str());
400 case GUI_ID_KEY_FAST_BUTTON:
401 this->fast->setText(narrow_to_wide(KeyNames[key_fast]).c_str());
403 case GUI_ID_KEY_USE_BUTTON:
404 this->use->setText(narrow_to_wide(KeyNames[key_use]).c_str());
406 case GUI_ID_KEY_DUMP_BUTTON:
407 this->dump->setText(narrow_to_wide(KeyNames[key_dump]).c_str());
415 bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
417 if (event.EventType == EET_KEY_INPUT_EVENT && activeKey >= 0
418 && event.KeyInput.PressedDown)
420 if (activeKey == GUI_ID_KEY_FORWARD_BUTTON)
422 this->forward->setText(
423 narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
424 this->key_forward = event.KeyInput.Key;
426 else if (activeKey == GUI_ID_KEY_BACKWARD_BUTTON)
428 this->backward->setText(
429 narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
430 this->key_backward = event.KeyInput.Key;
432 else if (activeKey == GUI_ID_KEY_LEFT_BUTTON)
435 narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
436 this->key_left = event.KeyInput.Key;
438 else if (activeKey == GUI_ID_KEY_RIGHT_BUTTON)
440 this->right->setText(
441 narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
442 this->key_right = event.KeyInput.Key;
444 else if (activeKey == GUI_ID_KEY_JUMP_BUTTON)
447 narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
448 this->key_jump = event.KeyInput.Key;
450 else if (activeKey == GUI_ID_KEY_SNEAK_BUTTON)
452 this->sneak->setText(
453 narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
454 this->key_sneak = event.KeyInput.Key;
456 else if (activeKey == GUI_ID_KEY_INVENTORY_BUTTON)
458 this->inventory->setText(
459 narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
460 this->key_inventory = event.KeyInput.Key;
462 else if (activeKey == GUI_ID_KEY_CHAT_BUTTON)
465 narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
466 this->key_chat = event.KeyInput.Key;
468 else if (activeKey == GUI_ID_KEY_RANGE_BUTTON)
470 this->range->setText(
471 narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
472 this->key_range = event.KeyInput.Key;
474 else if (activeKey == GUI_ID_KEY_FLY_BUTTON)
477 narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
478 this->key_fly = event.KeyInput.Key;
480 else if (activeKey == GUI_ID_KEY_FAST_BUTTON)
483 narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
484 this->key_fast = event.KeyInput.Key;
486 else if (activeKey == GUI_ID_KEY_USE_BUTTON)
489 narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
490 this->key_use = event.KeyInput.Key;
492 else if (activeKey == GUI_ID_KEY_DUMP_BUTTON)
495 narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
496 this->key_dump = event.KeyInput.Key;
502 if (event.EventType == EET_GUI_EVENT)
504 if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST
507 if (!canTakeFocus(event.GUIEvent.Element))
509 dstream << "GUIMainMenu: Not allowing focus change."
511 // Returning true disables focus change
515 if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED)
517 switch (event.GUIEvent.Caller->getID())
519 case GUI_ID_BACK_BUTTON: //back
523 case GUI_ID_ABORT_BUTTON: //abort
526 case GUI_ID_KEY_FORWARD_BUTTON:
528 activeKey = event.GUIEvent.Caller->getID();
529 this->forward->setText(L"press Key");
531 case GUI_ID_KEY_BACKWARD_BUTTON:
533 activeKey = event.GUIEvent.Caller->getID();
534 this->backward->setText(L"press Key");
536 case GUI_ID_KEY_LEFT_BUTTON:
538 activeKey = event.GUIEvent.Caller->getID();
539 this->left->setText(L"press Key");
541 case GUI_ID_KEY_RIGHT_BUTTON:
543 activeKey = event.GUIEvent.Caller->getID();
544 this->right->setText(L"press Key");
546 case GUI_ID_KEY_USE_BUTTON:
548 activeKey = event.GUIEvent.Caller->getID();
549 this->use->setText(L"press Key");
551 case GUI_ID_KEY_FLY_BUTTON:
553 activeKey = event.GUIEvent.Caller->getID();
554 this->fly->setText(L"press Key");
556 case GUI_ID_KEY_FAST_BUTTON:
558 activeKey = event.GUIEvent.Caller->getID();
559 this->fast->setText(L"press Key");
561 case GUI_ID_KEY_JUMP_BUTTON:
563 activeKey = event.GUIEvent.Caller->getID();
564 this->jump->setText(L"press Key");
566 case GUI_ID_KEY_CHAT_BUTTON:
568 activeKey = event.GUIEvent.Caller->getID();
569 this->chat->setText(L"press Key");
571 case GUI_ID_KEY_SNEAK_BUTTON:
573 activeKey = event.GUIEvent.Caller->getID();
574 this->sneak->setText(L"press Key");
576 case GUI_ID_KEY_INVENTORY_BUTTON:
578 activeKey = event.GUIEvent.Caller->getID();
579 this->inventory->setText(L"press Key");
581 case GUI_ID_KEY_DUMP_BUTTON:
583 activeKey = event.GUIEvent.Caller->getID();
584 this->dump->setText(L"press Key");
586 case GUI_ID_KEY_RANGE_BUTTON:
588 activeKey = event.GUIEvent.Caller->getID();
589 this->range->setText(L"press Key");
596 return Parent ? Parent->OnEvent(event) : false;