From 574bf11742c40203a4433c0b69264014b10b5a96 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 12 Oct 2008 17:27:00 +0000 Subject: container widget --- src/client/chat.cc | 7 +-- src/client/chat.h | 2 +- src/client/client.cc | 4 +- src/client/input.cc | 6 +-- src/math/vector2f.h | 8 ++++ src/ui/Makefile.am | 4 +- src/ui/container.cc | 59 ++++++++++++++++++++++++ src/ui/container.h | 19 +++++--- src/ui/menu.cc | 46 +++++++------------ src/ui/menu.h | 14 +++--- src/ui/ui.cc | 126 ++++++++++++++++++++++++++------------------------- src/ui/ui.h | 24 ++++++---- src/ui/widget.cc | 6 ++- src/ui/widget.h | 24 +++++----- src/ui/window.cc | 51 +++++++-------------- src/ui/window.h | 19 +++----- 16 files changed, 230 insertions(+), 189 deletions(-) create mode 100644 src/ui/container.cc diff --git a/src/client/chat.cc b/src/client/chat.cc index bdeebe2..87ba437 100644 --- a/src/client/chat.cc +++ b/src/client/chat.cc @@ -15,7 +15,7 @@ namespace client { -Chat::Chat(ui::Widget *parent) : ui::Widget(parent) +Chat::Chat(ui::Widget *parent) : ui::Window(parent) { set_label("chat"); history.clear(); @@ -42,10 +42,7 @@ Chat::~Chat() void Chat::show() { - Widget::show(); - - raise(); - set_focus(); + Window::show(); history_pos = history.rbegin(); (*history_pos).clear(); diff --git a/src/client/chat.h b/src/client/chat.h index 0bef2b4..f076075 100644 --- a/src/client/chat.h +++ b/src/client/chat.h @@ -16,7 +16,7 @@ namespace client { -class Chat : public ui::Widget +class Chat : public ui::Window { public: Chat(ui::Widget *parent = 0); diff --git a/src/client/client.cc b/src/client/client.cc index ac4c0e3..ae4f232 100644 --- a/src/client/client.cc +++ b/src/client/client.cc @@ -206,7 +206,7 @@ void Client::frame(float seconds) } else { // show the main menu on non-interactive modules if (!core::game()->interactive() && !ui::root()->active()) { - ui::root()->show_window("main"); + ui::root()->show_menu("main"); } } @@ -243,7 +243,7 @@ void Client::shutdown() void Client::notify_connect() { - ui::root()->hide_window(); + ui::root()->hide_menu(); } void Client::notify_disconnect() diff --git a/src/client/input.cc b/src/client/input.cc index d2c290b..22fd1c0 100644 --- a/src/client/input.cc +++ b/src/client/input.cc @@ -504,7 +504,7 @@ void key_pressed(Key *key) } else { if (ui::root()->active()) { - ui::root()->hide_window(); + ui::root()->hide_menu(); local_direction = 0.0f; local_pitch = 0.0f; local_roll = 0.0f; @@ -513,9 +513,9 @@ void key_pressed(Key *key) render::Camera::set_pitch(0.0f); } else { if (core::application()->connected()) { - ui::root()->show_window("game"); + ui::root()->show_menu("game"); } else { - ui::root()->show_window("main"); + ui::root()->show_menu("main"); } } } diff --git a/src/math/vector2f.h b/src/math/vector2f.h index 6029b3c..ee2d044 100644 --- a/src/math/vector2f.h +++ b/src/math/vector2f.h @@ -90,7 +90,15 @@ public: inline bool contains(float x, float y) const { return ((x >= 0) && (y >= 0) && (x <= coord[0]) && (y <= coord[1])); } + + inline float width() const { + return coord[0]; + } + inline float height() const { + return coord[1]; + } + /// x coordinate float &x; diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am index b0f1625..a68c307 100644 --- a/src/ui/Makefile.am +++ b/src/ui/Makefile.am @@ -10,6 +10,6 @@ endif noinst_HEADERS = bitmap.h button.h container.h definitions.h font.h input.h label.h \ menu.h paint.h palette.h ui.h widget.h window.h -libui_la_SOURCES = bitmap.cc button.cc font.cc input.cc label.cc menu.cc \ - paint.cc palette.cc ui.cc widget.cc window.cc +libui_la_SOURCES = bitmap.cc button.cc container.cc font.cc input.cc label.cc \ + menu.cc paint.cc palette.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 new file mode 100644 index 0000000..d544244 --- /dev/null +++ b/src/ui/container.cc @@ -0,0 +1,59 @@ +/* + ui/container.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/container.h" + +namespace ui +{ + +// TODO Container::direction +Container::Container(Widget *parent) : Window(parent) +{ + set_label("container"); + set_border(false); + + set_border(true); + set_background(true); + + container_childsize.assign(256, 48); + container_margin = 24; +} + +Container::~Container() +{ +} + +void Container::resize() +{ + float w = container_childsize.width() * 1.5f; + float h = children().size() * container_childsize.height() + (children().size()+1) * container_margin; + + set_size(w, h); + + const float x = container_childsize.width() * 0.25f; + float y = container_margin; + + // 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_location(x, y); + y += container_childsize.height() + container_margin; + } +} + +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; +} + +} diff --git a/src/ui/container.h b/src/ui/container.h index 77e987e..ae97bdf 100644 --- a/src/ui/container.h +++ b/src/ui/container.h @@ -4,33 +4,38 @@ the terms of the GNU General Public License version 2 */ -/* #ifndef __INCLUDED_UI_CONTAINER_H__ #define __INCLUDED_UI_CONTAINER_H__ #include -#include "ui/widget.h" + +#include "ui/window.h" namespace ui { /// a widget containing childs of equal size -class Container : public Widget { +class Container : public Window { public: Container(Widget *parent); ~Container(); - void set_margin(const float h, const float v); - void set_child_size(const float width, const float height); + 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 resize(); private: - math::Vector2f container_child_size; + float container_margin; + math::Vector2f container_childsize; }; } #endif // __INCLUDED_UI_CONTAINER_H__ -*/ + diff --git a/src/ui/menu.cc b/src/ui/menu.cc index 2a1829f..6931bd4 100644 --- a/src/ui/menu.cc +++ b/src/ui/menu.cc @@ -17,17 +17,12 @@ Menu::Menu(Window *parent, const char *label) : Window(parent) { set_label(label); set_border(false); - - menu_element_width = 256.0f; - menu_element_height = 48.0f; - menu_element_margin = 24.0f; + set_background(false); menu_background = new Bitmap(this); - menu_container = new Window(this); - menu_container->set_border(true); - menu_container->set_background(true); - - menu_container->set_label("container"); + menu_container = new Container(this); + + hide(); } Menu::~Menu() @@ -52,6 +47,9 @@ 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()) { @@ -76,13 +74,13 @@ void Menu::load() if (ini.in_section("menu")) { if (ini.got_key_string("background", strval)) { - set_background(strval.c_str()); - } else if (ini.got_key_float("elementwidth", menu_element_width)) { - continue; - } else if (ini.got_key_float("elementheight", menu_element_height)) { - continue; - } else if (ini.got_key_float("elementmargin", menu_element_margin)) { - continue; + 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(); } @@ -133,7 +131,7 @@ void Menu::load() ini.close(); } -void Menu::set_background(const char *texture) +void Menu::set_background_texture(const char *texture) { menu_background->set_texture(texture); } @@ -156,19 +154,7 @@ void Menu::resize() { set_size(parent()->size()); menu_background->set_size(size()); - - float n = (float) menu_container->children().size(); - menu_container->set_size(1.5f * menu_element_width, n * (menu_element_height + menu_element_margin) + menu_element_height); - menu_container->set_location(menu_element_width * 0.25, (height() - menu_container->height()) / 2.0f); - - // reposition all children within the container - size_t i = 0; - for (Children::iterator it = menu_container->children().begin(); it != menu_container->children().end(); it++) { - Widget *w = (*it); - w->set_size(menu_element_width, menu_element_height); - w->set_location(menu_element_width * 0.25f, menu_element_height * 0.5f + i * (menu_element_height + menu_element_margin)); - i++; - } + menu_container->set_location(menu_container->childsize().width() * 0.25, (height() - menu_container->height()) / 2.0f); } } diff --git a/src/ui/menu.h b/src/ui/menu.h index 1b4f17e..a909e20 100644 --- a/src/ui/menu.h +++ b/src/ui/menu.h @@ -8,6 +8,7 @@ #define __INCLUDED_UI_MENU_H__ #include "ui/bitmap.h" +#include "ui/container.h" #include "ui/button.h" #include "ui/label.h" #include "ui/window.h" @@ -27,23 +28,22 @@ public: /// load a menu from ini/menus/label.ini void load(); - void set_background(const char *texture); + /// set the background bitmap + void set_background_texture(const char *texture); + /// add a label Label *add_label(char const * text=0); + /// add a button with a command Button *add_button(char const *text=0, char const *command=0); protected: + /// resize event virtual void resize(); private: - float menu_element_width; - float menu_element_height; - float menu_element_margin; - Bitmap *menu_background; - Window *menu_container; - + Container *menu_container; }; } diff --git a/src/ui/ui.cc b/src/ui/ui.cc index 8d60543..2cadd8b 100644 --- a/src/ui/ui.cc +++ b/src/ui/ui.cc @@ -16,7 +16,6 @@ #include "ui/menu.h" #include "ui/ui.h" #include "ui/widget.h" -#include "ui/window.h" namespace ui { @@ -117,26 +116,24 @@ void func_menu(std::string const &args) aux::to_label(command); if (command.compare("hide") == 0) { - root()->hide_window(); + root()->hide_menu(); } else if (command.compare("close") == 0) { - root()->hide_window(); + root()->hide_menu(); } else if (command.compare("back") == 0) { - root()->previous_window(); + root()->previous_menu(); } else if (command.compare("previous") == 0) { - root()->previous_window(); + root()->previous_menu(); } else if (command.compare("list") == 0) { root()->list_menus(); } else { - root()->show_window(command.c_str()); + root()->show_menu(command.c_str()); } } -/* -- class UI ----------------------------------------------------- */ - UI *root() { return global_ui; @@ -193,6 +190,7 @@ UI::UI() : Window(0) set_label("root"); set_size(1024, 768); set_border(false); + set_background(false); // default palette ui_palette = new Palette(); @@ -221,14 +219,15 @@ UI::~UI() */ void UI::load() { - Windows::iterator it; - for (it = window_children.begin(); it != window_children.end(); it++) { - Window *window = (*it); - remove_child(window); + Menus::iterator it; + for (it = ui_menus.begin(); it != ui_menus.end(); it++) { + Window *menu = (*it); + remove_child(menu); } - window_children.clear(); + ui_menus.clear(); + ui_mouse_focus = this; - ui_active_window = 0; + ui_active_menu = 0; std::string filename("ui"); @@ -271,6 +270,7 @@ void UI::load() if (ini.got_key_string("menu", strval)) { aux::to_label(strval); menu = new Menu(this, strval.c_str()); + add_menu(menu); menu->load(); continue; } else { @@ -302,11 +302,11 @@ void UI::load() } } - con_debug << " " << ini.name() << " " << window_children.size() << " menus" << std::endl; + con_debug << " " << ini.name() << " " << ui_menus.size() << " menus" << std::endl; ini.close(); // fallback main menu - if (!find_window("main")) { + if (!find_menu("main")) { con_warn << "menu 'main' not found, using default" << std::endl; Menu *menu = new Menu(this, "main"); menu->add_label("Main Menu"); @@ -315,7 +315,7 @@ void UI::load() } // fallback game menu - if (!find_window("game")) { + if (!find_menu("game")) { con_warn << "menu 'game' not found, using default" << std::endl; Menu *menu = new Menu(this, "game"); menu->add_label("Game Menu"); @@ -330,58 +330,62 @@ void UI::list() const con_print << n << " user interface widgets" << std::endl; } -void UI::list_menus() const +UI::Menus::iterator UI::find_menu(Window *menu) { - for (Windows::const_iterator it = window_children.begin(); it != window_children.end(); it++) { - const Window *window = (*it); - con_print << " " << window->label() << std::endl; + Menus::iterator it; + for (it = ui_menus.begin(); it != ui_menus.end(); it++) { + if ((*it) == menu) + return it; } - con_print << window_children.size() << " menus" << std::endl; + + return it; } -void UI::add_window(Window *window) +Window *UI::find_menu(const char *label) { - Window::add_window(window); - window->hide(); + for (Menus::const_iterator it = ui_menus.begin(); it != ui_menus.end(); it++) { + if ((*it)->label().compare(label) == 0) { + return (*it); + } + } + + return 0; } -void UI::remove_window(Window *window) +void UI::list_menus() const { - if (ui_active_window == window) { - ui_active_window = 0; - ui_mouse_focus = this; - ui_input_focus = this; + for (Menus::const_iterator it = ui_menus.begin(); it != ui_menus.end(); it++) { + const Window *menu = (*it); + con_print << " " << menu->label() << std::endl; } - - Window::remove_window(window); + con_print << ui_menus.size() << " menus" << std::endl; } -Window *UI::find_window(const char *label) const +void UI::add_menu(Window *menu) { - for (Windows::const_iterator it = window_children.begin(); it != window_children.end(); it++) { - if ((*it)->label().compare(label) == 0) { - return (*it); - } + Menus::iterator it = find_menu(menu); + if (it == ui_menus.end()) { + ui_menus.push_back(menu); } - return 0; + } -void UI::show_window(const char *label) +void UI::show_menu(const char *label) { - Window *window = find_window(label); + Window *menu = find_menu(label); - if (window) { - if (ui_active_window) { - ui_active_window->hide(); - window->set_previous(ui_active_window); + if (menu) { + if (ui_active_menu) { + ui_active_menu->hide(); + menu->set_previous(ui_active_menu); } else { - window->clear_previous(); + menu->clear_previous(); } - ui_active_window = window; - ui_active_window->event_resize(); - ui_active_window->raise(); - ui_active_window->show(); - ui_active_window->set_focus(); + ui_active_menu = menu; + ui_active_menu->event_resize(); + ui_active_menu->raise(); + ui_active_menu->show(); + ui_active_menu->set_focus(); ui_mouse_focus = this; ui_input_focus = this; } else { @@ -389,29 +393,29 @@ void UI::show_window(const char *label) } } -void UI::hide_window() +void UI::hide_menu() { - if (ui_active_window) { - ui_active_window->hide(); - ui_active_window = 0; + if (ui_active_menu) { + ui_active_menu->hide(); + ui_active_menu = 0; } } -void UI::previous_window() +void UI::previous_menu() { - if (ui_active_window) { - if (ui_active_window->previous().size()) { - show_window(ui_active_window->previous().c_str()); + if (ui_active_menu) { + if (ui_active_menu->previous().size()) { + show_menu(ui_active_menu->previous().c_str()); } else { - hide_window(); + hide_menu(); } } } void UI::frame() { - if (ui_active_window && !ui_active_window->visible()) { - ui_active_window = 0; + if (ui_active_menu && !ui_active_menu->visible()) { + ui_active_menu = 0; } event_draw(); diff --git a/src/ui/ui.h b/src/ui/ui.h index eb2d4e0..583f76c 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -34,17 +34,17 @@ public: void load(); /// make a window the active window - void show_window(const char *label); + void show_menu(const char *label); /// hide the active window - void hide_window(); + void hide_menu(); /// show previous window - void previous_window(); + void previous_menu(); - /// return the active window + /// return the active menu Window *active() { - return ui_active_window; + return ui_active_menu; } /// return the widget with global mouse focus @@ -79,11 +79,13 @@ public: } protected: - Window *find_window(const char *label) const; - - virtual void add_window(Window *window); - virtual void remove_window(Window *window); + typedef std::list Menus; + Menus::iterator find_menu(Window *menu); + Window *find_menu(const char *label); + + void add_menu(Window *window); + /* -- event handlers --------------------------------------- */ /// handle keypress events @@ -97,9 +99,11 @@ private: Font *ui_font_small; Font *ui_font_large; - Window *ui_active_window; + Window *ui_active_menu; Widget *ui_mouse_focus; Widget *ui_input_focus; + + Menus ui_menus; /// TODO move to separate object to handle mouse cursor drawing math::Vector2f mouse_cursor; diff --git a/src/ui/widget.cc b/src/ui/widget.cc index e17e5ab..1ecfcc8 100644 --- a/src/ui/widget.cc +++ b/src/ui/widget.cc @@ -223,7 +223,9 @@ void Widget::remove_child(Widget *child) { Children::iterator it = find_child(child); if (it != widget_children.end()) { - delete(*it); + Widget *w = (*it); + w->widget_parent = 0; + delete(w); widget_children.erase(it); } } @@ -323,10 +325,10 @@ void Widget::event_draw() void Widget::event_resize() { - resize(); for (Children::iterator it = widget_children.begin(); it != widget_children.end(); it++) { (*it)->event_resize(); } + resize(); } /* -- event handlers ----------------------------------------------- */ diff --git a/src/ui/widget.h b/src/ui/widget.h index e069220..41ad795 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -27,9 +27,6 @@ class Widget { public: - /// type definition for child widgets - typedef std::list Children; - /// create a new widget Widget(Widget *parent=0); @@ -178,12 +175,6 @@ public: ///enable or disable widget background void set_background(bool background = true); - /// child widgets - inline Children &children() { - return widget_children; - } - - /* -- event distributors ----------------------------------- */ /// distribute resize event @@ -199,6 +190,14 @@ public: virtual bool event_mouse(const math::Vector2f &cursor); protected: + /// type definition for child widgets + typedef std::list Children; + + /// child widgets + inline Children &children() { + return widget_children; + } + /// find the widget that has input focus virtual Widget *find_input_focus(); @@ -212,6 +211,9 @@ protected: /// print widget description virtual void print(const size_t indent) const; + + /// true of this sibling has local focus + inline bool focus() const { return widget_focus; } /* -- coordinate mapping ----------------------------------- */ @@ -276,8 +278,8 @@ protected: /// draw the widget border virtual void draw_border(); - void add_child(Widget *child); - void remove_child(Widget *child); + virtual void add_child(Widget *child); + virtual void remove_child(Widget *child); private: bool widget_visible; diff --git a/src/ui/window.cc b/src/ui/window.cc index 4a60056..e79262f 100644 --- a/src/ui/window.cc +++ b/src/ui/window.cc @@ -10,19 +10,24 @@ namespace ui { -Window::Window(Window *parent) : Widget(static_cast(parent)) +Window::Window(Widget *parent) : Widget(parent) { set_label("window"); set_border(true); - - if (parent) { - parent->add_window(this); - } + set_background(true); + + set_focus(); } Window::~Window() { - window_children.clear(); +} + +void Window::show() { + resize(); + Widget::show(); + raise(); + set_focus(); } void Window::set_previous(Window *previous) @@ -40,36 +45,12 @@ void Window::draw_border() if (!border()) return; - paint::color(palette()->foreground()); - paint::border(global_location(), size()); -} - -Window::Windows::iterator Window::find_window(Window *window) -{ - Windows::iterator it; - for (it = window_children.begin(); it != window_children.end(); it++) { - if ((*it) == window) - return it; - } - - return it; -} - -void Window::add_window(Window *window) -{ - Windows::iterator it = find_window(window); - if (it == window_children.end()) { - window_children.push_back(window); - } -} - -void Window::remove_window(Window *window) -{ - Windows::iterator it = find_window(window); - if (it != window_children.end()) { - remove_child(*it); - window_children.erase(it); + if(focus()) { + paint::color(palette()->foreground()); + } else { + paint::color(palette()->border()); } + paint::border(global_location(), size()); } } diff --git a/src/ui/window.h b/src/ui/window.h index 919559f..2c0e2a5 100644 --- a/src/ui/window.h +++ b/src/ui/window.h @@ -16,33 +16,26 @@ class Window : public Widget { public: - Window(Window *parent=0); + Window(Widget *parent=0); ~Window(); virtual void draw_border(); /// set the label of the previous window void set_previous(Window *previous); + /// clear the label of the previous window void clear_previous(); + + /// showing a window sets focus + virtual void show(); inline const std::string &previous() const { return window_previous; } protected: - typedef std::list Windows; - Windows window_children; - - Windows::iterator find_window(Window *window); - - virtual void add_window(Window *window); - virtual void remove_window(Window *window); - - /// label of the previous window that got activated - /** This label is used to implement the 'menu previous' - * command - */ + std::string window_previous; }; -- cgit v1.2.3