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-2009 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 
00190         void setAlignment(EGUI_ALIGNMENT left, EGUI_ALIGNMENT right, EGUI_ALIGNMENT top, EGUI_ALIGNMENT bottom)
00191         {
00192                 AlignLeft = left;
00193                 AlignRight = right;
00194                 AlignTop = top;
00195                 AlignBottom = bottom;
00196 
00197                 if (Parent)
00198                 {
00199                         core::rect<s32> r(Parent->getAbsolutePosition());
00200 
00201                         core::dimension2df d((f32)r.getSize().Width, (f32)r.getSize().Height);
00202 
00203                         if (AlignLeft   == EGUIA_SCALE)
00204                                 ScaleRect.UpperLeftCorner.X = (f32)DesiredRect.UpperLeftCorner.X / d.Width;
00205                         if (AlignRight  == EGUIA_SCALE)
00206                                 ScaleRect.LowerRightCorner.X = (f32)DesiredRect.LowerRightCorner.X / d.Width;
00207                         if (AlignTop    == EGUIA_SCALE)
00208                                 ScaleRect.UpperLeftCorner.Y = (f32)DesiredRect.UpperLeftCorner.Y / d.Height;
00209                         if (AlignBottom == EGUIA_SCALE)
00210                                 ScaleRect.LowerRightCorner.Y = (f32)DesiredRect.LowerRightCorner.Y / d.Height;
00211                 }
00212         }
00213 
00214 
00216         virtual void updateAbsolutePosition()
00217         {
00218                 recalculateAbsolutePosition(false);
00219 
00220                 // update all children
00221                 core::list<IGUIElement*>::Iterator it = Children.begin();
00222                 for (; it != Children.end(); ++it)
00223                 {
00224                         (*it)->updateAbsolutePosition();
00225                 }
00226         }
00227 
00228 
00230 
00241         IGUIElement* getElementFromPoint(const core::position2d<s32>& point)
00242         {
00243                 IGUIElement* target = 0;
00244 
00245                 // we have to search from back to front, because later children
00246                 // might be drawn over the top of earlier ones.
00247 
00248                 core::list<IGUIElement*>::Iterator it = Children.getLast();
00249 
00250                 if (isVisible())
00251                 {
00252                         while(it != Children.end())
00253                         {
00254                                 target = (*it)->getElementFromPoint(point);
00255                                 if (target)
00256                                         return target;
00257 
00258                                 --it;
00259                         }
00260                 }
00261 
00262                 if (isVisible() && isPointInside(point))
00263                         target = this;
00264 
00265                 return target;
00266         }
00267 
00268 
00270 
00271         virtual bool isPointInside(const core::position2d<s32>& point) const
00272         {
00273                 return AbsoluteClippingRect.isPointInside(point);
00274         }
00275 
00276 
00278         virtual void addChild(IGUIElement* child)
00279         {
00280                 addChildToEnd(child);
00281                 if (child)
00282                 {
00283                         child->updateAbsolutePosition();
00284                 }
00285         }
00286 
00288         virtual void removeChild(IGUIElement* child)
00289         {
00290                 core::list<IGUIElement*>::Iterator it = Children.begin();
00291                 for (; it != Children.end(); ++it)
00292                         if ((*it) == child)
00293                         {
00294                                 (*it)->Parent = 0;
00295                                 (*it)->drop();
00296                                 Children.erase(it);
00297                                 return;
00298                         }
00299         }
00300 
00301 
00303         virtual void remove()
00304         {
00305                 if (Parent)
00306                         Parent->removeChild(this);
00307         }
00308 
00309 
00311         virtual void draw()
00312         {
00313                 if ( isVisible() )
00314                 {
00315                         core::list<IGUIElement*>::Iterator it = Children.begin();
00316                         for (; it != Children.end(); ++it)
00317                                 (*it)->draw();
00318                 }
00319         }
00320 
00321 
00323         virtual void OnPostRender(u32 timeMs)
00324         {
00325                 if ( isVisible() )
00326                 {
00327                         core::list<IGUIElement*>::Iterator it = Children.begin();
00328                         for (; it != Children.end(); ++it)
00329                                 (*it)->OnPostRender( timeMs );
00330                 }
00331         }
00332 
00333 
00335         virtual void move(core::position2d<s32> absoluteMovement)
00336         {
00337                 setRelativePosition(DesiredRect + absoluteMovement);
00338         }
00339 
00340 
00342         virtual bool isVisible() const
00343         {
00344                 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00345                 return IsVisible;
00346         }
00347 
00348 
00350         virtual void setVisible(bool visible)
00351         {
00352                 IsVisible = visible;
00353         }
00354 
00355 
00357         virtual bool isSubElement() const
00358         {
00359                 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00360                 return IsSubElement;
00361         }
00362 
00363 
00365 
00367         virtual void setSubElement(bool subElement)
00368         {
00369                 IsSubElement = subElement;
00370         }
00371 
00372 
00374 
00376         void setTabStop(bool enable)
00377         {
00378                 IsTabStop = enable;
00379         }
00380 
00381 
00383         bool isTabStop() const
00384         {
00385                 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00386                 return IsTabStop;
00387         }
00388 
00389 
00391 
00393         void setTabOrder(s32 index)
00394         {
00395                 // negative = autonumber
00396                 if (index < 0)
00397                 {
00398                         TabOrder = 0;
00399                         IGUIElement *el = getTabGroup();
00400                         while (IsTabGroup && el && el->Parent)
00401                                 el = el->Parent;
00402 
00403                         IGUIElement *first=0, *closest=0;
00404                         if (el)
00405                         {
00406                                 // find the highest element number
00407                                 el->getNextElement(-1, true, IsTabGroup, first, closest, true);
00408                                 if (first)
00409                                 {
00410                                         TabOrder = first->getTabOrder() + 1;
00411                                 }
00412                         }
00413 
00414                 }
00415                 else
00416                         TabOrder = index;
00417         }
00418 
00419 
00421         s32 getTabOrder() const
00422         {
00423                 return TabOrder;
00424         }
00425 
00426 
00428 
00430         void setTabGroup(bool isGroup)
00431         {
00432                 IsTabGroup = isGroup;
00433         }
00434 
00435 
00437         bool isTabGroup() const
00438         {
00439                 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00440                 return IsTabGroup;
00441         }
00442 
00443 
00445         IGUIElement* getTabGroup()
00446         {
00447                 IGUIElement *ret=this;
00448 
00449                 while (ret && !ret->isTabGroup())
00450                         ret = ret->getParent();
00451 
00452                 return ret;
00453         }
00454 
00455 
00457         virtual bool isEnabled() const
00458         {
00459                 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00460                 return IsEnabled;
00461         }
00462 
00463 
00465         virtual void setEnabled(bool enabled)
00466         {
00467                 IsEnabled = enabled;
00468         }
00469 
00470 
00472         virtual void setText(const wchar_t* text)
00473         {
00474                 Text = text;
00475         }
00476 
00477 
00479         virtual const wchar_t* getText() const
00480         {
00481                 return Text.c_str();
00482         }
00483 
00484 
00486         virtual void setToolTipText(const wchar_t* text)
00487         {
00488                 ToolTipText = text;
00489         }
00490 
00491 
00493         virtual const core::stringw& getToolTipText() const
00494         {
00495                 return ToolTipText;
00496         }
00497 
00498 
00500         virtual s32 getID() const
00501         {
00502                 return ID;
00503         }
00504 
00505 
00507         virtual void setID(s32 id)
00508         {
00509                 ID = id;
00510         }
00511 
00512 
00514         virtual bool OnEvent(const SEvent& event)
00515         {
00516                 return Parent ? Parent->OnEvent(event) : false;
00517         }
00518 
00519 
00521 
00522         virtual bool bringToFront(IGUIElement* element)
00523         {
00524                 core::list<IGUIElement*>::Iterator it = Children.begin();
00525                 for (; it != Children.end(); ++it)
00526                 {
00527                         if (element == (*it))
00528                         {
00529                                 Children.erase(it);
00530                                 Children.push_back(element);
00531                                 return true;
00532                         }
00533                 }
00534 
00535                 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00536                 return false;
00537         }
00538 
00539 
00541         virtual const core::list<IGUIElement*>& getChildren() const
00542         {
00543                 return Children;
00544         }
00545 
00546 
00548 
00554         virtual IGUIElement* getElementFromId(s32 id, bool searchchildren=false) const
00555         {
00556                 IGUIElement* e = 0;
00557 
00558                 core::list<IGUIElement*>::ConstIterator it = Children.begin();
00559                 for (; it != Children.end(); ++it)
00560                 {
00561                         if ((*it)->getID() == id)
00562                                 return (*it);
00563 
00564                         if (searchchildren)
00565                                 e = (*it)->getElementFromId(id, true);
00566 
00567                         if (e)
00568                                 return e;
00569                 }
00570 
00571                 return e;
00572         }
00573 
00574 
00577         bool isMyChild(IGUIElement* child) const
00578         {
00579                 if (!child)
00580                         return false;
00581                 do
00582                 {
00583                         if (child->Parent)
00584                                 child = child->Parent;
00585 
00586                 } while (child->Parent && child != this);
00587 
00588                 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00589                 return child == this;
00590         }
00591 
00592 
00594 
00601         bool getNextElement(s32 startOrder, bool reverse, bool group,
00602                 IGUIElement*& first, IGUIElement*& closest, bool includeInvisible=false) const
00603         {
00604                 // we'll stop searching if we find this number
00605                 s32 wanted = startOrder + ( reverse ? -1 : 1 );
00606                 if (wanted==-2)
00607                         wanted = 1073741824; // maximum s32
00608 
00609                 core::list<IGUIElement*>::ConstIterator it = Children.begin();
00610 
00611                 s32 closestOrder, currentOrder;
00612 
00613                 while(it != Children.end())
00614                 {
00615                         // ignore invisible elements and their children
00616                         if ( ( (*it)->isVisible() || includeInvisible ) &&
00617                                 (group == true || (*it)->isTabGroup() == false) )
00618                         {
00619                                 // only check tab stops and those with the same group status
00620                                 if ((*it)->isTabStop() && ((*it)->isTabGroup() == group))
00621                                 {
00622                                         currentOrder = (*it)->getTabOrder();
00623 
00624                                         // is this what we're looking for?
00625                                         if (currentOrder == wanted)
00626                                         {
00627                                                 closest = *it;
00628                                                 return true;
00629                                         }
00630 
00631                                         // is it closer than the current closest?
00632                                         if (closest)
00633                                         {
00634                                                 closestOrder = closest->getTabOrder();
00635                                                 if ( ( reverse && currentOrder > closestOrder && currentOrder < startOrder)
00636                                                         ||(!reverse && currentOrder < closestOrder && currentOrder > startOrder))
00637                                                 {
00638                                                         closest = *it;
00639                                                 }
00640                                         }
00641                                         else
00642                                         if ( (reverse && currentOrder < startOrder) || (!reverse && currentOrder > startOrder) )
00643                                         {
00644                                                 closest = *it;
00645                                         }
00646 
00647                                         // is it before the current first?
00648                                         if (first)
00649                                         {
00650                                                 closestOrder = first->getTabOrder();
00651 
00652                                                 if ( (reverse && closestOrder < currentOrder) || (!reverse && closestOrder > currentOrder) )
00653                                                 {
00654                                                         first = *it;
00655                                                 }
00656                                         }
00657                                         else
00658                                         {
00659                                                 first = *it;
00660                                         }
00661                                 }
00662                                 // search within children
00663                                 if ((*it)->getNextElement(startOrder, reverse, group, first, closest))
00664                                 {
00665                                         _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00666                                         return true;
00667                                 }
00668                         }
00669                         ++it;
00670                 }
00671                 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00672                 return false;
00673         }
00674 
00675 
00677 
00681         EGUI_ELEMENT_TYPE getType() const
00682         {
00683                 return Type;
00684         }
00685 
00687 
00695         virtual bool hasType(EGUI_ELEMENT_TYPE type) const
00696         {
00697                 return type == Type;
00698         }
00699 
00700 
00702 
00704         virtual const c8* getTypeName() const
00705         {
00706                 return GUIElementTypeNames[Type];
00707         }
00708 
00709 
00711 
00713         virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const
00714         {
00715                 out->addInt("Id", ID );
00716                 out->addString("Caption", getText());
00717                 out->addRect("Rect", DesiredRect);
00718                 out->addPosition2d("MinSize", core::position2di(MinSize.Width, MinSize.Height));
00719                 out->addPosition2d("MaxSize", core::position2di(MaxSize.Width, MaxSize.Height));
00720                 out->addEnum("LeftAlign", AlignLeft, GUIAlignmentNames);
00721                 out->addEnum("RightAlign", AlignRight, GUIAlignmentNames);
00722                 out->addEnum("TopAlign", AlignTop, GUIAlignmentNames);
00723                 out->addEnum("BottomAlign", AlignBottom, GUIAlignmentNames);
00724                 out->addBool("Visible", IsVisible);
00725                 out->addBool("Enabled", IsEnabled);
00726                 out->addBool("TabStop", IsTabStop);
00727                 out->addBool("TabGroup", IsTabGroup);
00728                 out->addInt("TabOrder", TabOrder);
00729                 out->addBool("NoClip", NoClip);
00730         }
00731 
00732 
00734 
00736         virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)
00737         {
00738                 setID(in->getAttributeAsInt("Id"));
00739                 setText(in->getAttributeAsStringW("Caption").c_str());
00740                 setVisible(in->getAttributeAsBool("Visible"));
00741                 setEnabled(in->getAttributeAsBool("Enabled"));
00742                 IsTabStop = in->getAttributeAsBool("TabStop");
00743                 IsTabGroup = in->getAttributeAsBool("TabGroup");
00744                 TabOrder = in->getAttributeAsInt("TabOrder");
00745 
00746                 core::position2di p = in->getAttributeAsPosition2d("MaxSize");
00747                 setMaxSize(core::dimension2du(p.X,p.Y));
00748 
00749                 p = in->getAttributeAsPosition2d("MinSize");
00750                 setMinSize(core::dimension2du(p.X,p.Y));
00751 
00752                 setAlignment((EGUI_ALIGNMENT) in->getAttributeAsEnumeration("LeftAlign", GUIAlignmentNames),
00753                         (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("RightAlign", GUIAlignmentNames),
00754                         (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("TopAlign", GUIAlignmentNames),
00755                         (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("BottomAlign", GUIAlignmentNames));
00756 
00757                 setRelativePosition(in->getAttributeAsRect("Rect"));
00758 
00759                 setNotClipped(in->getAttributeAsBool("NoClip"));
00760         }
00761 
00762 protected:
00763         // not virtual because needed in constructor
00764         void addChildToEnd(IGUIElement* child)
00765         {
00766                 if (child)
00767                 {
00768                         child->grab(); // prevent destruction when removed
00769                         child->remove(); // remove from old parent
00770                         child->LastParentRect = getAbsolutePosition();
00771                         child->Parent = this;
00772                         Children.push_back(child);
00773                 }
00774         }
00775 
00776         // not virtual because needed in constructor
00777         void recalculateAbsolutePosition(bool recursive)
00778         {
00779                 core::rect<s32> parentAbsolute(0,0,0,0);
00780                 core::rect<s32> parentAbsoluteClip;
00781                 f32 fw=0.f, fh=0.f;
00782 
00783                 if (Parent)
00784                 {
00785                         parentAbsolute = Parent->AbsoluteRect;
00786 
00787                         if (NoClip)
00788                         {
00789                                 IGUIElement* p=this;
00790                                 while (p && p->Parent)
00791                                         p = p->Parent;
00792                                 parentAbsoluteClip = p->AbsoluteClippingRect;
00793                         }
00794                         else
00795                                 parentAbsoluteClip = Parent->AbsoluteClippingRect;
00796                 }
00797 
00798                 const s32 diffx = parentAbsolute.getWidth() - LastParentRect.getWidth();
00799                 const s32 diffy = parentAbsolute.getHeight() - LastParentRect.getHeight();
00800 
00801                 if (AlignLeft == EGUIA_SCALE || AlignRight == EGUIA_SCALE)
00802                         fw = (f32)parentAbsolute.getWidth();
00803 
00804                 if (AlignTop == EGUIA_SCALE || AlignBottom == EGUIA_SCALE)
00805                         fh = (f32)parentAbsolute.getHeight();
00806 
00807                 switch (AlignLeft)
00808                 {
00809                         case EGUIA_UPPERLEFT:
00810                                 break;
00811                         case EGUIA_LOWERRIGHT:
00812                                 DesiredRect.UpperLeftCorner.X += diffx;
00813                                 break;
00814                         case EGUIA_CENTER:
00815                                 DesiredRect.UpperLeftCorner.X += diffx/2;
00816                                 break;
00817                         case EGUIA_SCALE:
00818                                 DesiredRect.UpperLeftCorner.X = core::round32(ScaleRect.UpperLeftCorner.X * fw);
00819                                 break;
00820                 }
00821 
00822                 switch (AlignRight)
00823                 {
00824                         case EGUIA_UPPERLEFT:
00825                                 break;
00826                         case EGUIA_LOWERRIGHT:
00827                                 DesiredRect.LowerRightCorner.X += diffx;
00828                                 break;
00829                         case EGUIA_CENTER:
00830                                 DesiredRect.LowerRightCorner.X += diffx/2;
00831                                 break;
00832                         case EGUIA_SCALE:
00833                                 DesiredRect.LowerRightCorner.X = core::round32(ScaleRect.LowerRightCorner.X * fw);
00834                                 break;
00835                 }
00836 
00837                 switch (AlignTop)
00838                 {
00839                         case EGUIA_UPPERLEFT:
00840                                 break;
00841                         case EGUIA_LOWERRIGHT:
00842                                 DesiredRect.UpperLeftCorner.Y += diffy;
00843                                 break;
00844                         case EGUIA_CENTER:
00845                                 DesiredRect.UpperLeftCorner.Y += diffy/2;
00846                                 break;
00847                         case EGUIA_SCALE:
00848                                 DesiredRect.UpperLeftCorner.Y = core::round32(ScaleRect.UpperLeftCorner.Y * fh);
00849                                 break;
00850                 }
00851 
00852                 switch (AlignBottom)
00853                 {
00854                         case EGUIA_UPPERLEFT:
00855                                 break;
00856                         case EGUIA_LOWERRIGHT:
00857                                 DesiredRect.LowerRightCorner.Y += diffy;
00858                                 break;
00859                         case EGUIA_CENTER:
00860                                 DesiredRect.LowerRightCorner.Y += diffy/2;
00861                                 break;
00862                         case EGUIA_SCALE:
00863                                 DesiredRect.LowerRightCorner.Y = core::round32(ScaleRect.LowerRightCorner.Y * fh);
00864                                 break;
00865                 }
00866 
00867                 RelativeRect = DesiredRect;
00868 
00869                 const s32 w = RelativeRect.getWidth();
00870                 const s32 h = RelativeRect.getHeight();
00871 
00872                 // make sure the desired rectangle is allowed
00873                 if (w < (s32)MinSize.Width)
00874                         RelativeRect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + MinSize.Width;
00875                 if (h < (s32)MinSize.Height)
00876                         RelativeRect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + MinSize.Height;
00877                 if (MaxSize.Width && w > (s32)MaxSize.Width)
00878                         RelativeRect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + MaxSize.Width;
00879                 if (MaxSize.Height && h > (s32)MaxSize.Height)
00880                         RelativeRect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + MaxSize.Height;
00881 
00882                 RelativeRect.repair();
00883 
00884                 AbsoluteRect = RelativeRect + parentAbsolute.UpperLeftCorner;
00885 
00886                 if (!Parent)
00887                         parentAbsoluteClip = AbsoluteRect;
00888 
00889                 AbsoluteClippingRect = AbsoluteRect;
00890                 AbsoluteClippingRect.clipAgainst(parentAbsoluteClip);
00891 
00892                 LastParentRect = parentAbsolute;
00893 
00894                 if ( recursive )
00895                 {
00896                         // update all children
00897                         core::list<IGUIElement*>::Iterator it = Children.begin();
00898                         for (; it != Children.end(); ++it)
00899                         {
00900                                 (*it)->recalculateAbsolutePosition(recursive);
00901                         }
00902                 }
00903         }
00904 
00905 protected:
00906 
00908         core::list<IGUIElement*> Children;
00909 
00911         IGUIElement* Parent;
00912 
00914         core::rect<s32> RelativeRect;
00915 
00917         core::rect<s32> AbsoluteRect;
00918 
00920         core::rect<s32> AbsoluteClippingRect;
00921 
00924         core::rect<s32> DesiredRect;
00925 
00927         core::rect<s32> LastParentRect;
00928 
00930         core::rect<f32> ScaleRect;
00931 
00933         core::dimension2du MaxSize, MinSize;
00934 
00936         bool IsVisible;
00937 
00939         bool IsEnabled;
00940 
00942         bool IsSubElement;
00943 
00945         bool NoClip;
00946 
00948         core::stringw Text;
00949 
00951         core::stringw ToolTipText;
00952 
00954         s32 ID;
00955 
00957         bool IsTabStop;
00958 
00960         s32 TabOrder;
00961 
00963         bool IsTabGroup;
00964 
00966         EGUI_ALIGNMENT AlignLeft, AlignRight, AlignTop, AlignBottom;
00967 
00969         IGUIEnvironment* Environment;
00970 
00972         EGUI_ELEMENT_TYPE Type;
00973 };
00974 
00975 
00976 } // end namespace gui
00977 } // end namespace irr
00978 
00979 #endif
00980 

The Irrlicht Engine
The Irrlicht Engine Documentation © 2003-2010 by Nikolaus Gebhardt. Generated on Sun Jan 31 16:45:16 2010 by Doxygen (1.6.2)