3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 Copyright (C) 2013 Ciaran Gultnieks <ciaran@ciarang.com>
5 Copyright (C) 2013 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 Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser 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"
27 #include <IGUICheckBox.h>
28 #include <IGUIEditBox.h>
29 #include <IGUIButton.h>
30 #include <IGUIStaticText.h>
35 #define KMaxButtonPerColumns 12
39 GUI_ID_BACK_BUTTON = 101, GUI_ID_ABORT_BUTTON, GUI_ID_SCROLL_BAR,
41 GUI_ID_KEY_FORWARD_BUTTON,
42 GUI_ID_KEY_BACKWARD_BUTTON,
43 GUI_ID_KEY_LEFT_BUTTON,
44 GUI_ID_KEY_RIGHT_BUTTON,
45 GUI_ID_KEY_USE_BUTTON,
46 GUI_ID_KEY_FLY_BUTTON,
47 GUI_ID_KEY_FAST_BUTTON,
48 GUI_ID_KEY_JUMP_BUTTON,
49 GUI_ID_KEY_NOCLIP_BUTTON,
50 GUI_ID_KEY_CHAT_BUTTON,
51 GUI_ID_KEY_CMD_BUTTON,
52 GUI_ID_KEY_CONSOLE_BUTTON,
53 GUI_ID_KEY_SNEAK_BUTTON,
54 GUI_ID_KEY_DROP_BUTTON,
55 GUI_ID_KEY_INVENTORY_BUTTON,
56 GUI_ID_KEY_DUMP_BUTTON,
57 GUI_ID_KEY_RANGE_BUTTON,
59 GUI_ID_CB_AUX1_DESCENDS,
60 GUI_ID_CB_DOUBLETAP_JUMP,
63 GUIKeyChangeMenu::GUIKeyChangeMenu(gui::IGUIEnvironment* env,
64 gui::IGUIElement* parent, s32 id, IMenuManager *menumgr) :
65 GUIModalMenu(env, parent, id, menumgr)
69 this->key_used_text = NULL;
71 for(size_t i=0; i<key_settings.size(); i++)
72 this->key_used.push_back(key_settings.at(i)->key);
75 GUIKeyChangeMenu::~GUIKeyChangeMenu()
79 for (std::vector<key_setting*>::iterator iter = key_settings.begin();
80 iter != key_settings.end(); iter ++) {
81 delete[] (*iter)->button_name;
87 void GUIKeyChangeMenu::removeChildren()
89 const core::list<gui::IGUIElement*> &children = getChildren();
90 core::list<gui::IGUIElement*> children_copy;
91 for (core::list<gui::IGUIElement*>::ConstIterator i = children.begin(); i
92 != children.end(); i++)
94 children_copy.push_back(*i);
96 for (core::list<gui::IGUIElement*>::Iterator i = children_copy.begin(); i
97 != children_copy.end(); i++)
103 void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
106 v2s32 size(620, 430);
108 core::rect < s32 > rect(screensize.X / 2 - size.X / 2,
109 screensize.Y / 2 - size.Y / 2, screensize.X / 2 + size.X / 2,
110 screensize.Y / 2 + size.Y / 2);
113 recalculateAbsolutePosition(false);
118 core::rect < s32 > rect(0, 0, 600, 40);
119 rect += topleft + v2s32(25, 3);
120 //gui::IGUIStaticText *t =
121 wchar_t* text = wgettext("Keybindings. (If this menu screws up, remove stuff from minetest.conf)");
122 Environment->addStaticText(text,
123 rect, false, true, this, -1);
125 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
130 v2s32 offset(25, 60);
132 for(size_t i = 0; i < key_settings.size(); i++)
134 key_setting *k = key_settings.at(i);
136 core::rect < s32 > rect(0, 0, 100, 20);
137 rect += topleft + v2s32(offset.X, offset.Y);
138 Environment->addStaticText(k->button_name, rect, false, true, this, -1);
142 core::rect < s32 > rect(0, 0, 100, 30);
143 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
144 wchar_t* text = wgettext(k->key.name());
145 k->button = Environment->addButton(rect, this, k->id, text );
148 if(i + 1 == KMaxButtonPerColumns)
149 offset = v2s32(250, 60);
151 offset += v2s32(0, 25);
155 s32 option_x = offset.X + 10;
156 s32 option_y = offset.Y;
159 core::rect<s32> rect(0, 0, option_w, 30);
160 rect += topleft + v2s32(option_x, option_y);
161 wchar_t* text = wgettext("\"Use\" = climb down");
162 Environment->addCheckBox(g_settings->getBool("aux1_descends"), rect, this,
163 GUI_ID_CB_AUX1_DESCENDS, text);
166 offset += v2s32(0, 25);
170 s32 option_x = offset.X + 10;
171 s32 option_y = offset.Y;
174 core::rect<s32> rect(0, 0, option_w, 30);
175 rect += topleft + v2s32(option_x, option_y);
176 wchar_t* text = wgettext("Double tap \"jump\" to toggle fly");
177 Environment->addCheckBox(g_settings->getBool("doubletap_jump"), rect, this,
178 GUI_ID_CB_DOUBLETAP_JUMP, text);
181 offset += v2s32(0, 25);
185 core::rect < s32 > rect(0, 0, 100, 30);
186 rect += topleft + v2s32(size.X - 100 - 20, size.Y - 40);
187 wchar_t* text = wgettext("Save");
188 Environment->addButton(rect, this, GUI_ID_BACK_BUTTON,
193 core::rect < s32 > rect(0, 0, 100, 30);
194 rect += topleft + v2s32(size.X - 100 - 20 - 100 - 20, size.Y - 40);
195 wchar_t* text = wgettext("Cancel");
196 Environment->addButton(rect, this, GUI_ID_ABORT_BUTTON,
204 void GUIKeyChangeMenu::drawMenu()
206 gui::IGUISkin* skin = Environment->getSkin();
209 video::IVideoDriver* driver = Environment->getVideoDriver();
211 video::SColor bgcolor(140, 0, 0, 0);
214 core::rect < s32 > rect(0, 0, 620, 620);
215 rect += AbsoluteRect.UpperLeftCorner;
216 driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
219 gui::IGUIElement::draw();
222 bool GUIKeyChangeMenu::acceptInput()
224 for(size_t i = 0; i < key_settings.size(); i++)
226 key_setting *k = key_settings.at(i);
227 g_settings->set(k->setting_name, k->key.sym());
230 gui::IGUIElement *e = getElementFromId(GUI_ID_CB_AUX1_DESCENDS);
231 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
232 g_settings->setBool("aux1_descends", ((gui::IGUICheckBox*)e)->isChecked());
235 gui::IGUIElement *e = getElementFromId(GUI_ID_CB_DOUBLETAP_JUMP);
236 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
237 g_settings->setBool("doubletap_jump", ((gui::IGUICheckBox*)e)->isChecked());
243 bool GUIKeyChangeMenu::resetMenu()
247 for(size_t i = 0; i < key_settings.size(); i++)
249 key_setting *k = key_settings.at(i);
250 if(k->id == activeKey)
252 wchar_t* text = wgettext(k->key.name());
253 k->button->setText(text);
263 bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
265 if (event.EventType == EET_KEY_INPUT_EVENT && activeKey >= 0
266 && event.KeyInput.PressedDown)
269 bool prefer_character = shift_down;
270 KeyPress kp(event.KeyInput, prefer_character);
272 bool shift_went_down = false;
274 (event.KeyInput.Key == irr::KEY_SHIFT ||
275 event.KeyInput.Key == irr::KEY_LSHIFT ||
276 event.KeyInput.Key == irr::KEY_RSHIFT))
277 shift_went_down = true;
279 // Remove Key already in use message
280 if(this->key_used_text)
282 this->key_used_text->remove();
283 this->key_used_text = NULL;
285 // Display Key already in use message
286 if (std::find(this->key_used.begin(), this->key_used.end(), kp) != this->key_used.end())
288 core::rect < s32 > rect(0, 0, 600, 40);
289 rect += v2s32(0, 0) + v2s32(25, 30);
290 wchar_t* text = wgettext("Key already in use");
291 this->key_used_text = Environment->addStaticText(text,
292 rect, false, true, this, -1);
294 //infostream << "Key already in use" << std::endl;
300 for(size_t i = 0; i < key_settings.size(); i++)
302 if(key_settings.at(i)->id == activeKey)
304 k = key_settings.at(i);
310 wchar_t* text = wgettext(k->key.name());
311 k->button->setText(text);
314 this->key_used.push_back(kp);
317 // Allow characters made with shift
327 if (event.EventType == EET_GUI_EVENT)
329 if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST
332 if (!canTakeFocus(event.GUIEvent.Element))
334 dstream << "GUIMainMenu: Not allowing focus change."
336 // Returning true disables focus change
340 if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED)
342 if(event.GUIEvent.Caller->getID() != GUI_ID_BACK_BUTTON &&
343 event.GUIEvent.Caller->getID() != GUI_ID_ABORT_BUTTON)
348 switch (event.GUIEvent.Caller->getID())
350 case GUI_ID_BACK_BUTTON: //back
354 case GUI_ID_ABORT_BUTTON: //abort
358 key_setting *k = NULL;
359 for(size_t i = 0; i < key_settings.size(); i++)
361 if(key_settings.at(i)->id == event.GUIEvent.Caller->getID())
363 k = key_settings.at(i);
371 activeKey = event.GUIEvent.Caller->getID();
372 wchar_t* text = wgettext("press key");
373 k->button->setText(text);
375 this->key_used.erase(std::remove(this->key_used.begin(),
376 this->key_used.end(), k->key), this->key_used.end());
379 Environment->setFocus(this);
384 return Parent ? Parent->OnEvent(event) : false;
387 void GUIKeyChangeMenu::add_key(int id, wchar_t* button_name, std::string setting_name)
389 key_setting *k = new key_setting;
392 k->button_name = button_name;
393 k->setting_name = setting_name;
394 k->key = getKeySetting(k->setting_name.c_str());
395 key_settings.push_back(k);
398 void GUIKeyChangeMenu::init_keys()
400 this->add_key(GUI_ID_KEY_FORWARD_BUTTON, wgettext("Forward"), "keymap_forward");
401 this->add_key(GUI_ID_KEY_BACKWARD_BUTTON, wgettext("Backward"), "keymap_backward");
402 this->add_key(GUI_ID_KEY_LEFT_BUTTON, wgettext("Left"), "keymap_left");
403 this->add_key(GUI_ID_KEY_RIGHT_BUTTON, wgettext("Right"), "keymap_right");
404 this->add_key(GUI_ID_KEY_USE_BUTTON, wgettext("Use"), "keymap_special1");
405 this->add_key(GUI_ID_KEY_JUMP_BUTTON, wgettext("Jump"), "keymap_jump");
406 this->add_key(GUI_ID_KEY_SNEAK_BUTTON, wgettext("Sneak"), "keymap_sneak");
407 this->add_key(GUI_ID_KEY_DROP_BUTTON, wgettext("Drop"), "keymap_drop");
408 this->add_key(GUI_ID_KEY_INVENTORY_BUTTON, wgettext("Inventory"), "keymap_inventory");
409 this->add_key(GUI_ID_KEY_CHAT_BUTTON, wgettext("Chat"), "keymap_chat");
410 this->add_key(GUI_ID_KEY_CMD_BUTTON, wgettext("Command"), "keymap_cmd");
411 this->add_key(GUI_ID_KEY_CONSOLE_BUTTON, wgettext("Console"), "keymap_console");
412 this->add_key(GUI_ID_KEY_FLY_BUTTON, wgettext("Toggle fly"), "keymap_freemove");
413 this->add_key(GUI_ID_KEY_FAST_BUTTON, wgettext("Toggle fast"), "keymap_fastmove");
414 this->add_key(GUI_ID_KEY_NOCLIP_BUTTON, wgettext("Toggle noclip"), "keymap_noclip");
415 this->add_key(GUI_ID_KEY_RANGE_BUTTON, wgettext("Range select"), "keymap_rangeselect");
416 this->add_key(GUI_ID_KEY_DUMP_BUTTON, wgettext("Print stacks"), "keymap_print_debug_stacks");