diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8/include/IGUIElement.h | 2074 |
1 files changed, 1037 insertions, 1037 deletions
diff --git a/libraries/irrlicht-1.8/include/IGUIElement.h b/libraries/irrlicht-1.8/include/IGUIElement.h index 40df446..098cd79 100644 --- a/libraries/irrlicht-1.8/include/IGUIElement.h +++ b/libraries/irrlicht-1.8/include/IGUIElement.h | |||
@@ -1,1037 +1,1037 @@ | |||
1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt | 1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt |
2 | // This file is part of the "Irrlicht Engine". | 2 | // This file is part of the "Irrlicht Engine". |
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | 3 | // For conditions of distribution and use, see copyright notice in irrlicht.h |
4 | 4 | ||
5 | #ifndef __I_GUI_ELEMENT_H_INCLUDED__ | 5 | #ifndef __I_GUI_ELEMENT_H_INCLUDED__ |
6 | #define __I_GUI_ELEMENT_H_INCLUDED__ | 6 | #define __I_GUI_ELEMENT_H_INCLUDED__ |
7 | 7 | ||
8 | #include "IAttributeExchangingObject.h" | 8 | #include "IAttributeExchangingObject.h" |
9 | #include "irrList.h" | 9 | #include "irrList.h" |
10 | #include "rect.h" | 10 | #include "rect.h" |
11 | #include "irrString.h" | 11 | #include "irrString.h" |
12 | #include "IEventReceiver.h" | 12 | #include "IEventReceiver.h" |
13 | #include "EGUIElementTypes.h" | 13 | #include "EGUIElementTypes.h" |
14 | #include "EGUIAlignment.h" | 14 | #include "EGUIAlignment.h" |
15 | #include "IAttributes.h" | 15 | #include "IAttributes.h" |
16 | 16 | ||
17 | namespace irr | 17 | namespace irr |
18 | { | 18 | { |
19 | namespace gui | 19 | namespace gui |
20 | { | 20 | { |
21 | 21 | ||
22 | class IGUIEnvironment; | 22 | class IGUIEnvironment; |
23 | 23 | ||
24 | //! Base class of all GUI elements. | 24 | //! Base class of all GUI elements. |
25 | class IGUIElement : public virtual io::IAttributeExchangingObject, public IEventReceiver | 25 | class IGUIElement : public virtual io::IAttributeExchangingObject, public IEventReceiver |
26 | { | 26 | { |
27 | public: | 27 | public: |
28 | 28 | ||
29 | //! Constructor | 29 | //! Constructor |
30 | IGUIElement(EGUI_ELEMENT_TYPE type, IGUIEnvironment* environment, IGUIElement* parent, | 30 | IGUIElement(EGUI_ELEMENT_TYPE type, IGUIEnvironment* environment, IGUIElement* parent, |
31 | s32 id, const core::rect<s32>& rectangle) | 31 | s32 id, const core::rect<s32>& rectangle) |
32 | : Parent(0), RelativeRect(rectangle), AbsoluteRect(rectangle), | 32 | : Parent(0), RelativeRect(rectangle), AbsoluteRect(rectangle), |
33 | AbsoluteClippingRect(rectangle), DesiredRect(rectangle), | 33 | AbsoluteClippingRect(rectangle), DesiredRect(rectangle), |
34 | MaxSize(0,0), MinSize(1,1), IsVisible(true), IsEnabled(true), | 34 | MaxSize(0,0), MinSize(1,1), IsVisible(true), IsEnabled(true), |
35 | IsSubElement(false), NoClip(false), ID(id), IsTabStop(false), TabOrder(-1), IsTabGroup(false), | 35 | IsSubElement(false), NoClip(false), ID(id), IsTabStop(false), TabOrder(-1), IsTabGroup(false), |
36 | AlignLeft(EGUIA_UPPERLEFT), AlignRight(EGUIA_UPPERLEFT), AlignTop(EGUIA_UPPERLEFT), AlignBottom(EGUIA_UPPERLEFT), | 36 | AlignLeft(EGUIA_UPPERLEFT), AlignRight(EGUIA_UPPERLEFT), AlignTop(EGUIA_UPPERLEFT), AlignBottom(EGUIA_UPPERLEFT), |
37 | Environment(environment), Type(type) | 37 | Environment(environment), Type(type) |
38 | { | 38 | { |
39 | #ifdef _DEBUG | 39 | #ifdef _DEBUG |
40 | setDebugName("IGUIElement"); | 40 | setDebugName("IGUIElement"); |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | // if we were given a parent to attach to | 43 | // if we were given a parent to attach to |
44 | if (parent) | 44 | if (parent) |
45 | { | 45 | { |
46 | parent->addChildToEnd(this); | 46 | parent->addChildToEnd(this); |
47 | recalculateAbsolutePosition(true); | 47 | recalculateAbsolutePosition(true); |
48 | } | 48 | } |
49 | } | 49 | } |
50 | 50 | ||
51 | 51 | ||
52 | //! Destructor | 52 | //! Destructor |
53 | virtual ~IGUIElement() | 53 | virtual ~IGUIElement() |
54 | { | 54 | { |
55 | // delete all children | 55 | // delete all children |
56 | core::list<IGUIElement*>::Iterator it = Children.begin(); | 56 | core::list<IGUIElement*>::Iterator it = Children.begin(); |
57 | for (; it != Children.end(); ++it) | 57 | for (; it != Children.end(); ++it) |
58 | { | 58 | { |
59 | (*it)->Parent = 0; | 59 | (*it)->Parent = 0; |
60 | (*it)->drop(); | 60 | (*it)->drop(); |
61 | } | 61 | } |
62 | } | 62 | } |
63 | 63 | ||
64 | 64 | ||
65 | //! Returns parent of this element. | 65 | //! Returns parent of this element. |
66 | IGUIElement* getParent() const | 66 | IGUIElement* getParent() const |
67 | { | 67 | { |
68 | return Parent; | 68 | return Parent; |
69 | } | 69 | } |
70 | 70 | ||
71 | 71 | ||
72 | //! Returns the relative rectangle of this element. | 72 | //! Returns the relative rectangle of this element. |
73 | core::rect<s32> getRelativePosition() const | 73 | core::rect<s32> getRelativePosition() const |
74 | { | 74 | { |
75 | return RelativeRect; | 75 | return RelativeRect; |
76 | } | 76 | } |
77 | 77 | ||
78 | 78 | ||
79 | //! Sets the relative rectangle of this element. | 79 | //! Sets the relative rectangle of this element. |
80 | /** \param r The absolute position to set */ | 80 | /** \param r The absolute position to set */ |
81 | void setRelativePosition(const core::rect<s32>& r) | 81 | void setRelativePosition(const core::rect<s32>& r) |
82 | { | 82 | { |
83 | if (Parent) | 83 | if (Parent) |
84 | { | 84 | { |
85 | const core::rect<s32>& r2 = Parent->getAbsolutePosition(); | 85 | const core::rect<s32>& r2 = Parent->getAbsolutePosition(); |
86 | 86 | ||
87 | core::dimension2df d((f32)(r2.getSize().Width), (f32)(r2.getSize().Height)); | 87 | core::dimension2df d((f32)(r2.getSize().Width), (f32)(r2.getSize().Height)); |
88 | 88 | ||
89 | if (AlignLeft == EGUIA_SCALE) | 89 | if (AlignLeft == EGUIA_SCALE) |
90 | ScaleRect.UpperLeftCorner.X = (f32)r.UpperLeftCorner.X / d.Width; | 90 | ScaleRect.UpperLeftCorner.X = (f32)r.UpperLeftCorner.X / d.Width; |
91 | if (AlignRight == EGUIA_SCALE) | 91 | if (AlignRight == EGUIA_SCALE) |
92 | ScaleRect.LowerRightCorner.X = (f32)r.LowerRightCorner.X / d.Width; | 92 | ScaleRect.LowerRightCorner.X = (f32)r.LowerRightCorner.X / d.Width; |
93 | if (AlignTop == EGUIA_SCALE) | 93 | if (AlignTop == EGUIA_SCALE) |
94 | ScaleRect.UpperLeftCorner.Y = (f32)r.UpperLeftCorner.Y / d.Height; | 94 | ScaleRect.UpperLeftCorner.Y = (f32)r.UpperLeftCorner.Y / d.Height; |
95 | if (AlignBottom == EGUIA_SCALE) | 95 | if (AlignBottom == EGUIA_SCALE) |
96 | ScaleRect.LowerRightCorner.Y = (f32)r.LowerRightCorner.Y / d.Height; | 96 | ScaleRect.LowerRightCorner.Y = (f32)r.LowerRightCorner.Y / d.Height; |
97 | } | 97 | } |
98 | 98 | ||
99 | DesiredRect = r; | 99 | DesiredRect = r; |
100 | updateAbsolutePosition(); | 100 | updateAbsolutePosition(); |
101 | } | 101 | } |
102 | 102 | ||
103 | //! Sets the relative rectangle of this element, maintaining its current width and height | 103 | //! Sets the relative rectangle of this element, maintaining its current width and height |
104 | /** \param position The new relative position to set. Width and height will not be changed. */ | 104 | /** \param position The new relative position to set. Width and height will not be changed. */ |
105 | void setRelativePosition(const core::position2di & position) | 105 | void setRelativePosition(const core::position2di & position) |
106 | { | 106 | { |
107 | const core::dimension2di mySize = RelativeRect.getSize(); | 107 | const core::dimension2di mySize = RelativeRect.getSize(); |
108 | const core::rect<s32> rectangle(position.X, position.Y, | 108 | const core::rect<s32> rectangle(position.X, position.Y, |
109 | position.X + mySize.Width, position.Y + mySize.Height); | 109 | position.X + mySize.Width, position.Y + mySize.Height); |
110 | setRelativePosition(rectangle); | 110 | setRelativePosition(rectangle); |
111 | } | 111 | } |
112 | 112 | ||
113 | 113 | ||
114 | //! Sets the relative rectangle of this element as a proportion of its parent's area. | 114 | //! Sets the relative rectangle of this element as a proportion of its parent's area. |
115 | /** \note This method used to be 'void setRelativePosition(const core::rect<f32>& r)' | 115 | /** \note This method used to be 'void setRelativePosition(const core::rect<f32>& r)' |
116 | \param r The rectangle to set, interpreted as a proportion of the parent's area. | 116 | \param r The rectangle to set, interpreted as a proportion of the parent's area. |
117 | Meaningful values are in the range [0...1], unless you intend this element to spill | 117 | Meaningful values are in the range [0...1], unless you intend this element to spill |
118 | outside its parent. */ | 118 | outside its parent. */ |
119 | void setRelativePositionProportional(const core::rect<f32>& r) | 119 | void setRelativePositionProportional(const core::rect<f32>& r) |
120 | { | 120 | { |
121 | if (!Parent) | 121 | if (!Parent) |
122 | return; | 122 | return; |
123 | 123 | ||
124 | const core::dimension2di& d = Parent->getAbsolutePosition().getSize(); | 124 | const core::dimension2di& d = Parent->getAbsolutePosition().getSize(); |
125 | 125 | ||
126 | DesiredRect = core::rect<s32>( | 126 | DesiredRect = core::rect<s32>( |
127 | core::floor32((f32)d.Width * r.UpperLeftCorner.X), | 127 | core::floor32((f32)d.Width * r.UpperLeftCorner.X), |
128 | core::floor32((f32)d.Height * r.UpperLeftCorner.Y), | 128 | core::floor32((f32)d.Height * r.UpperLeftCorner.Y), |
129 | core::floor32((f32)d.Width * r.LowerRightCorner.X), | 129 | core::floor32((f32)d.Width * r.LowerRightCorner.X), |
130 | core::floor32((f32)d.Height * r.LowerRightCorner.Y)); | 130 | core::floor32((f32)d.Height * r.LowerRightCorner.Y)); |
131 | 131 | ||
132 | ScaleRect = r; | 132 | ScaleRect = r; |
133 | 133 | ||
134 | updateAbsolutePosition(); | 134 | updateAbsolutePosition(); |
135 | } | 135 | } |
136 | 136 | ||
137 | 137 | ||
138 | //! Gets the absolute rectangle of this element | 138 | //! Gets the absolute rectangle of this element |
139 | core::rect<s32> getAbsolutePosition() const | 139 | core::rect<s32> getAbsolutePosition() const |
140 | { | 140 | { |
141 | return AbsoluteRect; | 141 | return AbsoluteRect; |
142 | } | 142 | } |
143 | 143 | ||
144 | 144 | ||
145 | //! Returns the visible area of the element. | 145 | //! Returns the visible area of the element. |
146 | core::rect<s32> getAbsoluteClippingRect() const | 146 | core::rect<s32> getAbsoluteClippingRect() const |
147 | { | 147 | { |
148 | return AbsoluteClippingRect; | 148 | return AbsoluteClippingRect; |
149 | } | 149 | } |
150 | 150 | ||
151 | 151 | ||
152 | //! Sets whether the element will ignore its parent's clipping rectangle | 152 | //! Sets whether the element will ignore its parent's clipping rectangle |
153 | /** \param noClip If true, the element will not be clipped by its parent's clipping rectangle. */ | 153 | /** \param noClip If true, the element will not be clipped by its parent's clipping rectangle. */ |
154 | void setNotClipped(bool noClip) | 154 | void setNotClipped(bool noClip) |
155 | { | 155 | { |
156 | NoClip = noClip; | 156 | NoClip = noClip; |
157 | updateAbsolutePosition(); | 157 | updateAbsolutePosition(); |
158 | } | 158 | } |
159 | 159 | ||
160 | 160 | ||
161 | //! Gets whether the element will ignore its parent's clipping rectangle | 161 | //! Gets whether the element will ignore its parent's clipping rectangle |
162 | /** \return true if the element is not clipped by its parent's clipping rectangle. */ | 162 | /** \return true if the element is not clipped by its parent's clipping rectangle. */ |
163 | bool isNotClipped() const | 163 | bool isNotClipped() const |
164 | { | 164 | { |
165 | return NoClip; | 165 | return NoClip; |
166 | } | 166 | } |
167 | 167 | ||
168 | 168 | ||
169 | //! Sets the maximum size allowed for this element | 169 | //! Sets the maximum size allowed for this element |
170 | /** If set to 0,0, there is no maximum size */ | 170 | /** If set to 0,0, there is no maximum size */ |
171 | void setMaxSize(core::dimension2du size) | 171 | void setMaxSize(core::dimension2du size) |
172 | { | 172 | { |
173 | MaxSize = size; | 173 | MaxSize = size; |
174 | updateAbsolutePosition(); | 174 | updateAbsolutePosition(); |
175 | } | 175 | } |
176 | 176 | ||
177 | 177 | ||
178 | //! Sets the minimum size allowed for this element | 178 | //! Sets the minimum size allowed for this element |
179 | void setMinSize(core::dimension2du size) | 179 | void setMinSize(core::dimension2du size) |
180 | { | 180 | { |
181 | MinSize = size; | 181 | MinSize = size; |
182 | if (MinSize.Width < 1) | 182 | if (MinSize.Width < 1) |
183 | MinSize.Width = 1; | 183 | MinSize.Width = 1; |
184 | if (MinSize.Height < 1) | 184 | if (MinSize.Height < 1) |
185 | MinSize.Height = 1; | 185 | MinSize.Height = 1; |
186 | updateAbsolutePosition(); | 186 | updateAbsolutePosition(); |
187 | } | 187 | } |
188 | 188 | ||
189 | 189 | ||
190 | //! The alignment defines how the borders of this element will be positioned when the parent element is resized. | 190 | //! The alignment defines how the borders of this element will be positioned when the parent element is resized. |
191 | void setAlignment(EGUI_ALIGNMENT left, EGUI_ALIGNMENT right, EGUI_ALIGNMENT top, EGUI_ALIGNMENT bottom) | 191 | void setAlignment(EGUI_ALIGNMENT left, EGUI_ALIGNMENT right, EGUI_ALIGNMENT top, EGUI_ALIGNMENT bottom) |
192 | { | 192 | { |
193 | AlignLeft = left; | 193 | AlignLeft = left; |
194 | AlignRight = right; | 194 | AlignRight = right; |
195 | AlignTop = top; | 195 | AlignTop = top; |
196 | AlignBottom = bottom; | 196 | AlignBottom = bottom; |
197 | 197 | ||
198 | if (Parent) | 198 | if (Parent) |
199 | { | 199 | { |
200 | core::rect<s32> r(Parent->getAbsolutePosition()); | 200 | core::rect<s32> r(Parent->getAbsolutePosition()); |
201 | 201 | ||
202 | core::dimension2df d((f32)r.getSize().Width, (f32)r.getSize().Height); | 202 | core::dimension2df d((f32)r.getSize().Width, (f32)r.getSize().Height); |
203 | 203 | ||
204 | if (AlignLeft == EGUIA_SCALE) | 204 | if (AlignLeft == EGUIA_SCALE) |
205 | ScaleRect.UpperLeftCorner.X = (f32)DesiredRect.UpperLeftCorner.X / d.Width; | 205 | ScaleRect.UpperLeftCorner.X = (f32)DesiredRect.UpperLeftCorner.X / d.Width; |
206 | if (AlignRight == EGUIA_SCALE) | 206 | if (AlignRight == EGUIA_SCALE) |
207 | ScaleRect.LowerRightCorner.X = (f32)DesiredRect.LowerRightCorner.X / d.Width; | 207 | ScaleRect.LowerRightCorner.X = (f32)DesiredRect.LowerRightCorner.X / d.Width; |
208 | if (AlignTop == EGUIA_SCALE) | 208 | if (AlignTop == EGUIA_SCALE) |
209 | ScaleRect.UpperLeftCorner.Y = (f32)DesiredRect.UpperLeftCorner.Y / d.Height; | 209 | ScaleRect.UpperLeftCorner.Y = (f32)DesiredRect.UpperLeftCorner.Y / d.Height; |
210 | if (AlignBottom == EGUIA_SCALE) | 210 | if (AlignBottom == EGUIA_SCALE) |
211 | ScaleRect.LowerRightCorner.Y = (f32)DesiredRect.LowerRightCorner.Y / d.Height; | 211 | ScaleRect.LowerRightCorner.Y = (f32)DesiredRect.LowerRightCorner.Y / d.Height; |
212 | } | 212 | } |
213 | } | 213 | } |
214 | 214 | ||
215 | 215 | ||
216 | //! Updates the absolute position. | 216 | //! Updates the absolute position. |
217 | virtual void updateAbsolutePosition() | 217 | virtual void updateAbsolutePosition() |
218 | { | 218 | { |
219 | recalculateAbsolutePosition(false); | 219 | recalculateAbsolutePosition(false); |
220 | 220 | ||
221 | // update all children | 221 | // update all children |
222 | core::list<IGUIElement*>::Iterator it = Children.begin(); | 222 | core::list<IGUIElement*>::Iterator it = Children.begin(); |
223 | for (; it != Children.end(); ++it) | 223 | for (; it != Children.end(); ++it) |
224 | { | 224 | { |
225 | (*it)->updateAbsolutePosition(); | 225 | (*it)->updateAbsolutePosition(); |
226 | } | 226 | } |
227 | } | 227 | } |
228 | 228 | ||
229 | 229 | ||
230 | //! Returns the topmost GUI element at the specific position. | 230 | //! Returns the topmost GUI element at the specific position. |
231 | /** | 231 | /** |
232 | This will check this GUI element and all of its descendants, so it | 232 | This will check this GUI element and all of its descendants, so it |
233 | may return this GUI element. To check all GUI elements, call this | 233 | may return this GUI element. To check all GUI elements, call this |
234 | function on device->getGUIEnvironment()->getRootGUIElement(). Note | 234 | function on device->getGUIEnvironment()->getRootGUIElement(). Note |
235 | that the root element is the size of the screen, so doing so (with | 235 | that the root element is the size of the screen, so doing so (with |
236 | an on-screen point) will always return the root element if no other | 236 | an on-screen point) will always return the root element if no other |
237 | element is above it at that point. | 237 | element is above it at that point. |
238 | \param point: The point at which to find a GUI element. | 238 | \param point: The point at which to find a GUI element. |
239 | \return The topmost GUI element at that point, or 0 if there are | 239 | \return The topmost GUI element at that point, or 0 if there are |
240 | no candidate elements at this point. | 240 | no candidate elements at this point. |
241 | */ | 241 | */ |
242 | IGUIElement* getElementFromPoint(const core::position2d<s32>& point) | 242 | IGUIElement* getElementFromPoint(const core::position2d<s32>& point) |
243 | { | 243 | { |
244 | IGUIElement* target = 0; | 244 | IGUIElement* target = 0; |
245 | 245 | ||
246 | // we have to search from back to front, because later children | 246 | // we have to search from back to front, because later children |
247 | // might be drawn over the top of earlier ones. | 247 | // might be drawn over the top of earlier ones. |
248 | 248 | ||
249 | core::list<IGUIElement*>::Iterator it = Children.getLast(); | 249 | core::list<IGUIElement*>::Iterator it = Children.getLast(); |
250 | 250 | ||
251 | if (isVisible()) | 251 | if (isVisible()) |
252 | { | 252 | { |
253 | while(it != Children.end()) | 253 | while(it != Children.end()) |
254 | { | 254 | { |
255 | target = (*it)->getElementFromPoint(point); | 255 | target = (*it)->getElementFromPoint(point); |
256 | if (target) | 256 | if (target) |
257 | return target; | 257 | return target; |
258 | 258 | ||
259 | --it; | 259 | --it; |
260 | } | 260 | } |
261 | } | 261 | } |
262 | 262 | ||
263 | if (isVisible() && isPointInside(point)) | 263 | if (isVisible() && isPointInside(point)) |
264 | target = this; | 264 | target = this; |
265 | 265 | ||
266 | return target; | 266 | return target; |
267 | } | 267 | } |
268 | 268 | ||
269 | 269 | ||
270 | //! Returns true if a point is within this element. | 270 | //! Returns true if a point is within this element. |
271 | /** Elements with a shape other than a rectangle should override this method */ | 271 | /** Elements with a shape other than a rectangle should override this method */ |
272 | virtual bool isPointInside(const core::position2d<s32>& point) const | 272 | virtual bool isPointInside(const core::position2d<s32>& point) const |
273 | { | 273 | { |
274 | return AbsoluteClippingRect.isPointInside(point); | 274 | return AbsoluteClippingRect.isPointInside(point); |
275 | } | 275 | } |
276 | 276 | ||
277 | 277 | ||
278 | //! Adds a GUI element as new child of this element. | 278 | //! Adds a GUI element as new child of this element. |
279 | virtual void addChild(IGUIElement* child) | 279 | virtual void addChild(IGUIElement* child) |
280 | { | 280 | { |
281 | addChildToEnd(child); | 281 | addChildToEnd(child); |
282 | if (child) | 282 | if (child) |
283 | { | 283 | { |
284 | child->updateAbsolutePosition(); | 284 | child->updateAbsolutePosition(); |
285 | } | 285 | } |
286 | } | 286 | } |
287 | 287 | ||
288 | //! Removes a child. | 288 | //! Removes a child. |
289 | virtual void removeChild(IGUIElement* child) | 289 | virtual void removeChild(IGUIElement* child) |
290 | { | 290 | { |
291 | core::list<IGUIElement*>::Iterator it = Children.begin(); | 291 | core::list<IGUIElement*>::Iterator it = Children.begin(); |
292 | for (; it != Children.end(); ++it) | 292 | for (; it != Children.end(); ++it) |
293 | if ((*it) == child) | 293 | if ((*it) == child) |
294 | { | 294 | { |
295 | (*it)->Parent = 0; | 295 | (*it)->Parent = 0; |
296 | (*it)->drop(); | 296 | (*it)->drop(); |
297 | Children.erase(it); | 297 | Children.erase(it); |
298 | return; | 298 | return; |
299 | } | 299 | } |
300 | } | 300 | } |
301 | 301 | ||
302 | 302 | ||
303 | //! Removes this element from its parent. | 303 | //! Removes this element from its parent. |
304 | virtual void remove() | 304 | virtual void remove() |
305 | { | 305 | { |
306 | if (Parent) | 306 | if (Parent) |
307 | Parent->removeChild(this); | 307 | Parent->removeChild(this); |
308 | } | 308 | } |
309 | 309 | ||
310 | 310 | ||
311 | //! Draws the element and its children. | 311 | //! Draws the element and its children. |
312 | virtual void draw() | 312 | virtual void draw() |
313 | { | 313 | { |
314 | if ( isVisible() ) | 314 | if ( isVisible() ) |
315 | { | 315 | { |
316 | core::list<IGUIElement*>::Iterator it = Children.begin(); | 316 | core::list<IGUIElement*>::Iterator it = Children.begin(); |
317 | for (; it != Children.end(); ++it) | 317 | for (; it != Children.end(); ++it) |
318 | (*it)->draw(); | 318 | (*it)->draw(); |
319 | } | 319 | } |
320 | } | 320 | } |
321 | 321 | ||
322 | 322 | ||
323 | //! animate the element and its children. | 323 | //! animate the element and its children. |
324 | virtual void OnPostRender(u32 timeMs) | 324 | virtual void OnPostRender(u32 timeMs) |
325 | { | 325 | { |
326 | if ( isVisible() ) | 326 | if ( isVisible() ) |
327 | { | 327 | { |
328 | core::list<IGUIElement*>::Iterator it = Children.begin(); | 328 | core::list<IGUIElement*>::Iterator it = Children.begin(); |
329 | for (; it != Children.end(); ++it) | 329 | for (; it != Children.end(); ++it) |
330 | (*it)->OnPostRender( timeMs ); | 330 | (*it)->OnPostRender( timeMs ); |
331 | } | 331 | } |
332 | } | 332 | } |
333 | 333 | ||
334 | 334 | ||
335 | //! Moves this element. | 335 | //! Moves this element. |
336 | virtual void move(core::position2d<s32> absoluteMovement) | 336 | virtual void move(core::position2d<s32> absoluteMovement) |
337 | { | 337 | { |
338 | setRelativePosition(DesiredRect + absoluteMovement); | 338 | setRelativePosition(DesiredRect + absoluteMovement); |
339 | } | 339 | } |
340 | 340 | ||
341 | 341 | ||
342 | //! Returns true if element is visible. | 342 | //! Returns true if element is visible. |
343 | virtual bool isVisible() const | 343 | virtual bool isVisible() const |
344 | { | 344 | { |
345 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; | 345 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; |
346 | return IsVisible; | 346 | return IsVisible; |
347 | } | 347 | } |
348 | 348 | ||
349 | 349 | ||
350 | //! Sets the visible state of this element. | 350 | //! Sets the visible state of this element. |
351 | virtual void setVisible(bool visible) | 351 | virtual void setVisible(bool visible) |
352 | { | 352 | { |
353 | IsVisible = visible; | 353 | IsVisible = visible; |
354 | } | 354 | } |
355 | 355 | ||
356 | 356 | ||
357 | //! Returns true if this element was created as part of its parent control | 357 | //! Returns true if this element was created as part of its parent control |
358 | virtual bool isSubElement() const | 358 | virtual bool isSubElement() const |
359 | { | 359 | { |
360 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; | 360 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; |
361 | return IsSubElement; | 361 | return IsSubElement; |
362 | } | 362 | } |
363 | 363 | ||
364 | 364 | ||
365 | //! Sets whether this control was created as part of its parent. | 365 | //! Sets whether this control was created as part of its parent. |
366 | /** For example, it is true when a scrollbar is part of a listbox. | 366 | /** For example, it is true when a scrollbar is part of a listbox. |
367 | SubElements are not saved to disk when calling guiEnvironment->saveGUI() */ | 367 | SubElements are not saved to disk when calling guiEnvironment->saveGUI() */ |
368 | virtual void setSubElement(bool subElement) | 368 | virtual void setSubElement(bool subElement) |
369 | { | 369 | { |
370 | IsSubElement = subElement; | 370 | IsSubElement = subElement; |
371 | } | 371 | } |
372 | 372 | ||
373 | 373 | ||
374 | //! If set to true, the focus will visit this element when using the tab key to cycle through elements. | 374 | //! If set to true, the focus will visit this element when using the tab key to cycle through elements. |
375 | /** If this element is a tab group (see isTabGroup/setTabGroup) then | 375 | /** If this element is a tab group (see isTabGroup/setTabGroup) then |
376 | ctrl+tab will be used instead. */ | 376 | ctrl+tab will be used instead. */ |
377 | void setTabStop(bool enable) | 377 | void setTabStop(bool enable) |
378 | { | 378 | { |
379 | IsTabStop = enable; | 379 | IsTabStop = enable; |
380 | } | 380 | } |
381 | 381 | ||
382 | 382 | ||
383 | //! Returns true if this element can be focused by navigating with the tab key | 383 | //! Returns true if this element can be focused by navigating with the tab key |
384 | bool isTabStop() const | 384 | bool isTabStop() const |
385 | { | 385 | { |
386 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; | 386 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; |
387 | return IsTabStop; | 387 | return IsTabStop; |
388 | } | 388 | } |
389 | 389 | ||
390 | 390 | ||
391 | //! Sets the priority of focus when using the tab key to navigate between a group of elements. | 391 | //! Sets the priority of focus when using the tab key to navigate between a group of elements. |
392 | /** See setTabGroup, isTabGroup and getTabGroup for information on tab groups. | 392 | /** See setTabGroup, isTabGroup and getTabGroup for information on tab groups. |
393 | Elements with a lower number are focused first */ | 393 | Elements with a lower number are focused first */ |
394 | void setTabOrder(s32 index) | 394 | void setTabOrder(s32 index) |
395 | { | 395 | { |
396 | // negative = autonumber | 396 | // negative = autonumber |
397 | if (index < 0) | 397 | if (index < 0) |
398 | { | 398 | { |
399 | TabOrder = 0; | 399 | TabOrder = 0; |
400 | IGUIElement *el = getTabGroup(); | 400 | IGUIElement *el = getTabGroup(); |
401 | while (IsTabGroup && el && el->Parent) | 401 | while (IsTabGroup && el && el->Parent) |
402 | el = el->Parent; | 402 | el = el->Parent; |
403 | 403 | ||
404 | IGUIElement *first=0, *closest=0; | 404 | IGUIElement *first=0, *closest=0; |
405 | if (el) | 405 | if (el) |
406 | { | 406 | { |
407 | // find the highest element number | 407 | // find the highest element number |
408 | el->getNextElement(-1, true, IsTabGroup, first, closest, true); | 408 | el->getNextElement(-1, true, IsTabGroup, first, closest, true); |
409 | if (first) | 409 | if (first) |
410 | { | 410 | { |
411 | TabOrder = first->getTabOrder() + 1; | 411 | TabOrder = first->getTabOrder() + 1; |
412 | } | 412 | } |
413 | } | 413 | } |
414 | 414 | ||
415 | } | 415 | } |
416 | else | 416 | else |
417 | TabOrder = index; | 417 | TabOrder = index; |
418 | } | 418 | } |
419 | 419 | ||
420 | 420 | ||
421 | //! Returns the number in the tab order sequence | 421 | //! Returns the number in the tab order sequence |
422 | s32 getTabOrder() const | 422 | s32 getTabOrder() const |
423 | { | 423 | { |
424 | return TabOrder; | 424 | return TabOrder; |
425 | } | 425 | } |
426 | 426 | ||
427 | 427 | ||
428 | //! Sets whether this element is a container for a group of elements which can be navigated using the tab key. | 428 | //! Sets whether this element is a container for a group of elements which can be navigated using the tab key. |
429 | /** For example, windows are tab groups. | 429 | /** For example, windows are tab groups. |
430 | Groups can be navigated using ctrl+tab, providing isTabStop is true. */ | 430 | Groups can be navigated using ctrl+tab, providing isTabStop is true. */ |
431 | void setTabGroup(bool isGroup) | 431 | void setTabGroup(bool isGroup) |
432 | { | 432 | { |
433 | IsTabGroup = isGroup; | 433 | IsTabGroup = isGroup; |
434 | } | 434 | } |
435 | 435 | ||
436 | 436 | ||
437 | //! Returns true if this element is a tab group. | 437 | //! Returns true if this element is a tab group. |
438 | bool isTabGroup() const | 438 | bool isTabGroup() const |
439 | { | 439 | { |
440 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; | 440 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; |
441 | return IsTabGroup; | 441 | return IsTabGroup; |
442 | } | 442 | } |
443 | 443 | ||
444 | 444 | ||
445 | //! Returns the container element which holds all elements in this element's tab group. | 445 | //! Returns the container element which holds all elements in this element's tab group. |
446 | IGUIElement* getTabGroup() | 446 | IGUIElement* getTabGroup() |
447 | { | 447 | { |
448 | IGUIElement *ret=this; | 448 | IGUIElement *ret=this; |
449 | 449 | ||
450 | while (ret && !ret->isTabGroup()) | 450 | while (ret && !ret->isTabGroup()) |
451 | ret = ret->getParent(); | 451 | ret = ret->getParent(); |
452 | 452 | ||
453 | return ret; | 453 | return ret; |
454 | } | 454 | } |
455 | 455 | ||
456 | 456 | ||
457 | //! Returns true if element is enabled | 457 | //! Returns true if element is enabled |
458 | /** Currently elements do _not_ care about parent-states. | 458 | /** Currently elements do _not_ care about parent-states. |
459 | So if you want to affect childs you have to enable/disable them all. | 459 | So if you want to affect childs you have to enable/disable them all. |
460 | The only exception to this are sub-elements which also check their parent. | 460 | The only exception to this are sub-elements which also check their parent. |
461 | */ | 461 | */ |
462 | virtual bool isEnabled() const | 462 | virtual bool isEnabled() const |
463 | { | 463 | { |
464 | if ( isSubElement() && IsEnabled && getParent() ) | 464 | if ( isSubElement() && IsEnabled && getParent() ) |
465 | return getParent()->isEnabled(); | 465 | return getParent()->isEnabled(); |
466 | 466 | ||
467 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; | 467 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; |
468 | return IsEnabled; | 468 | return IsEnabled; |
469 | } | 469 | } |
470 | 470 | ||
471 | 471 | ||
472 | //! Sets the enabled state of this element. | 472 | //! Sets the enabled state of this element. |
473 | virtual void setEnabled(bool enabled) | 473 | virtual void setEnabled(bool enabled) |
474 | { | 474 | { |
475 | IsEnabled = enabled; | 475 | IsEnabled = enabled; |
476 | } | 476 | } |
477 | 477 | ||
478 | 478 | ||
479 | //! Sets the new caption of this element. | 479 | //! Sets the new caption of this element. |
480 | virtual void setText(const wchar_t* text) | 480 | virtual void setText(const wchar_t* text) |
481 | { | 481 | { |
482 | Text = text; | 482 | Text = text; |
483 | } | 483 | } |
484 | 484 | ||
485 | 485 | ||
486 | //! Returns caption of this element. | 486 | //! Returns caption of this element. |
487 | virtual const wchar_t* getText() const | 487 | virtual const wchar_t* getText() const |
488 | { | 488 | { |
489 | return Text.c_str(); | 489 | return Text.c_str(); |
490 | } | 490 | } |
491 | 491 | ||
492 | 492 | ||
493 | //! Sets the new caption of this element. | 493 | //! Sets the new caption of this element. |
494 | virtual void setToolTipText(const wchar_t* text) | 494 | virtual void setToolTipText(const wchar_t* text) |
495 | { | 495 | { |
496 | ToolTipText = text; | 496 | ToolTipText = text; |
497 | } | 497 | } |
498 | 498 | ||
499 | 499 | ||
500 | //! Returns caption of this element. | 500 | //! Returns caption of this element. |
501 | virtual const core::stringw& getToolTipText() const | 501 | virtual const core::stringw& getToolTipText() const |
502 | { | 502 | { |
503 | return ToolTipText; | 503 | return ToolTipText; |
504 | } | 504 | } |
505 | 505 | ||
506 | 506 | ||
507 | //! Returns id. Can be used to identify the element. | 507 | //! Returns id. Can be used to identify the element. |
508 | virtual s32 getID() const | 508 | virtual s32 getID() const |
509 | { | 509 | { |
510 | return ID; | 510 | return ID; |
511 | } | 511 | } |
512 | 512 | ||
513 | 513 | ||
514 | //! Sets the id of this element | 514 | //! Sets the id of this element |
515 | virtual void setID(s32 id) | 515 | virtual void setID(s32 id) |
516 | { | 516 | { |
517 | ID = id; | 517 | ID = id; |
518 | } | 518 | } |
519 | 519 | ||
520 | 520 | ||
521 | //! Called if an event happened. | 521 | //! Called if an event happened. |
522 | virtual bool OnEvent(const SEvent& event) | 522 | virtual bool OnEvent(const SEvent& event) |
523 | { | 523 | { |
524 | return Parent ? Parent->OnEvent(event) : false; | 524 | return Parent ? Parent->OnEvent(event) : false; |
525 | } | 525 | } |
526 | 526 | ||
527 | 527 | ||
528 | //! Brings a child to front | 528 | //! Brings a child to front |
529 | /** \return True if successful, false if not. */ | 529 | /** \return True if successful, false if not. */ |
530 | virtual bool bringToFront(IGUIElement* element) | 530 | virtual bool bringToFront(IGUIElement* element) |
531 | { | 531 | { |
532 | core::list<IGUIElement*>::Iterator it = Children.begin(); | 532 | core::list<IGUIElement*>::Iterator it = Children.begin(); |
533 | for (; it != Children.end(); ++it) | 533 | for (; it != Children.end(); ++it) |
534 | { | 534 | { |
535 | if (element == (*it)) | 535 | if (element == (*it)) |
536 | { | 536 | { |
537 | Children.erase(it); | 537 | Children.erase(it); |
538 | Children.push_back(element); | 538 | Children.push_back(element); |
539 | return true; | 539 | return true; |
540 | } | 540 | } |
541 | } | 541 | } |
542 | 542 | ||
543 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; | 543 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; |
544 | return false; | 544 | return false; |
545 | } | 545 | } |
546 | 546 | ||
547 | 547 | ||
548 | //! Moves a child to the back, so it's siblings are drawn on top of it | 548 | //! Moves a child to the back, so it's siblings are drawn on top of it |
549 | /** \return True if successful, false if not. */ | 549 | /** \return True if successful, false if not. */ |
550 | virtual bool sendToBack(IGUIElement* child) | 550 | virtual bool sendToBack(IGUIElement* child) |
551 | { | 551 | { |
552 | core::list<IGUIElement*>::Iterator it = Children.begin(); | 552 | core::list<IGUIElement*>::Iterator it = Children.begin(); |
553 | if (child == (*it)) // already there | 553 | if (child == (*it)) // already there |
554 | return true; | 554 | return true; |
555 | for (; it != Children.end(); ++it) | 555 | for (; it != Children.end(); ++it) |
556 | { | 556 | { |
557 | if (child == (*it)) | 557 | if (child == (*it)) |
558 | { | 558 | { |
559 | Children.erase(it); | 559 | Children.erase(it); |
560 | Children.push_front(child); | 560 | Children.push_front(child); |
561 | return true; | 561 | return true; |
562 | } | 562 | } |
563 | } | 563 | } |
564 | 564 | ||
565 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; | 565 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; |
566 | return false; | 566 | return false; |
567 | } | 567 | } |
568 | 568 | ||
569 | //! Returns list with children of this element | 569 | //! Returns list with children of this element |
570 | virtual const core::list<IGUIElement*>& getChildren() const | 570 | virtual const core::list<IGUIElement*>& getChildren() const |
571 | { | 571 | { |
572 | return Children; | 572 | return Children; |
573 | } | 573 | } |
574 | 574 | ||
575 | 575 | ||
576 | //! Finds the first element with the given id. | 576 | //! Finds the first element with the given id. |
577 | /** \param id: Id to search for. | 577 | /** \param id: Id to search for. |
578 | \param searchchildren: Set this to true, if also children of this | 578 | \param searchchildren: Set this to true, if also children of this |
579 | element may contain the element with the searched id and they | 579 | element may contain the element with the searched id and they |
580 | should be searched too. | 580 | should be searched too. |
581 | \return Returns the first element with the given id. If no element | 581 | \return Returns the first element with the given id. If no element |
582 | with this id was found, 0 is returned. */ | 582 | with this id was found, 0 is returned. */ |
583 | virtual IGUIElement* getElementFromId(s32 id, bool searchchildren=false) const | 583 | virtual IGUIElement* getElementFromId(s32 id, bool searchchildren=false) const |
584 | { | 584 | { |
585 | IGUIElement* e = 0; | 585 | IGUIElement* e = 0; |
586 | 586 | ||
587 | core::list<IGUIElement*>::ConstIterator it = Children.begin(); | 587 | core::list<IGUIElement*>::ConstIterator it = Children.begin(); |
588 | for (; it != Children.end(); ++it) | 588 | for (; it != Children.end(); ++it) |
589 | { | 589 | { |
590 | if ((*it)->getID() == id) | 590 | if ((*it)->getID() == id) |
591 | return (*it); | 591 | return (*it); |
592 | 592 | ||
593 | if (searchchildren) | 593 | if (searchchildren) |
594 | e = (*it)->getElementFromId(id, true); | 594 | e = (*it)->getElementFromId(id, true); |
595 | 595 | ||
596 | if (e) | 596 | if (e) |
597 | return e; | 597 | return e; |
598 | } | 598 | } |
599 | 599 | ||
600 | return e; | 600 | return e; |
601 | } | 601 | } |
602 | 602 | ||
603 | 603 | ||
604 | //! returns true if the given element is a child of this one. | 604 | //! returns true if the given element is a child of this one. |
605 | //! \param child: The child element to check | 605 | //! \param child: The child element to check |
606 | bool isMyChild(IGUIElement* child) const | 606 | bool isMyChild(IGUIElement* child) const |
607 | { | 607 | { |
608 | if (!child) | 608 | if (!child) |
609 | return false; | 609 | return false; |
610 | do | 610 | do |
611 | { | 611 | { |
612 | if (child->Parent) | 612 | if (child->Parent) |
613 | child = child->Parent; | 613 | child = child->Parent; |
614 | 614 | ||
615 | } while (child->Parent && child != this); | 615 | } while (child->Parent && child != this); |
616 | 616 | ||
617 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; | 617 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; |
618 | return child == this; | 618 | return child == this; |
619 | } | 619 | } |
620 | 620 | ||
621 | 621 | ||
622 | //! searches elements to find the closest next element to tab to | 622 | //! searches elements to find the closest next element to tab to |
623 | /** \param startOrder: The TabOrder of the current element, -1 if none | 623 | /** \param startOrder: The TabOrder of the current element, -1 if none |
624 | \param reverse: true if searching for a lower number | 624 | \param reverse: true if searching for a lower number |
625 | \param group: true if searching for a higher one | 625 | \param group: true if searching for a higher one |
626 | \param first: element with the highest/lowest known tab order depending on search direction | 626 | \param first: element with the highest/lowest known tab order depending on search direction |
627 | \param closest: the closest match, depending on tab order and direction | 627 | \param closest: the closest match, depending on tab order and direction |
628 | \param includeInvisible: includes invisible elements in the search (default=false) | 628 | \param includeInvisible: includes invisible elements in the search (default=false) |
629 | \return true if successfully found an element, false to continue searching/fail */ | 629 | \return true if successfully found an element, false to continue searching/fail */ |
630 | bool getNextElement(s32 startOrder, bool reverse, bool group, | 630 | bool getNextElement(s32 startOrder, bool reverse, bool group, |
631 | IGUIElement*& first, IGUIElement*& closest, bool includeInvisible=false) const | 631 | IGUIElement*& first, IGUIElement*& closest, bool includeInvisible=false) const |
632 | { | 632 | { |
633 | // we'll stop searching if we find this number | 633 | // we'll stop searching if we find this number |
634 | s32 wanted = startOrder + ( reverse ? -1 : 1 ); | 634 | s32 wanted = startOrder + ( reverse ? -1 : 1 ); |
635 | if (wanted==-2) | 635 | if (wanted==-2) |
636 | wanted = 1073741824; // maximum s32 | 636 | wanted = 1073741824; // maximum s32 |
637 | 637 | ||
638 | core::list<IGUIElement*>::ConstIterator it = Children.begin(); | 638 | core::list<IGUIElement*>::ConstIterator it = Children.begin(); |
639 | 639 | ||
640 | s32 closestOrder, currentOrder; | 640 | s32 closestOrder, currentOrder; |
641 | 641 | ||
642 | while(it != Children.end()) | 642 | while(it != Children.end()) |
643 | { | 643 | { |
644 | // ignore invisible elements and their children | 644 | // ignore invisible elements and their children |
645 | if ( ( (*it)->isVisible() || includeInvisible ) && | 645 | if ( ( (*it)->isVisible() || includeInvisible ) && |
646 | (group == true || (*it)->isTabGroup() == false) ) | 646 | (group == true || (*it)->isTabGroup() == false) ) |
647 | { | 647 | { |
648 | // only check tab stops and those with the same group status | 648 | // only check tab stops and those with the same group status |
649 | if ((*it)->isTabStop() && ((*it)->isTabGroup() == group)) | 649 | if ((*it)->isTabStop() && ((*it)->isTabGroup() == group)) |
650 | { | 650 | { |
651 | currentOrder = (*it)->getTabOrder(); | 651 | currentOrder = (*it)->getTabOrder(); |
652 | 652 | ||
653 | // is this what we're looking for? | 653 | // is this what we're looking for? |
654 | if (currentOrder == wanted) | 654 | if (currentOrder == wanted) |
655 | { | 655 | { |
656 | closest = *it; | 656 | closest = *it; |
657 | return true; | 657 | return true; |
658 | } | 658 | } |
659 | 659 | ||
660 | // is it closer than the current closest? | 660 | // is it closer than the current closest? |
661 | if (closest) | 661 | if (closest) |
662 | { | 662 | { |
663 | closestOrder = closest->getTabOrder(); | 663 | closestOrder = closest->getTabOrder(); |
664 | if ( ( reverse && currentOrder > closestOrder && currentOrder < startOrder) | 664 | if ( ( reverse && currentOrder > closestOrder && currentOrder < startOrder) |
665 | ||(!reverse && currentOrder < closestOrder && currentOrder > startOrder)) | 665 | ||(!reverse && currentOrder < closestOrder && currentOrder > startOrder)) |
666 | { | 666 | { |
667 | closest = *it; | 667 | closest = *it; |
668 | } | 668 | } |
669 | } | 669 | } |
670 | else | 670 | else |
671 | if ( (reverse && currentOrder < startOrder) || (!reverse && currentOrder > startOrder) ) | 671 | if ( (reverse && currentOrder < startOrder) || (!reverse && currentOrder > startOrder) ) |
672 | { | 672 | { |
673 | closest = *it; | 673 | closest = *it; |
674 | } | 674 | } |
675 | 675 | ||
676 | // is it before the current first? | 676 | // is it before the current first? |
677 | if (first) | 677 | if (first) |
678 | { | 678 | { |
679 | closestOrder = first->getTabOrder(); | 679 | closestOrder = first->getTabOrder(); |
680 | 680 | ||
681 | if ( (reverse && closestOrder < currentOrder) || (!reverse && closestOrder > currentOrder) ) | 681 | if ( (reverse && closestOrder < currentOrder) || (!reverse && closestOrder > currentOrder) ) |
682 | { | 682 | { |
683 | first = *it; | 683 | first = *it; |
684 | } | 684 | } |
685 | } | 685 | } |
686 | else | 686 | else |
687 | { | 687 | { |
688 | first = *it; | 688 | first = *it; |
689 | } | 689 | } |
690 | } | 690 | } |
691 | // search within children | 691 | // search within children |
692 | if ((*it)->getNextElement(startOrder, reverse, group, first, closest)) | 692 | if ((*it)->getNextElement(startOrder, reverse, group, first, closest)) |
693 | { | 693 | { |
694 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; | 694 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; |
695 | return true; | 695 | return true; |
696 | } | 696 | } |
697 | } | 697 | } |
698 | ++it; | 698 | ++it; |
699 | } | 699 | } |
700 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; | 700 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; |
701 | return false; | 701 | return false; |
702 | } | 702 | } |
703 | 703 | ||
704 | 704 | ||
705 | //! Returns the type of the gui element. | 705 | //! Returns the type of the gui element. |
706 | /** This is needed for the .NET wrapper but will be used | 706 | /** This is needed for the .NET wrapper but will be used |
707 | later for serializing and deserializing. | 707 | later for serializing and deserializing. |
708 | If you wrote your own GUIElements, you need to set the type for your element as first parameter | 708 | If you wrote your own GUIElements, you need to set the type for your element as first parameter |
709 | in the constructor of IGUIElement. For own (=unknown) elements, simply use EGUIET_ELEMENT as type */ | 709 | in the constructor of IGUIElement. For own (=unknown) elements, simply use EGUIET_ELEMENT as type */ |
710 | EGUI_ELEMENT_TYPE getType() const | 710 | EGUI_ELEMENT_TYPE getType() const |
711 | { | 711 | { |
712 | return Type; | 712 | return Type; |
713 | } | 713 | } |
714 | 714 | ||
715 | //! Returns true if the gui element supports the given type. | 715 | //! Returns true if the gui element supports the given type. |
716 | /** This is mostly used to check if you can cast a gui element to the class that goes with the type. | 716 | /** This is mostly used to check if you can cast a gui element to the class that goes with the type. |
717 | Most gui elements will only support their own type, but if you derive your own classes from interfaces | 717 | Most gui elements will only support their own type, but if you derive your own classes from interfaces |
718 | you can overload this function and add a check for the type of the base-class additionally. | 718 | you can overload this function and add a check for the type of the base-class additionally. |
719 | This allows for checks comparable to the dynamic_cast of c++ with enabled rtti. | 719 | This allows for checks comparable to the dynamic_cast of c++ with enabled rtti. |
720 | Note that you can't do that by calling BaseClass::hasType(type), but you have to do an explicit | 720 | Note that you can't do that by calling BaseClass::hasType(type), but you have to do an explicit |
721 | comparison check, because otherwise the base class usually just checks for the membervariable | 721 | comparison check, because otherwise the base class usually just checks for the membervariable |
722 | Type which contains the type of your derived class. | 722 | Type which contains the type of your derived class. |
723 | */ | 723 | */ |
724 | virtual bool hasType(EGUI_ELEMENT_TYPE type) const | 724 | virtual bool hasType(EGUI_ELEMENT_TYPE type) const |
725 | { | 725 | { |
726 | return type == Type; | 726 | return type == Type; |
727 | } | 727 | } |
728 | 728 | ||
729 | 729 | ||
730 | //! Returns the type name of the gui element. | 730 | //! Returns the type name of the gui element. |
731 | /** This is needed serializing elements. For serializing your own elements, override this function | 731 | /** This is needed serializing elements. For serializing your own elements, override this function |
732 | and return your own type name which is created by your IGUIElementFactory */ | 732 | and return your own type name which is created by your IGUIElementFactory */ |
733 | virtual const c8* getTypeName() const | 733 | virtual const c8* getTypeName() const |
734 | { | 734 | { |
735 | return GUIElementTypeNames[Type]; | 735 | return GUIElementTypeNames[Type]; |
736 | } | 736 | } |
737 | 737 | ||
738 | //! Returns the name of the element. | 738 | //! Returns the name of the element. |
739 | /** \return Name as character string. */ | 739 | /** \return Name as character string. */ |
740 | virtual const c8* getName() const | 740 | virtual const c8* getName() const |
741 | { | 741 | { |
742 | return Name.c_str(); | 742 | return Name.c_str(); |
743 | } | 743 | } |
744 | 744 | ||
745 | 745 | ||
746 | //! Sets the name of the element. | 746 | //! Sets the name of the element. |
747 | /** \param name New name of the gui element. */ | 747 | /** \param name New name of the gui element. */ |
748 | virtual void setName(const c8* name) | 748 | virtual void setName(const c8* name) |
749 | { | 749 | { |
750 | Name = name; | 750 | Name = name; |
751 | } | 751 | } |
752 | 752 | ||
753 | 753 | ||
754 | //! Sets the name of the element. | 754 | //! Sets the name of the element. |
755 | /** \param name New name of the gui element. */ | 755 | /** \param name New name of the gui element. */ |
756 | virtual void setName(const core::stringc& name) | 756 | virtual void setName(const core::stringc& name) |
757 | { | 757 | { |
758 | Name = name; | 758 | Name = name; |
759 | } | 759 | } |
760 | 760 | ||
761 | 761 | ||
762 | //! Writes attributes of the scene node. | 762 | //! Writes attributes of the scene node. |
763 | /** Implement this to expose the attributes of your scene node for | 763 | /** Implement this to expose the attributes of your scene node for |
764 | scripting languages, editors, debuggers or xml serialization purposes. */ | 764 | scripting languages, editors, debuggers or xml serialization purposes. */ |
765 | virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const | 765 | virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const |
766 | { | 766 | { |
767 | out->addString("Name", Name.c_str()); | 767 | out->addString("Name", Name.c_str()); |
768 | out->addInt("Id", ID ); | 768 | out->addInt("Id", ID ); |
769 | out->addString("Caption", getText()); | 769 | out->addString("Caption", getText()); |
770 | out->addRect("Rect", DesiredRect); | 770 | out->addRect("Rect", DesiredRect); |
771 | out->addPosition2d("MinSize", core::position2di(MinSize.Width, MinSize.Height)); | 771 | out->addPosition2d("MinSize", core::position2di(MinSize.Width, MinSize.Height)); |
772 | out->addPosition2d("MaxSize", core::position2di(MaxSize.Width, MaxSize.Height)); | 772 | out->addPosition2d("MaxSize", core::position2di(MaxSize.Width, MaxSize.Height)); |
773 | out->addEnum("LeftAlign", AlignLeft, GUIAlignmentNames); | 773 | out->addEnum("LeftAlign", AlignLeft, GUIAlignmentNames); |
774 | out->addEnum("RightAlign", AlignRight, GUIAlignmentNames); | 774 | out->addEnum("RightAlign", AlignRight, GUIAlignmentNames); |
775 | out->addEnum("TopAlign", AlignTop, GUIAlignmentNames); | 775 | out->addEnum("TopAlign", AlignTop, GUIAlignmentNames); |
776 | out->addEnum("BottomAlign", AlignBottom, GUIAlignmentNames); | 776 | out->addEnum("BottomAlign", AlignBottom, GUIAlignmentNames); |
777 | out->addBool("Visible", IsVisible); | 777 | out->addBool("Visible", IsVisible); |
778 | out->addBool("Enabled", IsEnabled); | 778 | out->addBool("Enabled", IsEnabled); |
779 | out->addBool("TabStop", IsTabStop); | 779 | out->addBool("TabStop", IsTabStop); |
780 | out->addBool("TabGroup", IsTabGroup); | 780 | out->addBool("TabGroup", IsTabGroup); |
781 | out->addInt("TabOrder", TabOrder); | 781 | out->addInt("TabOrder", TabOrder); |
782 | out->addBool("NoClip", NoClip); | 782 | out->addBool("NoClip", NoClip); |
783 | } | 783 | } |
784 | 784 | ||
785 | 785 | ||
786 | //! Reads attributes of the scene node. | 786 | //! Reads attributes of the scene node. |
787 | /** Implement this to set the attributes of your scene node for | 787 | /** Implement this to set the attributes of your scene node for |
788 | scripting languages, editors, debuggers or xml deserialization purposes. */ | 788 | scripting languages, editors, debuggers or xml deserialization purposes. */ |
789 | virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) | 789 | virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) |
790 | { | 790 | { |
791 | setName(in->getAttributeAsString("Name")); | 791 | setName(in->getAttributeAsString("Name")); |
792 | setID(in->getAttributeAsInt("Id")); | 792 | setID(in->getAttributeAsInt("Id")); |
793 | setText(in->getAttributeAsStringW("Caption").c_str()); | 793 | setText(in->getAttributeAsStringW("Caption").c_str()); |
794 | setVisible(in->getAttributeAsBool("Visible")); | 794 | setVisible(in->getAttributeAsBool("Visible")); |
795 | setEnabled(in->getAttributeAsBool("Enabled")); | 795 | setEnabled(in->getAttributeAsBool("Enabled")); |
796 | IsTabStop = in->getAttributeAsBool("TabStop"); | 796 | IsTabStop = in->getAttributeAsBool("TabStop"); |
797 | IsTabGroup = in->getAttributeAsBool("TabGroup"); | 797 | IsTabGroup = in->getAttributeAsBool("TabGroup"); |
798 | TabOrder = in->getAttributeAsInt("TabOrder"); | 798 | TabOrder = in->getAttributeAsInt("TabOrder"); |
799 | 799 | ||
800 | core::position2di p = in->getAttributeAsPosition2d("MaxSize"); | 800 | core::position2di p = in->getAttributeAsPosition2d("MaxSize"); |
801 | setMaxSize(core::dimension2du(p.X,p.Y)); | 801 | setMaxSize(core::dimension2du(p.X,p.Y)); |
802 | 802 | ||
803 | p = in->getAttributeAsPosition2d("MinSize"); | 803 | p = in->getAttributeAsPosition2d("MinSize"); |
804 | setMinSize(core::dimension2du(p.X,p.Y)); | 804 | setMinSize(core::dimension2du(p.X,p.Y)); |
805 | 805 | ||
806 | setAlignment((EGUI_ALIGNMENT) in->getAttributeAsEnumeration("LeftAlign", GUIAlignmentNames), | 806 | setAlignment((EGUI_ALIGNMENT) in->getAttributeAsEnumeration("LeftAlign", GUIAlignmentNames), |
807 | (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("RightAlign", GUIAlignmentNames), | 807 | (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("RightAlign", GUIAlignmentNames), |
808 | (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("TopAlign", GUIAlignmentNames), | 808 | (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("TopAlign", GUIAlignmentNames), |
809 | (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("BottomAlign", GUIAlignmentNames)); | 809 | (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("BottomAlign", GUIAlignmentNames)); |
810 | 810 | ||
811 | setRelativePosition(in->getAttributeAsRect("Rect")); | 811 | setRelativePosition(in->getAttributeAsRect("Rect")); |
812 | 812 | ||
813 | setNotClipped(in->getAttributeAsBool("NoClip")); | 813 | setNotClipped(in->getAttributeAsBool("NoClip")); |
814 | } | 814 | } |
815 | 815 | ||
816 | protected: | 816 | protected: |
817 | // not virtual because needed in constructor | 817 | // not virtual because needed in constructor |
818 | void addChildToEnd(IGUIElement* child) | 818 | void addChildToEnd(IGUIElement* child) |
819 | { | 819 | { |
820 | if (child) | 820 | if (child) |
821 | { | 821 | { |
822 | child->grab(); // prevent destruction when removed | 822 | child->grab(); // prevent destruction when removed |
823 | child->remove(); // remove from old parent | 823 | child->remove(); // remove from old parent |
824 | child->LastParentRect = getAbsolutePosition(); | 824 | child->LastParentRect = getAbsolutePosition(); |
825 | child->Parent = this; | 825 | child->Parent = this; |
826 | Children.push_back(child); | 826 | Children.push_back(child); |
827 | } | 827 | } |
828 | } | 828 | } |
829 | 829 | ||
830 | // not virtual because needed in constructor | 830 | // not virtual because needed in constructor |
831 | void recalculateAbsolutePosition(bool recursive) | 831 | void recalculateAbsolutePosition(bool recursive) |
832 | { | 832 | { |
833 | core::rect<s32> parentAbsolute(0,0,0,0); | 833 | core::rect<s32> parentAbsolute(0,0,0,0); |
834 | core::rect<s32> parentAbsoluteClip; | 834 | core::rect<s32> parentAbsoluteClip; |
835 | f32 fw=0.f, fh=0.f; | 835 | f32 fw=0.f, fh=0.f; |
836 | 836 | ||
837 | if (Parent) | 837 | if (Parent) |
838 | { | 838 | { |
839 | parentAbsolute = Parent->AbsoluteRect; | 839 | parentAbsolute = Parent->AbsoluteRect; |
840 | 840 | ||
841 | if (NoClip) | 841 | if (NoClip) |
842 | { | 842 | { |
843 | IGUIElement* p=this; | 843 | IGUIElement* p=this; |
844 | while (p && p->Parent) | 844 | while (p && p->Parent) |
845 | p = p->Parent; | 845 | p = p->Parent; |
846 | parentAbsoluteClip = p->AbsoluteClippingRect; | 846 | parentAbsoluteClip = p->AbsoluteClippingRect; |
847 | } | 847 | } |
848 | else | 848 | else |
849 | parentAbsoluteClip = Parent->AbsoluteClippingRect; | 849 | parentAbsoluteClip = Parent->AbsoluteClippingRect; |
850 | } | 850 | } |
851 | 851 | ||
852 | const s32 diffx = parentAbsolute.getWidth() - LastParentRect.getWidth(); | 852 | const s32 diffx = parentAbsolute.getWidth() - LastParentRect.getWidth(); |
853 | const s32 diffy = parentAbsolute.getHeight() - LastParentRect.getHeight(); | 853 | const s32 diffy = parentAbsolute.getHeight() - LastParentRect.getHeight(); |
854 | 854 | ||
855 | if (AlignLeft == EGUIA_SCALE || AlignRight == EGUIA_SCALE) | 855 | if (AlignLeft == EGUIA_SCALE || AlignRight == EGUIA_SCALE) |
856 | fw = (f32)parentAbsolute.getWidth(); | 856 | fw = (f32)parentAbsolute.getWidth(); |
857 | 857 | ||
858 | if (AlignTop == EGUIA_SCALE || AlignBottom == EGUIA_SCALE) | 858 | if (AlignTop == EGUIA_SCALE || AlignBottom == EGUIA_SCALE) |
859 | fh = (f32)parentAbsolute.getHeight(); | 859 | fh = (f32)parentAbsolute.getHeight(); |
860 | 860 | ||
861 | switch (AlignLeft) | 861 | switch (AlignLeft) |
862 | { | 862 | { |
863 | case EGUIA_UPPERLEFT: | 863 | case EGUIA_UPPERLEFT: |
864 | break; | 864 | break; |
865 | case EGUIA_LOWERRIGHT: | 865 | case EGUIA_LOWERRIGHT: |
866 | DesiredRect.UpperLeftCorner.X += diffx; | 866 | DesiredRect.UpperLeftCorner.X += diffx; |
867 | break; | 867 | break; |
868 | case EGUIA_CENTER: | 868 | case EGUIA_CENTER: |
869 | DesiredRect.UpperLeftCorner.X += diffx/2; | 869 | DesiredRect.UpperLeftCorner.X += diffx/2; |
870 | break; | 870 | break; |
871 | case EGUIA_SCALE: | 871 | case EGUIA_SCALE: |
872 | DesiredRect.UpperLeftCorner.X = core::round32(ScaleRect.UpperLeftCorner.X * fw); | 872 | DesiredRect.UpperLeftCorner.X = core::round32(ScaleRect.UpperLeftCorner.X * fw); |
873 | break; | 873 | break; |
874 | } | 874 | } |
875 | 875 | ||
876 | switch (AlignRight) | 876 | switch (AlignRight) |
877 | { | 877 | { |
878 | case EGUIA_UPPERLEFT: | 878 | case EGUIA_UPPERLEFT: |
879 | break; | 879 | break; |
880 | case EGUIA_LOWERRIGHT: | 880 | case EGUIA_LOWERRIGHT: |
881 | DesiredRect.LowerRightCorner.X += diffx; | 881 | DesiredRect.LowerRightCorner.X += diffx; |
882 | break; | 882 | break; |
883 | case EGUIA_CENTER: | 883 | case EGUIA_CENTER: |
884 | DesiredRect.LowerRightCorner.X += diffx/2; | 884 | DesiredRect.LowerRightCorner.X += diffx/2; |
885 | break; | 885 | break; |
886 | case EGUIA_SCALE: | 886 | case EGUIA_SCALE: |
887 | DesiredRect.LowerRightCorner.X = core::round32(ScaleRect.LowerRightCorner.X * fw); | 887 | DesiredRect.LowerRightCorner.X = core::round32(ScaleRect.LowerRightCorner.X * fw); |
888 | break; | 888 | break; |
889 | } | 889 | } |
890 | 890 | ||
891 | switch (AlignTop) | 891 | switch (AlignTop) |
892 | { | 892 | { |
893 | case EGUIA_UPPERLEFT: | 893 | case EGUIA_UPPERLEFT: |
894 | break; | 894 | break; |
895 | case EGUIA_LOWERRIGHT: | 895 | case EGUIA_LOWERRIGHT: |
896 | DesiredRect.UpperLeftCorner.Y += diffy; | 896 | DesiredRect.UpperLeftCorner.Y += diffy; |
897 | break; | 897 | break; |
898 | case EGUIA_CENTER: | 898 | case EGUIA_CENTER: |
899 | DesiredRect.UpperLeftCorner.Y += diffy/2; | 899 | DesiredRect.UpperLeftCorner.Y += diffy/2; |
900 | break; | 900 | break; |
901 | case EGUIA_SCALE: | 901 | case EGUIA_SCALE: |
902 | DesiredRect.UpperLeftCorner.Y = core::round32(ScaleRect.UpperLeftCorner.Y * fh); | 902 | DesiredRect.UpperLeftCorner.Y = core::round32(ScaleRect.UpperLeftCorner.Y * fh); |
903 | break; | 903 | break; |
904 | } | 904 | } |
905 | 905 | ||
906 | switch (AlignBottom) | 906 | switch (AlignBottom) |
907 | { | 907 | { |
908 | case EGUIA_UPPERLEFT: | 908 | case EGUIA_UPPERLEFT: |
909 | break; | 909 | break; |
910 | case EGUIA_LOWERRIGHT: | 910 | case EGUIA_LOWERRIGHT: |
911 | DesiredRect.LowerRightCorner.Y += diffy; | 911 | DesiredRect.LowerRightCorner.Y += diffy; |
912 | break; | 912 | break; |
913 | case EGUIA_CENTER: | 913 | case EGUIA_CENTER: |
914 | DesiredRect.LowerRightCorner.Y += diffy/2; | 914 | DesiredRect.LowerRightCorner.Y += diffy/2; |
915 | break; | 915 | break; |
916 | case EGUIA_SCALE: | 916 | case EGUIA_SCALE: |
917 | DesiredRect.LowerRightCorner.Y = core::round32(ScaleRect.LowerRightCorner.Y * fh); | 917 | DesiredRect.LowerRightCorner.Y = core::round32(ScaleRect.LowerRightCorner.Y * fh); |
918 | break; | 918 | break; |
919 | } | 919 | } |
920 | 920 | ||
921 | RelativeRect = DesiredRect; | 921 | RelativeRect = DesiredRect; |
922 | 922 | ||
923 | const s32 w = RelativeRect.getWidth(); | 923 | const s32 w = RelativeRect.getWidth(); |
924 | const s32 h = RelativeRect.getHeight(); | 924 | const s32 h = RelativeRect.getHeight(); |
925 | 925 | ||
926 | // make sure the desired rectangle is allowed | 926 | // make sure the desired rectangle is allowed |
927 | if (w < (s32)MinSize.Width) | 927 | if (w < (s32)MinSize.Width) |
928 | RelativeRect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + MinSize.Width; | 928 | RelativeRect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + MinSize.Width; |
929 | if (h < (s32)MinSize.Height) | 929 | if (h < (s32)MinSize.Height) |
930 | RelativeRect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + MinSize.Height; | 930 | RelativeRect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + MinSize.Height; |
931 | if (MaxSize.Width && w > (s32)MaxSize.Width) | 931 | if (MaxSize.Width && w > (s32)MaxSize.Width) |
932 | RelativeRect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + MaxSize.Width; | 932 | RelativeRect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + MaxSize.Width; |
933 | if (MaxSize.Height && h > (s32)MaxSize.Height) | 933 | if (MaxSize.Height && h > (s32)MaxSize.Height) |
934 | RelativeRect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + MaxSize.Height; | 934 | RelativeRect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + MaxSize.Height; |
935 | 935 | ||
936 | RelativeRect.repair(); | 936 | RelativeRect.repair(); |
937 | 937 | ||
938 | AbsoluteRect = RelativeRect + parentAbsolute.UpperLeftCorner; | 938 | AbsoluteRect = RelativeRect + parentAbsolute.UpperLeftCorner; |
939 | 939 | ||
940 | if (!Parent) | 940 | if (!Parent) |
941 | parentAbsoluteClip = AbsoluteRect; | 941 | parentAbsoluteClip = AbsoluteRect; |
942 | 942 | ||
943 | AbsoluteClippingRect = AbsoluteRect; | 943 | AbsoluteClippingRect = AbsoluteRect; |
944 | AbsoluteClippingRect.clipAgainst(parentAbsoluteClip); | 944 | AbsoluteClippingRect.clipAgainst(parentAbsoluteClip); |
945 | 945 | ||
946 | LastParentRect = parentAbsolute; | 946 | LastParentRect = parentAbsolute; |
947 | 947 | ||
948 | if ( recursive ) | 948 | if ( recursive ) |
949 | { | 949 | { |
950 | // update all children | 950 | // update all children |
951 | core::list<IGUIElement*>::Iterator it = Children.begin(); | 951 | core::list<IGUIElement*>::Iterator it = Children.begin(); |
952 | for (; it != Children.end(); ++it) | 952 | for (; it != Children.end(); ++it) |
953 | { | 953 | { |
954 | (*it)->recalculateAbsolutePosition(recursive); | 954 | (*it)->recalculateAbsolutePosition(recursive); |
955 | } | 955 | } |
956 | } | 956 | } |
957 | } | 957 | } |
958 | 958 | ||
959 | protected: | 959 | protected: |
960 | 960 | ||
961 | //! List of all children of this element | 961 | //! List of all children of this element |
962 | core::list<IGUIElement*> Children; | 962 | core::list<IGUIElement*> Children; |
963 | 963 | ||
964 | //! Pointer to the parent | 964 | //! Pointer to the parent |
965 | IGUIElement* Parent; | 965 | IGUIElement* Parent; |
966 | 966 | ||
967 | //! relative rect of element | 967 | //! relative rect of element |
968 | core::rect<s32> RelativeRect; | 968 | core::rect<s32> RelativeRect; |
969 | 969 | ||
970 | //! absolute rect of element | 970 | //! absolute rect of element |
971 | core::rect<s32> AbsoluteRect; | 971 | core::rect<s32> AbsoluteRect; |
972 | 972 | ||
973 | //! absolute clipping rect of element | 973 | //! absolute clipping rect of element |
974 | core::rect<s32> AbsoluteClippingRect; | 974 | core::rect<s32> AbsoluteClippingRect; |
975 | 975 | ||
976 | //! the rectangle the element would prefer to be, | 976 | //! the rectangle the element would prefer to be, |
977 | //! if it was not constrained by parent or max/min size | 977 | //! if it was not constrained by parent or max/min size |
978 | core::rect<s32> DesiredRect; | 978 | core::rect<s32> DesiredRect; |
979 | 979 | ||
980 | //! for calculating the difference when resizing parent | 980 | //! for calculating the difference when resizing parent |
981 | core::rect<s32> LastParentRect; | 981 | core::rect<s32> LastParentRect; |
982 | 982 | ||
983 | //! relative scale of the element inside its parent | 983 | //! relative scale of the element inside its parent |
984 | core::rect<f32> ScaleRect; | 984 | core::rect<f32> ScaleRect; |
985 | 985 | ||
986 | //! maximum and minimum size of the element | 986 | //! maximum and minimum size of the element |
987 | core::dimension2du MaxSize, MinSize; | 987 | core::dimension2du MaxSize, MinSize; |
988 | 988 | ||
989 | //! is visible? | 989 | //! is visible? |
990 | bool IsVisible; | 990 | bool IsVisible; |
991 | 991 | ||
992 | //! is enabled? | 992 | //! is enabled? |
993 | bool IsEnabled; | 993 | bool IsEnabled; |
994 | 994 | ||
995 | //! is a part of a larger whole and should not be serialized? | 995 | //! is a part of a larger whole and should not be serialized? |
996 | bool IsSubElement; | 996 | bool IsSubElement; |
997 | 997 | ||
998 | //! does this element ignore its parent's clipping rectangle? | 998 | //! does this element ignore its parent's clipping rectangle? |
999 | bool NoClip; | 999 | bool NoClip; |
1000 | 1000 | ||
1001 | //! caption | 1001 | //! caption |
1002 | core::stringw Text; | 1002 | core::stringw Text; |
1003 | 1003 | ||
1004 | //! tooltip | 1004 | //! tooltip |
1005 | core::stringw ToolTipText; | 1005 | core::stringw ToolTipText; |
1006 | 1006 | ||
1007 | //! users can set this for identificating the element by string | 1007 | //! users can set this for identificating the element by string |
1008 | core::stringc Name; | 1008 | core::stringc Name; |
1009 | 1009 | ||
1010 | //! users can set this for identificating the element by integer | 1010 | //! users can set this for identificating the element by integer |
1011 | s32 ID; | 1011 | s32 ID; |
1012 | 1012 | ||
1013 | //! tab stop like in windows | 1013 | //! tab stop like in windows |
1014 | bool IsTabStop; | 1014 | bool IsTabStop; |
1015 | 1015 | ||
1016 | //! tab order | 1016 | //! tab order |
1017 | s32 TabOrder; | 1017 | s32 TabOrder; |
1018 | 1018 | ||
1019 | //! tab groups are containers like windows, use ctrl+tab to navigate | 1019 | //! tab groups are containers like windows, use ctrl+tab to navigate |
1020 | bool IsTabGroup; | 1020 | bool IsTabGroup; |
1021 | 1021 | ||
1022 | //! tells the element how to act when its parent is resized | 1022 | //! tells the element how to act when its parent is resized |
1023 | EGUI_ALIGNMENT AlignLeft, AlignRight, AlignTop, AlignBottom; | 1023 | EGUI_ALIGNMENT AlignLeft, AlignRight, AlignTop, AlignBottom; |
1024 | 1024 | ||
1025 | //! GUI Environment | 1025 | //! GUI Environment |
1026 | IGUIEnvironment* Environment; | 1026 | IGUIEnvironment* Environment; |
1027 | 1027 | ||
1028 | //! type of element | 1028 | //! type of element |
1029 | EGUI_ELEMENT_TYPE Type; | 1029 | EGUI_ELEMENT_TYPE Type; |
1030 | }; | 1030 | }; |
1031 | 1031 | ||
1032 | 1032 | ||
1033 | } // end namespace gui | 1033 | } // end namespace gui |
1034 | } // end namespace irr | 1034 | } // end namespace irr |
1035 | 1035 | ||
1036 | #endif | 1036 | #endif |
1037 | 1037 | ||