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
59 GUIKeyChangeMenu::GUIKeyChangeMenu(gui::IGUIEnvironment* env,
60 gui::IGUIElement* parent, s32 id, IMenuManager *menumgr) :
61 GUIModalMenu(env, parent, id, menumgr)
65 this->key_used_text = NULL;
67 for(size_t i=0; i<key_settings.size(); i++)
68 this->key_used.push_back(key_settings.at(i)->key);
71 GUIKeyChangeMenu::~GUIKeyChangeMenu()
76 void GUIKeyChangeMenu::removeChildren()
78 const core::list<gui::IGUIElement*> &children = getChildren();
79 core::list<gui::IGUIElement*> children_copy;
80 for (core::list<gui::IGUIElement*>::ConstIterator i = children.begin(); i
81 != children.end(); i++)
83 children_copy.push_back(*i);
85 for (core::list<gui::IGUIElement*>::Iterator i = children_copy.begin(); i
86 != children_copy.end(); i++)
92 void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
97 core::rect < s32 > rect(screensize.X / 2 - size.X / 2,
98 screensize.Y / 2 - size.Y / 2, screensize.X / 2 + size.X / 2,
99 screensize.Y / 2 + size.Y / 2);
102 recalculateAbsolutePosition(false);
107 core::rect < s32 > rect(0, 0, 600, 40);
108 rect += topleft + v2s32(25, 3);
109 //gui::IGUIStaticText *t =
110 Environment->addStaticText(wgettext("Keybindings. (If this menu screws up, remove stuff from minetest.conf)"),
111 rect, false, true, this, -1);
112 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
117 v2s32 offset(25, 60);
119 for(size_t i = 0; i < key_settings.size(); i++)
121 key_setting *k = key_settings.at(i);
123 core::rect < s32 > rect(0, 0, 100, 20);
124 rect += topleft + v2s32(offset.X, offset.Y);
125 Environment->addStaticText(k->button_name, rect, false, true, this, -1);
129 core::rect < s32 > rect(0, 0, 100, 30);
130 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
131 k->button = Environment->addButton(rect, this, k->id, wgettext(k->key.name()));
133 if(i + 1 == KMaxButtonPerColumns)
134 offset = v2s32(250, 60);
136 offset += v2s32(0, 25);
140 core::rect < s32 > rect(0, 0, 100, 30);
141 rect += topleft + v2s32(size.X - 100 - 20, size.Y - 40);
142 Environment->addButton(rect, this, GUI_ID_BACK_BUTTON,
146 core::rect < s32 > rect(0, 0, 100, 30);
147 rect += topleft + v2s32(size.X - 100 - 20 - 100 - 20, size.Y - 40);
148 Environment->addButton(rect, this, GUI_ID_ABORT_BUTTON,
155 void GUIKeyChangeMenu::drawMenu()
157 gui::IGUISkin* skin = Environment->getSkin();
160 video::IVideoDriver* driver = Environment->getVideoDriver();
162 video::SColor bgcolor(140, 0, 0, 0);
165 core::rect < s32 > rect(0, 0, 620, 620);
166 rect += AbsoluteRect.UpperLeftCorner;
167 driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
170 gui::IGUIElement::draw();
173 bool GUIKeyChangeMenu::acceptInput()
175 for(size_t i = 0; i < key_settings.size(); i++)
177 key_setting *k = key_settings.at(i);
178 g_settings->set(k->setting_name, k->key.sym());
184 bool GUIKeyChangeMenu::resetMenu()
188 for(size_t i = 0; i < key_settings.size(); i++)
190 key_setting *k = key_settings.at(i);
191 if(k->id == activeKey)
193 k->button->setText(wgettext(k->key.name()));
202 bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
204 if (event.EventType == EET_KEY_INPUT_EVENT && activeKey >= 0
205 && event.KeyInput.PressedDown)
208 bool prefer_character = shift_down;
209 KeyPress kp(event.KeyInput, prefer_character);
211 bool shift_went_down = false;
213 (event.KeyInput.Key == irr::KEY_SHIFT ||
214 event.KeyInput.Key == irr::KEY_LSHIFT ||
215 event.KeyInput.Key == irr::KEY_RSHIFT))
216 shift_went_down = true;
218 // Remove Key already in use message
219 if(this->key_used_text)
221 this->key_used_text->remove();
222 this->key_used_text = NULL;
224 // Display Key already in use message
225 if (std::find(this->key_used.begin(), this->key_used.end(), kp) != this->key_used.end())
227 core::rect < s32 > rect(0, 0, 600, 40);
228 rect += v2s32(0, 0) + v2s32(25, 30);
229 this->key_used_text = Environment->addStaticText(wgettext("Key already in use"),
230 rect, false, true, this, -1);
231 //infostream << "Key already in use" << std::endl;
237 for(size_t i = 0; i < key_settings.size(); i++)
239 if(key_settings.at(i)->id == activeKey)
241 k = key_settings.at(i);
247 k->button->setText(wgettext(k->key.name()));
249 this->key_used.push_back(kp);
252 // Allow characters made with shift
262 if (event.EventType == EET_GUI_EVENT)
264 if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST
267 if (!canTakeFocus(event.GUIEvent.Element))
269 dstream << "GUIMainMenu: Not allowing focus change."
271 // Returning true disables focus change
275 if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED)
277 if(event.GUIEvent.Caller->getID() != GUI_ID_BACK_BUTTON &&
278 event.GUIEvent.Caller->getID() != GUI_ID_ABORT_BUTTON)
283 switch (event.GUIEvent.Caller->getID())
285 case GUI_ID_BACK_BUTTON: //back
289 case GUI_ID_ABORT_BUTTON: //abort
293 key_setting *k = NULL;
294 for(size_t i = 0; i < key_settings.size(); i++)
296 if(key_settings.at(i)->id == event.GUIEvent.Caller->getID())
298 k = key_settings.at(i);
306 activeKey = event.GUIEvent.Caller->getID();
307 k->button->setText(wgettext("press key"));
308 this->key_used.erase(std::remove(this->key_used.begin(),
309 this->key_used.end(), k->key), this->key_used.end());
312 Environment->setFocus(this);
317 return Parent ? Parent->OnEvent(event) : false;
320 void GUIKeyChangeMenu::add_key(int id, std::string button_name, std::string setting_name)
322 key_setting *k = new key_setting;
324 k->button_name = wgettext(button_name.c_str());
325 k->setting_name = setting_name;
326 k->key = getKeySetting(k->setting_name.c_str());
327 key_settings.push_back(k);
330 void GUIKeyChangeMenu::init_keys()
332 this->add_key(GUI_ID_KEY_FORWARD_BUTTON, "Forward", "keymap_forward");
333 this->add_key(GUI_ID_KEY_BACKWARD_BUTTON, "Backward", "keymap_backward");
334 this->add_key(GUI_ID_KEY_LEFT_BUTTON, "Left", "keymap_left");
335 this->add_key(GUI_ID_KEY_RIGHT_BUTTON, "Right", "keymap_right");
336 this->add_key(GUI_ID_KEY_USE_BUTTON, "Use", "keymap_special1");
337 this->add_key(GUI_ID_KEY_JUMP_BUTTON, "Jump", "keymap_jump");
338 this->add_key(GUI_ID_KEY_SNEAK_BUTTON, "Sneak", "keymap_sneak");
339 this->add_key(GUI_ID_KEY_DROP_BUTTON, "Drop", "keymap_drop");
340 this->add_key(GUI_ID_KEY_INVENTORY_BUTTON, "Inventory", "keymap_inventory");
341 this->add_key(GUI_ID_KEY_CHAT_BUTTON, "Chat", "keymap_chat");
342 this->add_key(GUI_ID_KEY_CMD_BUTTON, "Command", "keymap_cmd");
343 this->add_key(GUI_ID_KEY_CONSOLE_BUTTON, "Console", "keymap_console");
344 this->add_key(GUI_ID_KEY_FLY_BUTTON, "Toggle fly", "keymap_freemove");
345 this->add_key(GUI_ID_KEY_FAST_BUTTON, "Toggle fast", "keymap_fastmove");
346 this->add_key(GUI_ID_KEY_RANGE_BUTTON, "Range select", "keymap_rangeselect");
347 this->add_key(GUI_ID_KEY_DUMP_BUTTON, "Print stacks", "keymap_print_debug_stacks");