Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2015-02-08 21:51:53 +0000
committerStijn Buys <ingar@osirion.org>2015-02-08 21:51:53 +0000
commit77d877160d5c3b8a7e9c30e81bd6ca1f4060b5f9 (patch)
tree7e3c8de8f0aeea2e03b086b5ff1a3c7b60892e25
parent4fdf7de0f1454966754bb22d1828fc2b69c172f4 (diff)
Added a menu to configure key controls.
-rw-r--r--src/client/Makefile.am4
-rw-r--r--src/client/control.cc23
-rw-r--r--src/client/control.h53
-rw-r--r--src/client/controlsettingsmenu.cc380
-rw-r--r--src/client/controlsettingsmenu.h76
-rw-r--r--src/client/input.cc36
-rw-r--r--src/client/input.h3
-rw-r--r--src/client/keyboard.cc143
-rw-r--r--src/client/keyboard.h16
-rw-r--r--src/client/mainmenu.cc4
10 files changed, 718 insertions, 20 deletions
diff --git a/src/client/Makefile.am b/src/client/Makefile.am
index 1ed6446..f3fd69c 100644
--- a/src/client/Makefile.am
+++ b/src/client/Makefile.am
@@ -15,6 +15,8 @@ noinst_HEADERS = \
chat.h \
client.h \
clientext.h \
+ control.h \
+ controlsettingsmenu.h \
entitymenu.h \
galaxymapwidget.h \
gamewindow.h \
@@ -51,6 +53,8 @@ libclient_la_SOURCES = \
chat.cc \
client.cc \
clientext.cc \
+ control.cc \
+ controlsettingsmenu.cc \
entitymenu.cc \
galaxymapwidget.cc \
gamewindow.cc \
diff --git a/src/client/control.cc b/src/client/control.cc
new file mode 100644
index 0000000..ab8c99f
--- /dev/null
+++ b/src/client/control.cc
@@ -0,0 +1,23 @@
+/*
+ client/control.h
+ This file is part of the Osirion project and is distributed under
+ the terms and conditions of the GNU General Public License version 2
+*/
+
+#include "client/control.h"
+
+namespace client
+{
+
+Control::Control(const char *name, const char *command, const char *keyname)
+{
+ _name.assign(name);
+ _command.assign(command);
+ _keyname.assign(keyname);
+}
+
+Control::~Control()
+{
+}
+
+} // namespace client
diff --git a/src/client/control.h b/src/client/control.h
new file mode 100644
index 0000000..bf30418
--- /dev/null
+++ b/src/client/control.h
@@ -0,0 +1,53 @@
+/*
+ client/control.h
+ This file is part of the Osirion project and is distributed under
+ the terms and conditions of the GNU General Public License version 2
+*/
+
+#ifndef __INCLUDED_CLIENT_CONTROL_H__
+#define __INCLUDED_CLIENT_CONTROL_H__
+
+#include <string>
+
+namespace client
+{
+
+/**
+ * @brief a client key control.
+ * A Control maps commands to key names
+ */
+class Control
+{
+public:
+ Control(const char *name, const char *command, const char * keyname = 0);
+ ~Control();
+
+ inline const std::string &name() const
+ {
+ return _name;
+ }
+
+ inline const std::string & command() const
+ {
+ return _command;
+ }
+
+ inline const std::string & keyname() const
+ {
+ return _keyname;
+ }
+
+ inline void set_keyname(const std::string &keyname)
+ {
+ _keyname.assign(keyname);
+ }
+
+private:
+ std::string _name;
+ std::string _command;
+ std::string _keyname;
+};
+
+} // namespace client
+
+#endif // __INCLUDED_CLIENT_CONTROL_H__
diff --git a/src/client/controlsettingsmenu.cc b/src/client/controlsettingsmenu.cc
new file mode 100644
index 0000000..e061d93
--- /dev/null
+++ b/src/client/controlsettingsmenu.cc
@@ -0,0 +1,380 @@
+/*
+ client/controlsettingsmenu.cc
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#include "client/controlsettingsmenu.h"
+#include "client/input.h"
+#include "ui/iconbutton.h"
+#include "ui/label.h"
+#include "ui/listview.h"
+#include "ui/ui.h"
+
+namespace client {
+
+class ControlListItem : public ui::ListItem
+{
+public:
+ ControlListItem(ui::ListView *parent, Control *control) : ui::ListItem(parent, "")
+ {
+ set_border(false);
+
+ _namelabel = new ui::Label(this);
+ _namelabel->set_border(true);
+ _namelabel->set_background(false);
+ _namelabel->set_alignment(ui::AlignVCenter | ui::AlignLeft);
+
+ _keylabel = new ui::Button(this);
+ _keylabel->set_border(true);
+ _keylabel->set_background(false);
+ _keylabel->set_alignment(ui::AlignCenter);
+
+ set_control(control);
+
+ }
+
+ virtual ~ControlListItem()
+ {
+ }
+
+ inline Control *control()
+ {
+ return _control;
+ }
+
+ void refresh()
+ {
+ if (_control)
+ {
+ _namelabel->set_text(_control->name());
+ _keylabel->set_text(_control->keyname());
+ }
+ else
+ {
+ _namelabel->clear();
+ _keylabel->clear();
+ }
+ }
+
+ void set_control(Control *control)
+ {
+ _control = control;
+ refresh();
+ }
+
+protected:
+ virtual void resize()
+ {
+ const float w = width() * 0.5f;
+ const float h = height();
+
+ _namelabel->set_size(w, h);
+ _namelabel->set_location(0.0f, 0.0f);
+
+ _keylabel->set_size(width() - w, h);
+ _keylabel->set_location(width() - w, 0.0f);
+
+ }
+
+ virtual bool on_emit(Widget *sender, const Event event, void *data)
+ {
+ if (event == ui::Widget::EventButtonClicked)
+ {
+ if (sender == _keylabel)
+ {
+ emit(EventListItemClicked);
+ return true;
+ }
+ }
+ return ui::ListItem::on_emit(sender, event, data);
+ }
+
+private:
+ ui::Label *_namelabel;
+ ui::Button *_keylabel;
+
+ Control *_control;
+
+};
+
+class ControlKeyWindow : public ui::Window
+{
+public:
+ ControlKeyWindow(ui::Widget *parent = 0) : ui::Window(parent)
+ {
+ set_border(false);
+ set_background(false);
+ set_label("controlkeywindow");
+
+ _frame = new ui::Window(this);
+ _frame->set_border(true);
+ _frame->set_background(true);
+
+ _namelabel = new ui::Label(_frame);
+ _namelabel->set_border(false);
+ _namelabel->set_background(false);
+ _namelabel->set_alignment(ui::AlignCenter);
+
+ _keylabel = new ui::Label(_frame);
+ _keylabel->set_border(false);
+ _keylabel->set_background(false);
+ _keylabel->set_alignment(ui::AlignCenter);
+
+ _okbutton = new ui::Button(_frame, "OK");
+ _cancelbutton = new ui::Button(_frame, "Cancel");
+ }
+
+ virtual ~ControlKeyWindow()
+ {
+ }
+
+ inline const std::string &key() const
+ {
+ return _keylabel->text();
+ }
+
+ void set_control(Control *control)
+ {
+ _control = control;
+ _namelabel->set_text("Press key ^F" + _control->name() );
+ _keylabel->set_text(_control->keyname());
+ }
+
+protected:
+ virtual void resize()
+ {
+ const float padding = ui::root()->font_large()->height();
+
+ set_size(parent()->size());
+
+ _frame->set_size(
+ ui::UI::elementsize.width() * 3.0f,
+ ui::UI::elementsize.width() * 1.5f
+ );
+ _frame->set_location(
+ (width() - _frame->width()) * 0.5f,
+ (height() - _frame->height()) * 0.5f
+ );
+
+ const float h = ui::root()->font_large()->height() * 2.0f;
+ _namelabel->set_size(_frame->width() - padding * 2.0f, h * 2.0f);
+ _namelabel->set_location(padding, padding);
+
+ _keylabel->set_size(_frame->width() - padding * 2.0f, h);
+ _keylabel->set_location(padding, _namelabel->bottom() + padding);
+
+ _okbutton->set_size(ui::UI::elementsize);
+ _cancelbutton->set_size(ui::UI::elementsize);
+
+ const float l = (_frame->width() - _okbutton->width() - _cancelbutton->width() - padding * 2.0f) * 0.5f;
+ _okbutton->set_location(l, _frame->height() - _okbutton->height() - padding);
+ _cancelbutton->set_location(_okbutton->right() + padding, _frame->height() - _cancelbutton->height() - padding);
+
+ }
+
+ void capture_keypress()
+ {
+ std::string keyname;
+ if (input::last_key_pressed()) {
+ Key::Modifier mod = input::modifier();
+ if (mod == Key::Shift)
+ keyname.assign("shift+");
+ else if (mod == Key::Ctrl)
+ keyname.assign("ctrl+");
+ else if (mod == Key::Alt)
+ keyname.assign("alt+");
+ keyname.append(input::last_key_pressed()->name());
+ }
+ _keylabel->set_text(keyname);
+ }
+
+ virtual bool on_mousepress(const unsigned int button)
+ {
+ capture_keypress();
+ return true;
+
+ }
+
+ virtual bool on_mousewheel(const math::Vector2f & direction)
+ {
+ capture_keypress();
+ return true;
+ }
+
+ virtual bool on_keypress(const int key, const unsigned int modifier)
+ {
+ if (key == SDLK_ESCAPE)
+ {
+ hide();
+ return true;
+ }
+ else
+ {
+ capture_keypress();
+ return true;
+ }
+ return false;
+ }
+
+ virtual bool on_emit(Widget *sender, const Event event, void *data)
+ {
+ if (event == Widget::EventButtonClicked)
+ {
+ if (sender == _okbutton)
+ {
+ if (_control->keyname().size())
+ {
+ input::keyboard->unbind(_control->keyname());
+ }
+
+ _control->set_keyname(_keylabel->text());
+
+ if (_control->keyname().size())
+ {
+ input::keyboard->bind(_control->keyname(), _control->command());
+ }
+
+ input::keyboard->load_controls();
+
+ hide();
+ return true;
+ }
+ else if (sender == _cancelbutton)
+ {
+ hide();
+ return true;
+ }
+ }
+ return ui::Window::on_emit(sender, event, data);
+ }
+
+private:
+ ui::Window *_frame;
+
+ ui::Label *_namelabel;
+ ui::Label *_keylabel;
+ ui::Button *_okbutton;
+ ui::Button *_cancelbutton;
+
+ Control *_control;
+};
+
+ControlSettingsMenu::ControlSettingsMenu(ui::Widget *parent, const char *label) : ui::Window(parent)
+{
+ set_label(label);
+ set_border(true);
+ set_background(true);
+ set_font(ui::root()->font_small());
+
+ // window title
+ _titlelabel = new ui::Label(this);
+ _titlelabel->set_label("title");
+ _titlelabel->set_background(false);
+ _titlelabel->set_border(false);
+ _titlelabel->set_font(ui::root()->font_large());
+ _titlelabel->set_alignment(ui::AlignCenter);
+ _titlelabel->set_text("CONTROLS");
+
+ // close button
+ _closebutton = new ui::IconButton(_titlelabel, "bitmaps/icons/window_close");
+
+ // command listview
+ _controlslistview = new ui::ListView(this);
+ _controlslistview->set_background(true);
+
+ _controlkeywindow = new ControlKeyWindow(this);
+ _controlkeywindow->hide();
+}
+
+ControlSettingsMenu::~ControlSettingsMenu()
+{
+}
+
+void ControlSettingsMenu::refresh()
+{
+ _controlslistview->clear();
+
+ input::keyboard->load_controls();
+
+ for (Keyboard::Controls::iterator cit = input::keyboard->controls().begin(); cit != input::keyboard->controls().end(); ++cit)
+ {
+ ui::ListItem *listitem = new ControlListItem(_controlslistview, (*cit));
+ listitem->set_font(ui::root()->font_tiny());
+ listitem->set_height(listitem->font()->height() * 2.0f);
+ }
+
+ _controlslistview->event_resize();
+}
+
+void ControlSettingsMenu::show()
+{
+ refresh();
+ ui::Window::show();
+}
+
+void ControlSettingsMenu::apply()
+{
+}
+
+void ControlSettingsMenu::resize()
+{
+ const float padding = ui::root()->font_large()->height();
+
+ // resize title label
+ _titlelabel->set_size(width() - padding * 2.0f, _titlelabel->font()->height());
+ _titlelabel->set_location(padding, padding);
+
+ // resize close button
+ _closebutton->set_size(_titlelabel->font()->height(), _titlelabel->font()->height());
+ _closebutton->set_location(_titlelabel->width() - _closebutton->width(), 0);
+
+ // resize listview
+ _controlslistview->set_location(_titlelabel->left(), _titlelabel->bottom() + padding);
+ _controlslistview->set_size(_titlelabel->width(), height() - _titlelabel->bottom() - padding * 2.0f);
+}
+
+bool ControlSettingsMenu::on_emit(ui::Widget *sender, const ui::Widget::Event event, void *data)
+{
+ if (sender == _closebutton)
+ {
+ if (event == ui::Widget::EventButtonClicked)
+ {
+ parent()->hide();
+ return true;
+ }
+ }
+ else if (sender == _controlslistview)
+ {
+ if (event == ui::Widget::EventListViewChanged)
+ {
+ if (_controlslistview->selected())
+ {
+ ControlListItem *listitem = static_cast<ControlListItem *>(_controlslistview->selected());
+ _controlkeywindow->set_control(listitem->control());
+ _controlkeywindow->show();
+ }
+ return true;
+ }
+ }
+ else if (sender == _controlkeywindow)
+ {
+ if (event == ui::Widget::EventWindowHide)
+ {
+ for (ui::Widget::Children::iterator it = _controlslistview->children().begin(); it != _controlslistview->children().end(); ++it)
+ {
+ ControlListItem *listitem = dynamic_cast<ControlListItem *>(*it);
+ if (listitem)
+ {
+ listitem->refresh();
+ }
+
+ }
+ return true;
+ }
+
+ }
+ return Window::on_emit(sender, event, data);
+}
+
+} // namespace client \ No newline at end of file
diff --git a/src/client/controlsettingsmenu.h b/src/client/controlsettingsmenu.h
new file mode 100644
index 0000000..169e14e
--- /dev/null
+++ b/src/client/controlsettingsmenu.h
@@ -0,0 +1,76 @@
+/*
+ client/controlsettingsmenu.h
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#ifndef __INCLUDED_CLIENT_CONTROLSETTINGSMENU_H__
+#define __INCLUDED_CLIENT_CONTROLSETTINGSMENU_H__
+
+#include "ui/window.h"
+
+namespace ui
+{
+ class Label;
+ class ListView;
+ class IconButton;
+}
+
+namespace client
+{
+
+ class ControlKeyWindow;
+
+/**
+ * @brief the options menu
+ * */
+class ControlSettingsMenu : public ui::Window
+{
+public:
+ /**
+ * @brief default constructor
+ * */
+ ControlSettingsMenu(ui::Widget *parent = 0, const char *label = 0);
+
+ /**
+ * @brief default destructor
+ * */
+ virtual ~ControlSettingsMenu();
+
+ /**
+ * @brief show window
+ * */
+ virtual void show();
+
+protected:
+ /**
+ * @brief emit event handler
+ * */
+ virtual bool on_emit(ui::Widget *sender, const ui::Widget::Event event, void *data);
+
+ /**
+ * @brief resize event handler
+ * */
+ virtual void resize();
+
+private:
+ /**
+ * @brief refresh widget content
+ * */
+ void refresh();
+
+ /**
+ * @brief apply changes
+ * */
+ void apply();
+
+ ui::Label *_titlelabel;
+ ui::IconButton *_closebutton;
+ ui::ListView *_controlslistview;
+ ControlKeyWindow *_controlkeywindow;
+
+};
+
+}
+
+#endif // __INCLUDED_CLIENT_CONTROLSETTINGSMENU_H__
diff --git a/src/client/input.cc b/src/client/input.cc
index 0ffffad..72fa5af 100644
--- a/src/client/input.cc
+++ b/src/client/input.cc
@@ -804,6 +804,10 @@ void frame()
case SDL_MOUSEBUTTONDOWN:
key = keyboard->press(512 + event.button.button);
pressed = true;
+
+ last_key = key; // remember the last key that was pressed
+ last_key_time = client()->time();
+
if ((key && console_key_pressed(key)) || ui::root()->input_mouse_button(true, event.button.button))
{
key = 0;
@@ -830,25 +834,31 @@ void frame()
break;
case SDL_MOUSEWHEEL:
+ if (event.wheel.y > 0)
+ {
+ key = keyboard->press(600);
+ } else if (event.wheel.y < 0)
+ {
+ key = keyboard->press(601);
+ }
+ pressed = true;
+
+ last_key = key; // remember the last key that was pressed
+ last_key_time = client()->time();
+
if (ui::root()->input_mouse_wheel(math::Vector2f((float)event.wheel.x, (float) event.wheel.y)))
{
key = 0;
- } else
- {
- if (event.wheel.y > 0)
- {
- key = keyboard->press(600);
- } else if (event.wheel.y < 0)
- {
- key = keyboard->press(601);
- }
- pressed = true;
}
break;
case SDL_JOYBUTTONDOWN:
key = keyboard->press(564 + event.jbutton.button);
pressed = true;
+
+ last_key = key; // remember the last key that was pressed
+ last_key_time = client()->time();
+
break;
case SDL_JOYBUTTONUP:
@@ -865,6 +875,10 @@ void frame()
keyboard_modifiers = event.key.keysym.mod;
key = keyboard->press(event.key.keysym.scancode);
pressed = true;
+
+ last_key = key; // remember the last key that was pressed
+ last_key_time = client()->time();
+
if ((key && console_key_pressed(key)) || ui::root()->input_key(true, Keyboard::translate_keysym(event.key.keysym.sym, keyboard_modifiers), keyboard_modifiers))
{
key = 0;
@@ -891,8 +905,6 @@ void frame()
if (key) {
if (pressed) {
key_pressed(key);
- last_key = key; // remember the last key that was pressed
- last_key_time = client()->time();
} else {
key_released(key);
}
diff --git a/src/client/input.h b/src/client/input.h
index ad837a9..f030969 100644
--- a/src/client/input.h
+++ b/src/client/input.h
@@ -8,6 +8,7 @@
#define __INCLUDED_cLIENT_INPUT_H__
#include "client/key.h"
+#include "client/keyboard.h"
#include "core/cvar.h"
namespace client
@@ -57,6 +58,8 @@ extern bool joystick_control;
extern float local_thrust;
+extern Keyboard *keyboard;
+
} // namespace input
} // namespace client
diff --git a/src/client/keyboard.cc b/src/client/keyboard.cc
index bb3b20d..75cc5cb 100644
--- a/src/client/keyboard.cc
+++ b/src/client/keyboard.cc
@@ -152,11 +152,12 @@ Keyboard::Keyboard()
add_key(SDL_SCANCODE_KP_ENTER, "kpenter", '\n', "ui_chat");
add_key(SDL_SCANCODE_KP_EQUALS, "kpequal", '=');
add_key(SDL_SCANCODE_KP_LESS, "kpless", '<');
-
- add_key(SDL_SCANCODE_UP, "up", 0, "+camup");
- add_key(SDL_SCANCODE_DOWN, "down", 0, "+camdown");
- add_key(SDL_SCANCODE_RIGHT, "right", 0, "+camright");
- add_key(SDL_SCANCODE_LEFT, "left", 0, "+camleft");
+
+ add_key(SDL_SCANCODE_LEFT, "left", 0, "+ lookleft");
+ add_key(SDL_SCANCODE_RIGHT, "right", 0, "+lookright");
+ add_key(SDL_SCANCODE_UP, "up", 0, "+lookup");
+ add_key(SDL_SCANCODE_DOWN, "down", 0, "+lookdown");
+
add_key(SDL_SCANCODE_INSERT, "insert");
add_key(SDL_SCANCODE_HOME, "home");
@@ -234,6 +235,74 @@ Keyboard::Keyboard()
add_key(1037, "joy13");
add_key(1038, "joy14");
add_key(1039, "joy15");
+
+ // ------------------ CONTROLS
+ add_control("Toggle mouse control", "ui_control", "space");
+ add_control("Mouse control", "+control", "mouse1");
+
+ add_control("Turn left", "+left", "kp4");
+ add_control("Turn right", "+right", "kp6");
+ add_control("Turn up", "+up", "kp8");
+ add_control("Turn down", "+down", "kp2");
+
+ add_control("Strafe left", "+strafeleft", "a");
+ add_control("Strafe right", "+straferight", "d");
+ add_control("Strafe up", "+strafeup", "r");
+ add_control("Strafe down", "+strafedown", "f");
+
+ add_control("Roll left", "+rollleft", "q");
+ add_control("Roll right", "+rollright", "e");
+
+ add_control("Decrease thruster", "+thrustdown", "kpmin");
+ add_control("Increase thruster", "+thrustup", "kpplus");
+
+ add_control("Aferburner", "+afterburner", "w");
+ add_control("Reverse engine", "+reverse", "s");
+
+ add_control("Impulse engine", "impulse", "tab");
+
+ add_control("Fire weapons", "+fire", "mouse2");
+
+ add_control("Beam cargo", "beam", "b");
+
+ add_control("Open inventory", "ui_inventory", "i");
+ add_control("Open map", "ui_map", "m");
+ add_control("Open chat", "ui_chat", "enter");
+ add_control("Open talk", "ui_chatbar", "t");
+
+ add_control("Target next object", "target_next", "n");
+ add_control("Target previous object", "target_prev", "shift+n");
+ add_control("Target none", "target_none", "ctrl+n");
+ add_control("Target next ship", "target_controlable_next", "x");
+ add_control("Target previous ship", "target_controlable_prev", "shift+x");
+ add_control("Target center", "target_center", "ctrl+x");
+
+ add_control("Camera next", "view_next", "v");
+ add_control("Camera previous", "view_prev", "shift+v");
+ add_control("Camera zoom in", "+zoomin", "kpdiv");
+ add_control("Camera zoom out", "+zoomout", "kpmul");
+
+ add_control("Camera turn left", "+lookleft", "left");
+ add_control("Camera turn right", "+lookright", "right");
+ add_control("Camera turn up", "+lookup", "up");
+ add_control("Camera turn down", "+lookdown", "down");
+
+ add_control("Freelook", "+freelook", "lshift");
+
+ add_control("Free flight", "freeflight", "f1");
+ add_control("Autopilot goto", "@goto", "f2");
+ add_control("Autopilot dock", "@dock", "f3");
+ add_control("Autopilot formation", "@formation", "f4");
+
+ add_control("Quicksave", "savegame", "f5");
+ add_control("Quickload", "loadgame", "f9");
+
+ add_control("Wingmen toggle recall", "wingmen recall", "shift+c");
+ add_control("Wingmen toggle combat", "wingmen combat", "shift+b");
+
+ add_control("Screenshot", "screenshot", "print");
+ add_control("Toggle fullscreen", "toggle r_fullscreen", "alt+enter");
+ add_control("Toggle console", "+console", "`");
}
Keyboard::~Keyboard()
@@ -251,6 +320,13 @@ Keyboard::~Keyboard()
delete(*ait);
}
_actions.clear();
+
+ // clear control list
+ for (Controls::iterator cit = _controls.begin(); cit != _controls.end(); ++cit)
+ {
+ delete(*cit);
+ }
+ _controls.clear();
}
void Keyboard::save_binds() const
@@ -294,7 +370,7 @@ void Keyboard::save_binds() const
ofs.close();
}
-void Keyboard::load_binds() const
+void Keyboard::load_binds()
{
std::string filename(filesystem::writedir());
filename.append("binds.cfg");
@@ -313,6 +389,53 @@ void Keyboard::load_binds() const
core::CommandBuffer::exec(line);
}
}
+
+ load_controls();
+}
+
+void Keyboard::load_controls()
+{
+ for (Controls::iterator cit = _controls.begin(); cit != _controls.end(); ++cit)
+ {
+ Control *control = *cit;
+ bool found = false;
+ for (Keys::iterator kit = _keys.begin(); kit != _keys.end();)
+ {
+ Key *key = (*kit).second;
+ if (control->command().compare(key->bind(Key::None)) == 0)
+ {
+ control->set_keyname(key->name());
+ kit = _keys.end();
+ found = true;
+ }
+ else if (control->command().compare(key->bind(Key::Shift)) == 0)
+ {
+ control->set_keyname("shift+" + key->name());
+ kit = _keys.end();
+ found = true;
+ }
+ else if (control->command().compare(key->bind(Key::Ctrl)) == 0)
+ {
+ control->set_keyname("ctrl+" + key->name());
+ kit = _keys.end();
+ found = true;
+ }
+ else if (control->command().compare(key->bind(Key::Alt)) == 0)
+ {
+ control->set_keyname("alt+" + key->name());
+ kit = _keys.end();
+ found = true;
+ }
+ else
+ {
+ ++kit;
+ }
+ }
+ if (!found)
+ {
+ control->set_keyname("");
+ }
+ }
}
void Keyboard::reset()
@@ -506,7 +629,6 @@ Key * Keyboard::add_key(const unsigned int scancode, const char *name, const cha
std::string bindstr(bind);
this->bind(key->name(), bindstr);
}
-
return key;
}
@@ -517,6 +639,13 @@ Action * Keyboard::add_action(const char *name, Action::Identifier id, const cha
return action;
}
+Control *Keyboard::add_control(const char *name, const char *command, const char *keyname)
+{
+ Control *control = new Control(name, command, keyname);
+ _controls.push_back(control);
+ return control;
+}
+
void Keyboard::list_actions() const
{
for (Actions::const_iterator it = _actions.begin(); it != _actions.end(); ++it)
diff --git a/src/client/keyboard.h b/src/client/keyboard.h
index 2ebb568..a665c55 100644
--- a/src/client/keyboard.h
+++ b/src/client/keyboard.h
@@ -14,6 +14,7 @@
#include "SDL2/SDL.h"
#include "client/action.h"
+#include "client/control.h"
#include "client/key.h"
namespace client
@@ -25,6 +26,8 @@ public:
typedef std::map<unsigned int, Key *> Keys;
typedef std::list<Action *> Actions;
+
+ typedef std::list<Control *> Controls;
Keyboard();
~Keyboard();
@@ -57,10 +60,13 @@ public:
void list_binds() const;
/// load keyboard binds
- void load_binds() const;
+ void load_binds();
/// save keyboard binds
void save_binds() const;
+
+ /// load controls
+ void load_controls();
/// a key has been pressed
Key *press(const unsigned int scancode);
@@ -78,14 +84,22 @@ public:
{
return _keys;
}
+
+ inline Controls & controls()
+ {
+ return _controls;
+ }
private:
Key *add_key(const unsigned int scancode, const char *name, const char ascii = 0, const char *bind = 0);
Action *add_action(const char *name, Action::Identifier id, const char *description = 0);
+
+ Control *add_control(const char *name, const char *command, const char *keyname = 0);
Keys _keys;
Actions _actions;
+ Controls _controls;
};
}
diff --git a/src/client/mainmenu.cc b/src/client/mainmenu.cc
index 89c29be..8813688 100644
--- a/src/client/mainmenu.cc
+++ b/src/client/mainmenu.cc
@@ -5,6 +5,7 @@
*/
#include "client/buttonmenu.h"
+#include "client/controlsettingsmenu.h"
#include "client/mainmenu.h"
#include "client/savegamemenu.h"
#include "core/core.h"
@@ -192,6 +193,9 @@ void MainMenu::load()
mainmenu_joinmenu = (ui::Widget *) new ButtonMenu(this, "join");
static_cast<ButtonMenu *>(mainmenu_joinmenu)->set_compact();
+ // control settings menu
+ new ControlSettingsMenu(this, "controls");
+
// load custom menus, this needs to be done before the
// non-buttonmenu child widgets are created
load_definitions();