From a14d80f83aebe75241bf63b4f3ffca3a5d952577 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Mon, 6 Oct 2008 18:22:32 +0000 Subject: libui updates, support menu .ini files --- src/ui/Makefile.am | 7 ++-- src/ui/bitmap.cc | 55 ++++++++++++++++++++++++ src/ui/bitmap.h | 36 ++++++++++++++++ src/ui/button.cc | 24 ++++++++++- src/ui/button.h | 10 ++++- src/ui/label.cc | 24 +++++++++-- src/ui/label.h | 17 +++++++- src/ui/menu.cc | 102 ++++++++++++++++++++++++++++++++++++++++----- src/ui/menu.h | 17 ++++++-- src/ui/ui.cc | 120 +++++++++++++++++++++++++++++++++++++++++++++++------ src/ui/ui.h | 12 +++++- src/ui/widget.cc | 27 ++++++------ src/ui/widget.h | 19 ++++++--- src/ui/window.cc | 9 ++-- 14 files changed, 415 insertions(+), 64 deletions(-) create mode 100644 src/ui/bitmap.cc create mode 100644 src/ui/bitmap.h (limited to 'src/ui') diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am index c64860a..17bcd70 100644 --- a/src/ui/Makefile.am +++ b/src/ui/Makefile.am @@ -2,8 +2,9 @@ INCLUDES = -I$(top_srcdir)/src METASOURCES = AUTO noinst_LTLIBRARIES = libui.la -noinst_HEADERS = button.h label.h menu.h palette.h ui.h widget.h window.h +noinst_HEADERS = bitmap.h button.h label.h menu.h palette.h ui.h widget.h \ + window.h -libui_la_SOURCES = button.cc label.cc menu.cc palette.cc ui.cc widget.cc \ - window.cc +libui_la_SOURCES = bitmap.cc button.cc label.cc menu.cc palette.cc ui.cc \ + widget.cc window.cc libui_la_LDFLAGS = -avoid-version -no-undefined diff --git a/src/ui/bitmap.cc b/src/ui/bitmap.cc new file mode 100644 index 0000000..d848a52 --- /dev/null +++ b/src/ui/bitmap.cc @@ -0,0 +1,55 @@ +/* + ui/bitmap.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include "ui/bitmap.h" +#include "auxiliary/functions.h" +#include "render/primitives.h" +#include "sys/sys.h" + +namespace ui +{ + +Bitmap::Bitmap(Widget *parent, const char *texture) : Widget(parent) +{ + set_border(false); + set_background(true); + set_label("bitmap"); + + set_texture(texture); +} + +Bitmap::~Bitmap() +{} + +void Bitmap::print(size_t indent) +{ + std::string marker(""); + con_print << aux::pad_left(marker, indent*2) << label() << " \"" << texture() << "\"" << std::endl; +} + +void Bitmap::set_texture(std::string const & texture) +{ + bitmap_texture.assign(texture); +} + +void Bitmap::set_texture(const char *texture) +{ + if (texture) + bitmap_texture.assign(texture); + else + bitmap_texture.clear(); +} + +void Bitmap::draw_background() +{ + if (bitmap_texture.size()) { + render::gl::color(1.0f, 1.0f, 1.0f, 1.0f); + render::primitives::bitmap(global_location(), size(), bitmap_texture); + } +} + +} + diff --git a/src/ui/bitmap.h b/src/ui/bitmap.h new file mode 100644 index 0000000..1f60ef9 --- /dev/null +++ b/src/ui/bitmap.h @@ -0,0 +1,36 @@ +/* + ui/bitmap.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_BITMAP_H__ +#define __INCLUDED_UI_BITMAP_H__ + +#include "ui/widget.h" + +namespace ui { + +class Bitmap : public Widget { +public: + Bitmap (Widget *parent, const char *texture=0); + ~Bitmap(); + + inline std::string const &texture() const { return bitmap_texture; } + void set_texture(std::string const & texture); + void set_texture(const char *texture); + + /// print bitmap description + virtual void print(size_t indent); + +protected: + virtual void draw_background(); + +private: + std::string bitmap_texture; +}; + +} + +#endif // __INCLUDED_UI_BITMAP_H__ + diff --git a/src/ui/button.cc b/src/ui/button.cc index 09e8695..73a349e 100644 --- a/src/ui/button.cc +++ b/src/ui/button.cc @@ -5,18 +5,38 @@ */ #include "ui/button.h" +#include "auxiliary/functions.h" +#include "sys/sys.h" namespace ui { -Button::Button (Widget *parent, char const *text, char const *command) : Label(parent, text) +Button::Button (Widget *parent, const char *text, const char *command) : Label(parent, text) { set_label("button"); + set_command(command); +} + +Button::~Button() +{ +} + +void Button::print(size_t indent) +{ + std::string marker(""); + con_print << aux::pad_left(marker, indent*2) << label() << " \"" << text() << "\" \"" << command() << "\"" << std::endl; +} + +void Button::set_command(const char *command) +{ if (command) button_command.assign(command); + else + button_command.clear(); } -Button::~Button() +void Button::set_command(std::string const &command) { + button_command.assign(command); } void Button::draw() diff --git a/src/ui/button.h b/src/ui/button.h index eac5f1d..a9fee13 100644 --- a/src/ui/button.h +++ b/src/ui/button.h @@ -14,9 +14,17 @@ namespace ui { class Button : public Label { public: - Button (Widget *parent, char const *text=0, char const *command=0); + Button (Widget *parent, const char *text=0, const char *command=0); ~Button(); + void set_command(std::string const &command); + void set_command(const char *command); + + inline std::string const & command() const { return button_command; } + + /// print button description + virtual void print(size_t indent); + protected: virtual void draw(); diff --git a/src/ui/label.cc b/src/ui/label.cc index f924452..aee6a36 100644 --- a/src/ui/label.cc +++ b/src/ui/label.cc @@ -12,15 +12,33 @@ using math::Vector2f; namespace ui { -Label::Label(Widget *parent, char const *text) : Widget(parent) +Label::Label(Widget *parent, const char *text) : Widget(parent) { set_label("label"); + set_text(text); +} + +Label::~Label() +{ +} + +void Label::print(size_t indent) +{ + std::string marker(""); + con_print << aux::pad_left(marker, indent*2) << label() << " \"" << text() << "\"" << std::endl; +} + +void Label::set_text(const char *text) +{ if (text) label_text.assign(text); + else + label_text.clear(); } -Label::~Label() +void Label::set_text(std::string const &text) { + label_text.assign(text); } void Label::draw() @@ -38,7 +56,7 @@ void Label::draw_text() if (palette()) render::gl::color(palette()->foreground()); - render::primitives::text_centered(to_global(location()), size(), label_text); + render::primitives::text_centered(global_location(), size(), label_text); } } diff --git a/src/ui/label.h b/src/ui/label.h index f88f808..460ac8a 100644 --- a/src/ui/label.h +++ b/src/ui/label.h @@ -12,14 +12,29 @@ namespace ui { +/// a widget displaying centered text class Label : public Widget { public: - Label(Widget *parent, char const *text=0); + Label(Widget *parent, const char *text=0); ~Label(); + /// set the text displayed by the label + void set_text(std::string const &text); + + /// set the text displayed by the label + void set_text(const char *text); + + /// return the text displayed by the label + inline std::string const &text() const { return label_text; } + + /// print label description + virtual void print(size_t indent); + protected: + /// draw the label virtual void draw(); + /// draw the label text virtual void draw_text(); private: diff --git a/src/ui/menu.cc b/src/ui/menu.cc index c20457d..9485e82 100644 --- a/src/ui/menu.cc +++ b/src/ui/menu.cc @@ -4,6 +4,7 @@ the terms of the GNU General Public License version 2 */ +#include "filesystem/filesystem.h" #include "ui/label.h" #include "ui/button.h" #include "ui/menu.h" @@ -15,39 +16,118 @@ const float element_width = 256.0f; const float element_height = 64.0f; const float element_margin = 24.0f; -Menu::Menu(Window *parent, const char *label) : Window(parent), menu_container(this) +Menu::Menu(Window *parent, const char *label) : Window(parent) { set_label(label); set_border(false); - menu_container.set_label("container"); + menu_background = new Bitmap(this); + menu_container = new Window(this); + + menu_container->set_label("container"); } Menu::~Menu() { } -void Menu::add_label(char const * text) +void Menu::load() +{ + std::string filename("menus/"); + filename.append(label()); + + filesystem::IniFile ini; + + ini.open(filename); + + if (!ini.is_open()) { + con_error << "Could not open " << ini.name() << std::endl; + return; + } + + std::string strval; + Button *button = 0; + Label *label = 0; + + while (ini.getline()) { + if (ini.got_section()) { + + //con_debug << " " << ini.name() << " [" << ini.section() << "]" << std::endl; + + if (ini.got_section("menu")) { + + } else if (ini.got_section("button")) { + button = add_button(); + + } else if (ini.got_section("label")) { + label = add_label(); + + } else if (ini.got_section()) { + ini.unknown_section(); + } + + } else if (ini.got_key()) { + + //con_debug << " " << ini.name() << " " << ini.key() << "=" << ini.value() << std::endl; + + if (ini.in_section("menu")) { + if (ini.got_key_string("background", strval)) { + set_background(strval.c_str()); + } else { + ini.unkown_key(); + } + } else if (ini.in_section("button")) { + if (ini.got_key_string("text", strval)) { + button->set_text(strval); + + } else if (ini.got_key_string("command", strval)) { + button->set_command(strval); + + } else { + ini.unkown_key(); + } + } else if (ini.in_section("label")) { + if (ini.got_key_string("text", strval)) { + label->set_text(strval); + } else { + ini.unkown_key(); + } + } + + } + } + + con_debug << " " << ini.name() << " " << children().size() << " widgets" << std::endl; + ini.close(); +} + +void Menu::set_background(const char *texture) +{ + menu_background->set_texture(texture); +} + +Label *Menu::add_label(char const * text) { - new Label(&menu_container, text); + return new Label(menu_container, text); } -void Menu::add_button(char const *text, char const *command) +Button *Menu::add_button(char const *text, char const *command) { - new Button(&menu_container, text, command); + return new Button(menu_container, text, command); } void Menu::resize() { - set_size(parent()->size().x, parent()->size().y); + size().assign(parent()->size()); + menu_background->size().assign(size()); - float n = (float) menu_container.children().size(); - menu_container.set_size(2.0f * element_width, n * (element_height + element_margin) + element_height); - menu_container.set_location(element_margin, (height() - menu_container.height()) / 2.0f); + float n = (float) menu_container->children().size(); + menu_container->set_size(2.0f * element_width, n * (element_height + element_margin) + element_height); + menu_container->set_location(element_margin, (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++) { + for (Children::iterator it = menu_container->children().begin(); it != menu_container->children().end(); it++) { Widget *w = (*it); w->set_size(element_width, element_height); w->set_location(element_width * 0.5f, element_height * 0.5f + i * (element_height + element_margin)); diff --git a/src/ui/menu.h b/src/ui/menu.h index 7ed905b..422b23f 100644 --- a/src/ui/menu.h +++ b/src/ui/menu.h @@ -7,24 +7,35 @@ #ifndef __INCLUDED_UI_MENU_H__ #define __INCLUDED_UI_MENU_H__ +#include "ui/bitmap.h" +#include "ui/button.h" +#include "ui/label.h" #include "ui/window.h" namespace ui { +/// a menu container class Menu : public Window { public: + /// create a new menu Menu(Window *parent, const char * label); ~Menu(); - void add_label(char const * text); - void add_button(char const *text, char const *command); + /// load a menu from ini/menus/label.ini + void load(); + + Label *add_label(char const * text=0); + Button *add_button(char const *text=0, char const *command=0); + + void set_background(const char *texture); protected: virtual void resize(); private: - Window menu_container; + Bitmap *menu_background; + Window *menu_container; }; } diff --git a/src/ui/ui.cc b/src/ui/ui.cc index be75f11..ac5c0b8 100644 --- a/src/ui/ui.cc +++ b/src/ui/ui.cc @@ -9,6 +9,7 @@ #include "auxiliary/functions.h" #include "core/core.h" +#include "filesystem/filesystem.h" #include "sys/sys.h" #include "ui/button.h" #include "ui/label.h" @@ -28,6 +29,14 @@ void func_list_ui(std::string const &args) } } + +void func_list_menu(std::string const &args) +{ + if (global_ui) { + global_ui->list_menus(); + } +} + void help() { con_print << "^BUser interface functions" << std::endl; @@ -35,6 +44,7 @@ void help() con_print << " ui list list widgets" << std::endl; con_print << " ui show show user interface" << std::endl; con_print << " ui hide hide user interface" << std::endl; + con_print << " ui restart reload menu files" << std::endl; } void func_ui(std::string const &args) @@ -61,6 +71,8 @@ void func_ui(std::string const &args) global_ui->show(); } else if (command.compare("hide") == 0) { global_ui->hide(); + } else if (command.compare("restart") == 0) { + global_ui->load(); } else { help(); } @@ -89,7 +101,7 @@ void func_menu(std::string const &args) root()->hide_window(); } else if (command.compare("list") == 0) { - + root()->list_menus(); } else { root()->show_window(command.c_str()); } @@ -109,6 +121,9 @@ void init() core::Func *func = core::Func::add("list_ui", func_list_ui); func->set_info("list user interface widgets"); + func = core::Func::add("list_menu", func_list_menu); + func->set_info("list available menus"); + func = core::Func::add("ui", func_ui); func->set_info("[command] [options] user interface subcommands"); @@ -121,6 +136,7 @@ void shutdown() con_print << "^BShutting down user interface..." << std::endl; core::Func::remove("list_ui"); + core::Func::remove("list_menu"); core::Func::remove("menu"); core::Func::remove("ui"); @@ -143,23 +159,87 @@ UI::UI() : Window(0) set_size(1024, 768); set_border(false); + load(); +} + +void UI::load() +{ + Windows::iterator it; + for (it = window_children.begin(); it != window_children.end(); it++) { + Window *window = (*it); + remove_child(window); + } + window_children.clear(); ui_active_window = 0; + std::string filename("ui"); + + filesystem::IniFile ini; + + ini.open(filename); + + if (!ini.is_open()) { + con_error << "Could not open " << ini.name() << std::endl; + return; + } + + std::string strval; + math::Color color; Menu *menu = 0; + + while (ini.getline()) { + + if (ini.got_section()) { - menu = new Menu(this, "main"); - menu->add_label("Main menu"); - menu->add_button("New Game", "connect"); - menu->add_button("Connect to...", "menu connect"); - menu->add_button("Options...", "menu options"); - menu->add_button("Quit", "quit"); + //con_debug << " " << ini.name() << " [" << ini.section() << "]" << std::endl; - menu = new Menu(this, "options"); - menu->add_label("Options menu"); + if (ini.got_section("ui")) { + continue; + + } else if (ini.got_section("colors")) { + continue; + + } else { + ini.unknown_section(); + continue; + } + + } else if (ini.got_key()) { + + //con_debug << " " << ini.name() << " " << ini.key() << "=" << ini.value() << std::endl; + + if (ini.in_section("ui")) { + + if (ini.got_key_string("menu", strval)) { + aux::to_label(strval); + menu = new Menu(this, strval.c_str()); + menu->load(); + continue; + } else { + ini.unkown_key(); + } + + } else if (ini.in_section("colors")) { + + if (ini.got_key_color("foreground", color)) { + widget_palette->set_foreground(color); + continue; + } else if (ini.got_key_color("background", color)) { + widget_palette->set_background(color); + continue; + } else if (ini.got_key_color("border", color)) { + widget_palette->set_border(color); + continue; + } else { + ini.unkown_key(); + } + } + } + } - menu = new Menu(this, "connect"); - menu->add_label("Connect to..."); -} + con_debug << " " << ini.name() << " " << window_children.size() << " menus" << std::endl; + ini.close(); +} UI::~UI() { @@ -173,6 +253,16 @@ void UI::list() con_print << n << " user interface widgets" << std::endl; } +void UI::list_menus() +{ + Windows::iterator it; + for (it = window_children.begin(); it != window_children.end(); it++) { + Window *window = (*it); + con_print << " " << window->label() << std::endl; + } + con_print << window_children.size() << " menus" << std::endl; +} + void UI::add_window(Window *window) { Window::add_window(window); @@ -183,6 +273,7 @@ void UI::remove_window(Window *window) { if (ui_active_window == window) ui_active_window = 0; + Window::remove_window(window); } @@ -211,4 +302,9 @@ void UI::hide_window() } } +void UI::set_mouse_cursor(float x, float y) +{ + mouse_cursor.assign(x, y); +} + } diff --git a/src/ui/ui.h b/src/ui/ui.h index c516d47..527d959 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -24,6 +24,12 @@ public: /// list widgets void list(); + /// list meus + void list_menus(); + + /// reload menu files + void load(); + /// make a window the active window void show_window(char const *label); @@ -33,12 +39,16 @@ public: /// return the active window Window *active() { return ui_active_window; } + /// set mouse cursor position + void set_mouse_cursor(float x, float y); + protected: virtual void add_window(Window *window); virtual void remove_window(Window *window); private: - Window *ui_active_window; + Window *ui_active_window; + math::Vector2f mouse_cursor; }; /// initialize the user interface diff --git a/src/ui/widget.cc b/src/ui/widget.cc index 94260cb..068d60f 100644 --- a/src/ui/widget.cc +++ b/src/ui/widget.cc @@ -19,8 +19,8 @@ Widget::Widget(Widget *parent) { widget_label.assign("widget"); if (widget_parent) { - widget_palette = parent->widget_palette; parent->add_child(this); + widget_palette = parent->widget_palette; } else { widget_palette = 0; } @@ -28,30 +28,29 @@ Widget::Widget(Widget *parent) { Widget::~Widget() { - if (widget_parent) { - widget_parent->remove_child(this); - } - for (Children::iterator it = widget_children.begin(); it != widget_children.end(); it++) { - (*it)->widget_parent = 0; delete (*it); + (*it) = 0; } - widget_children.clear(); } size_t Widget::list(size_t indent) { + print(indent); size_t n = 1; - std::string marker(""); - con_print << aux::pad_left(marker, indent*2) << label() << " " << (size_t)(this) << std::endl; - for (Children::iterator it = widget_children.begin(); it != widget_children.end(); it++) { n += (*it)->list(indent+1); } return n; } +void Widget::print(size_t indent) +{ + std::string marker(""); + con_print << aux::pad_left(marker, indent*2) << label() << std::endl; +} + void Widget::show() { widget_visible = true; @@ -128,9 +127,9 @@ void Widget::add_child(Widget *child) void Widget::remove_child(Widget *child) { - Children::iterator it = find_child(child); if (it != widget_children.end()) { + delete (*it); widget_children.erase(it); } } @@ -172,8 +171,7 @@ void Widget::draw_background() if (palette()) render::gl::color(palette()->background()); - math::Vector2f v(to_global(location())); - render::primitives::rectangle(v, size()); + render::primitives::rectangle(global_location(), size()); } void Widget::draw_border() @@ -183,8 +181,7 @@ void Widget::draw_border() if (palette()) render::gl::color(palette()->border()); - math::Vector2f v(to_global(location())); - render::primitives::border(v, size()); + render::primitives::border(global_location(), size()); } } diff --git a/src/ui/widget.h b/src/ui/widget.h index 97c6a01..fcb8e6b 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -10,8 +10,11 @@ #include #include +#include "auxiliary/functions.h" +#include "math/color.h" #include "math/vector2f.h" #include "ui/palette.h" +#include "sys/sys.h" namespace ui { @@ -111,8 +114,12 @@ protected: /// list widget content size_t list(size_t indent); - /// map local widget coordinates to global coordinates - inline math::Vector2f to_global(math::Vector2f v) { + /// print widget description + virtual void print(size_t indent); + + /// map local widget location to global location + inline math::Vector2f global_location() { + math::Vector2f v(widget_location); Widget *parent = widget_parent; while (parent) { v += parent->location(); @@ -121,9 +128,11 @@ protected: return v; } -private: - + /// remove a child widget + void remove_child(Widget *child); + Palette *widget_palette; +private: bool widget_visible; bool widget_background; bool widget_border; @@ -137,8 +146,6 @@ private: Children::iterator find_child(Widget *child); void add_child(Widget *child); - - void remove_child(Widget *child); }; } diff --git a/src/ui/window.cc b/src/ui/window.cc index 8763b53..60fbf56 100644 --- a/src/ui/window.cc +++ b/src/ui/window.cc @@ -21,9 +21,6 @@ Window::Window(Window *parent) : Widget(static_cast(parent)) Window::~Window() { - if (parent()) { - static_cast(parent())->remove_window(this); - } window_children.clear(); } @@ -34,8 +31,7 @@ void Window::draw_border() if (palette()) render::gl::color(palette()->foreground()); - math::Vector2f v(to_global(location())); - render::primitives::border(v, size()); + render::primitives::border(global_location(), size()); } Window::Windows::iterator Window::find_window(Window *window) @@ -59,10 +55,11 @@ void Window::add_window(Window *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); } } + } -- cgit v1.2.3