/* ui/widget.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_WIDGET_H__ #define __INCLUDED_UI_WIDGET_H__ #include "SDL2/SDL.h" #include #include #include "auxiliary/functions.h" #include "math/color.h" #include "math/vector2f.h" #include "ui/font.h" #include "ui/palette.h" #include "ui/definitions.h" #include "sys/sys.h" namespace ui { class Widget { public: /// type definition for child widgets typedef std::list Children; /// types of custom events a widget can emit enum Event { EventNone = 0, EventButtonClicked = 1, EventListItemClicked = 2, EventListViewChanged = 3, EventSliderChanged = 4, EventScrollBarChanged = 5, EventWindowShow = 6, EventWindowHide = 7, EventClicked = 8, EventDoubleClicked = 9 }; /// create a new widget Widget(Widget *parent = 0); /// destroy a widget virtual ~Widget(); /// parent widget this widget belongs to inline Widget *parent() const { return widget_parent; } /* -- inspectors -------------------------------------------- */ /// child widgets inline Children &children() { return widget_children; } /// pixel coordinates of the top-left corner of this widget within its parent inline const math::Vector2f &location() const { return widget_location; } /// size of this widget in pixels inline const math::Vector2f &size() const { return widget_size; } /// x coordinate of the left of the widget /** * @see location() */ inline const float left() const { return widget_location.x(); } /// x coordinate of the right of the widget /** * @see location() * @see size() */ inline const float right() const { return widget_location.x() + widget_size.width(); } /// y coordinate of the top of the widget /** * @see location() */ inline const float top() const { return widget_location.y(); } /// y coordinate of the bottom of the widget /** * @see location() * @see size() */ inline const float bottom() const { return widget_location.y() + widget_size.height(); } /// width of the widget in pixels /** * @see size() */ inline const float width() const { return widget_size.width(); } /// height of the widget in pixels /** * @see size() */ inline const float height() const { return widget_size.height(); } /// widget label inline const std::string &label() const { return widget_label; } /// true if this widget will draw a background inline const bool background() const { return widget_background; } /// true if this widget will draw a border inline const bool border() const { return widget_border; } /// true if this widget is visible inline const bool visible() const { return widget_visible; } /// true if this widget is not visible inline const bool hidden() const { return !widget_visible; } /// true if the widget is enabled inline const bool enabled() const { return widget_enabled; } /// true if the widget is disabled inline const bool disabled() const { return !widget_enabled; } /// the palette used to draw this widget const Palette *palette() const; /// the font used to draw this widget const Font *font() const; /// return true if the widget has input focus bool has_input_focus() const; /// returns true if the widget has mouse focus bool has_mouse_focus() const; /// return true of the widget is a child widget bool is_child(const Widget *widget) const; /// return the next sibling Widget *next_sibling(); /* -- 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 virtual void show(); /// hide the widget virtual void hide(); /// set visibility void set_visible(const bool visible = true); /// enable or disable the widget virtual void enable(); /// enable or disable the widget virtual void disable(); ///set enabled or disabled state void set_enabled(const bool enabled = true); /// set input focus void set_focus(); /// set the widget geometry void set_geometry(const float x, const float y, const float w, const float h); /// set the widget geometry void set_geometry(const math::Vector2f &location, const math::Vector2f &size); /// set location of the top-left corner, relative to the parent void set_location(const float x, const float y); /// set location of the top-left corner, relative to the parent void set_location(const math::Vector2f &location); /// set the widgets width and height void set_size(const float w, const float h); /// set the widgets width and height void set_size(const math::Vector2f &size); /// set the widgets width void set_width(const float w); /// set the widgets height void set_height(const float h); /// set the widgets palette void set_palette(const Palette *palette); /// set the widgets font void set_font(const Font *font); /// set the widgets label void set_label(const std::string &label); /// set the widgets label void set_label(const char *label); /// enable or disable widget border void set_border(const bool border = true); /// enable or disable widget background void set_background(const bool background = true); /* -- event distributors --------------------------------------- */ /** * @brief calls the resize event handler and sends the event to all child widgets * @see resize **/ void event_resize(); /** * @brief calls the draw event handler and sends the event to all child widgets * @see draw **/ void event_draw(); /** * @brief calls the key event handlers and sends unhandled keys to the parent widget * @see on_keypress * @see on_keyrelease **/ bool event_key(const bool pressed, const int key, const unsigned int modifier); /** * @brief calls the on_mousepress and on_mouserelease event handlers and sends undhandled events to the parent widget * @see on_mousepress * @see on_mouserelease * */ bool event_mouse_button(const bool pressed, const unsigned int button); /** * @brief calls the on_mousewheel event handlers and sends unhandled events to the parent widget * @see on_mousewheel * */ bool event_mouse_wheel(const math::Vector2f & direction); /** * @brief calls the mouse event handlers and sends unhandled keys to the parent widget * @see on_mousemove * @see on_mouseover **/ void event_mouse(const math::Vector2f & cursor); /** * @brief calls the custom event handler and sends unhandled events to the parent widget * @see on_emit **/ bool event_emit(Widget *sender, const Event event, void *data = 0); /** * @brief emit a custom event * */ inline void emit(const Event event, void *data=0) { event_emit(this, event, data); } protected: /// find the widget that has input focus virtual Widget *find_input_focus(); /// find widget that has mouse focus /** @param cursor mouse cursor position relative to this widget's location */ Widget *find_mouse_focus(const math::Vector2f & cursor); /// find a visible widget Widget *find_visible_child(const Widget *widget); /// list widget content size_t list(const size_t indent, const bool visible_only = false) const; /// print widget description virtual void print(const size_t indent) const; /// true of this sibling has local focus inline bool focus() const { return widget_focus; } /* -- coordinate mapping ----------------------------------- */ /// map local widget location to global location inline math::Vector2f global_location() { math::Vector2f v(widget_location); Widget *parent = widget_parent; while (parent) { v += parent->location(); parent = parent->parent(); } return v; } /// map local coordinates to global coordinates inline math::Vector2f to_global_coords(const math::Vector2f &local) { math::Vector2f v(local); Widget *parent = widget_parent; do { v += parent->location(); parent = parent->parent(); } while (parent); return v; } /// map global coordinates to local coordinates inline math::Vector2f to_local_coords(const math::Vector2f &global) { math::Vector2f v(global); Widget *parent = this; while (parent) { v -= parent->location(); parent = parent->parent(); } return v; } /* -- event handlers --------------------------------------- */ /// called when the mouse receives mouse movement virtual void on_mousemove(const math::Vector2f &cursor); /// called when the mouse enters the widget virtual void on_mouseover(const math::Vector2f &cursor); /** * @brief mouse button press event handler * */ virtual bool on_mousepress(const unsigned int button); /** * @brief mouse button release event handler * */ virtual bool on_mouserelease(const unsigned int button); /// called when the scrollwheel is used virtual bool on_mousewheel(const math::Vector2f & direction); /// called when the widget receives a key press virtual bool on_keypress(const int key, const unsigned int modifier); /// called when the widget receives a key release virtual bool on_keyrelease(const int key, const unsigned int modifier); /// called when the widget receives a custom event virtual bool on_emit(Widget *sender, const Event event, void *data=0); /* -- draw functions --------------------------------------- */ /// resize event virtual void resize(); /// draw the widget virtual void draw(); /// draw the widget background virtual void draw_background(); /// draw the widget border virtual void draw_border(); /// draw denug state virtual void draw_debug(); /// add a child widget virtual void add_child(Widget *child); /// remove a child widget virtual void remove_child(Widget *child); /// remove all child widgets virtual void remove_children(); private: bool widget_visible; bool widget_background; bool widget_border; bool widget_focus; bool widget_enabled; math::Vector2f widget_location; math::Vector2f widget_size; std::string widget_label; Children widget_children; const Palette *widget_palette; const Font *widget_font; Widget *widget_parent; Children::iterator find_child(Widget *child); }; } #endif // __INCLUDED_UI_WIDGET_H__