From 77d877160d5c3b8a7e9c30e81bd6ca1f4060b5f9 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 8 Feb 2015 21:51:53 +0000 Subject: Added a menu to configure key controls. --- src/client/Makefile.am | 4 + src/client/control.cc | 23 +++ src/client/control.h | 53 ++++++ src/client/controlsettingsmenu.cc | 380 ++++++++++++++++++++++++++++++++++++++ src/client/controlsettingsmenu.h | 76 ++++++++ src/client/input.cc | 36 ++-- src/client/input.h | 3 + src/client/keyboard.cc | 143 +++++++++++++- src/client/keyboard.h | 16 +- src/client/mainmenu.cc | 4 + 10 files changed, 718 insertions(+), 20 deletions(-) create mode 100644 src/client/control.cc create mode 100644 src/client/control.h create mode 100644 src/client/controlsettingsmenu.cc create mode 100644 src/client/controlsettingsmenu.h 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 + +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(_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(*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 Keys; typedef std::list Actions; + + typedef std::list 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(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(); -- cgit v1.2.3