diff options
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/Makefile.am | 4 | ||||
-rw-r--r-- | src/ui/button.cc | 14 | ||||
-rw-r--r-- | src/ui/button.h | 4 | ||||
-rw-r--r-- | src/ui/definitions.h | 28 | ||||
-rw-r--r-- | src/ui/label.cc | 8 | ||||
-rw-r--r-- | src/ui/label.h | 7 | ||||
-rw-r--r-- | src/ui/menu.cc | 37 | ||||
-rw-r--r-- | src/ui/paint.cc | 73 | ||||
-rw-r--r-- | src/ui/paint.h | 8 | ||||
-rw-r--r-- | src/ui/ui.cc | 35 | ||||
-rw-r--r-- | src/ui/ui.h | 23 | ||||
-rw-r--r-- | src/ui/widget.cc | 92 | ||||
-rw-r--r-- | src/ui/widget.h | 44 |
13 files changed, 292 insertions, 85 deletions
diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am index 5d14589..5c7815b 100644 --- a/src/ui/Makefile.am +++ b/src/ui/Makefile.am @@ -7,8 +7,8 @@ else noinst_LTLIBRARIES = libui.la endif -noinst_HEADERS = bitmap.h button.h font.h label.h menu.h paint.h \ - palette.h ui.h widget.h window.h +noinst_HEADERS = bitmap.h button.h definitions.h font.h label.h \ + menu.h paint.h palette.h ui.h widget.h window.h libui_la_SOURCES = bitmap.cc button.cc font.cc label.cc menu.cc paint.cc \ palette.cc ui.cc widget.cc window.cc diff --git a/src/ui/button.cc b/src/ui/button.cc index d6384c9..1ac5fd8 100644 --- a/src/ui/button.cc +++ b/src/ui/button.cc @@ -17,6 +17,7 @@ Button::Button (Widget *parent, const char *text, const char *command) : Label(p { set_label("button"); set_command(command); + set_alignment(AlignCenter); } Button::~Button() @@ -51,6 +52,7 @@ void Button::draw_border() paint::color(palette()->foreground()); else paint::color(palette()->border()); + paint::border(global_location(), size()); } @@ -64,21 +66,23 @@ void Button::draw_text() else paint::color(palette()->foreground()); - paint::text_centered(global_location(), size(), text(), font()); + paint::text(global_location(), size(), font(), text(), alignment()); } -void Button::keypress(unsigned int key, unsigned int modifier) +bool Button::keypress(unsigned int key, unsigned int modifier) { - + return false; } -void Button::keyrelease(unsigned int key, unsigned int modifier) +bool Button::keyrelease(unsigned int key, unsigned int modifier) { if (key == 512 + SDL_BUTTON_LEFT) { core::cmd() << button_command << std::endl; audio::play("ui/button"); + return true; } -} + return false; } +} diff --git a/src/ui/button.h b/src/ui/button.h index 34c3ba4..c074467 100644 --- a/src/ui/button.h +++ b/src/ui/button.h @@ -26,8 +26,8 @@ public: virtual void print(size_t indent); /// handle keyboard events - virtual void keypress(unsigned int key, unsigned int modifier); - virtual void keyrelease(unsigned int key, unsigned int modifier); + virtual bool keypress(unsigned int key, unsigned int modifier); + virtual bool keyrelease(unsigned int key, unsigned int modifier); protected: /// draw the button border diff --git a/src/ui/definitions.h b/src/ui/definitions.h new file mode 100644 index 0000000..d5d7fe9 --- /dev/null +++ b/src/ui/definitions.h @@ -0,0 +1,28 @@ +/* + ui/definitions.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_DEFINITIONS_H__ +#define __INCLUDED_UI_DEFINITIONS_H__ + +namespace ui { + +enum Alignment { + AlignAuto = 0x0000, + AlignLeft = 0x0001, + AlignHCenter = 0x0002, + AlignRight = 0x0004, + + AlignTop = 0x0010, + AlignVCenter = 0x0020, + AlignBottom = 0x0040, + + AlignCenter = AlignHCenter | AlignVCenter +}; + +} + +#endif // __INCLUDED_UI_DEFINITIONS_H__ + diff --git a/src/ui/label.cc b/src/ui/label.cc index 1b142c4..6f496fc 100644 --- a/src/ui/label.cc +++ b/src/ui/label.cc @@ -16,6 +16,7 @@ Label::Label(Widget *parent, const char *text) : Widget(parent) { set_label("label"); set_text(text); + set_alignment(AlignLeft | AlignTop); } Label::~Label() @@ -41,6 +42,11 @@ void Label::set_text(std::string const &text) label_text.assign(text); } +void Label::set_alignment(unsigned int alignment) +{ + label_alignment = alignment; +} + void Label::draw() { Widget::draw(); @@ -54,7 +60,7 @@ void Label::draw_text() return; paint::color(palette()->foreground()); - paint::text_centered(global_location(), size(), text(), font()); + paint::text(global_location(), size(), font(), text(), alignment()); } } diff --git a/src/ui/label.h b/src/ui/label.h index 460ac8a..45171b2 100644 --- a/src/ui/label.h +++ b/src/ui/label.h @@ -24,9 +24,15 @@ public: /// set the text displayed by the label void set_text(const char *text); + /// set the text alignment + void set_alignment(unsigned int alignment); + /// return the text displayed by the label inline std::string const &text() const { return label_text; } + /// text alignment + inline unsigned int alignment() const { return label_alignment; } + /// print label description virtual void print(size_t indent); @@ -39,6 +45,7 @@ protected: private: std::string label_text; + unsigned int label_alignment; }; } diff --git a/src/ui/menu.cc b/src/ui/menu.cc index 34aa96c..af9929c 100644 --- a/src/ui/menu.cc +++ b/src/ui/menu.cc @@ -23,7 +23,8 @@ Menu::Menu(Window *parent, const char *label) : Window(parent) menu_background = new Bitmap(this); menu_container = new Window(this); - menu_container->set_border(false); + menu_container->set_border(true); + menu_container->set_background(true); menu_container->set_label("container"); } @@ -91,12 +92,34 @@ void Menu::load() } else if (ini.got_key_string("command", strval)) { button->set_command(strval); + } else if (ini.got_key_string("align", strval)) { + aux::to_label(strval); + if (strval.compare("left") == 0) { + button->set_alignment(AlignLeft | AlignVCenter); + } else if (strval.compare("center") == 0) { + button->set_alignment(AlignCenter); + } else if (strval.compare("right") == 0) { + button->set_alignment(AlignRight | AlignVCenter); + } else { + ini.unknown_value(); + } } else { ini.unkown_key(); } } else if (ini.in_section("label")) { if (ini.got_key_string("text", strval)) { label->set_text(strval); + } else if (ini.got_key_string("align", strval)) { + aux::to_label(strval); + if (strval.compare("left") == 0) { + label->set_alignment(AlignLeft | AlignHCenter); + } else if (strval.compare("center") == 0) { + label->set_alignment(AlignCenter); + } else if (strval.compare("right") == 0) { + label->set_alignment(AlignRight | AlignHCenter); + } else { + ini.unknown_value(); + } } else { ini.unkown_key(); } @@ -116,7 +139,11 @@ void Menu::set_background(const char *texture) Label *Menu::add_label(char const * text) { - return new Label(menu_container, text); + Label *label = new Label(menu_container, text); + label->set_alignment(AlignCenter); + label->set_border(false); + label->set_font(ui::root()->font_large()); + return label; } Button *Menu::add_button(char const *text, char const *command) @@ -130,15 +157,15 @@ void Menu::resize() menu_background->size().assign(size()); float n = (float) menu_container->children().size(); - menu_container->set_size(2.0f * menu_element_width, n * (menu_element_height + menu_element_margin) + menu_element_height); - menu_container->set_location(menu_element_margin, (height() - menu_container->height()) / 2.0f); + 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.5f, menu_element_height * 0.5f + i * (menu_element_height + menu_element_margin)); + w->set_location(menu_element_width * 0.25f, menu_element_height * 0.5f + i * (menu_element_height + menu_element_margin)); i++; } } diff --git a/src/ui/paint.cc b/src/ui/paint.cc index 935cf92..ce5a5c2 100644 --- a/src/ui/paint.cc +++ b/src/ui/paint.cc @@ -93,6 +93,79 @@ void text_centered(math::Vector2f const &location, math::Vector2f const &size, s disable(GL_TEXTURE_2D); } +void text(math::Vector2f const &location, Font const *font, std::stringstream & textstream) +{ + using namespace render::gl; + render::Text::setfont(font->name().c_str(), font->width(), font->height()); + + // enable OpenGL textures + enable(GL_TEXTURE_2D); + + render::Text::draw(location.x, location.y, textstream); + + // disable texturing + disable(GL_TEXTURE_2D); +} + +void text(math::Vector2f const &location, math::Vector2f const &size, + Font const *font, + std::string const &text, + unsigned int align) +{ + unsigned int align_horizontal = (align & 0x000F); + if (!align_horizontal) + align_horizontal = AlignLeft; + + unsigned int align_vertical = (align & 0x00F0); + if (!align_vertical) + align_vertical = AlignTop; + + // apply text font + using namespace render::gl; + render::Text::setfont(font->name().c_str(), font->width(), font->height()); + + // enable OpenGL textures + enable(GL_TEXTURE_2D); + + // determine the width and height of the text + // FIXME support multiline text + float text_height = 1.0f * font->height(); + float text_width = (float) aux::text_strip(text).size() * font->width(); + + // calculate drawing position + math::Vector2f v(location); + + switch(align_horizontal) { + case AlignLeft: + v.x += font->width(); + break; + case AlignHCenter: + v.x += (size.x - text_width) / 2.0f; + break; + case AlignRight: + v.x += size.x - text_width - font->width(); + break; + } + + switch(align_vertical) { + case AlignTop: + v.y += font->height()*0.5f; + break; + case AlignVCenter: + v.y += (size.y - text_height) / 2.0f; + break; + case AlignBottom: + v.y += size.y - text_height - font->height()*0.5f; + break; + } + + render::Text::draw(v.x, v.y, text); + + // disable texturing + disable(GL_TEXTURE_2D); + +} + } } diff --git a/src/ui/paint.h b/src/ui/paint.h index b75290d..3128481 100644 --- a/src/ui/paint.h +++ b/src/ui/paint.h @@ -29,8 +29,12 @@ void rectangle(math::Vector2f const &location, math::Vector2f const &size); /// draw a rectangular bitmap void bitmap(math::Vector2f const &location, math::Vector2f const &size, std::string const &texture); -/// draw one line of centered text -void text_centered(math::Vector2f const &location, math::Vector2f const &size, std::string const &text, Font const *font); +/// draw text +void text(math::Vector2f const &location, math::Vector2f const &size, Font const *font, std::string const &text, + unsigned int align = AlignCenter); + +/// draw textstream +void text(math::Vector2f const &location, Font const *font, std::stringstream & textstream); } diff --git a/src/ui/ui.cc b/src/ui/ui.cc index 2b09938..bba9ea6 100644 --- a/src/ui/ui.cc +++ b/src/ui/ui.cc @@ -132,8 +132,15 @@ UI *root() void init() { con_print << "^BInitializing user interface..." << std::endl; - if (!global_ui) + + if (!global_ui) { global_ui = new UI(); + } else { + con_warn << "User interface already initialized!" << std::endl; + return; + } + + global_ui->load(); core::Func *func = core::Func::add("list_ui", func_list_ui); func->set_info("list user interface widgets"); @@ -178,11 +185,8 @@ UI::UI() : Window(0) // default fonts ui_font_small = new Font("gui", 12, 18); - ui_font_medium = new Font("gui", 14, 24); - ui_font_large = new Font("gui", 16, 30); + ui_font_large = new Font("gui", 14, 24); set_font(ui_font_small); - - load(); } UI::~UI() @@ -190,7 +194,6 @@ UI::~UI() delete ui_palette; delete ui_font_small; - delete ui_font_medium; delete ui_font_large; } @@ -315,7 +318,6 @@ void UI::add_window(Window *window) { Window::add_window(window); window->hide(); - window->set_font(ui_font_medium); } void UI::remove_window(Window *window) @@ -347,6 +349,7 @@ void UI::show_window(const char *label) ui_active_window->hide(); ui_active_window = window; ui_active_window->event_resize(); + ui_active_window->raise(); ui_active_window->show(); ui_focus = window; } else { @@ -364,23 +367,29 @@ void UI::hide_window() void UI::frame() { - ui_focus = find_focus(mouse_cursor); + ui_focus = event_focus(mouse_cursor); event_draw(); } -void UI::event_mousemove(float x, float y) +void UI::input_mouse(float x, float y) { mouse_cursor.assign(x, y); } -void UI::event_keypress(unsigned int key, unsigned int modifier) +void UI::input_key(bool pressed, unsigned int key, unsigned int modifier) { - ui_focus->keypress(key, modifier); + ui_focus->event_key(pressed, key, modifier); } -void UI::event_keyrelease(unsigned int key, unsigned int modifier) +bool UI::keypress(unsigned int key, unsigned int modifier) { - ui_focus->keyrelease(key, modifier); + return true; } +bool UI::keyrelease(unsigned int key, unsigned int modifier) +{ + return true; } + +} + diff --git a/src/ui/ui.h b/src/ui/ui.h index b3b2259..3a4ba75 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -40,29 +40,38 @@ public: /// return the active window Window *active() { return ui_active_window; } - /// handle mouse cursor - void event_mousemove(float x, float y); + /// mouse cursor input + void input_mouse(float x, float y); - /// handle keyboard input - void event_keypress(unsigned int key, unsigned int modifier); - void event_keyrelease(unsigned int key, unsigned int modifier); + /// keyboard input + void input_key(bool pressed, unsigned int key, unsigned int modifier); /// run a user interface frame void frame(); - /// return the widget that has the focus + /// return the widget which has the focus inline Widget *focus() { return ui_focus; } + /* -- Fonts ------------------------------------------------ */ + /// default small font + inline Font *font_small() { return ui_font_small; } + + /// default medium font + inline Font *font_large() { return ui_font_large; } + protected: Window *find_window(const char *label); virtual void add_window(Window *window); virtual void remove_window(Window *window); + /// handle keyboard input + virtual bool keypress(unsigned int key, unsigned int modifier); + virtual bool keyrelease(unsigned int key, unsigned int modifier); + private: Palette *ui_palette; Font *ui_font_small; - Font *ui_font_medium; Font *ui_font_large; Window *ui_active_window; diff --git a/src/ui/widget.cc b/src/ui/widget.cc index 4ff577c..b2c436d 100644 --- a/src/ui/widget.cc +++ b/src/ui/widget.cc @@ -71,6 +71,30 @@ Font const *Widget::font() const { } } +void Widget::lower() +{ + if (!parent()) + return; + + Children::iterator it = parent()->find_child(this); + if (it != parent()->children().end()) { + parent()->children().erase(it); + parent()->children().push_front(this); + } +} + +void Widget::raise() +{ + if (!parent()) + return; + + Children::iterator it = parent()->find_child(this); + if (it != parent()->children().end()) { + parent()->children().erase(it); + parent()->children().push_back(this); + } +} + void Widget::show() { widget_visible = true; @@ -81,6 +105,12 @@ void Widget::hide() widget_visible = false; } + +void Widget::set_visible(bool visible) +{ + widget_visible = visible; +} + void Widget::set_border(bool border) { widget_border = border; @@ -122,6 +152,11 @@ void Widget::set_size(float const w, float const h) widget_size.assign(w, h); } +void Widget::set_size(math::Vector2f const &size) +{ + widget_size.assign(size); +} + void Widget::set_width(float const w) { widget_size.x = w; @@ -159,30 +194,6 @@ void Widget::remove_child(Widget *child) } } -void Widget::raise() -{ - if (!parent()) - return; - - Children::iterator it = find_child(this); - if (it != parent()->children().end()) { - parent()->children().erase(it); - parent()->children().push_front(this); - } -} - -void Widget::lower() -{ - if (!parent()) - return; - - Children::iterator it = find_child(this); - if (it != parent()->children().end()) { - parent()->children().erase(it); - parent()->children().push_back(this); - } -} - void Widget::event_resize() { resize(); @@ -231,7 +242,7 @@ void Widget::draw_border() paint::border(global_location(), size()); } -Widget *Widget::find_focus(math::Vector2f const & pos) +Widget *Widget::event_focus(math::Vector2f const & pos) { // this widget is not visible if (!visible()) @@ -245,7 +256,7 @@ Widget *Widget::find_focus(math::Vector2f const & pos) for (Children::reverse_iterator rit = widget_children.rbegin(); rit != widget_children.rend(); ++rit) { Widget *w = (*rit); if (w->visible()) { - Widget *f = w->find_focus(pos - w->location()); + Widget *f = w->event_focus(pos - w->location()); if (f) return f; } @@ -261,13 +272,30 @@ bool Widget::has_focus() const return (root()->focus() == this); } -void Widget::mousemove(float x, float y) -{} +bool Widget::event_key(bool pressed, unsigned int key, unsigned int modifier) +{ + bool handled; + + if (pressed) { + handled = keypress(key, modifier); + } else { + handled = keyrelease(key, modifier); + } -void Widget::keypress(unsigned int key, unsigned int modifier) -{} + if (!handled && parent()) + handled = parent()->event_key(pressed, key, modifier); -void Widget::keyrelease(unsigned int key, unsigned int modifier) -{} + return handled; +} + +bool Widget::keypress(unsigned int key, unsigned int modifier) +{ + return false; +} + +bool Widget::keyrelease(unsigned int key, unsigned int modifier) +{ + return false; +} } diff --git a/src/ui/widget.h b/src/ui/widget.h index 54c8d96..2078134 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -17,6 +17,7 @@ #include "math/vector2f.h" #include "ui/font.h" #include "ui/palette.h" +#include "ui/definitions.h" #include "sys/sys.h" namespace ui { @@ -66,18 +67,30 @@ public: /* -- mutators --------------------------------------------- */ + /// raise the widget to the top of the widget stack + void raise(); + + /// lower the widget to the bottom of the widget stack + void lower(); + /// show the widget void show(); /// hide the widget void hide(); + /// set visibility + void set_visible(bool visible = true); + /// set location of the top-left corner void set_location(float const x, float const y); /// set the widgets width and height void set_size(float const w, float const h); + /// set the widgets width and height + void set_size(math::Vector2f const &size); + /// set the widgets width void set_width(float const w); @@ -106,24 +119,28 @@ public: /// draw event virtual void event_draw(); - /// handle mouse movement - virtual void mousemove(float x, float y); - - /// handle keyboard events - virtual void keypress(unsigned int key, unsigned int modifier); + /// keyboard event + virtual bool event_key(bool pressed, unsigned int key, unsigned int modifier); - virtual void keyrelease(unsigned int key, unsigned int modifier); + /// find the child widget with focus + /** @param pos local position within the widget + */ + Widget *event_focus(math::Vector2f const & pos); /// child widgets inline Children &children() { return widget_children; } - /// raise the widget to the top of the widget stack - void raise(); +protected: + /// handle keyboard events + /** returns true if the event was handled by this widget + */ + virtual bool keypress(unsigned int key, unsigned int modifier); - /// lower the widget to the bottom of the widget stack - void lower(); + /// handle keyboard events + /** returns true if the event was handled by this widget + */ + virtual bool keyrelease(unsigned int key, unsigned int modifier); -protected: /// draw the widget virtual void draw(); @@ -179,11 +196,6 @@ protected: /// remove a child widget void remove_child(Widget *child); - /// find the child widget with focus - /** @param pos local position within the widget - */ - Widget *find_focus(math::Vector2f const & pos); - private: bool widget_visible; bool widget_background; |