From 9d39702824e8fae5127e09fb5a05b521b48cd028 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 9 Nov 2008 11:43:28 +0000 Subject: docking menus --- src/ui/Makefile.am | 9 ++--- src/ui/container.cc | 25 ++++---------- src/ui/container.h | 11 ------- src/ui/menu.cc | 23 +++---------- src/ui/menuview.cc | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/ui/menuview.h | 42 +++++++++++++++++++++++ src/ui/ui.cc | 48 +++++++++++++++++++++++++-- src/ui/ui.h | 8 +++++ src/ui/widget.cc | 5 +++ src/ui/widget.h | 6 ++++ 10 files changed, 219 insertions(+), 53 deletions(-) create mode 100644 src/ui/menuview.cc create mode 100644 src/ui/menuview.h (limited to 'src/ui') diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am index b2126fd..e230203 100644 --- a/src/ui/Makefile.am +++ b/src/ui/Makefile.am @@ -7,10 +7,11 @@ else noinst_LTLIBRARIES = libui.la endif -noinst_HEADERS = bitmap.h button.h console.h container.h definitions.h font.h inputbox.h label.h \ - menu.h paint.h palette.h scrollpane.h ui.h widget.h window.h +noinst_HEADERS = bitmap.h button.h console.h container.h definitions.h font.h \ + inputbox.h label.h menu.h menuview.h paint.h palette.h scrollpane.h ui.h \ + widget.h window.h libui_la_SOURCES = bitmap.cc button.cc console.cc console.h container.cc \ - font.cc inputbox.cc label.cc menu.cc paint.cc palette.cc scrollpane.cc ui.cc \ - widget.cc window.cc + font.cc inputbox.cc label.cc menu.cc menuview.cc paint.cc palette.cc \ + scrollpane.cc ui.cc widget.cc window.cc libui_la_LDFLAGS = -avoid-version -no-undefined diff --git a/src/ui/container.cc b/src/ui/container.cc index 977ff4d..915ec98 100644 --- a/src/ui/container.cc +++ b/src/ui/container.cc @@ -7,6 +7,7 @@ #include "ui/container.h" #include "ui/paint.h" +#include "ui/ui.h" namespace ui { @@ -19,9 +20,6 @@ Container::Container(Widget *parent) : Window(parent) set_border(true); set_background(true); - - container_childsize.assign(256, 48); - container_margin = 24; } Container::~Container() @@ -30,31 +28,22 @@ Container::~Container() void Container::resize() { - float w = container_childsize.width() * 1.5f; - float h = children().size() * (container_childsize.height() + margin()) + container_childsize.height(); + float w = UI::elementsize.width() * 1.5f; + float h = children().size() * (UI::elementsize.height() + UI::elementmargin) + UI::elementsize.height(); set_size(w, h); - const float x = container_childsize.width() * 0.25f; - float y = container_childsize.height() * 0.5f; + const float x = UI::elementsize.width() * 0.25f; + float y = UI::elementsize.height() * 0.5f; // reposition all children within the container for (Children::iterator it = children().begin(); it != children().end(); it++) { Widget *w = (*it); - w->set_size(container_childsize); + w->set_size(UI::elementsize); w->set_location(x, y); - y += container_childsize.height() + container_margin; + y += UI::elementsize.height() + UI::elementmargin; } } -void Container::set_childsize(const float w, const float h) -{ - container_childsize.assign(w, h); -} - -void Container::set_margin(const float margin) -{ - container_margin = margin; -} void Container::draw_border() { diff --git a/src/ui/container.h b/src/ui/container.h index 5556759..2045772 100644 --- a/src/ui/container.h +++ b/src/ui/container.h @@ -19,21 +19,10 @@ public: Container(Widget *parent); ~Container(); - void set_margin(const float); - void set_childsize(const float width, const float height); - - inline const math::Vector2f & childsize() const { return container_childsize; } - - inline float margin() const { return container_margin; } - protected: virtual void draw_border(); virtual void resize(); - -private: - float container_margin; - math::Vector2f container_childsize; }; } diff --git a/src/ui/menu.cc b/src/ui/menu.cc index 8421f7f..36599be 100644 --- a/src/ui/menu.cc +++ b/src/ui/menu.cc @@ -47,16 +47,11 @@ void Menu::load() std::string strval; Button *button = 0; Label *label = 0; - float w = menu_container->childsize().width(); - float h = menu_container->childsize().height(); - float m = menu_container->margin(); while (ini.getline()) { if (ini.got_section()) { - - //con_debug << " " << ini.name() << " [" << ini.section() << "]" << std::endl; - if (ini.got_section("menu")) { + continue; } else if (ini.got_section("button")) { button = add_button(); @@ -67,31 +62,23 @@ void Menu::load() } else if (ini.got_section()) { ini.unknown_section(); } - - } else if (ini.got_key()) { - - //con_debug << " " << ini.name() << " " << ini.key() << "=" << ini.value() << std::endl; - + } else if (ini.got_key()) { if (ini.in_section("menu")) { if (ini.got_key_string("background", strval)) { menu_background->set_texture(strval); - } else if (ini.got_key_float("elementwidth", w)) { - menu_container->set_childsize(w,h); - } else if (ini.got_key_float("elementheight", h)) { - menu_container->set_childsize(w,h); - } else if (ini.got_key_float("elementmargin", m)) { - menu_container->set_margin(m); } else { ini.unkown_key(); } } else if (ini.in_section("button")) { if (ini.got_key_string("text", strval)) { + aux::strip_quotes(strval); button->set_text(strval); } else if (ini.got_key_string("command", strval)) { for (size_t i =0; i <= strval.size(); i++) { if (strval[i] == ',') strval[i] = ';'; } + aux::strip_quotes(strval); button->set_command(strval); } else if (ini.got_key_string("align", strval)) { @@ -157,7 +144,7 @@ void Menu::resize() { set_size(parent()->size()); menu_background->set_size(size()); - menu_container->set_location(menu_container->childsize().width() * 0.25, (height() - menu_container->height()) / 2.0f); + menu_container->set_location(UI::elementsize.width() * 0.25, (height() - menu_container->height()) / 2.0f); } } diff --git a/src/ui/menuview.cc b/src/ui/menuview.cc new file mode 100644 index 0000000..71bdd1a --- /dev/null +++ b/src/ui/menuview.cc @@ -0,0 +1,95 @@ +/* + ui/menuview.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include "ui/menuview.h" +#include "ui/ui.h" + +namespace ui +{ + +MenuView::MenuView(Window *parent, const char * label) : Window(parent) +{ + set_border(false); + set_background(false); + set_label(label); + + menu_container = new Container(this); + menu_label = new Label(this); + + hide(); +} + +MenuView::~MenuView() +{ +} + +void MenuView::resize() +{ + set_size(parent()->size()); + menu_label->set_location(UI::elementsize.width() * 0.25, UI::elementsize.width() * 0.25); + menu_label->set_size(UI::elementsize.width() * 1.5f, UI::elementsize.height()); + + menu_container->set_location(UI::elementsize.width() * 0.25, (height() - menu_container->height()) / 2.0f); +} + +void MenuView::generate(core::Entity *entity, const char *menulabel) +{ + if (!menulabel) + return; + + + con_debug << "generating menu " << entity->label() << " " << menulabel << std::endl; + + remove_children(); + menu_container = new Container(this); + + menu_label = new Label(this, entity->name().c_str()); + menu_label->set_background(true); + menu_label->set_alignment(AlignCenter); + menu_label->set_font(ui::root()->font_large()); + + core::MenuDescription *menudescr = 0; + for (core::Entity::Menus::iterator it = entity->menus().begin(); it != entity->menus().end(); it++) { + if ((*it)->label().compare(menulabel) == 0) { + menudescr = (*it); + } + } + + if (!menudescr) { + menu_container->event_resize(); + resize(); + return; + } + + if (menudescr->text().size()) { + Label *label = new Label(menu_container); + label->set_text(menudescr->text()); + label->set_alignment(AlignCenter); + label->set_border(false); + label->set_font(ui::root()->font_large()); + } + + for (core::MenuDescription::Buttons::iterator it = menudescr->buttons().begin(); it != menudescr->buttons().end(); it++) { + core::ButtonDescription *buttondescr = (*it); + Button *button = new Button(menu_container, buttondescr->text().c_str(), buttondescr->command().c_str()); + switch (buttondescr->alignment()) { + case core::ButtonDescription::Center: + button->set_alignment(AlignCenter); + break; + case core::ButtonDescription::Left: + button->set_alignment(AlignLeft | AlignVCenter); + break; + case core::ButtonDescription::Right: + button->set_alignment(AlignRight | AlignVCenter); + break; + } + } + + menu_container->event_resize(); + resize(); +} + +} diff --git a/src/ui/menuview.h b/src/ui/menuview.h new file mode 100644 index 0000000..041d71a --- /dev/null +++ b/src/ui/menuview.h @@ -0,0 +1,42 @@ +/* + ui/menuview.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_UI_MENUVIEW_H__ +#define __INCLUDED_UI_MENUVIEW_H__ + +#include "core/entity.h" +#include "ui/bitmap.h" +#include "ui/container.h" +#include "ui/button.h" +#include "ui/label.h" +#include "ui/window.h" + +namespace ui +{ + +/// a menu container +class MenuView : public Window +{ +public: + /// create a new menu + MenuView(Window *parent, const char * label); + ~MenuView(); + + /// generate a menu from menu descriptions + void generate(core::Entity *entity, const char *menulabel); + +protected: + /// resize event + virtual void resize(); + +private: + Container *menu_container; + Label *menu_label; +}; + +} + +#endif // __INCLUDED_UI_MENUVIEW_H__ diff --git a/src/ui/ui.cc b/src/ui/ui.cc index 4774387..7d57ce0 100644 --- a/src/ui/ui.cc +++ b/src/ui/ui.cc @@ -16,6 +16,7 @@ #include "ui/button.h" #include "ui/label.h" #include "ui/menu.h" +#include "ui/menuview.h" #include "ui/paint.h" #include "ui/ui.h" #include "ui/widget.h" @@ -27,6 +28,9 @@ namespace ui bool UI::ui_debug = false; +float UI::elementmargin = 16; +math::Vector2f UI::elementsize(256, 48); + UI *global_ui = 0; void func_list_ui(std::string const &args) @@ -137,6 +141,12 @@ void func_menu(std::string const &args) } else if (command.compare("list") == 0) { root()->list_menus(); + } else if (command.compare("view") == 0) { + std::string label; + if (!(argstr >> label)) { + label.assign("main"); + } + root()->show_menuview(label); } else { root()->show_menu(command.c_str()); } @@ -244,6 +254,8 @@ void UI::load() } ui_menus.clear(); + add_menu(new MenuView(this, "view")); + ui_mouse_focus = this; ui_active_menu = 0; @@ -261,6 +273,11 @@ void UI::load() std::string strval; math::Color color; Menu *menu = 0; + + float w = elementsize.width(); + float h = elementsize.height(); + float m = elementmargin; + while (ini.getline()) { @@ -291,6 +308,12 @@ void UI::load() add_menu(menu); menu->load(); continue; + } else if (ini.got_key_float("elementwidth", w)) { + elementsize.assign(w, h); + } else if (ini.got_key_float("elementheight", h)) { + elementsize.assign(w, h); + } else if (ini.got_key_float("elementmargin", m)) { + elementmargin = m; } else { ini.unkown_key(); } @@ -402,6 +425,20 @@ void UI::add_menu(Window *menu) } +void UI::show_menuview(const std::string &label) +{ + if (!core::localplayer()->view()) + return; + + if (!core::localplayer()->view()->menus().size()) + return; + + MenuView *menuview = static_cast(find_menu("view")); + menuview->generate(core::localplayer()->view(), label.c_str()); + + show_menu("view"); +} + void UI::show_menu(const char *label) { Window *menu = find_menu(label); @@ -501,8 +538,15 @@ bool UI::on_keypress(const int key, const unsigned int modifier) case SDLK_ESCAPE: if (active()) { - hide_menu(); - audio::play("ui/menu"); + if (active()->label().compare("view") == 0) { + if (core::application()->connected()) { + show_menu("game"); + audio::play("ui/menu"); + } + } else { + hide_menu(); + audio::play("ui/menu"); + } } else { if (core::application()->connected()) { show_menu("game"); diff --git a/src/ui/ui.h b/src/ui/ui.h index f41df24..ae42ad6 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -37,6 +37,9 @@ public: /// make a window the active window void show_menu(const char *label); + /// make the entity view menu the active window + void show_menuview(const std::string &label); + /// hide the active window void hide_menu(); @@ -89,6 +92,11 @@ public: static bool ui_debug; + + + static float elementmargin; + static math::Vector2f elementsize; + protected: typedef std::list Menus; diff --git a/src/ui/widget.cc b/src/ui/widget.cc index 046cb01..1270997 100644 --- a/src/ui/widget.cc +++ b/src/ui/widget.cc @@ -34,6 +34,11 @@ Widget::Widget(Widget *parent) } Widget::~Widget() +{ + remove_children(); +} + +void Widget::remove_children() { for (Children::iterator it = widget_children.begin(); it != widget_children.end(); it++) { delete(*it); diff --git a/src/ui/widget.h b/src/ui/widget.h index 60670b6..c002c73 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -278,8 +278,14 @@ protected: /// draw the widget border virtual void draw_border(); + /// add a child widget virtual void add_child(Widget *child); + + /// remove a child widget virtual void remove_child(Widget *child); + + /// remove all child widgets + virtual void remove_children(); private: void draw_debug_border(); -- cgit v1.2.3