Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreGuiContainer.cpp

Go to the documentation of this file.
00001 
00002 /*
00003 -----------------------------------------------------------------------------
00004 This source file is part of OGRE
00005     (Object-oriented Graphics Rendering Engine)
00006 For the latest info, see http://www.ogre3d.org/
00007 
00008 Copyright © 2000-2002 The OGRE Team
00009 Also see acknowledgements in Readme.html
00010 
00011 This program is free software you can redistribute it and/or modify it under
00012 the terms of the GNU Lesser General Public License as published by the Free Software
00013 Foundation either version 2 of the License, or (at your option) any later
00014 version.
00015 
00016 This program is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY without even the implied warranty of MERCHANTABILITY or FITNESS
00018 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00019 
00020 You should have received a copy of the GNU Lesser General Public License along with
00021 this program if not, write to the Free Software Foundation, Inc., 59 Temple
00022 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00023 http://www.gnu.org/copyleft/lesser.txt.
00024 -----------------------------------------------------------------------------
00025 */
00026 #include "OgreStableHeaders.h"
00027 
00028 #include "OgreGuiContainer.h"
00029 #include "OgreException.h"
00030 #include "OgreMouseEvent.h"
00031 #include "OgreGuiManager.h"
00032 
00033 namespace Ogre {
00034 
00035     //---------------------------------------------------------------------
00036     GuiContainer::GuiContainer(const String& name)
00037         : GuiElement(name),
00038         mChildrenProcessEvents(true)
00039     {
00040     }
00041     //---------------------------------------------------------------------
00042     GuiContainer::~GuiContainer()
00043     {
00044         GuiContainer::ChildIterator ci = getChildIterator();
00045         while (ci.hasMoreElements())
00046         {
00047             GuiElement* child = ci.getNext();
00048             child->_setParent(0);
00049         }
00050     }
00051     //---------------------------------------------------------------------
00052     void GuiContainer::addChild(GuiElement* elem)
00053     {
00054         if (elem->isContainer())
00055         {
00056             addChildImpl(static_cast<GuiContainer*>(elem));
00057         }
00058         else
00059         {
00060             addChildImpl(elem);
00061         }
00062 
00063     }
00064     //---------------------------------------------------------------------
00065     void GuiContainer::addChildImpl(GuiElement* elem)
00066     {
00067         String name = elem->getName();
00068         ChildMap::iterator i = mChildren.find(name);
00069         if (i != mChildren.end())
00070         {
00071             Except(Exception::ERR_DUPLICATE_ITEM, "Child with name " + name + 
00072                 " already defined.", "GuiContainer::addChild");
00073         }
00074 
00075         mChildren.insert(ChildMap::value_type(name, elem));
00076         // tell child about parent & ZOrder
00077         elem->_notifyParent(this, mOverlay);
00078         elem->_notifyZOrder(mZOrder + 1);
00079         elem->_notifyWorldTransforms(mXForm);
00080         elem->_notifyViewport();
00081 
00082     }
00083     //---------------------------------------------------------------------
00084     void GuiContainer::addChildImpl(GuiContainer* cont)
00085     {
00086         // Add to main map first 
00087         // This will pick up duplicates
00088         GuiElement* pElem = cont;
00089         addChildImpl(pElem);
00090 
00091         /*
00092         cont->_notifyParent(this, mOverlay);
00093         cont->_notifyZOrder(mZOrder + 1);
00094         cont->_notifyWorldTransforms(mXForm);
00095 
00096         // tell children of new container the current overlay
00097         ChildIterator it = cont->getChildIterator();
00098         while (it.hasMoreElements())
00099         {
00100             // Give children ZOrder 1 higher than this
00101             GuiElement* pElemChild = it.getNext();
00102             pElemChild->_notifyParent(cont, mOverlay);
00103             pElemChild->_notifyZOrder(cont->getZOrder() + 1);
00104             pElemChild->_notifyWorldTransforms(mXForm);
00105         }
00106         */
00107 
00108         // Now add to specific map too
00109         mChildContainers.insert(ChildContainerMap::value_type(cont->getName(), cont));
00110 
00111     }
00112     //---------------------------------------------------------------------
00113     void GuiContainer::removeChild(const String& name)
00114     {
00115         ChildMap::iterator i = mChildren.find(name);
00116         if (i == mChildren.end())
00117         {
00118             Except(Exception::ERR_ITEM_NOT_FOUND, "Child with name " + name + 
00119                 " not found.", "GuiContainer::removeChild");
00120         }
00121 
00122         GuiElement* element = i->second;
00123         mChildren.erase(i);
00124 
00125             // remove from container list (if found)
00126         ChildContainerMap::iterator j = mChildContainers.find(name);
00127         if (j != mChildContainers.end())
00128             mChildContainers.erase(j);
00129 
00130         element->_setParent(0);
00131     }
00132     //---------------------------------------------------------------------
00133     void GuiContainer::_addChild(GuiElement* elem)
00134     {
00135         if (elem->isContainer())
00136         {
00137             addChildImpl(static_cast<GuiContainer*>(elem));
00138         }
00139         else
00140         {
00141             addChildImpl(elem);
00142         }
00143     }
00144     //---------------------------------------------------------------------
00145     void GuiContainer::_removeChild(const String& name)
00146     {
00147         ChildMap::iterator i = mChildren.find(name);
00148         if (i == mChildren.end())
00149         {
00150             Except(Exception::ERR_ITEM_NOT_FOUND, "Child with name " + name + 
00151                 " not found.", "GuiContainer::removeChild");
00152         }
00153 
00154         GuiElement* element = i->second;
00155         mChildren.erase(i);
00156 
00157             // remove from container list (if found)
00158         ChildContainerMap::iterator j = mChildContainers.find(name);
00159         if (j != mChildContainers.end())
00160             mChildContainers.erase(j);
00161 
00162         element->_setParent(0);
00163     }
00164     //---------------------------------------------------------------------
00165     GuiElement* GuiContainer::getChild(const String& name)
00166     {
00167         ChildMap::iterator i = mChildren.find(name);
00168         if (i == mChildren.end())
00169         {
00170             Except(Exception::ERR_ITEM_NOT_FOUND, "Child with name " + name + 
00171                 " not found.", "GuiContainer::getChild");
00172         }
00173 
00174         return i->second;
00175     }
00176     //---------------------------------------------------------------------
00177     GuiContainer::ChildIterator GuiContainer::getChildIterator(void)
00178     {
00179         return ChildIterator(mChildren.begin(), mChildren.end());
00180     }
00181     //---------------------------------------------------------------------
00182     GuiContainer::ChildContainerIterator GuiContainer::getChildContainerIterator(void)
00183     {
00184         return ChildContainerIterator(mChildContainers.begin(), mChildContainers.end());
00185     }
00186 
00187     //---------------------------------------------------------------------
00188     void GuiContainer::_positionsOutOfDate(void)
00189     {
00190         GuiElement::_positionsOutOfDate();
00191 
00192         ChildIterator it = getChildIterator();
00193         while (it.hasMoreElements())
00194         {
00195             it.getNext()->_positionsOutOfDate();
00196         }
00197     }
00198 
00199     //---------------------------------------------------------------------
00200     void GuiContainer::_update(void)
00201     {
00202         // call superclass
00203         GuiElement::_update();
00204 
00205         // Update children
00206         ChildIterator it = getChildIterator();
00207         while (it.hasMoreElements())
00208         {
00209             it.getNext()->_update();
00210         }
00211 
00212 
00213     }
00214     //---------------------------------------------------------------------
00215     void GuiContainer::_notifyZOrder(ushort newZOrder)
00216     {
00217         GuiElement::_notifyZOrder(newZOrder);
00218 
00219         // Update children
00220         ChildIterator it = getChildIterator();
00221         while (it.hasMoreElements())
00222         {
00223             // Give children ZOrder 1 higher than this
00224             it.getNext()->_notifyZOrder(newZOrder + 1);
00225         }
00226     }
00227     //---------------------------------------------------------------------
00228     void GuiContainer::_notifyWorldTransforms(const Matrix4& xform)
00229     {
00230         GuiElement::_notifyWorldTransforms(xform);
00231 
00232         // Update children
00233         ChildIterator it = getChildIterator();
00234         while (it.hasMoreElements())
00235         {
00236             it.getNext()->_notifyWorldTransforms(xform);
00237         }
00238     }
00239     //---------------------------------------------------------------------
00240     void GuiContainer::_notifyViewport()
00241     {
00242         GuiElement::_notifyViewport();
00243 
00244         // Update children
00245         ChildIterator it = getChildIterator();
00246         while (it.hasMoreElements())
00247         {
00248             it.getNext()->_notifyViewport();
00249         }
00250     }
00251     //---------------------------------------------------------------------
00252     void GuiContainer::_notifyParent(GuiContainer* parent, Overlay* overlay)
00253     {
00254         GuiElement::_notifyParent(parent, overlay);
00255 
00256         // Update children
00257         ChildIterator it = getChildIterator();
00258         while (it.hasMoreElements())
00259         {
00260             // Notify the children of the overlay 
00261             it.getNext()->_notifyParent(this, overlay);
00262         }
00263     }
00264 
00265     //---------------------------------------------------------------------
00266     void GuiContainer::_updateRenderQueue(RenderQueue* queue)
00267     {
00268         if (mVisible)
00269         {
00270 
00271             GuiElement::_updateRenderQueue(queue);
00272 
00273             // Also add children
00274             ChildIterator it = getChildIterator();
00275             while (it.hasMoreElements())
00276             {
00277                 // Give children ZOrder 1 higher than this
00278                 it.getNext()->_updateRenderQueue(queue);
00279             }
00280         }
00281 
00282     }
00283 
00284 
00285     GuiElement* GuiContainer::findElementAt(Real x, Real y)         // relative to parent
00286     {
00287 
00288         GuiElement* ret = NULL;
00289 
00290         int currZ = -1;
00291 
00292         if (mVisible)
00293         {
00294             ret = GuiElement::findElementAt(x,y);   //default to the current container if no others are found
00295             if (ret && mChildrenProcessEvents)
00296             {
00297                 ChildIterator it = getChildIterator();
00298                 while (it.hasMoreElements())
00299                 {
00300                     GuiElement* currentGuiElement = it.getNext();
00301                     if (currentGuiElement->isVisible() && currentGuiElement->isEnabled())
00302                     {
00303                         int z = currentGuiElement->getZOrder();
00304                         if (z > currZ)
00305                         {
00306                             GuiElement* elementFound = currentGuiElement->findElementAt(x ,y );
00307                             if (elementFound)
00308                             {
00309                                 currZ = z;
00310                                 ret = elementFound;
00311                             }
00312                         }
00313                     }
00314                 }
00315             }
00316         }
00317         return ret;
00318     }
00319 
00320     void GuiContainer::copyFromTemplate(GuiElement* templateGui)
00321     {
00322         GuiElement::copyFromTemplate(templateGui);
00323 
00324             if (templateGui->isContainer() && isContainer())
00325             {
00326              GuiContainer::ChildIterator it = static_cast<GuiContainer*>(templateGui)->getChildIterator();
00327              while (it.hasMoreElements())
00328                  {
00329                        GuiElement* oldChildElement = it.getNext();
00330                        if (oldChildElement->isCloneable())
00331                        {
00332                    GuiElement* newChildElement = 
00333                        GuiManager::getSingleton().createGuiElement(oldChildElement->getTypeName(), mName+"/"+oldChildElement->getName());
00334                    oldChildElement->copyParametersTo(newChildElement);
00335                    addChild((GuiContainer*)newChildElement);
00336                }
00337            }
00338         }
00339     }
00340 
00341     GuiElement* GuiContainer::clone(const String& instanceName)
00342     {
00343         GuiContainer *newContainer;
00344 
00345         newContainer = static_cast<GuiContainer*>(GuiElement::clone(instanceName));
00346 
00347           ChildIterator it = getChildIterator();
00348           while (it.hasMoreElements())
00349               {
00350                     GuiElement* oldChildElement = it.getNext();
00351                     if (oldChildElement->isCloneable())
00352                     {
00353                 GuiElement* newChildElement = oldChildElement->clone(instanceName);
00354                 newContainer->_addChild(newChildElement);
00355             }
00356         }
00357 
00358         return newContainer;
00359     }
00360 
00361 }
00362 

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:28 2004