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)
64 this->key_used_text = NULL;
66 for(size_t i=0; i<key_settings.size(); i++)
67 this->key_used.push_back(key_settings.at(i)->key);
70 GUIKeyChangeMenu::~GUIKeyChangeMenu()
75 void GUIKeyChangeMenu::removeChildren()
77 const core::list<gui::IGUIElement*> &children = getChildren();
78 core::list<gui::IGUIElement*> children_copy;
79 for (core::list<gui::IGUIElement*>::ConstIterator i = children.begin(); i
80 != children.end(); i++)
82 children_copy.push_back(*i);
84 for (core::list<gui::IGUIElement*>::Iterator i = children_copy.begin(); i
85 != children_copy.end(); i++)
91 void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
96 core::rect < s32 > rect(screensize.X / 2 - size.X / 2,
97 screensize.Y / 2 - size.Y / 2, screensize.X / 2 + size.X / 2,
98 screensize.Y / 2 + size.Y / 2);
101 recalculateAbsolutePosition(false);
106 core::rect < s32 > rect(0, 0, 600, 40);
107 rect += topleft + v2s32(25, 3);
108 //gui::IGUIStaticText *t =
109 Environment->addStaticText(wgettext("Keybindings. (If this menu screws up, remove stuff from minetest.conf)"),
110 rect, false, true, this, -1);
111 //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
116 v2s32 offset(25, 60);
118 for(size_t i = 0; i < key_settings.size(); i++)
120 key_setting *k = key_settings.at(i);
122 core::rect < s32 > rect(0, 0, 100, 20);
123 rect += topleft + v2s32(offset.X, offset.Y);
124 Environment->addStaticText(k->button_name, rect, false, true, this, -1);
128 core::rect < s32 > rect(0, 0, 100, 30);
129 rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
130 k->button = Environment->addButton(rect, this, k->id, wgettext(k->key.name()));
132 if(i + 1 == KMaxButtonPerColumns)
133 offset = v2s32(250, 60);
135 offset += v2s32(0, 25);
139 core::rect < s32 > rect(0, 0, 100, 30);
140 rect += topleft + v2s32(size.X - 100 - 20, size.Y - 40);
141 Environment->addButton(rect, this, GUI_ID_BACK_BUTTON,
145 core::rect < s32 > rect(0, 0, 100, 30);
146 rect += topleft + v2s32(size.X - 100 - 20 - 100 - 20, size.Y - 40);
147 Environment->addButton(rect, this, GUI_ID_ABORT_BUTTON,
154 void GUIKeyChangeMenu::drawMenu()
156 gui::IGUISkin* skin = Environment->getSkin();
159 video::IVideoDriver* driver = Environment->getVideoDriver();
161 video::SColor bgcolor(140, 0, 0, 0);
164 core::rect < s32 > rect(0, 0, 620, 620);
165 rect += AbsoluteRect.UpperLeftCorner;
166 driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
169 gui::IGUIElement::draw();
172 bool GUIKeyChangeMenu::acceptInput()
174 for(size_t i = 0; i < key_settings.size(); i++)
176 key_setting *k = key_settings.at(i);
177 g_settings->set(k->setting_name, k->key.sym());
183 bool GUIKeyChangeMenu::resetMenu()
187 for(size_t i = 0; i < key_settings.size(); i++)
189 key_setting *k = key_settings.at(i);
190 if(k->id == activeKey)
192 k->button->setText(wgettext(k->key.name()));
201 bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
203 if (event.EventType == EET_KEY_INPUT_EVENT && activeKey >= 0
204 && event.KeyInput.PressedDown)
207 KeyPress kp(event.KeyInput);
209 // Remove Key already in use message
210 if(this->key_used_text)
212 this->key_used_text->remove();
213 this->key_used_text = NULL;
215 // Display Key already in use message
216 if (std::find(this->key_used.begin(), this->key_used.end(), kp) != this->key_used.end())
218 core::rect < s32 > rect(0, 0, 600, 40);
219 rect += v2s32(0, 0) + v2s32(25, 30);
220 this->key_used_text = Environment->addStaticText(wgettext("Key already in use"),
221 rect, false, true, this, -1);
222 //infostream << "Key already in use" << std::endl;
228 for(size_t i = 0; i < key_settings.size(); i++)
230 if(key_settings.at(i)->id == activeKey)
232 k = key_settings.at(i);
238 k->button->setText(wgettext(k->key.name()));
240 this->key_used.push_back(kp);
247 if (event.EventType == EET_GUI_EVENT)
249 if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST
252 if (!canTakeFocus(event.GUIEvent.Element))
254 dstream << "GUIMainMenu: Not allowing focus change."
256 // Returning true disables focus change
260 if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED)
262 if(event.GUIEvent.Caller->getID() != GUI_ID_BACK_BUTTON &&
263 event.GUIEvent.Caller->getID() != GUI_ID_ABORT_BUTTON)
268 switch (event.GUIEvent.Caller->getID())
270 case GUI_ID_BACK_BUTTON: //back
274 case GUI_ID_ABORT_BUTTON: //abort
278 key_setting *k = NULL;
279 for(size_t i = 0; i < key_settings.size(); i++)
281 if(key_settings.at(i)->id == event.GUIEvent.Caller->getID())
283 k = key_settings.at(i);
290 activeKey = event.GUIEvent.Caller->getID();
291 k->button->setText(wgettext("press key"));
292 this->key_used.erase(std::remove(this->key_used.begin(),
293 this->key_used.end(), k->key), this->key_used.end());
296 Environment->setFocus(this);
301 return Parent ? Parent->OnEvent(event) : false;
304 void GUIKeyChangeMenu::add_key(int id, std::string button_name, std::string setting_name)
306 key_setting *k = new key_setting;
308 k->button_name = wgettext(button_name.c_str());
309 k->setting_name = setting_name;
310 k->key = getKeySetting(k->setting_name.c_str());
311 key_settings.push_back(k);
314 void GUIKeyChangeMenu::init_keys()
316 this->add_key(GUI_ID_KEY_FORWARD_BUTTON, "Forward", "keymap_forward");
317 this->add_key(GUI_ID_KEY_BACKWARD_BUTTON, "Backward", "keymap_backward");
318 this->add_key(GUI_ID_KEY_LEFT_BUTTON, "Left", "keymap_left");
319 this->add_key(GUI_ID_KEY_RIGHT_BUTTON, "Right", "keymap_right");
320 this->add_key(GUI_ID_KEY_USE_BUTTON, "Use", "keymap_special1");
321 this->add_key(GUI_ID_KEY_JUMP_BUTTON, "Jump", "keymap_jump");
322 this->add_key(GUI_ID_KEY_SNEAK_BUTTON, "Sneak", "keymap_sneak");
323 this->add_key(GUI_ID_KEY_DROP_BUTTON, "Drop", "keymap_drop");
324 this->add_key(GUI_ID_KEY_INVENTORY_BUTTON, "Inventory", "keymap_inventory");
325 this->add_key(GUI_ID_KEY_CHAT_BUTTON, "Chat", "keymap_chat");
326 this->add_key(GUI_ID_KEY_CMD_BUTTON, "Command", "keymap_cmd");
327 this->add_key(GUI_ID_KEY_CONSOLE_BUTTON, "Console", "keymap_console");
328 this->add_key(GUI_ID_KEY_FLY_BUTTON, "Toggle fly", "keymap_freemove");
329 this->add_key(GUI_ID_KEY_FAST_BUTTON, "Toggle fast", "keymap_fastmove");
330 this->add_key(GUI_ID_KEY_RANGE_BUTTON, "Range select", "keymap_rangeselect");
331 this->add_key(GUI_ID_KEY_DUMP_BUTTON, "Print stacks", "keymap_print_debug_stacks");