|
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 */ |