From f54bd48a884e4e3c95818f042a4b2418a6e070a4 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Tue, 7 Oct 2008 17:14:27 +0000 Subject: working button click --- src/ui/button.cc | 31 ++++++++++++++++++++++++++- src/ui/button.h | 7 +++++++ src/ui/menu.cc | 24 ++++++++++++++------- src/ui/menu.h | 10 +++++++-- src/ui/palette.cc | 10 +++++++-- src/ui/palette.h | 5 +++++ src/ui/ui.cc | 63 ++++++++++++++++++++++++++++++++++++++++++++----------- src/ui/ui.h | 17 +++++++++++---- src/ui/widget.cc | 48 ++++++++++++++++++++++++++++++++++++++---- src/ui/widget.h | 58 +++++++++++++++++++++++++++++++++++++++++++------- 10 files changed, 232 insertions(+), 41 deletions(-) (limited to 'src/ui') diff --git a/src/ui/button.cc b/src/ui/button.cc index 73a349e..0910995 100644 --- a/src/ui/button.cc +++ b/src/ui/button.cc @@ -4,9 +4,11 @@ the terms of the GNU General Public License version 2 */ -#include "ui/button.h" #include "auxiliary/functions.h" +#include "render/primitives.h" #include "sys/sys.h" +#include "ui/button.h" +#include "core/commandbuffer.h" namespace ui { @@ -44,6 +46,33 @@ void Button::draw() Label::draw(); } +void Button::draw_text() +{ + if (!text().size()) + return; + + if (palette()) { + if (has_focus()) + render::gl::color(palette()->highlight()); + else + render::gl::color(palette()->foreground()); + } + + render::primitives::text_centered(global_location(), size(), text()); +} + +void Button::event_keypress(unsigned int key, unsigned int modifier) +{ + +} + +void Button::event_keyrelease(unsigned int key, unsigned int modifier) +{ + if (key == 512 + SDL_BUTTON_LEFT) { + core::cmd() << button_command << std::endl; + } +} + } diff --git a/src/ui/button.h b/src/ui/button.h index a9fee13..bdf310b 100644 --- a/src/ui/button.h +++ b/src/ui/button.h @@ -25,9 +25,16 @@ public: /// print button description virtual void print(size_t indent); + /// handle keyboard input + virtual void event_keypress(unsigned int key, unsigned int modifier); + virtual void event_keyrelease(unsigned int key, unsigned int modifier); + protected: virtual void draw(); + /// draw the button + virtual void draw_text(); + private: std::string button_command; }; diff --git a/src/ui/menu.cc b/src/ui/menu.cc index 9485e82..34aa96c 100644 --- a/src/ui/menu.cc +++ b/src/ui/menu.cc @@ -12,23 +12,25 @@ namespace ui { -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) { set_label(label); set_border(false); + menu_element_width = 256.0f; + menu_element_height = 48.0f; + menu_element_margin = 24.0f; + menu_background = new Bitmap(this); menu_container = new Window(this); + menu_container->set_border(false); menu_container->set_label("container"); } Menu::~Menu() { + // menu_container and menu_background are deleted by Widget::~Widget() } void Menu::load() @@ -73,6 +75,12 @@ 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; } else { ini.unkown_key(); } @@ -122,15 +130,15 @@ void Menu::resize() 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); + 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); // 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(element_width, element_height); - w->set_location(element_width * 0.5f, element_height * 0.5f + i * (element_height + element_margin)); + 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)); i++; } } diff --git a/src/ui/menu.h b/src/ui/menu.h index 422b23f..376e069 100644 --- a/src/ui/menu.h +++ b/src/ui/menu.h @@ -25,17 +25,23 @@ public: /// load a menu from ini/menus/label.ini void load(); + void set_background(const char *texture); + Label *add_label(char const * text=0); - Button *add_button(char const *text=0, char const *command=0); - void set_background(const char *texture); + Button *add_button(char const *text=0, char const *command=0); protected: virtual void resize(); private: + float menu_element_width; + float menu_element_height; + float menu_element_margin; + Bitmap *menu_background; Window *menu_container; + }; } diff --git a/src/ui/palette.cc b/src/ui/palette.cc index 04d7f00..cb6ee91 100644 --- a/src/ui/palette.cc +++ b/src/ui/palette.cc @@ -11,8 +11,9 @@ namespace ui { Palette::Palette() { - palette_foreground.assign(1.0f, 1.0f); - palette_background.assign(0.8f, 0.5f); + palette_foreground.assign(0.8f, 1.0f); + palette_highlight.assign(1.0f, 1.0f); + palette_background.assign(0.5f, 0.5f); palette_border.assign(0.0f, 8.0f, 0.0f); } @@ -25,6 +26,11 @@ void Palette::set_foreground(math::Color const &color) palette_foreground.assign(color); } +void Palette::set_highlight(math::Color const &color) +{ + palette_highlight.assign(color); +} + void Palette::set_background(math::Color const &color) { palette_background.assign(color); diff --git a/src/ui/palette.h b/src/ui/palette.h index 1b9eeb8..edd738f 100644 --- a/src/ui/palette.h +++ b/src/ui/palette.h @@ -20,12 +20,16 @@ public: void set_foreground(math::Color const &color); + void set_highlight(math::Color const &color); + void set_background(math::Color const &color); void set_border(math::Color const &color); inline math::Color const &foreground() const { return palette_foreground; } + inline math::Color const &highlight() const { return palette_highlight; } + inline math::Color const &background() const { return palette_background; } inline math::Color const &border() const { return palette_border; } @@ -33,6 +37,7 @@ public: private: math::Color palette_foreground; + math::Color palette_highlight; math::Color palette_background; math::Color palette_border; }; diff --git a/src/ui/ui.cc b/src/ui/ui.cc index ac5c0b8..0700c37 100644 --- a/src/ui/ui.cc +++ b/src/ui/ui.cc @@ -29,6 +29,12 @@ void func_list_ui(std::string const &args) } } +void func_ui_restart(std::string const &args) +{ + if (global_ui) { + global_ui->load(); + } +} void func_list_menu(std::string const &args) { @@ -44,7 +50,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; + con_print << " ui restart reload user interface files" << std::endl; } void func_ui(std::string const &args) @@ -78,6 +84,17 @@ void func_ui(std::string const &args) } } +void help_menu() +{ + con_print << "^Bmenu functions" << std::endl; + con_print << " menu help show this help" << std::endl; + con_print << " menu list list available menus" << std::endl; + con_print << " menu hide hide the current menu" << std::endl; + con_print << " menu close close the current menu" << std::endl; + con_print << " menu [name] show a menu" << std::endl; + root()->list_menus(); +} + void func_menu(std::string const &args) { if (!global_ui) { @@ -125,10 +142,13 @@ void init() func->set_info("list available menus"); func = core::Func::add("ui", func_ui); - func->set_info("[command] [options] user interface subcommands"); + func->set_info("[command] user interface functions"); + + func = core::Func::add("ui_restart", func_ui_restart); + func->set_info("[command] [options] reload user interface files"); func = core::Func::add("menu", func_menu); - func->set_info("[hide|close|menuname] show or hide a menu"); + func->set_info("[command] menu functions"); } void shutdown() @@ -146,12 +166,6 @@ void shutdown() } } -void frame() -{ - if (global_ui) - global_ui->draw_event(); -} - UI::UI() : Window(0) { set_palette(new Palette()); @@ -170,6 +184,7 @@ void UI::load() remove_child(window); } window_children.clear(); + ui_focus = this; ui_active_window = 0; std::string filename("ui"); @@ -224,6 +239,9 @@ void UI::load() if (ini.got_key_color("foreground", color)) { widget_palette->set_foreground(color); continue; + } else if (ini.got_key_color("highlight", color)) { + widget_palette->set_highlight(color); + continue; } else if (ini.got_key_color("background", color)) { widget_palette->set_background(color); continue; @@ -271,8 +289,10 @@ void UI::add_window(Window *window) void UI::remove_window(Window *window) { - if (ui_active_window == window) + if (ui_active_window == window) { ui_active_window = 0; + ui_focus = this; + } Window::remove_window(window); } @@ -285,8 +305,9 @@ void UI::show_window(char const *label) if (ui_active_window) ui_active_window->hide(); ui_active_window = (*it); - ui_active_window->resize_event(); + ui_active_window->event_resize(); ui_active_window->show(); + ui_focus = this; return; } } @@ -302,9 +323,27 @@ void UI::hide_window() } } -void UI::set_mouse_cursor(float x, float y) +void UI::frame() +{ + ui_focus = find_focus(mouse_cursor); + event_draw(); +} + +void UI::event_mousecursor(float x, float y) { mouse_cursor.assign(x, y); } +void UI::event_keypress(unsigned int key, unsigned int modifier) +{ + if (ui_focus != this) + ui_focus->event_keypress(key, modifier); +} + +void UI::event_keyrelease(unsigned int key, unsigned int modifier) +{ + if (ui_focus != this) + ui_focus->event_keyrelease(key, modifier); +} + } diff --git a/src/ui/ui.h b/src/ui/ui.h index 527d959..28b6997 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -39,8 +39,18 @@ public: /// return the active window Window *active() { return ui_active_window; } - /// set mouse cursor position - void set_mouse_cursor(float x, float y); + /// handle mouse cursor + virtual void event_mousecursor(float x, float y); + + /// handle keyboard input + virtual void event_keypress(unsigned int key, unsigned int modifier); + virtual void event_keyrelease(unsigned int key, unsigned int modifier); + + /// run a user interface frame + void frame(); + + /// return the widget that has the focus + inline Widget *focus() { return ui_focus; } protected: virtual void add_window(Window *window); @@ -48,6 +58,7 @@ protected: private: Window *ui_active_window; + Widget *ui_focus; math::Vector2f mouse_cursor; }; @@ -57,8 +68,6 @@ void init(); /// shutdown the user interface void shutdown(); -void frame(); - /// the global root window UI *root(); diff --git a/src/ui/widget.cc b/src/ui/widget.cc index 068d60f..506d1e7 100644 --- a/src/ui/widget.cc +++ b/src/ui/widget.cc @@ -7,6 +7,7 @@ #include "auxiliary/functions.h" #include "render/primitives.h" #include "sys/sys.h" +#include "ui/ui.h" #include "ui/widget.h" namespace ui { @@ -134,11 +135,11 @@ void Widget::remove_child(Widget *child) } } -void Widget::resize_event() +void Widget::event_resize() { resize(); for (Children::iterator it = widget_children.begin(); it != widget_children.end(); it++) { - (*it)->resize_event(); + (*it)->event_resize(); } } @@ -146,7 +147,7 @@ void Widget::resize() { } -void Widget::draw_event() +void Widget::event_draw() { if (!widget_visible) return; @@ -154,7 +155,7 @@ void Widget::draw_event() draw(); for (Children::iterator it = widget_children.begin(); it != widget_children.end(); it++) { if ((*it)->visible()) - (*it)->draw_event(); + (*it)->event_draw(); } } @@ -184,4 +185,43 @@ void Widget::draw_border() render::primitives::border(global_location(), size()); } +Widget *Widget::find_focus(math::Vector2f const & pos) +{ + // this widget is not visible + if (!visible()) + return 0; + + // pos is outside this + if ((pos.x < 0) || (pos.y < 0) || (pos.x > size().x) || (pos.y > size().y)) + return 0; + + // reverse-iterate children + 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()); + if (f) + return f; + } + + } + + // no child has focus + return this; +} + +bool Widget::has_focus() const +{ + return (root()->focus() == this); +} + +void Widget::event_mousecursor(float x, float y) +{} + +void Widget::event_keypress(unsigned int key, unsigned int modifier) +{} + +void Widget::event_keyrelease(unsigned int key, unsigned int modifier) +{} + } diff --git a/src/ui/widget.h b/src/ui/widget.h index fcb8e6b..13f392e 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -7,6 +7,8 @@ #ifndef __INCLUDED_UI_WIDGET_H__ #define __INCLUDED_UI_WIDGET_H__ +#include "SDL/SDL.h" + #include #include @@ -21,6 +23,9 @@ namespace ui { class Widget { public: + /// type definition for child widgets + typedef std::list Children; + /// create a new widget Widget(Widget *parent=0); @@ -28,8 +33,6 @@ public: virtual ~Widget(); /* -- inspectors -------------------------------------------- */ - inline bool visible() const { return widget_visible; } - inline math::Vector2f &location() { return widget_location; } inline math::Vector2f &size() { return widget_size; } @@ -48,10 +51,14 @@ public: inline bool border() const { return widget_border; } - inline bool background() { return widget_background; } + inline bool background() const { return widget_background; } inline Widget *parent() { return widget_parent; } + inline bool visible() const { return widget_visible; } + + bool has_focus() const; + /* -- mutators --------------------------------------------- */ @@ -87,13 +94,18 @@ public: void set_background(bool background); /// resize event - virtual void resize_event(); + virtual void event_resize(); /// draw event - virtual void draw_event(); + virtual void event_draw(); - /// type definition for child widgets - typedef std::list Children; + /// handle mouse cursor + virtual void event_mousecursor(float x, float y); + + /// handle keyboard input + virtual void event_keypress(unsigned int key, unsigned int modifier); + + virtual void event_keyrelease(unsigned int key, unsigned int modifier); /// child widgets inline Children &children() { return widget_children; } @@ -117,8 +129,31 @@ protected: /// print widget description virtual void print(size_t indent); + /// map local coordinates to global coordinates + inline math::Vector2f to_global_coords(math::Vector2f const &local) + { + math::Vector2f v(local); + Widget *parent = widget_parent; + do { + v -= parent->location(); + parent = parent->widget_parent; + } while(parent); + return v; + } + + /// map global coordinates to local coordinates + inline math::Vector2f to_local_coords(math::Vector2f const &global) { + math::Vector2f v(global); + Widget *parent = this; + while (parent) { + v += parent->location(); + parent = parent->widget_parent; + } + return v; + } + /// map local widget location to global location - inline math::Vector2f global_location() { + inline math::Vector2f global_location() const { math::Vector2f v(widget_location); Widget *parent = widget_parent; while (parent) { @@ -131,7 +166,13 @@ 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); + Palette *widget_palette; + private: bool widget_visible; bool widget_background; @@ -141,6 +182,7 @@ private: std::string widget_label; Children widget_children; + Widget *widget_parent; Children::iterator find_child(Widget *child); -- cgit v1.2.3