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/controlsettingsmenu.cc | 380 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 380 insertions(+) create mode 100644 src/client/controlsettingsmenu.cc (limited to 'src/client/controlsettingsmenu.cc') 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 -- cgit v1.2.3