aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/include/IGUIElement.h
diff options
context:
space:
mode:
authorDavid Walter Seikel2013-01-13 18:54:10 +1000
committerDavid Walter Seikel2013-01-13 18:54:10 +1000
commit959831f4ef5a3e797f576c3de08cd65032c997ad (patch)
treee7351908be5995f0b325b2ebeaa02d5a34b82583 /libraries/irrlicht-1.8/include/IGUIElement.h
parentAdd info about changes to Irrlicht. (diff)
downloadSledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.zip
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.gz
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.bz2
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.xz
Remove damned ancient DOS line endings from Irrlicht. Hopefully I did not go overboard.
Diffstat (limited to 'libraries/irrlicht-1.8/include/IGUIElement.h')
-rw-r--r--libraries/irrlicht-1.8/include/IGUIElement.h2074
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
17namespace irr 17namespace irr
18{ 18{
19namespace gui 19namespace gui
20{ 20{
21 21
22class IGUIEnvironment; 22class IGUIEnvironment;
23 23
24//! Base class of all GUI elements. 24//! Base class of all GUI elements.
25class IGUIElement : public virtual io::IAttributeExchangingObject, public IEventReceiver 25class IGUIElement : public virtual io::IAttributeExchangingObject, public IEventReceiver
26{ 26{
27public: 27public:
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
816protected: 816protected:
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
959protected: 959protected:
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