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_CHAT_BUTTON,
50 GUI_ID_KEY_CMD_BUTTON,
51 GUI_ID_KEY_CONSOLE_BUTTON,
52 GUI_ID_KEY_SNEAK_BUTTON,
53 GUI_ID_KEY_DROP_BUTTON,
54 GUI_ID_KEY_INVENTORY_BUTTON,
55 GUI_ID_KEY_DUMP_BUTTON,
56 GUI_ID_KEY_RANGE_BUTTON,
58 GUI_ID_CB_AUX1_DESCENDS,
61 GUIKeyChangeMenu::GUIKeyChangeMenu(gui::IGUIEnvironment* env,
62 gui::IGUIElement* parent, s32 id, IMenuManager *menumgr) :
63 GUIModalMenu(env, parent, id, menumgr)
67 this->key_used_text = NULL;
69 for(size_t i=0; i<key_settings.size(); i++)
70 this->key_used.push_back(key_settings.at(i)->key);
73 GUIKeyChangeMenu::~GUIKeyChangeMenu()
78 void GUIKeyChangeMenu::removeChildren()
80 const core::list<gui::IGUIElement*> &children = getChildren();
81 core::list<gui::IGUIElement*> children_copy;
82 for (core::list<gui::IGUIElement*>::ConstIterator i = children.begin(); i
83 != children.end(); i++)
85 children_copy.push_back(*i);
87 for (core::list<gui::IGUIElement*>::Iterator i = children_copy.begin(); i
88 != children_copy.end(); i++)
94 void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
99 core::rect < s32 > rect(screensize.X / 2 - size.X / 2,
100 screensize.Y / 2 - size.Y / 2, screensize.X / 2 + size.X / 2,
101 screensize.Y / 2 + size.Y / 2);
104 recalculateAbsolutePosition(false);
109 core::rect < s32 > rect(0, 0, 600, 40);
110 rect += topleft + v2s32(25, 3);
111 //gui::IGUIStaticText *t =
112 Environment->addStaticText(wgettext("Keybindings. (If this menu screws up, remove stuff from minetest.conf)"),
113 rect, false, true, this, -1);
114 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
119 v2s32 offset(25, 60);
121 for(size_t i = 0; i < key_settings.size(); i++)
123 key_setting *k = key_settings.at(i);
125 core::rect < s32 > rect(0, 0, 100, 20);
126 rect += topleft + v2s32(offset.X, offset.Y);
127 Environment->addStaticText(k->button_name, rect, false, true, this, -1);
131 core::rect < s32 > rect(0, 0, 100, 30);
132 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
133 k->button = Environment->addButton(rect, this, k->id, wgettext(k->key.name()));
135 if(i + 1 == KMaxButtonPerColumns)
136 offset = v2s32(250, 60);
138 offset += v2s32(0, 25);
142 s32 option_x = offset.X + 10;
143 s32 option_y = offset.Y;
146 core::rect<s32> rect(0, 0, option_w, 30);
147 rect += topleft + v2s32(option_x, option_y);
148 Environment->addCheckBox(g_settings->getBool("aux1_descends"), rect, this,
149 GUI_ID_CB_AUX1_DESCENDS, wgettext("\"Use\" = climb down"));
154 core::rect < s32 > rect(0, 0, 100, 30);
155 rect += topleft + v2s32(size.X - 100 - 20, size.Y - 40);
156 Environment->addButton(rect, this, GUI_ID_BACK_BUTTON,
160 core::rect < s32 > rect(0, 0, 100, 30);
161 rect += topleft + v2s32(size.X - 100 - 20 - 100 - 20, size.Y - 40);
162 Environment->addButton(rect, this, GUI_ID_ABORT_BUTTON,
169 void GUIKeyChangeMenu::drawMenu()
171 gui::IGUISkin* skin = Environment->getSkin();
174 video::IVideoDriver* driver = Environment->getVideoDriver();
176 video::SColor bgcolor(140, 0, 0, 0);
179 core::rect < s32 > rect(0, 0, 620, 620);
180 rect += AbsoluteRect.UpperLeftCorner;
181 driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
184 gui::IGUIElement::draw();
187 bool GUIKeyChangeMenu::acceptInput()
189 for(size_t i = 0; i < key_settings.size(); i++)
191 key_setting *k = key_settings.at(i);
192 g_settings->set(k->setting_name, k->key.sym());
195 gui::IGUIElement *e = getElementFromId(GUI_ID_CB_AUX1_DESCENDS);
196 if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
197 g_settings->setBool("aux1_descends", ((gui::IGUICheckBox*)e)->isChecked());
203 bool GUIKeyChangeMenu::resetMenu()
207 for(size_t i = 0; i < key_settings.size(); i++)
209 key_setting *k = key_settings.at(i);
210 if(k->id == activeKey)
212 k->button->setText(wgettext(k->key.name()));
221 bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
223 if (event.EventType == EET_KEY_INPUT_EVENT && activeKey >= 0
224 && event.KeyInput.PressedDown)
227 bool prefer_character = shift_down;
228 KeyPress kp(event.KeyInput, prefer_character);
230 bool shift_went_down = false;
232 (event.KeyInput.Key == irr::KEY_SHIFT ||
233 event.KeyInput.Key == irr::KEY_LSHIFT ||
234 event.KeyInput.Key == irr::KEY_RSHIFT))
235 shift_went_down = true;
237 // Remove Key already in use message
238 if(this->key_used_text)
240 this->key_used_text->remove();
241 this->key_used_text = NULL;
243 // Display Key already in use message
244 if (std::find(this->key_used.begin(), this->key_used.end(), kp) != this->key_used.end())
246 core::rect < s32 > rect(0, 0, 600, 40);
247 rect += v2s32(0, 0) + v2s32(25, 30);
248 this->key_used_text = Environment->addStaticText(wgettext("Key already in use"),
249 rect, false, true, this, -1);
250 //infostream << "Key already in use" << std::endl;
256 for(size_t i = 0; i < key_settings.size(); i++)
258 if(key_settings.at(i)->id == activeKey)
260 k = key_settings.at(i);
266 k->button->setText(wgettext(k->key.name()));
268 this->key_used.push_back(kp);
271 // Allow characters made with shift
281 if (event.EventType == EET_GUI_EVENT)
283 if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST
286 if (!canTakeFocus(event.GUIEvent.Element))
288 dstream << "GUIMainMenu: Not allowing focus change."
290 // Returning true disables focus change
294 if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED)
296 if(event.GUIEvent.Caller->getID() != GUI_ID_BACK_BUTTON &&
297 event.GUIEvent.Caller->getID() != GUI_ID_ABORT_BUTTON)
302 switch (event.GUIEvent.Caller->getID())
304 case GUI_ID_BACK_BUTTON: //back
308 case GUI_ID_ABORT_BUTTON: //abort
312 key_setting *k = NULL;
313 for(size_t i = 0; i < key_settings.size(); i++)
315 if(key_settings.at(i)->id == event.GUIEvent.Caller->getID())
317 k = key_settings.at(i);
325 activeKey = event.GUIEvent.Caller->getID();
326 k->button->setText(wgettext("press key"));
327 this->key_used.erase(std::remove(this->key_used.begin(),
328 this->key_used.end(), k->key), this->key_used.end());
331 Environment->setFocus(this);
336 return Parent ? Parent->OnEvent(event) : false;
339 void GUIKeyChangeMenu::add_key(int id, std::string button_name, std::string setting_name)
341 key_setting *k = new key_setting;
343 k->button_name = wgettext(button_name.c_str());
344 k->setting_name = setting_name;
345 k->key = getKeySetting(k->setting_name.c_str());
346 key_settings.push_back(k);
349 void GUIKeyChangeMenu::init_keys()
351 this->add_key(GUI_ID_KEY_FORWARD_BUTTON, "Forward", "keymap_forward");
352 this->add_key(GUI_ID_KEY_BACKWARD_BUTTON, "Backward", "keymap_backward");
353 this->add_key(GUI_ID_KEY_LEFT_BUTTON, "Left", "keymap_left");
354 this->add_key(GUI_ID_KEY_RIGHT_BUTTON, "Right", "keymap_right");
355 this->add_key(GUI_ID_KEY_USE_BUTTON, "Use", "keymap_special1");
356 this->add_key(GUI_ID_KEY_JUMP_BUTTON, "Jump", "keymap_jump");
357 this->add_key(GUI_ID_KEY_SNEAK_BUTTON, "Sneak", "keymap_sneak");
358 this->add_key(GUI_ID_KEY_DROP_BUTTON, "Drop", "keymap_drop");
359 this->add_key(GUI_ID_KEY_INVENTORY_BUTTON, "Inventory", "keymap_inventory");
360 this->add_key(GUI_ID_KEY_CHAT_BUTTON, "Chat", "keymap_chat");
361 this->add_key(GUI_ID_KEY_CMD_BUTTON, "Command", "keymap_cmd");
362 this->add_key(GUI_ID_KEY_CONSOLE_BUTTON, "Console", "keymap_console");
363 this->add_key(GUI_ID_KEY_FLY_BUTTON, "Toggle fly", "keymap_freemove");
364 this->add_key(GUI_ID_KEY_FAST_BUTTON, "Toggle fast", "keymap_fastmove");
365 this->add_key(GUI_ID_KEY_RANGE_BUTTON, "Range select", "keymap_rangeselect");
366 this->add_key(GUI_ID_KEY_DUMP_BUTTON, "Print stacks", "keymap_print_debug_stacks");