Home | Namespaces | Hierarchy | Alphabetical List | Class list | Files | Namespace Members | Class members | File members | Tutorials

IGUIElement.h

Go to the documentation of this file.
00001 // Copyright (C) 2002-2010 Nikolaus Gebhardt
00002 // This file is part of the "Irrlicht Engine".
00003 // For conditions of distribution and use, see copyright notice in irrlicht.h
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                 // if we were given a parent to attach to
00044                 if (parent)
00045                 {
00046                         parent->addChildToEnd(this);
00047                         recalculateAbsolutePosition(true);
00048                 }
00049         }
00050 
00051 
00053         virtual ~IGUIElement()
00054         {
00055                 // delete all children
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                 // update all children
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                 // we have to search from back to front, because later children
00247                 // might be drawn over the top of earlier ones.
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                 // negative = autonumber
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                                 // find the highest element number
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         virtual bool isEnabled() const
00459         {
00460                 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00461                 return IsEnabled;
00462         }
00463 
00464 
00466         virtual void setEnabled(bool enabled)
00467         {
00468                 IsEnabled = enabled;
00469         }
00470 
00471 
00473         virtual void setText(const wchar_t* text)
00474         {
00475                 Text = text;
00476         }
00477 
00478 
00480         virtual const wchar_t* getText() const
00481         {
00482                 return Text.c_str();
00483         }
00484 
00485 
00487         virtual void setToolTipText(const wchar_t* text)
00488         {
00489                 ToolTipText = text;
00490         }
00491 
00492 
00494         virtual const core::stringw& getToolTipText() const
00495         {
00496                 return ToolTipText;
00497         }
00498 
00499 
00501         virtual s32 getID() const
00502         {
00503                 return ID;
00504         }
00505 
00506 
00508         virtual void setID(s32 id)
00509         {
00510                 ID = id;
00511         }
00512 
00513 
00515         virtual bool OnEvent(const SEvent& event)
00516         {
00517                 return Parent ? Parent->OnEvent(event) : false;
00518         }
00519 
00520 
00522 
00523         virtual bool bringToFront(IGUIElement* element)
00524         {
00525                 core::list<IGUIElement*>::Iterator it = Children.begin();
00526                 for (; it != Children.end(); ++it)
00527                 {
00528                         if (element == (*it))
00529                         {
00530                                 Children.erase(it);
00531                                 Children.push_back(element);
00532                                 return true;
00533                         }
00534                 }
00535 
00536                 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00537                 return false;
00538         }
00539 
00540 
00542         virtual const core::list<IGUIElement*>& getChildren() const
00543         {
00544                 return Children;
00545         }
00546 
00547 
00549 
00555         virtual IGUIElement* getElementFromId(s32 id, bool searchchildren=false) const
00556         {
00557                 IGUIElement* e = 0;
00558 
00559                 core::list<IGUIElement*>::ConstIterator it = Children.begin();
00560                 for (; it != Children.end(); ++it)
00561                 {
00562                         if ((*it)->getID() == id)
00563                                 return (*it);
00564 
00565                         if (searchchildren)
00566                                 e = (*it)->getElementFromId(id, true);
00567 
00568                         if (e)
00569                                 return e;
00570                 }
00571 
00572                 return e;
00573         }
00574 
00575 
00578         bool isMyChild(IGUIElement* child) const
00579         {
00580                 if (!child)
00581                         return false;
00582                 do
00583                 {
00584                         if (child->Parent)
00585                                 child = child->Parent;
00586 
00587                 } while (child->Parent && child != this);
00588 
00589                 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00590                 return child == this;
00591         }
00592 
00593 
00595 
00602         bool getNextElement(s32 startOrder, bool reverse, bool group,
00603                 IGUIElement*& first, IGUIElement*& closest, bool includeInvisible=false) const
00604         {
00605                 // we'll stop searching if we find this number
00606                 s32 wanted = startOrder + ( reverse ? -1 : 1 );
00607                 if (wanted==-2)
00608                         wanted = 1073741824; // maximum s32
00609 
00610                 core::list<IGUIElement*>::ConstIterator it = Children.begin();
00611 
00612                 s32 closestOrder, currentOrder;
00613 
00614                 while(it != Children.end())
00615                 {
00616                         // ignore invisible elements and their children
00617                         if ( ( (*it)->isVisible() || includeInvisible ) &&
00618                                 (group == true || (*it)->isTabGroup() == false) )
00619                         {
00620                                 // only check tab stops and those with the same group status
00621                                 if ((*it)->isTabStop() && ((*it)->isTabGroup() == group))
00622                                 {
00623                                         currentOrder = (*it)->getTabOrder();
00624 
00625                                         // is this what we're looking for?
00626                                         if (currentOrder == wanted)
00627                                         {
00628                                                 closest = *it;
00629                                                 return true;
00630                                         }
00631 
00632                                         // is it closer than the current closest?
00633                                         if (closest)
00634                                         {
00635                                                 closestOrder = closest->getTabOrder();
00636                                                 if ( ( reverse && currentOrder > closestOrder && currentOrder < startOrder)
00637                                                         ||(!reverse && currentOrder < closestOrder && currentOrder > startOrder))
00638                                                 {
00639                                                         closest = *it;
00640                                                 }
00641                                         }
00642                                         else
00643                                         if ( (reverse && currentOrder < startOrder) || (!reverse && currentOrder > startOrder) )
00644                                         {
00645                                                 closest = *it;
00646                                         }
00647 
00648                                         // is it before the current first?
00649                                         if (first)
00650                                         {
00651                                                 closestOrder = first->getTabOrder();
00652 
00653                                                 if ( (reverse && closestOrder < currentOrder) || (!reverse && closestOrder > currentOrder) )
00654                                                 {
00655                                                         first = *it;
00656                                                 }
00657                                         }
00658                                         else
00659                                         {
00660                                                 first = *it;
00661                                         }
00662                                 }
00663                                 // search within children
00664                                 if ((*it)->getNextElement(startOrder, reverse, group, first, closest))
00665                                 {
00666                                         _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00667                                         return true;
00668                                 }
00669                         }
00670                         ++it;
00671                 }
00672                 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00673                 return false;
00674         }
00675 
00676 
00678 
00682         EGUI_ELEMENT_TYPE getType() const
00683         {
00684                 return Type;
00685         }
00686 
00688 
00696         virtual bool hasType(EGUI_ELEMENT_TYPE type) const
00697         {
00698                 return type == Type;
00699         }
00700 
00701 
00703 
00705         virtual const c8* getTypeName() const
00706         {
00707                 return GUIElementTypeNames[Type];
00708         }
00709 
00710 
00712 
00714         virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const
00715         {
00716                 out->addInt("Id", ID );
00717                 out->addString("Caption", getText());
00718                 out->addRect("Rect", DesiredRect);
00719                 out->addPosition2d("MinSize", core::position2di(MinSize.Width, MinSize.Height));
00720                 out->addPosition2d("MaxSize", core::position2di(MaxSize.Width, MaxSize.Height));
00721                 out->addEnum("LeftAlign", AlignLeft, GUIAlignmentNames);
00722                 out->addEnum("RightAlign", AlignRight, GUIAlignmentNames);
00723                 out->addEnum("TopAlign", AlignTop, GUIAlignmentNames);
00724                 out->addEnum("BottomAlign", AlignBottom, GUIAlignmentNames);
00725                 out->addBool("Visible", IsVisible);
00726                 out->addBool("Enabled", IsEnabled);
00727                 out->addBool("TabStop", IsTabStop);
00728                 out->addBool("TabGroup", IsTabGroup);
00729                 out->addInt("TabOrder", TabOrder);
00730                 out->addBool("NoClip", NoClip);
00731         }
00732 
00733 
00735 
00737         virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)
00738         {
00739                 setID(in->getAttributeAsInt("Id"));
00740                 setText(in->getAttributeAsStringW("Caption").c_str());
00741                 setVisible(in->getAttributeAsBool("Visible"));
00742                 setEnabled(in->getAttributeAsBool("Enabled"));
00743                 IsTabStop = in->getAttributeAsBool("TabStop");
00744                 IsTabGroup = in->getAttributeAsBool("TabGroup");
00745                 TabOrder = in->getAttributeAsInt("TabOrder");
00746 
00747                 core::position2di p = in->getAttributeAsPosition2d("MaxSize");
00748                 setMaxSize(core::dimension2du(p.X,p.Y));
00749 
00750                 p = in->getAttributeAsPosition2d("MinSize");
00751                 setMinSize(core::dimension2du(p.X,p.Y));
00752 
00753                 setAlignment((EGUI_ALIGNMENT) in->getAttributeAsEnumeration("LeftAlign", GUIAlignmentNames),
00754                         (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("RightAlign", GUIAlignmentNames),
00755                         (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("TopAlign", GUIAlignmentNames),
00756                         (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("BottomAlign", GUIAlignmentNames));
00757 
00758                 setRelativePosition(in->getAttributeAsRect("Rect"));
00759 
00760                 setNotClipped(in->getAttributeAsBool("NoClip"));
00761         }
00762 
00763 protected:
00764         // not virtual because needed in constructor
00765         void addChildToEnd(IGUIElement* child)
00766         {
00767                 if (child)
00768                 {
00769                         child->grab(); // prevent destruction when removed
00770                         child->remove(); // remove from old parent
00771                         child->LastParentRect = getAbsolutePosition();
00772                         child->Parent = this;
00773                         Children.push_back(child);
00774                 }
00775         }
00776 
00777         // not virtual because needed in constructor
00778         void recalculateAbsolutePosition(bool recursive)
00779         {
00780                 core::rect<s32> parentAbsolute(0,0,0,0);
00781                 core::rect<s32> parentAbsoluteClip;
00782                 f32 fw=0.f, fh=0.f;
00783 
00784                 if (Parent)
00785                 {
00786                         parentAbsolute = Parent->AbsoluteRect;
00787 
00788                         if (NoClip)
00789                         {
00790                                 IGUIElement* p=this;
00791                                 while (p && p->Parent)
00792                                         p = p->Parent;
00793                                 parentAbsoluteClip = p->AbsoluteClippingRect;
00794                         }
00795                         else
00796                                 parentAbsoluteClip = Parent->AbsoluteClippingRect;
00797                 }
00798 
00799                 const s32 diffx = parentAbsolute.getWidth() - LastParentRect.getWidth();
00800                 const s32 diffy = parentAbsolute.getHeight() - LastParentRect.getHeight();
00801 
00802                 if (AlignLeft == EGUIA_SCALE || AlignRight == EGUIA_SCALE)
00803                         fw = (f32)parentAbsolute.getWidth();
00804 
00805                 if (AlignTop == EGUIA_SCALE || AlignBottom == EGUIA_SCALE)
00806                         fh = (f32)parentAbsolute.getHeight();
00807 
00808                 switch (AlignLeft)
00809                 {
00810                         case EGUIA_UPPERLEFT:
00811                                 break;
00812                         case EGUIA_LOWERRIGHT:
00813                                 DesiredRect.UpperLeftCorner.X += diffx;
00814                                 break;
00815                         case EGUIA_CENTER:
00816                                 DesiredRect.UpperLeftCorner.X += diffx/2;
00817                                 break;
00818                         case EGUIA_SCALE:
00819                                 DesiredRect.UpperLeftCorner.X = core::round32(ScaleRect.UpperLeftCorner.X * fw);
00820                                 break;
00821                 }
00822 
00823                 switch (AlignRight)
00824                 {
00825                         case EGUIA_UPPERLEFT:
00826                                 break;
00827                         case EGUIA_LOWERRIGHT:
00828                                 DesiredRect.LowerRightCorner.X += diffx;
00829                                 break;
00830                         case EGUIA_CENTER:
00831                                 DesiredRect.LowerRightCorner.X += diffx/2;
00832                                 break;
00833                         case EGUIA_SCALE:
00834                                 DesiredRect.LowerRightCorner.X = core::round32(ScaleRect.LowerRightCorner.X * fw);
00835                                 break;
00836                 }
00837 
00838                 switch (AlignTop)
00839                 {
00840                         case EGUIA_UPPERLEFT:
00841                                 break;
00842                         case EGUIA_LOWERRIGHT:
00843                                 DesiredRect.UpperLeftCorner.Y += diffy;
00844                                 break;
00845                         case EGUIA_CENTER:
00846                                 DesiredRect.UpperLeftCorner.Y += diffy/2;
00847                                 break;
00848                         case EGUIA_SCALE:
00849                                 DesiredRect.UpperLeftCorner.Y = core::round32(ScaleRect.UpperLeftCorner.Y * fh);
00850                                 break;
00851                 }
00852 
00853                 switch (AlignBottom)
00854                 {
00855                         case EGUIA_UPPERLEFT:
00856                                 break;
00857                         case EGUIA_LOWERRIGHT:
00858                                 DesiredRect.LowerRightCorner.Y += diffy;
00859                                 break;
00860                         case EGUIA_CENTER:
00861                                 DesiredRect.LowerRightCorner.Y += diffy/2;
00862                                 break;
00863                         case EGUIA_SCALE:
00864                                 DesiredRect.LowerRightCorner.Y = core::round32(ScaleRect.LowerRightCorner.Y * fh);
00865                                 break;
00866                 }
00867 
00868                 RelativeRect = DesiredRect;
00869 
00870                 const s32 w = RelativeRect.getWidth();
00871                 const s32 h = RelativeRect.getHeight();
00872 
00873                 // make sure the desired rectangle is allowed
00874                 if (w < (s32)MinSize.Width)
00875                         RelativeRect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + MinSize.Width;
00876                 if (h < (s32)MinSize.Height)
00877                         RelativeRect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + MinSize.Height;
00878                 if (MaxSize.Width && w > (s32)MaxSize.Width)
00879                         RelativeRect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + MaxSize.Width;
00880                 if (MaxSize.Height && h > (s32)MaxSize.Height)
00881                         RelativeRect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + MaxSize.Height;
00882 
00883                 RelativeRect.repair();
00884 
00885                 AbsoluteRect = RelativeRect + parentAbsolute.UpperLeftCorner;
00886 
00887                 if (!Parent)
00888                         parentAbsoluteClip = AbsoluteRect;
00889 
00890                 AbsoluteClippingRect = AbsoluteRect;
00891                 AbsoluteClippingRect.clipAgainst(parentAbsoluteClip);
00892 
00893                 LastParentRect = parentAbsolute;
00894 
00895                 if ( recursive )
00896                 {
00897                         // update all children
00898                         core::list<IGUIElement*>::Iterator it = Children.begin();
00899                         for (; it != Children.end(); ++it)
00900                         {
00901                                 (*it)->recalculateAbsolutePosition(recursive);
00902                         }
00903                 }
00904         }
00905 
00906 protected:
00907 
00909         core::list<IGUIElement*> Children;
00910 
00912         IGUIElement* Parent;
00913 
00915         core::rect<s32> RelativeRect;
00916 
00918         core::rect<s32> AbsoluteRect;
00919 
00921         core::rect<s32> AbsoluteClippingRect;
00922 
00925         core::rect<s32> DesiredRect;
00926 
00928         core::rect<s32> LastParentRect;
00929 
00931         core::rect<f32> ScaleRect;
00932 
00934         core::dimension2du MaxSize, MinSize;
00935 
00937         bool IsVisible;
00938 
00940         bool IsEnabled;
00941 
00943         bool IsSubElement;
00944 
00946         bool NoClip;
00947 
00949         core::stringw Text;
00950 
00952         core::stringw ToolTipText;
00953 
00955         s32 ID;
00956 
00958         bool IsTabStop;
00959 
00961         s32 TabOrder;
00962 
00964         bool IsTabGroup;
00965 
00967         EGUI_ALIGNMENT AlignLeft, AlignRight, AlignTop, AlignBottom;
00968 
00970         IGUIEnvironment* Environment;
00971 
00973         EGUI_ELEMENT_TYPE Type;
00974 };
00975 
00976 
00977 } // end namespace gui
00978 } // end namespace irr
00979 
00980 #endif
00981 

The Irrlicht Engine
The Irrlicht Engine Documentation © 2003-2010 by Nikolaus Gebhardt. Generated on Sun Oct 24 12:41:56 2010 by Doxygen (1.6.2)