diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/client/client.cc | 37 | ||||
-rw-r--r-- | src/client/client.h | 8 | ||||
-rw-r--r-- | src/client/input.cc | 9 | ||||
-rw-r--r-- | src/client/video.cc | 2 | ||||
-rw-r--r-- | src/client/view.cc | 41 | ||||
-rw-r--r-- | src/core/application.cc | 7 | ||||
-rw-r--r-- | src/core/application.h | 3 | ||||
-rw-r--r-- | src/ui/button.cc | 31 | ||||
-rw-r--r-- | src/ui/button.h | 7 | ||||
-rw-r--r-- | src/ui/menu.cc | 24 | ||||
-rw-r--r-- | src/ui/menu.h | 10 | ||||
-rw-r--r-- | src/ui/palette.cc | 10 | ||||
-rw-r--r-- | src/ui/palette.h | 5 | ||||
-rw-r--r-- | src/ui/ui.cc | 63 | ||||
-rw-r--r-- | src/ui/ui.h | 17 | ||||
-rw-r--r-- | src/ui/widget.cc | 48 | ||||
-rw-r--r-- | src/ui/widget.h | 58 |
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); |