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 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,
62 GUIKeyChangeMenu::GUIKeyChangeMenu(gui::IGUIEnvironment* env,
63 gui::IGUIElement* parent, s32 id, IMenuManager *menumgr) :
64 GUIModalMenu(env, parent, id, menumgr)
68 this->key_used_text = NULL;
70 for(size_t i=0; i<key_settings.size(); i++)
71 this->key_used.push_back(key_settings.at(i)->key);
74 GUIKeyChangeMenu::~GUIKeyChangeMenu()
79 void GUIKeyChangeMenu::removeChildren()
81 const core::list<gui::IGUIElement*> &children = getChildren();
82 core::list<gui::IGUIElement*> children_copy;
83 for (core::list<gui::IGUIElement*>::ConstIterator i = children.begin(); i
84 != children.end(); i++)
86 children_copy.push_back(*i);
88 for (core::list<gui::IGUIElement*>::Iterator i = children_copy.begin(); i
89 != children_copy.end(); i++)
95 void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
100 core::rect < s32 > rect(screensize.X / 2 - size.X / 2,
101 screensize.Y / 2 - size.Y / 2, screensize.X / 2 + size.X / 2,
102 screensize.Y / 2 + size.Y / 2);
105 recalculateAbsolutePosition(false);
110 core::rect < s32 > rect(0, 0, 600, 40);
111 rect += topleft + v2s32(25, 3);
112 //gui::IGUIStaticText *t =
113 Environment->addStaticText(wgettext("Keybindings. (If this menu screws up, remove stuff from minetest.conf)"),
114 rect, false, true, this, -1);
115 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
120 v2s32 offset(25, 60);
122 for(size_t i = 0; i < key_settings.size(); i++)
124 key_setting *k = key_settings.at(i);
126 core::rect < s32 > rect(0, 0, 100, 20);
127 rect += topleft + v2s32(offset.X, offset.Y);
128 Environment->addStaticText(k->button_name, rect, false, true, this, -1);
132 core::rect < s32 > rect(0, 0, 100, 30);
133 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
134 k->button = Environment->addButton(rect, this, k->id, wgettext(k->key.name()));
136 if(i + 1 == KMaxButtonPerColumns)
137 offset = v2s32(250, 60);
139 offset += v2s32(0, 25);
143 s32 option_x = offset.X + 10;
144 s32 option_y = offset.Y;
147 core::rect<s32> rect(0, 0, option_w, 30);
148 rect += topleft + v2s32(option_x, option_y);
149 Environment->addCheckBox(g_settings->getBool("aux1_descends"), rect, this,
150 GUI_ID_CB_AUX1_DESCENDS, wgettext("\"Use\" = climb down"));
155 core::rect < s32 > rect(0, 0, 100, 30);
156 rect += topleft + v2s32(size.X - 100 - 20, size.Y - 40);
157 Environment->addButton(rect, this, GUI_ID_BACK_BUTTON,
161 core::rect < s32 > rect(0, 0, 100, 30);
162 rect += topleft + v2s32(size.X - 100 - 20 - 100 - 20, size.Y - 40);
163 Environment->addButton(rect, this, GUI_ID_ABORT_BUTTON,
170 void GUIKeyChangeMenu::drawMenu()
172 gui::IGUISkin* skin = Environment->getSkin();
175 video::IVideoDriver* driver = Environment->getVideoDriver();
177 video::SColor bgcolor(140, 0, 0, 0);
180 core::rect < s32 > rect(0, 0, 620, 620);
181 rect += AbsoluteRect.UpperLeftCorner;
182 driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
185 gui::IGUIElement::draw();
188 bool GUIKeyChangeMenu::acceptInput()
190 for(size_t i = 0; i < key_settings.size(); i++)
192 key_setting *k = key_settings.at(i);
193 g_settings->set(k->setting_name, k->key.sym());
196 gui::IGUIElement *e = getElementFromId(GUI_ID_CB_AUX1_DESCENDS);
197 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
198 g_settings->setBool("aux1_descends", ((gui::IGUICheckBox*)e)->isChecked());
204 bool GUIKeyChangeMenu::resetMenu()
208 for(size_t i = 0; i < key_settings.size(); i++)
210 key_setting *k = key_settings.at(i);
211 if(k->id == activeKey)
213 k->button->setText(wgettext(k->key.name()));
222 bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
224 if (event.EventType == EET_KEY_INPUT_EVENT && activeKey >= 0
225 && event.KeyInput.PressedDown)
228 bool prefer_character = shift_down;
229 KeyPress kp(event.KeyInput, prefer_character);
231 bool shift_went_down = false;
233 (event.KeyInput.Key == irr::KEY_SHIFT ||
234 event.KeyInput.Key == irr::KEY_LSHIFT ||
235 event.KeyInput.Key == irr::KEY_RSHIFT))
236 shift_went_down = true;
238 // Remove Key already in use message
239 if(this->key_used_text)
241 this->key_used_text->remove();
242 this->key_used_text = NULL;
244 // Display Key already in use message
245 if (std::find(this->key_used.begin(), this->key_used.end(), kp) != this->key_used.end())
247 core::rect < s32 > rect(0, 0, 600, 40);
248 rect += v2s32(0, 0) + v2s32(25, 30);
249 this->key_used_text = Environment->addStaticText(wgettext("Key already in use"),
250 rect, false, true, this, -1);
251 //infostream << "Key already in use" << std::endl;
257 for(size_t i = 0; i < key_settings.size(); i++)
259 if(key_settings.at(i)->id == activeKey)
261 k = key_settings.at(i);
267 k->button->setText(wgettext(k->key.name()));
269 this->key_used.push_back(kp);
272 // Allow characters made with shift
282 if (event.EventType == EET_GUI_EVENT)
284 if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST
287 if (!canTakeFocus(event.GUIEvent.Element))
289 dstream << "GUIMainMenu: Not allowing focus change."
291 // Returning true disables focus change
295 if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED)
297 if(event.GUIEvent.Caller->getID() != GUI_ID_BACK_BUTTON &&
298 event.GUIEvent.Caller->getID() != GUI_ID_ABORT_BUTTON)
303 switch (event.GUIEvent.Caller->getID())
305 case GUI_ID_BACK_BUTTON: //back
309 case GUI_ID_ABORT_BUTTON: //abort
313 key_setting *k = NULL;
314 for(size_t i = 0; i < key_settings.size(); i++)
316 if(key_settings.at(i)->id == event.GUIEvent.Caller->getID())
318 k = key_settings.at(i);
326 activeKey = event.GUIEvent.Caller->getID();
327 k->button->setText(wgettext("press key"));
328 this->key_used.erase(std::remove(this->key_used.begin(),
329 this->key_used.end(), k->key), this->key_used.end());
332 Environment->setFocus(this);
337 return Parent ? Parent->OnEvent(event) : false;
340 void GUIKeyChangeMenu::add_key(int id, std::string button_name, std::string setting_name)
342 key_setting *k = new key_setting;
344 k->button_name = wgettext(button_name.c_str());
345 k->setting_name = setting_name;
346 k->key = getKeySetting(k->setting_name.c_str());
347 key_settings.push_back(k);
350 void GUIKeyChangeMenu::init_keys()
352 this->add_key(GUI_ID_KEY_FORWARD_BUTTON, "Forward", "keymap_forward");
353 this->add_key(GUI_ID_KEY_BACKWARD_BUTTON, "Backward", "keymap_backward");
354 this->add_key(GUI_ID_KEY_LEFT_BUTTON, "Left", "keymap_left");
355 this->add_key(GUI_ID_KEY_RIGHT_BUTTON, "Right", "keymap_right");
356 this->add_key(GUI_ID_KEY_USE_BUTTON, "Use", "keymap_special1");
357 this->add_key(GUI_ID_KEY_JUMP_BUTTON, "Jump", "keymap_jump");
358 this->add_key(GUI_ID_KEY_SNEAK_BUTTON, "Sneak", "keymap_sneak");
359 this->add_key(GUI_ID_KEY_DROP_BUTTON, "Drop", "keymap_drop");
360 this->add_key(GUI_ID_KEY_INVENTORY_BUTTON, "Inventory", "keymap_inventory");
361 this->add_key(GUI_ID_KEY_CHAT_BUTTON, "Chat", "keymap_chat");
362 this->add_key(GUI_ID_KEY_CMD_BUTTON, "Command", "keymap_cmd");
363 this->add_key(GUI_ID_KEY_CONSOLE_BUTTON, "Console", "keymap_console");
364 this->add_key(GUI_ID_KEY_FLY_BUTTON, "Toggle fly", "keymap_freemove");
365 this->add_key(GUI_ID_KEY_FAST_BUTTON, "Toggle fast", "keymap_fastmove");
366 this->add_key(GUI_ID_KEY_NOCLIP_BUTTON, "Toggle noclip", "keymap_noclip");
367 this->add_key(GUI_ID_KEY_RANGE_BUTTON, "Range select", "keymap_rangeselect");
368 this->add_key(GUI_ID_KEY_DUMP_BUTTON, "Print stacks", "keymap_print_debug_stacks");