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,
202 void GUIKeyChangeMenu::drawMenu()
204 gui::IGUISkin* skin = Environment->getSkin();
207 video::IVideoDriver* driver = Environment->getVideoDriver();
209 video::SColor bgcolor(140, 0, 0, 0);
212 core::rect < s32 > rect(0, 0, 620, 620);
213 rect += AbsoluteRect.UpperLeftCorner;
214 driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
217 gui::IGUIElement::draw();
220 bool GUIKeyChangeMenu::acceptInput()
222 for(size_t i = 0; i < key_settings.size(); i++)
224 key_setting *k = key_settings.at(i);
225 g_settings->set(k->setting_name, k->key.sym());
228 gui::IGUIElement *e = getElementFromId(GUI_ID_CB_AUX1_DESCENDS);
229 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
230 g_settings->setBool("aux1_descends", ((gui::IGUICheckBox*)e)->isChecked());
233 gui::IGUIElement *e = getElementFromId(GUI_ID_CB_DOUBLETAP_JUMP);
234 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
235 g_settings->setBool("doubletap_jump", ((gui::IGUICheckBox*)e)->isChecked());
241 bool GUIKeyChangeMenu::resetMenu()
245 for(size_t i = 0; i < key_settings.size(); i++)
247 key_setting *k = key_settings.at(i);
248 if(k->id == activeKey)
250 wchar_t* text = wgettext(k->key.name());
251 k->button->setText(text);
261 bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
263 if (event.EventType == EET_KEY_INPUT_EVENT && activeKey >= 0
264 && event.KeyInput.PressedDown)
267 bool prefer_character = shift_down;
268 KeyPress kp(event.KeyInput, prefer_character);
270 bool shift_went_down = false;
272 (event.KeyInput.Key == irr::KEY_SHIFT ||
273 event.KeyInput.Key == irr::KEY_LSHIFT ||
274 event.KeyInput.Key == irr::KEY_RSHIFT))
275 shift_went_down = true;
277 // Remove Key already in use message
278 if(this->key_used_text)
280 this->key_used_text->remove();
281 this->key_used_text = NULL;
283 // Display Key already in use message
284 if (std::find(this->key_used.begin(), this->key_used.end(), kp) != this->key_used.end())
286 core::rect < s32 > rect(0, 0, 600, 40);
287 rect += v2s32(0, 0) + v2s32(25, 30);
288 wchar_t* text = wgettext("Key already in use");
289 this->key_used_text = Environment->addStaticText(text,
290 rect, false, true, this, -1);
292 //infostream << "Key already in use" << std::endl;
298 for(size_t i = 0; i < key_settings.size(); i++)
300 if(key_settings.at(i)->id == activeKey)
302 k = key_settings.at(i);
308 wchar_t* text = wgettext(k->key.name());
309 k->button->setText(text);
312 this->key_used.push_back(kp);
314 // Allow characters made with shift
324 if (event.EventType == EET_GUI_EVENT)
326 if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST
329 if (!canTakeFocus(event.GUIEvent.Element))
331 dstream << "GUIMainMenu: Not allowing focus change."
333 // Returning true disables focus change
337 if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED)
339 switch (event.GUIEvent.Caller->getID())
341 case GUI_ID_BACK_BUTTON: //back
345 case GUI_ID_ABORT_BUTTON: //abort
349 key_setting *k = NULL;
350 for(size_t i = 0; i < key_settings.size(); i++)
352 if(key_settings.at(i)->id == event.GUIEvent.Caller->getID())
354 k = key_settings.at(i);
362 activeKey = event.GUIEvent.Caller->getID();
363 wchar_t* text = wgettext("press key");
364 k->button->setText(text);
366 this->key_used.erase(std::remove(this->key_used.begin(),
367 this->key_used.end(), k->key), this->key_used.end());
370 Environment->setFocus(this);
373 return Parent ? Parent->OnEvent(event) : false;
376 void GUIKeyChangeMenu::add_key(int id, wchar_t* button_name, std::string setting_name)
378 key_setting *k = new key_setting;
381 k->button_name = button_name;
382 k->setting_name = setting_name;
383 k->key = getKeySetting(k->setting_name.c_str());
384 key_settings.push_back(k);
387 void GUIKeyChangeMenu::init_keys()
389 this->add_key(GUI_ID_KEY_FORWARD_BUTTON, wgettext("Forward"), "keymap_forward");
390 this->add_key(GUI_ID_KEY_BACKWARD_BUTTON, wgettext("Backward"), "keymap_backward");
391 this->add_key(GUI_ID_KEY_LEFT_BUTTON, wgettext("Left"), "keymap_left");
392 this->add_key(GUI_ID_KEY_RIGHT_BUTTON, wgettext("Right"), "keymap_right");
393 this->add_key(GUI_ID_KEY_USE_BUTTON, wgettext("Use"), "keymap_special1");
394 this->add_key(GUI_ID_KEY_JUMP_BUTTON, wgettext("Jump"), "keymap_jump");
395 this->add_key(GUI_ID_KEY_SNEAK_BUTTON, wgettext("Sneak"), "keymap_sneak");
396 this->add_key(GUI_ID_KEY_DROP_BUTTON, wgettext("Drop"), "keymap_drop");
397 this->add_key(GUI_ID_KEY_INVENTORY_BUTTON, wgettext("Inventory"), "keymap_inventory");
398 this->add_key(GUI_ID_KEY_CHAT_BUTTON, wgettext("Chat"), "keymap_chat");
399 this->add_key(GUI_ID_KEY_CMD_BUTTON, wgettext("Command"), "keymap_cmd");
400 this->add_key(GUI_ID_KEY_CONSOLE_BUTTON, wgettext("Console"), "keymap_console");
401 this->add_key(GUI_ID_KEY_FLY_BUTTON, wgettext("Toggle fly"), "keymap_freemove");
402 this->add_key(GUI_ID_KEY_FAST_BUTTON, wgettext("Toggle fast"), "keymap_fastmove");
403 this->add_key(GUI_ID_KEY_NOCLIP_BUTTON, wgettext("Toggle noclip"), "keymap_noclip");
404 this->add_key(GUI_ID_KEY_RANGE_BUTTON, wgettext("Range select"), "keymap_rangeselect");
405 this->add_key(GUI_ID_KEY_DUMP_BUTTON, wgettext("Print stacks"), "keymap_print_debug_stacks");