src/widget/widget.h
branchcpp_gui
changeset 6264 9fc3b5467396
child 6265 7054c910251d
equal deleted inserted replaced
6263:19dab6a68886 6264:9fc3b5467396
       
     1 /* $Id$ */
       
     2 
       
     3 #ifndef WIDGET_H
       
     4 #define WIDGET_H
       
     5 
       
     6 
       
     7 #include <list>
       
     8 #include <map>
       
     9 #include "../macros.h"
       
    10 #include "../string.h"
       
    11 #include "../order.h"
       
    12 #include "../rail.h"
       
    13 #include "../airport.h"
       
    14 #include "../misc/rect.hpp"
       
    15 #include "../misc/countedptr.hpp"
       
    16 
       
    17 #include "window_event_base.h"
       
    18 
       
    19 enum FrameFlags;
       
    20 
       
    21 namespace gui {
       
    22 
       
    23 struct Widget;
       
    24 typedef CCountedPtr<Widget> WidgetPtr;
       
    25 
       
    26 struct CompositeWidget;
       
    27 typedef CCountedPtr<CompositeWidget> CompositeWidgetPtr;
       
    28 
       
    29 typedef int32 WidgetId;
       
    30 
       
    31 struct Widget : public SimpleCountedObject {
       
    32 	struct Handler {
       
    33 		EventHandlerDelegatePtr m_delegate;
       
    34 
       
    35 		Handler(EventHandlerDelegate *d)
       
    36 			: m_delegate(d)
       
    37 		{}
       
    38 	};
       
    39 	typedef std::list<Handler> Handlers;
       
    40 
       
    41 	CompositeWidget *m_container;       ///< widget container (can be any panel or window)
       
    42 	WidgetId        m_id;               ///< Widget id in its container
       
    43 	Rect16          m_rect;             ///< The position offsets relative to the container
       
    44 	uint16          m_data;             ///< The String/Image or special code (list-matrices) of a widget
       
    45 	byte            m_display_flags;    ///< Resize direction, alignment, etc. during resizing, see @ResizeFlags
       
    46 	byte            m_color;            ///< Widget color, see docs/ottd-colourtext-palette.png
       
    47 	bool            m_is_closing : 1;   ///< Widget was logically destroyed
       
    48 	bool            m_dont_clip : 1;    ///< should not be clipped by parent (container)
       
    49 	StringID        m_tooltips;         ///< Tooltips that are shown when right clicking on a widget
       
    50 	Handlers        m_handlers;         ///< dynamically registered event handlers
       
    51 
       
    52 	Widget()
       
    53 		: m_container(NULL), m_id(0), m_rect(), m_data(0), m_display_flags(0), m_color(0)
       
    54 		, m_is_closing(false), m_tooltips(0)
       
    55 	{}
       
    56 
       
    57 	Widget(CompositeWidget *container, WidgetId id, byte display_flags, byte color, const Rect16 &rect, StringID tooltips)
       
    58 		: m_container(container)
       
    59 		, m_id(id)
       
    60 		, m_rect(rect)
       
    61 		, m_data(0)
       
    62 		, m_display_flags(display_flags)
       
    63 		, m_color(color)
       
    64 		, m_is_closing(false)
       
    65 		, m_dont_clip(false)
       
    66 		, m_tooltips(tooltips)
       
    67 	{}
       
    68 
       
    69 	int16 Left() const;
       
    70 	int16 Top() const;
       
    71 	int16 Right() const;
       
    72 	int16 Bottom() const;
       
    73 	int16 Width() const;
       
    74 	int16 Height() const;
       
    75 	const Point16& TopLeft() const;
       
    76 	const Point16& BottomRight() const;
       
    77 	Point16 Size() const;
       
    78 	Point16 CenterPt() const;
       
    79 	const Rect16& GetRect() const;
       
    80 
       
    81 	void SetLeft(int16 val);
       
    82 	void SetTop(int16 val);
       
    83 	void SetRight(int16 val);
       
    84 	void SetBottom(int16 val);
       
    85 	void SetWidth(int16 val);
       
    86 	void SetHeight(int16 val);
       
    87 	void SetTopLeft(const Point16 &pt);
       
    88 	void SetBottomRight(const Point16 &pt);
       
    89 	void SetSize(const Point16 &pt);
       
    90 	void SetRect(const Rect16 &rect);
       
    91 
       
    92 	WidgetId GetId() const;
       
    93 
       
    94 	void AddHandler(EventHandlerDelegate *d);
       
    95 	void CallHandlers(EventBase &e);
       
    96 
       
    97 	void Invalidate() {}; ///< now we redraw gui all the time, so no processing is needed here
       
    98 	static /*static*/ void FillRect(const Rect16 &rc, int color);
       
    99 	static void DrawFrameRect(int left, int top, int right, int bottom, int ctab, FrameFlags flags);
       
   100 	void DrawFrameRect(int ctab, FrameFlags flags);
       
   101 
       
   102 	virtual BaseWindow* GetWindow();
       
   103 	virtual Widget* WidgetFromPt(const Point16 &pt);
       
   104 
       
   105 	virtual void Close();
       
   106 
       
   107 	virtual void DrawBackground(EvtPaint &ev);
       
   108 
       
   109 	/**
       
   110 	 * OnCreate() handler called when window gets created. Override this method in your
       
   111 	 * Window subclass and place widgets into your window from there.
       
   112 	 */
       
   113 	virtual void OnCreate(EvtCreate &ev) {};
       
   114 	virtual void OnDestroy(EvtDestroy &ev) {};
       
   115 	virtual void OnPaint(EvtPaint &ev) = 0;
       
   116 	virtual void OnKeyPress(EvtKeyPress &ev) {};
       
   117 	virtual void OnLeftClick(EvtClick &ev);
       
   118 	virtual void OnRightClick(EvtRightClick &ev);
       
   119 
       
   120 	/**
       
   121 	 * Dispatch event by its type calling appropriate OnCreate(), OnDestroy(), etc.
       
   122 	 */
       
   123 	virtual void DispatchEvent(EventBase &ev);
       
   124 
       
   125 	/**
       
   126 	 * @function AddReflectHandlerT Registers reflected event handler. Use it from
       
   127 	 * BaseWindow subclasses (Window implementations) to register custom event handler.
       
   128 	 * For example if you are implementing 'MyWindow' class and want to handle OnLeftClick()
       
   129 	 * event for your button 'MyButton', define your handler method inside 'MyWindow' class
       
   130 	 * like:
       
   131 	 *       void MyWindow::MyButtonClickHandler(gui::EvtClick &e)
       
   132 	 *       {
       
   133 	 *          ...
       
   134 	 *       }
       
   135 	 * then from inside OnCreate() handler, create your button 'my_button' and
       
   136 	 * call:
       
   137 	 *       my_button->AddReflectHandlerT(&MyWindow::MyButtonClickHandler);
       
   138 	 * and your MyButtonClickHandler will be called on every click on my_button.
       
   139 	 */
       
   140 	template <class Twnd_cls, EventCode Tevt_code> void AddReflectHandlerT(void (Twnd_cls::*handler)(gui::EventT<Tevt_code>&))
       
   141 	{
       
   142 		typedef ReflectHandlerDelegateT<Twnd_cls, Tevt_code> Delegate;
       
   143 		AddHandler(new Delegate(handler));
       
   144 	}
       
   145 };
       
   146 
       
   147 struct CompositeWidget : public Widget {
       
   148 	typedef Widget super;
       
   149 	typedef std::map<WidgetId, WidgetPtr> Widgets;
       
   150 	typedef Widgets::iterator WidgetIterator;
       
   151 	typedef Widgets::reverse_iterator WidgetReverseIterator;
       
   152 
       
   153 protected:
       
   154 	Widgets m_widgets;
       
   155 
       
   156 public:
       
   157 	CompositeWidget()
       
   158 		: Widget()
       
   159 	{}
       
   160 
       
   161 	CompositeWidget(CompositeWidget *container, WidgetId id, byte display_flags, byte color, const Rect16 &rect, StringID tooltips)
       
   162 		: Widget(container, id, display_flags, color, rect, tooltips)
       
   163 	{}
       
   164 
       
   165 	void AddWidget(Widget *wd);
       
   166 	Widget* GetWidget(WidgetId id);
       
   167 	Widget* RemoveWidget(WidgetId id);
       
   168 
       
   169 	/*virtual*/ Widget* WidgetFromPt(const Point16 &pt);
       
   170 
       
   171 	virtual void Close();
       
   172 
       
   173 	/*virtual*/ void OnPaint(EvtPaint &ev);
       
   174 	/*virtual*/ void OnLeftClick(EvtClick &ev);
       
   175 	/*virtual*/ void OnRightClick(EvtRightClick &ev);
       
   176 };
       
   177 
       
   178 struct Button : public Widget {
       
   179 	typedef Widget super;
       
   180 
       
   181 protected:
       
   182 	bool m_pushed;
       
   183 
       
   184 public:
       
   185 	Button()
       
   186 		: Widget()
       
   187 		, m_pushed(false)
       
   188 	{}
       
   189 
       
   190 	Button(CompositeWidget *container, WidgetId id, byte display_flags, byte color, const Rect16 &rect, StringID tooltips)
       
   191 		: Widget(container, id, display_flags, color, rect, tooltips)
       
   192 		, m_pushed(false)
       
   193 	{}
       
   194 
       
   195 	/*virtual*/ void DrawBackground(EvtPaint &ev);
       
   196 
       
   197 	/*virtual*/ void OnLeftClick(EvtClick &ev);
       
   198 };
       
   199 
       
   200 struct TextButton : public Button {
       
   201 	typedef Button super;
       
   202 
       
   203 protected:
       
   204 	StringID m_text;
       
   205 
       
   206 public:
       
   207 	TextButton()
       
   208 		: Button()
       
   209 	{}
       
   210 
       
   211 	TextButton(CompositeWidget *container, WidgetId id, byte display_flags, byte color, const Rect16 &rect, StringID tooltips, StringID text)
       
   212 		: Button(container, id, display_flags, color, rect, tooltips)
       
   213 		, m_text(text)
       
   214 	{}
       
   215 
       
   216 	/*virtual*/ void OnPaint(EvtPaint &ev);
       
   217 };
       
   218 
       
   219 
       
   220 
       
   221 
       
   222 
       
   223 
       
   224 
       
   225 
       
   226 
       
   227 
       
   228 
       
   229 }; // namespace gui
       
   230 
       
   231 enum FrameFlags {
       
   232 	FR_NONE         = 0x00,
       
   233 	FR_TRANSPARENT  = 0x01,  ///< Makes the background transparent if set
       
   234 	FR_BORDERONLY   = 0x10,  ///< Draw border only, no background
       
   235 	FR_LOWERED      = 0x20,  ///< If set the frame is lowered and the background color brighter (ie. buttons when pressed)
       
   236 	FR_DARKENED     = 0x40,  ///< If set the background is darker, allows for lowered frames with normal background color when used with FR_LOWERED (ie. dropdown boxes)
       
   237 };
       
   238 
       
   239 DECLARE_ENUM_AS_BIT_SET(FrameFlags);
       
   240 
       
   241 
       
   242 #endif /* WIDGET_H */