/* 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/button.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::UI::padding; 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::UI::padding; // 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