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 Fri May 14 23:22:14 2004