Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src/ui
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/ui
parentf8d1ee921c83b7b148883b3ee16e4ec9c776d6db (diff)
working button click
Diffstat (limited to 'src/ui')
-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
10 files changed, 232 insertions, 41 deletions
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);