Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-10-07 17:14:27 +0000
committerStijn Buys <ingar@osirion.org>2008-10-07 17:14:27 +0000
commitf54bd48a884e4e3c95818f042a4b2418a6e070a4 (patch)
tree73e82729a2f97b58e94ffd6944ac1ad47bf8314e /src
parentf8d1ee921c83b7b148883b3ee16e4ec9c776d6db (diff)
working button click
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am3
-rw-r--r--src/client/client.cc37
-rw-r--r--src/client/client.h8
-rw-r--r--src/client/input.cc9
-rw-r--r--src/client/video.cc2
-rw-r--r--src/client/view.cc41
-rw-r--r--src/core/application.cc7
-rw-r--r--src/core/application.h3
-rw-r--r--src/ui/button.cc31
-rw-r--r--src/ui/button.h7
-rw-r--r--src/ui/menu.cc24
-rw-r--r--src/ui/menu.h10
-rw-r--r--src/ui/palette.cc10
-rw-r--r--src/ui/palette.h5
-rw-r--r--src/ui/ui.cc63
-rw-r--r--src/ui/ui.h17
-rw-r--r--src/ui/widget.cc48
-rw-r--r--src/ui/widget.h58
18 files changed, 300 insertions, 83 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 014d2cd..9def3fe 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -33,7 +33,8 @@ osirion_SOURCES = osirion.cc
EXTRA_osirion_SOURCES = osirion-res.rc
osirion_DEPENDENCIES = $(ICON_CLIENT) $(top_builddir)/src/core/libcore.la \
$(top_builddir)/src/audio/libaudio.la $(top_builddir)/src/render/librender.la \
- $(top_builddir)/src/client/libclient.la $(top_builddir)/src/game/libgame.la
+ $(top_builddir)/src/ui/libui.la $(top_builddir)/src/client/libclient.la \
+ $(top_builddir)/src/game/libgame.la
osirion_CFLAGS = $(LIBSDL_CFLAGS) $(GL_CFLAGS) $(GLUT_CFLAGS)
osirion_LDADD = $(top_builddir)/src/game/libgame.la $(top_builddir)/src/ui/libui.la \
$(top_builddir)/src/client/libclient.la $(top_builddir)/src/audio/libaudio.la \
diff --git a/src/client/client.cc b/src/client/client.cc
index b218166..e9bfba8 100644
--- a/src/client/client.cc
+++ b/src/client/client.cc
@@ -168,9 +168,8 @@ void Client::run()
if ((d > 0)) {
if (d >= client_frame_lenght) {
float elapsed = (float)(d) / 1000.f;
- core::Application::frame(elapsed);
- video::frame(elapsed);
- input::frame(elapsed);
+
+ frame(elapsed);
client_previous_timestamp = client_current_timestamp;
} else {
@@ -183,6 +182,30 @@ void Client::run()
}
+void Client::frame(float seconds)
+{
+ core::Application::frame(seconds);
+
+ if (!core::application()->connected()) {
+ // load the intro if nothing is running
+ if (core::application()->load("intro")) {
+ core::application()->connect("");
+ }
+ // if all fails, show the console
+ if (!core::application()->connected() && !console()->visible()) {
+ console()->toggle();
+ }
+ } else {
+ // show the main menu on non-interactive modules
+ if (!core::game()->interactive() && !ui::root()->active()) {
+ ui::root()->show_window("main");
+ }
+ }
+
+ video::frame(seconds);
+ input::frame(seconds);
+}
+
void Client::shutdown()
{
con_print << "^BShutting down client..." << std::endl;
@@ -258,8 +281,14 @@ void Client::notify_zoneclear(core::Zone *zone)
void Client::notify_disconnect()
{
// FIXME unload sounds
-
render::unload();
+ view::clear_zone(0);
+}
+
+void Client::notify_connect()
+{
+ ui::root()->hide_window();
+ view::clear_zone(0);
}
} // namespace client
diff --git a/src/client/client.h b/src/client/client.h
index 6da5c5f..dc4f05f 100644
--- a/src/client/client.h
+++ b/src/client/client.h
@@ -40,8 +40,16 @@ public:
/// clear zone notification
virtual void notify_zoneclear(core::Zone *zone);
+ /// connect notification
+ virtual void notify_connect();
+
/// disconnect notification
virtual void notify_disconnect();
+
+protected:
+ /// run a client frame
+ virtual void frame(float seconds);
+
};
diff --git a/src/client/input.cc b/src/client/input.cc
index d6f83f9..41f79fe 100644
--- a/src/client/input.cc
+++ b/src/client/input.cc
@@ -527,6 +527,9 @@ void key_pressed(Key *key)
if (key->sym() < 512)
console()->keypressed(translate_keysym(key->sym(), keyboard_modifiers));
+ } else if (ui::root()->active()) {
+ ui::root()->event_keypress(key->sym(), keyboard_modifiers);
+
} else if (chat::visible()) {
// send key events to the chat box
if (key->sym() < 512)
@@ -555,6 +558,10 @@ void key_pressed(Key *key)
void key_released(Key *key)
{
+ if (ui::root()->active()) {
+ ui::root()->event_keyrelease(key->sym(), keyboard_modifiers);
+ }
+
if (core::application()->connected() && core::localcontrol()) {
if ((key->sym() == 512 + SDL_BUTTON_LEFT) && targets::hover() && (key->waspressed() <= (input_mousedelay->value()/1000.0f) ) ) {
@@ -707,7 +714,7 @@ void frame(float seconds)
mouse_x = event.motion.x;
mouse_y = event.motion.y;
mouse_lastmoved = client()->time();
- ui::root()->set_mouse_cursor((float) mouse_x, (float) mouse_y);
+ ui::root()->event_mousecursor((float) mouse_x, (float) mouse_y);
break;
case SDL_MOUSEBUTTONDOWN:
diff --git a/src/client/video.cc b/src/client/video.cc
index 4046260..123bd88 100644
--- a/src/client/video.cc
+++ b/src/client/video.cc
@@ -74,7 +74,7 @@ void reset()
// resize user interface
if (ui::root()) {
ui::root()->set_size((float) width, (float) height);
- ui::root()->resize_event();
+ ui::root()->event_resize();
}
// reset the view
diff --git a/src/client/view.cc b/src/client/view.cc
index 7f9efa1..50b5b61 100644
--- a/src/client/view.cc
+++ b/src/client/view.cc
@@ -57,6 +57,7 @@ void init()
draw_devinfo = core::Cvar::get("draw_devinfo", "0", core::Cvar::Archive);
draw_devinfo->set_info("[bool] draw developer information");
+ // FIXME integrate with libui
draw_ui = core::Cvar::get("draw_ui", "1", core::Cvar::Archive);
draw_ui->set_info("[bool] draw the user interface");
@@ -107,7 +108,7 @@ void clear_zone(core::Zone *zone)
zone->set_sky_texture(0);
}
}
-
+/*
void draw_loader()
{
using namespace render;
@@ -153,7 +154,7 @@ void draw_banner()
gl::end();
}
-
+*/
/*
FIXME should be merged with the render passes
and in the bbox pass
@@ -777,20 +778,6 @@ void frame(float seconds)
render::Stats::clear();
- // load the intro
- if (!core::application()->connected()) {
- if (core::application()->load("intro")) {
- current_zone = 0;
- core::application()->connect("");
- }
- } else {
- /*
- if (!core::game()->interactive() && !ui::root()->active()) {
- ui::root()->show_window("main");
- }
- */
- }
-
if (core::application()->connected() && core::game()->serverframetime()) {
if (core::localplayer()->zone() != current_zone) {
if (current_zone)
@@ -803,10 +790,6 @@ void frame(float seconds)
if (targets::current()) // draw target docks etc
draw_entity_world_target(targets::current());
- } else {
- // FIXME this should be handle through a module_disconnect signal
- // this should to the same as calling clear_zone(0)
- current_zone = 0;
}
// switch to orthographic projection to draw the GUI
@@ -820,27 +803,15 @@ void frame(float seconds)
// draw the user interface
gl::color(1.0f, 1.0f, 1.0f, 1.0f);
gl::disable(GL_TEXTURE_2D);
+ gl::enable(GL_BLEND);
- ui::frame();
+ ui::root()->frame();
// draw the hud - TODO move as much as possible into ui::
- gl::enable(GL_BLEND);
+
gl::enable(GL_TEXTURE_2D);
gl::color(1.0f, 1.0f, 1.0f, 1.0f);
- if (!core::application()->connected()) {
- // draw the loader bitmap
- draw_loader();
-
- // force console on if not connected
- if (!console()->visible())
- console()->toggle();
-
- } /*else if (!core::game()->interactive()) {
- // draw the banner bitmap
- draw_banner();
- }*/
-
// draw text elements
if (draw_ui->value()) {
Text::setfont("gui", 12, 18);
diff --git a/src/core/application.cc b/src/core/application.cc
index c02db9b..3f08a36 100644
--- a/src/core/application.cc
+++ b/src/core/application.cc
@@ -348,12 +348,15 @@ void Application::connect(std::string const &host)
if (!application_game->running()) {
delete application_game;
application_game = 0;
+ } else {
+ notify_connect();
}
} else {
application_game = new GameServer();
if (application_game->running()) {
con_print << "^BConnected to local game.\n";
+ notify_connect();
} else {
delete application_game;
application_game = 0;
@@ -544,4 +547,8 @@ void Application::notify_disconnect()
}
+void Application::notify_connect()
+{
+}
+
}
diff --git a/src/core/application.h b/src/core/application.h
index 3769941..9ac82f7 100644
--- a/src/core/application.h
+++ b/src/core/application.h
@@ -75,6 +75,9 @@ public:
/// zone clear notification
virtual void notify_zoneclear(Zone *zone);
+ /// connect notification
+ virtual void notify_connect();
+
/// disconnect notification
virtual void notify_disconnect();
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 <string>
#include <list>
@@ -21,6 +23,9 @@ namespace ui {
class Widget {
public:
+ /// type definition for child widgets
+ typedef std::list<Widget *> 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<Widget *> 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);