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 Documentation © 2003-2010 by Nikolaus Gebhardt. Generated on Sun Feb 14 13:06:56 2010 by Doxygen (1.6.2)