00001
00002
00003
00004
00005 #ifndef __I_GUI_ELEMENT_H_INCLUDED__
00006 #define __I_GUI_ELEMENT_H_INCLUDED__
00007
00008 #include "IAttributeExchangingObject.h"
00009 #include "irrList.h"
00010 #include "rect.h"
00011 #include "irrString.h"
00012 #include "IEventReceiver.h"
00013 #include "EGUIElementTypes.h"
00014 #include "EGUIAlignment.h"
00015 #include "IAttributes.h"
00016
00017 namespace irr
00018 {
00019 namespace gui
00020 {
00021
00022 class IGUIEnvironment;
00023
00025 class IGUIElement : public virtual io::IAttributeExchangingObject, public IEventReceiver
00026 {
00027 public:
00028
00030 IGUIElement(EGUI_ELEMENT_TYPE type, IGUIEnvironment* environment, IGUIElement* parent,
00031 s32 id, const core::rect<s32>& rectangle)
00032 : Parent(0), RelativeRect(rectangle), AbsoluteRect(rectangle),
00033 AbsoluteClippingRect(rectangle), DesiredRect(rectangle),
00034 MaxSize(0,0), MinSize(1,1), IsVisible(true), IsEnabled(true),
00035 IsSubElement(false), NoClip(false), ID(id), IsTabStop(false), TabOrder(-1), IsTabGroup(false),
00036 AlignLeft(EGUIA_UPPERLEFT), AlignRight(EGUIA_UPPERLEFT), AlignTop(EGUIA_UPPERLEFT), AlignBottom(EGUIA_UPPERLEFT),
00037 Environment(environment), Type(type)
00038 {
00039 #ifdef _DEBUG
00040 setDebugName("IGUIElement");
00041 #endif
00042
00043
00044 if (parent)
00045 {
00046 parent->addChildToEnd(this);
00047 recalculateAbsolutePosition(true);
00048 }
00049 }
00050
00051
00053 virtual ~IGUIElement()
00054 {
00055
00056 core::list<IGUIElement*>::Iterator it = Children.begin();
00057 for (; it != Children.end(); ++it)
00058 {
00059 (*it)->Parent = 0;
00060 (*it)->drop();
00061 }
00062 }
00063
00064
00066 IGUIElement* getParent() const
00067 {
00068 return Parent;
00069 }
00070
00071
00073 core::rect<s32> getRelativePosition() const
00074 {
00075 return RelativeRect;
00076 }
00077
00078
00080
00081 void setRelativePosition(const core::rect<s32>& r)
00082 {
00083 if (Parent)
00084 {
00085 const core::rect<s32>& r2 = Parent->getAbsolutePosition();
00086
00087 core::dimension2df d((f32)(r2.getSize().Width), (f32)(r2.getSize().Height));
00088
00089 if (AlignLeft == EGUIA_SCALE)
00090 ScaleRect.UpperLeftCorner.X = (f32)r.UpperLeftCorner.X / d.Width;
00091 if (AlignRight == EGUIA_SCALE)
00092 ScaleRect.LowerRightCorner.X = (f32)r.LowerRightCorner.X / d.Width;
00093 if (AlignTop == EGUIA_SCALE)
00094 ScaleRect.UpperLeftCorner.Y = (f32)r.UpperLeftCorner.Y / d.Height;
00095 if (AlignBottom == EGUIA_SCALE)
00096 ScaleRect.LowerRightCorner.Y = (f32)r.LowerRightCorner.Y / d.Height;
00097 }
00098
00099 DesiredRect = r;
00100 updateAbsolutePosition();
00101 }
00102
00104
00105 void setRelativePosition(const core::position2di & position)
00106 {
00107 const core::dimension2di mySize = RelativeRect.getSize();
00108 const core::rect<s32> rectangle(position.X, position.Y,
00109 position.X + mySize.Width, position.Y + mySize.Height);
00110 setRelativePosition(rectangle);
00111 }
00112
00113
00115
00119 void setRelativePositionProportional(const core::rect<f32>& r)
00120 {
00121 if (!Parent)
00122 return;
00123
00124 const core::dimension2di& d = Parent->getAbsolutePosition().getSize();
00125
00126 DesiredRect = core::rect<s32>(
00127 core::floor32((f32)d.Width * r.UpperLeftCorner.X),
00128 core::floor32((f32)d.Height * r.UpperLeftCorner.Y),
00129 core::floor32((f32)d.Width * r.LowerRightCorner.X),
00130 core::floor32((f32)d.Height * r.LowerRightCorner.Y));
00131
00132 ScaleRect = r;
00133
00134 updateAbsolutePosition();
00135 }
00136
00137
00139 core::rect<s32> getAbsolutePosition() const
00140 {
00141 return AbsoluteRect;
00142 }
00143
00144
00146 core::rect<s32> getAbsoluteClippingRect() const
00147 {
00148 return AbsoluteClippingRect;
00149 }
00150
00151
00153
00154 void setNotClipped(bool noClip)
00155 {
00156 NoClip = noClip;
00157 updateAbsolutePosition();
00158 }
00159
00160
00162
00163 bool isNotClipped() const
00164 {
00165 return NoClip;
00166 }
00167
00168
00170
00171 void setMaxSize(core::dimension2du size)
00172 {
00173 MaxSize = size;
00174 updateAbsolutePosition();
00175 }
00176
00177
00179 void setMinSize(core::dimension2du size)
00180 {
00181 MinSize = size;
00182 if (MinSize.Width < 1)
00183 MinSize.Width = 1;
00184 if (MinSize.Height < 1)
00185 MinSize.Height = 1;
00186 updateAbsolutePosition();
00187 }
00188
00189
00191 void setAlignment(EGUI_ALIGNMENT left, EGUI_ALIGNMENT right, EGUI_ALIGNMENT top, EGUI_ALIGNMENT bottom)
00192 {
00193 AlignLeft = left;
00194 AlignRight = right;
00195 AlignTop = top;
00196 AlignBottom = bottom;
00197
00198 if (Parent)
00199 {
00200 core::rect<s32> r(Parent->getAbsolutePosition());
00201
00202 core::dimension2df d((f32)r.getSize().Width, (f32)r.getSize().Height);
00203
00204 if (AlignLeft == EGUIA_SCALE)
00205 ScaleRect.UpperLeftCorner.X = (f32)DesiredRect.UpperLeftCorner.X / d.Width;
00206 if (AlignRight == EGUIA_SCALE)
00207 ScaleRect.LowerRightCorner.X = (f32)DesiredRect.LowerRightCorner.X / d.Width;
00208 if (AlignTop == EGUIA_SCALE)
00209 ScaleRect.UpperLeftCorner.Y = (f32)DesiredRect.UpperLeftCorner.Y / d.Height;
00210 if (AlignBottom == EGUIA_SCALE)
00211 ScaleRect.LowerRightCorner.Y = (f32)DesiredRect.LowerRightCorner.Y / d.Height;
00212 }
00213 }
00214
00215
00217 virtual void updateAbsolutePosition()
00218 {
00219 recalculateAbsolutePosition(false);
00220
00221
00222 core::list<IGUIElement*>::Iterator it = Children.begin();
00223 for (; it != Children.end(); ++it)
00224 {
00225 (*it)->updateAbsolutePosition();
00226 }
00227 }
00228
00229
00231
00242 IGUIElement* getElementFromPoint(const core::position2d<s32>& point)
00243 {
00244 IGUIElement* target = 0;
00245
00246
00247
00248
00249 core::list<IGUIElement*>::Iterator it = Children.getLast();
00250
00251 if (isVisible())
00252 {
00253 while(it != Children.end())
00254 {
00255 target = (*it)->getElementFromPoint(point);
00256 if (target)
00257 return target;
00258
00259 --it;
00260 }
00261 }
00262
00263 if (isVisible() && isPointInside(point))
00264 target = this;
00265
00266 return target;
00267 }
00268
00269
00271
00272 virtual bool isPointInside(const core::position2d<s32>& point) const
00273 {
00274 return AbsoluteClippingRect.isPointInside(point);
00275 }
00276
00277
00279 virtual void addChild(IGUIElement* child)
00280 {
00281 addChildToEnd(child);
00282 if (child)
00283 {
00284 child->updateAbsolutePosition();
00285 }
00286 }
00287
00289 virtual void removeChild(IGUIElement* child)
00290 {
00291 core::list<IGUIElement*>::Iterator it = Children.begin();
00292 for (; it != Children.end(); ++it)
00293 if ((*it) == child)
00294 {
00295 (*it)->Parent = 0;
00296 (*it)->drop();
00297 Children.erase(it);
00298 return;
00299 }
00300 }
00301
00302
00304 virtual void remove()
00305 {
00306 if (Parent)
00307 Parent->removeChild(this);
00308 }
00309
00310
00312 virtual void draw()
00313 {
00314 if ( isVisible() )
00315 {
00316 core::list<IGUIElement*>::Iterator it = Children.begin();
00317 for (; it != Children.end(); ++it)
00318 (*it)->draw();
00319 }
00320 }
00321
00322
00324 virtual void OnPostRender(u32 timeMs)
00325 {
00326 if ( isVisible() )
00327 {
00328 core::list<IGUIElement*>::Iterator it = Children.begin();
00329 for (; it != Children.end(); ++it)
00330 (*it)->OnPostRender( timeMs );
00331 }
00332 }
00333
00334
00336 virtual void move(core::position2d<s32> absoluteMovement)
00337 {
00338 setRelativePosition(DesiredRect + absoluteMovement);
00339 }
00340
00341
00343 virtual bool isVisible() const
00344 {
00345 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00346 return IsVisible;
00347 }
00348
00349
00351 virtual void setVisible(bool visible)
00352 {
00353 IsVisible = visible;
00354 }
00355
00356
00358 virtual bool isSubElement() const
00359 {
00360 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00361 return IsSubElement;
00362 }
00363
00364
00366
00368 virtual void setSubElement(bool subElement)
00369 {
00370 IsSubElement = subElement;
00371 }
00372
00373
00375
00377 void setTabStop(bool enable)
00378 {
00379 IsTabStop = enable;
00380 }
00381
00382
00384 bool isTabStop() const
00385 {
00386 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00387 return IsTabStop;
00388 }
00389
00390
00392
00394 void setTabOrder(s32 index)
00395 {
00396
00397 if (index < 0)
00398 {
00399 TabOrder = 0;
00400 IGUIElement *el = getTabGroup();
00401 while (IsTabGroup && el && el->Parent)
00402 el = el->Parent;
00403
00404 IGUIElement *first=0, *closest=0;
00405 if (el)
00406 {
00407
00408 el->getNextElement(-1, true, IsTabGroup, first, closest, true);
00409 if (first)
00410 {
00411 TabOrder = first->getTabOrder() + 1;
00412 }
00413 }
00414
00415 }
00416 else
00417 TabOrder = index;
00418 }
00419
00420
00422 s32 getTabOrder() const
00423 {
00424 return TabOrder;
00425 }
00426
00427
00429
00431 void setTabGroup(bool isGroup)
00432 {
00433 IsTabGroup = isGroup;
00434 }
00435
00436
00438 bool isTabGroup() const
00439 {
00440 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00441 return IsTabGroup;
00442 }
00443
00444
00446 IGUIElement* getTabGroup()
00447 {
00448 IGUIElement *ret=this;
00449
00450 while (ret && !ret->isTabGroup())
00451 ret = ret->getParent();
00452
00453 return ret;
00454 }
00455
00456
00458
00462 virtual bool isEnabled() const
00463 {
00464 if ( isSubElement() && IsEnabled && getParent() )
00465 return getParent()->isEnabled();
00466
00467 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00468 return IsEnabled;
00469 }
00470
00471
00473 virtual void setEnabled(bool enabled)
00474 {
00475 IsEnabled = enabled;
00476 }
00477
00478
00480 virtual void setText(const wchar_t* text)
00481 {
00482 Text = text;
00483 }
00484
00485
00487 virtual const wchar_t* getText() const
00488 {
00489 return Text.c_str();
00490 }
00491
00492
00494 virtual void setToolTipText(const wchar_t* text)
00495 {
00496 ToolTipText = text;
00497 }
00498
00499
00501 virtual const core::stringw& getToolTipText() const
00502 {
00503 return ToolTipText;
00504 }
00505
00506
00508 virtual s32 getID() const
00509 {
00510 return ID;
00511 }
00512
00513
00515 virtual void setID(s32 id)
00516 {
00517 ID = id;
00518 }
00519
00520
00522 virtual bool OnEvent(const SEvent& event)
00523 {
00524 return Parent ? Parent->OnEvent(event) : false;
00525 }
00526
00527
00529
00530 virtual bool bringToFront(IGUIElement* element)
00531 {
00532 core::list<IGUIElement*>::Iterator it = Children.begin();
00533 for (; it != Children.end(); ++it)
00534 {
00535 if (element == (*it))
00536 {
00537 Children.erase(it);
00538 Children.push_back(element);
00539 return true;
00540 }
00541 }
00542
00543 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00544 return false;
00545 }
00546
00547
00549
00550 virtual bool sendToBack(IGUIElement* child)
00551 {
00552 core::list<IGUIElement*>::Iterator it = Children.begin();
00553 if (child == (*it))
00554 return true;
00555 for (; it != Children.end(); ++it)
00556 {
00557 if (child == (*it))
00558 {
00559 Children.erase(it);
00560 Children.push_front(child);
00561 return true;
00562 }
00563 }
00564
00565 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00566 return false;
00567 }
00568
00570 virtual const core::list<IGUIElement*>& getChildren() const
00571 {
00572 return Children;
00573 }
00574
00575
00577
00583 virtual IGUIElement* getElementFromId(s32 id, bool searchchildren=false) const
00584 {
00585 IGUIElement* e = 0;
00586
00587 core::list<IGUIElement*>::ConstIterator it = Children.begin();
00588 for (; it != Children.end(); ++it)
00589 {
00590 if ((*it)->getID() == id)
00591 return (*it);
00592
00593 if (searchchildren)
00594 e = (*it)->getElementFromId(id, true);
00595
00596 if (e)
00597 return e;
00598 }
00599
00600 return e;
00601 }
00602
00603
00606 bool isMyChild(IGUIElement* child) const
00607 {
00608 if (!child)
00609 return false;
00610 do
00611 {
00612 if (child->Parent)
00613 child = child->Parent;
00614
00615 } while (child->Parent && child != this);
00616
00617 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00618 return child == this;
00619 }
00620
00621
00623
00630 bool getNextElement(s32 startOrder, bool reverse, bool group,
00631 IGUIElement*& first, IGUIElement*& closest, bool includeInvisible=false) const
00632 {
00633
00634 s32 wanted = startOrder + ( reverse ? -1 : 1 );
00635 if (wanted==-2)
00636 wanted = 1073741824;
00637
00638 core::list<IGUIElement*>::ConstIterator it = Children.begin();
00639
00640 s32 closestOrder, currentOrder;
00641
00642 while(it != Children.end())
00643 {
00644
00645 if ( ( (*it)->isVisible() || includeInvisible ) &&
00646 (group == true || (*it)->isTabGroup() == false) )
00647 {
00648
00649 if ((*it)->isTabStop() && ((*it)->isTabGroup() == group))
00650 {
00651 currentOrder = (*it)->getTabOrder();
00652
00653
00654 if (currentOrder == wanted)
00655 {
00656 closest = *it;
00657 return true;
00658 }
00659
00660
00661 if (closest)
00662 {
00663 closestOrder = closest->getTabOrder();
00664 if ( ( reverse && currentOrder > closestOrder && currentOrder < startOrder)
00665 ||(!reverse && currentOrder < closestOrder && currentOrder > startOrder))
00666 {
00667 closest = *it;
00668 }
00669 }
00670 else
00671 if ( (reverse && currentOrder < startOrder) || (!reverse && currentOrder > startOrder) )
00672 {
00673 closest = *it;
00674 }
00675
00676
00677 if (first)
00678 {
00679 closestOrder = first->getTabOrder();
00680
00681 if ( (reverse && closestOrder < currentOrder) || (!reverse && closestOrder > currentOrder) )
00682 {
00683 first = *it;
00684 }
00685 }
00686 else
00687 {
00688 first = *it;
00689 }
00690 }
00691
00692 if ((*it)->getNextElement(startOrder, reverse, group, first, closest))
00693 {
00694 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00695 return true;
00696 }
00697 }
00698 ++it;
00699 }
00700 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00701 return false;
00702 }
00703
00704
00706
00710 EGUI_ELEMENT_TYPE getType() const
00711 {
00712 return Type;
00713 }
00714
00716
00724 virtual bool hasType(EGUI_ELEMENT_TYPE type) const
00725 {
00726 return type == Type;
00727 }
00728
00729
00731
00733 virtual const c8* getTypeName() const
00734 {
00735 return GUIElementTypeNames[Type];
00736 }
00737
00739
00740 virtual const c8* getName() const
00741 {
00742 return Name.c_str();
00743 }
00744
00745
00747
00748 virtual void setName(const c8* name)
00749 {
00750 Name = name;
00751 }
00752
00753
00755
00756 virtual void setName(const core::stringc& name)
00757 {
00758 Name = name;
00759 }
00760
00761
00763
00765 virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const
00766 {
00767 out->addString("Name", Name.c_str());
00768 out->addInt("Id", ID );
00769 out->addString("Caption", getText());
00770 out->addRect("Rect", DesiredRect);
00771 out->addPosition2d("MinSize", core::position2di(MinSize.Width, MinSize.Height));
00772 out->addPosition2d("MaxSize", core::position2di(MaxSize.Width, MaxSize.Height));
00773 out->addEnum("LeftAlign", AlignLeft, GUIAlignmentNames);
00774 out->addEnum("RightAlign", AlignRight, GUIAlignmentNames);
00775 out->addEnum("TopAlign", AlignTop, GUIAlignmentNames);
00776 out->addEnum("BottomAlign", AlignBottom, GUIAlignmentNames);
00777 out->addBool("Visible", IsVisible);
00778 out->addBool("Enabled", IsEnabled);
00779 out->addBool("TabStop", IsTabStop);
00780 out->addBool("TabGroup", IsTabGroup);
00781 out->addInt("TabOrder", TabOrder);
00782 out->addBool("NoClip", NoClip);
00783 }
00784
00785
00787
00789 virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)
00790 {
00791 setName(in->getAttributeAsString("Name"));
00792 setID(in->getAttributeAsInt("Id"));
00793 setText(in->getAttributeAsStringW("Caption").c_str());
00794 setVisible(in->getAttributeAsBool("Visible"));
00795 setEnabled(in->getAttributeAsBool("Enabled"));
00796 IsTabStop = in->getAttributeAsBool("TabStop");
00797 IsTabGroup = in->getAttributeAsBool("TabGroup");
00798 TabOrder = in->getAttributeAsInt("TabOrder");
00799
00800 core::position2di p = in->getAttributeAsPosition2d("MaxSize");
00801 setMaxSize(core::dimension2du(p.X,p.Y));
00802
00803 p = in->getAttributeAsPosition2d("MinSize");
00804 setMinSize(core::dimension2du(p.X,p.Y));
00805
00806 setAlignment((EGUI_ALIGNMENT) in->getAttributeAsEnumeration("LeftAlign", GUIAlignmentNames),
00807 (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("RightAlign", GUIAlignmentNames),
00808 (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("TopAlign", GUIAlignmentNames),
00809 (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("BottomAlign", GUIAlignmentNames));
00810
00811 setRelativePosition(in->getAttributeAsRect("Rect"));
00812
00813 setNotClipped(in->getAttributeAsBool("NoClip"));
00814 }
00815
00816 protected:
00817
00818 void addChildToEnd(IGUIElement* child)
00819 {
00820 if (child)
00821 {
00822 child->grab();
00823 child->remove();
00824 child->LastParentRect = getAbsolutePosition();
00825 child->Parent = this;
00826 Children.push_back(child);
00827 }
00828 }
00829
00830
00831 void recalculateAbsolutePosition(bool recursive)
00832 {
00833 core::rect<s32> parentAbsolute(0,0,0,0);
00834 core::rect<s32> parentAbsoluteClip;
00835 f32 fw=0.f, fh=0.f;
00836
00837 if (Parent)
00838 {
00839 parentAbsolute = Parent->AbsoluteRect;
00840
00841 if (NoClip)
00842 {
00843 IGUIElement* p=this;
00844 while (p && p->Parent)
00845 p = p->Parent;
00846 parentAbsoluteClip = p->AbsoluteClippingRect;
00847 }
00848 else
00849 parentAbsoluteClip = Parent->AbsoluteClippingRect;
00850 }
00851
00852 const s32 diffx = parentAbsolute.getWidth() - LastParentRect.getWidth();
00853 const s32 diffy = parentAbsolute.getHeight() - LastParentRect.getHeight();
00854
00855 if (AlignLeft == EGUIA_SCALE || AlignRight == EGUIA_SCALE)
00856 fw = (f32)parentAbsolute.getWidth();
00857
00858 if (AlignTop == EGUIA_SCALE || AlignBottom == EGUIA_SCALE)
00859 fh = (f32)parentAbsolute.getHeight();
00860
00861 switch (AlignLeft)
00862 {
00863 case EGUIA_UPPERLEFT:
00864 break;
00865 case EGUIA_LOWERRIGHT:
00866 DesiredRect.UpperLeftCorner.X += diffx;
00867 break;
00868 case EGUIA_CENTER:
00869 DesiredRect.UpperLeftCorner.X += diffx/2;
00870 break;
00871 case EGUIA_SCALE:
00872 DesiredRect.UpperLeftCorner.X = core::round32(ScaleRect.UpperLeftCorner.X * fw);
00873 break;
00874 }
00875
00876 switch (AlignRight)
00877 {
00878 case EGUIA_UPPERLEFT:
00879 break;
00880 case EGUIA_LOWERRIGHT:
00881 DesiredRect.LowerRightCorner.X += diffx;
00882 break;
00883 case EGUIA_CENTER:
00884 DesiredRect.LowerRightCorner.X += diffx/2;
00885 break;
00886 case EGUIA_SCALE:
00887 DesiredRect.LowerRightCorner.X = core::round32(ScaleRect.LowerRightCorner.X * fw);
00888 break;
00889 }
00890
00891 switch (AlignTop)
00892 {
00893 case EGUIA_UPPERLEFT:
00894 break;
00895 case EGUIA_LOWERRIGHT:
00896 DesiredRect.UpperLeftCorner.Y += diffy;
00897 break;
00898 case EGUIA_CENTER:
00899 DesiredRect.UpperLeftCorner.Y += diffy/2;
00900 break;
00901 case EGUIA_SCALE:
00902 DesiredRect.UpperLeftCorner.Y = core::round32(ScaleRect.UpperLeftCorner.Y * fh);
00903 break;
00904 }
00905
00906 switch (AlignBottom)
00907 {
00908 case EGUIA_UPPERLEFT:
00909 break;
00910 case EGUIA_LOWERRIGHT:
00911 DesiredRect.LowerRightCorner.Y += diffy;
00912 break;
00913 case EGUIA_CENTER:
00914 DesiredRect.LowerRightCorner.Y += diffy/2;
00915 break;
00916 case EGUIA_SCALE:
00917 DesiredRect.LowerRightCorner.Y = core::round32(ScaleRect.LowerRightCorner.Y * fh);
00918 break;
00919 }
00920
00921 RelativeRect = DesiredRect;
00922
00923 const s32 w = RelativeRect.getWidth();
00924 const s32 h = RelativeRect.getHeight();
00925
00926
00927 if (w < (s32)MinSize.Width)
00928 RelativeRect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + MinSize.Width;
00929 if (h < (s32)MinSize.Height)
00930 RelativeRect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + MinSize.Height;
00931 if (MaxSize.Width && w > (s32)MaxSize.Width)
00932 RelativeRect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + MaxSize.Width;
00933 if (MaxSize.Height && h > (s32)MaxSize.Height)
00934 RelativeRect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + MaxSize.Height;
00935
00936 RelativeRect.repair();
00937
00938 AbsoluteRect = RelativeRect + parentAbsolute.UpperLeftCorner;
00939
00940 if (!Parent)
00941 parentAbsoluteClip = AbsoluteRect;
00942
00943 AbsoluteClippingRect = AbsoluteRect;
00944 AbsoluteClippingRect.clipAgainst(parentAbsoluteClip);
00945
00946 LastParentRect = parentAbsolute;
00947
00948 if ( recursive )
00949 {
00950
00951 core::list<IGUIElement*>::Iterator it = Children.begin();
00952 for (; it != Children.end(); ++it)
00953 {
00954 (*it)->recalculateAbsolutePosition(recursive);
00955 }
00956 }
00957 }
00958
00959 protected:
00960
00962 core::list<IGUIElement*> Children;
00963
00965 IGUIElement* Parent;
00966
00968 core::rect<s32> RelativeRect;
00969
00971 core::rect<s32> AbsoluteRect;
00972
00974 core::rect<s32> AbsoluteClippingRect;
00975
00978 core::rect<s32> DesiredRect;
00979
00981 core::rect<s32> LastParentRect;
00982
00984 core::rect<f32> ScaleRect;
00985
00987 core::dimension2du MaxSize, MinSize;
00988
00990 bool IsVisible;
00991
00993 bool IsEnabled;
00994
00996 bool IsSubElement;
00997
00999 bool NoClip;
01000
01002 core::stringw Text;
01003
01005 core::stringw ToolTipText;
01006
01008 core::stringc Name;
01009
01011 s32 ID;
01012
01014 bool IsTabStop;
01015
01017 s32 TabOrder;
01018
01020 bool IsTabGroup;
01021
01023 EGUI_ALIGNMENT AlignLeft, AlignRight, AlignTop, AlignBottom;
01024
01026 IGUIEnvironment* Environment;
01027
01029 EGUI_ELEMENT_TYPE Type;
01030 };
01031
01032
01033 }
01034 }
01035
01036 #endif
01037