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()
80 void GUIKeyChangeMenu::removeChildren()
82 const core::list<gui::IGUIElement*> &children = getChildren();
83 core::list<gui::IGUIElement*> children_copy;
84 for (core::list<gui::IGUIElement*>::ConstIterator i = children.begin(); i
85 != children.end(); i++)
87 children_copy.push_back(*i);
89 for (core::list<gui::IGUIElement*>::Iterator i = children_copy.begin(); i
90 != children_copy.end(); i++)
96 void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
101 core::rect < s32 > rect(screensize.X / 2 - size.X / 2,
102 screensize.Y / 2 - size.Y / 2, screensize.X / 2 + size.X / 2,
103 screensize.Y / 2 + size.Y / 2);
106 recalculateAbsolutePosition(false);
111 core::rect < s32 > rect(0, 0, 600, 40);
112 rect += topleft + v2s32(25, 3);
113 //gui::IGUIStaticText *t =
114 Environment->addStaticText(wgettext("Keybindings. (If this menu screws up, remove stuff from minetest.conf)"),
115 rect, false, true, this, -1);
116 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
121 v2s32 offset(25, 60);
123 for(size_t i = 0; i < key_settings.size(); i++)
125 key_setting *k = key_settings.at(i);
127 core::rect < s32 > rect(0, 0, 100, 20);
128 rect += topleft + v2s32(offset.X, offset.Y);
129 Environment->addStaticText(k->button_name, rect, false, true, this, -1);
133 core::rect < s32 > rect(0, 0, 100, 30);
134 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
135 k->button = Environment->addButton(rect, this, k->id, wgettext(k->key.name()));
137 if(i + 1 == KMaxButtonPerColumns)
138 offset = v2s32(250, 60);
140 offset += v2s32(0, 25);
144 s32 option_x = offset.X + 10;
145 s32 option_y = offset.Y;
148 core::rect<s32> rect(0, 0, option_w, 30);
149 rect += topleft + v2s32(option_x, option_y);
150 Environment->addCheckBox(g_settings->getBool("aux1_descends"), rect, this,
151 GUI_ID_CB_AUX1_DESCENDS, wgettext("\"Use\" = climb down"));
153 offset += v2s32(0, 25);
157 s32 option_x = offset.X + 10;
158 s32 option_y = offset.Y;
161 core::rect<s32> rect(0, 0, option_w, 30);
162 rect += topleft + v2s32(option_x, option_y);
163 Environment->addCheckBox(g_settings->getBool("doubletap_jump"), rect, this,
164 GUI_ID_CB_DOUBLETAP_JUMP, wgettext("Double tap \"jump\" to toggle fly"));
166 offset += v2s32(0, 25);
170 core::rect < s32 > rect(0, 0, 100, 30);
171 rect += topleft + v2s32(size.X - 100 - 20, size.Y - 40);
172 Environment->addButton(rect, this, GUI_ID_BACK_BUTTON,
176 core::rect < s32 > rect(0, 0, 100, 30);
177 rect += topleft + v2s32(size.X - 100 - 20 - 100 - 20, size.Y - 40);
178 Environment->addButton(rect, this, GUI_ID_ABORT_BUTTON,
185 void GUIKeyChangeMenu::drawMenu()
187 gui::IGUISkin* skin = Environment->getSkin();
190 video::IVideoDriver* driver = Environment->getVideoDriver();
192 video::SColor bgcolor(140, 0, 0, 0);
195 core::rect < s32 > rect(0, 0, 620, 620);
196 rect += AbsoluteRect.UpperLeftCorner;
197 driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
200 gui::IGUIElement::draw();
203 bool GUIKeyChangeMenu::acceptInput()
205 for(size_t i = 0; i < key_settings.size(); i++)
207 key_setting *k = key_settings.at(i);
208 g_settings->set(k->setting_name, k->key.sym());
211 gui::IGUIElement *e = getElementFromId(GUI_ID_CB_AUX1_DESCENDS);
212 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
213 g_settings->setBool("aux1_descends", ((gui::IGUICheckBox*)e)->isChecked());
216 gui::IGUIElement *e = getElementFromId(GUI_ID_CB_DOUBLETAP_JUMP);
217 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
218 g_settings->setBool("doubletap_jump", ((gui::IGUICheckBox*)e)->isChecked());
224 bool GUIKeyChangeMenu::resetMenu()
228 for(size_t i = 0; i < key_settings.size(); i++)
230 key_setting *k = key_settings.at(i);
231 if(k->id == activeKey)
233 k->button->setText(wgettext(k->key.name()));
242 bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
244 if (event.EventType == EET_KEY_INPUT_EVENT && activeKey >= 0
245 && event.KeyInput.PressedDown)
248 bool prefer_character = shift_down;
249 KeyPress kp(event.KeyInput, prefer_character);
251 bool shift_went_down = false;
253 (event.KeyInput.Key == irr::KEY_SHIFT ||
254 event.KeyInput.Key == irr::KEY_LSHIFT ||
255 event.KeyInput.Key == irr::KEY_RSHIFT))
256 shift_went_down = true;
258 // Remove Key already in use message
259 if(this->key_used_text)
261 this->key_used_text->remove();
262 this->key_used_text = NULL;
264 // Display Key already in use message
265 if (std::find(this->key_used.begin(), this->key_used.end(), kp) != this->key_used.end())
267 core::rect < s32 > rect(0, 0, 600, 40);
268 rect += v2s32(0, 0) + v2s32(25, 30);
269 this->key_used_text = Environment->addStaticText(wgettext("Key already in use"),
270 rect, false, true, this, -1);
271 //infostream << "Key already in use" << std::endl;
277 for(size_t i = 0; i < key_settings.size(); i++)
279 if(key_settings.at(i)->id == activeKey)
281 k = key_settings.at(i);
287 k->button->setText(wgettext(k->key.name()));
289 this->key_used.push_back(kp);
292 // Allow characters made with shift
302 if (event.EventType == EET_GUI_EVENT)
304 if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST
307 if (!canTakeFocus(event.GUIEvent.Element))
309 dstream << "GUIMainMenu: Not allowing focus change."
311 // Returning true disables focus change
315 if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED)
317 if(event.GUIEvent.Caller->getID() != GUI_ID_BACK_BUTTON &&
318 event.GUIEvent.Caller->getID() != GUI_ID_ABORT_BUTTON)
323 switch (event.GUIEvent.Caller->getID())
325 case GUI_ID_BACK_BUTTON: //back
329 case GUI_ID_ABORT_BUTTON: //abort
333 key_setting *k = NULL;
334 for(size_t i = 0; i < key_settings.size(); i++)
336 if(key_settings.at(i)->id == event.GUIEvent.Caller->getID())
338 k = key_settings.at(i);
346 activeKey = event.GUIEvent.Caller->getID();
347 k->button->setText(wgettext("press key"));
348 this->key_used.erase(std::remove(this->key_used.begin(),
349 this->key_used.end(), k->key), this->key_used.end());
352 Environment->setFocus(this);
357 return Parent ? Parent->OnEvent(event) : false;
360 void GUIKeyChangeMenu::add_key(int id, std::string button_name, std::string setting_name)
362 key_setting *k = new key_setting;
364 k->button_name = wgettext(button_name.c_str());
365 k->setting_name = setting_name;
366 k->key = getKeySetting(k->setting_name.c_str());
367 key_settings.push_back(k);
370 void GUIKeyChangeMenu::init_keys()
372 this->add_key(GUI_ID_KEY_FORWARD_BUTTON, gettext("Forward"), "keymap_forward");
373 this->add_key(GUI_ID_KEY_BACKWARD_BUTTON, gettext("Backward"), "keymap_backward");
374 this->add_key(GUI_ID_KEY_LEFT_BUTTON, gettext("Left"), "keymap_left");
375 this->add_key(GUI_ID_KEY_RIGHT_BUTTON, gettext("Right"), "keymap_right");
376 this->add_key(GUI_ID_KEY_USE_BUTTON, gettext("Use"), "keymap_special1");
377 this->add_key(GUI_ID_KEY_JUMP_BUTTON, gettext("Jump"), "keymap_jump");
378 this->add_key(GUI_ID_KEY_SNEAK_BUTTON, gettext("Sneak"), "keymap_sneak");
379 this->add_key(GUI_ID_KEY_DROP_BUTTON, gettext("Drop"), "keymap_drop");
380 this->add_key(GUI_ID_KEY_INVENTORY_BUTTON, gettext("Inventory"), "keymap_inventory");
381 this->add_key(GUI_ID_KEY_CHAT_BUTTON, gettext("Chat"), "keymap_chat");
382 this->add_key(GUI_ID_KEY_CMD_BUTTON, gettext("Command"), "keymap_cmd");
383 this->add_key(GUI_ID_KEY_CONSOLE_BUTTON, gettext("Console"), "keymap_console");
384 this->add_key(GUI_ID_KEY_FLY_BUTTON, gettext("Toggle fly"), "keymap_freemove");
385 this->add_key(GUI_ID_KEY_FAST_BUTTON, gettext("Toggle fast"), "keymap_fastmove");
386 this->add_key(GUI_ID_KEY_NOCLIP_BUTTON, gettext("Toggle noclip"), "keymap_noclip");
387 this->add_key(GUI_ID_KEY_RANGE_BUTTON, gettext("Range select"), "keymap_rangeselect");
388 this->add_key(GUI_ID_KEY_DUMP_BUTTON, gettext("Print stacks"), "keymap_print_debug_stacks");