Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/OgreOverlayContainer.cpp @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 12.4 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#include "OgreStableHeaders.h"
30
31#include "OgreOverlayContainer.h"
32#include "OgreException.h"
33#include "OgreOverlayManager.h"
34
35namespace Ogre {
36
37    //---------------------------------------------------------------------
38    OverlayContainer::OverlayContainer(const String& name)
39        : OverlayElement(name),
40                mChildrenProcessEvents(true)
41    {
42    }
43    //---------------------------------------------------------------------
44    OverlayContainer::~OverlayContainer()
45    {
46                // remove from parent overlay if root
47                if (mOverlay && !mParent)
48                {
49                        mOverlay->remove2D(this);
50                }
51
52        OverlayContainer::ChildIterator ci = getChildIterator();
53        while (ci.hasMoreElements())
54        {
55            OverlayElement* child = ci.getNext();
56                        child->_notifyParent(0, 0);
57        }
58    }
59    //---------------------------------------------------------------------
60    void OverlayContainer::addChild(OverlayElement* elem)
61    {
62        if (elem->isContainer())
63                {
64                        addChildImpl(static_cast<OverlayContainer*>(elem));
65                }
66                else
67                {
68                        addChildImpl(elem);
69                }
70
71        }
72    //---------------------------------------------------------------------
73    void OverlayContainer::addChildImpl(OverlayElement* elem)
74    {
75        String name = elem->getName();
76        ChildMap::iterator i = mChildren.find(name);
77        if (i != mChildren.end())
78        {
79            OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Child with name " + name + 
80                " already defined.", "OverlayContainer::addChild");
81        }
82
83        mChildren.insert(ChildMap::value_type(name, elem));
84        // tell child about parent & ZOrder
85        elem->_notifyParent(this, mOverlay);
86            elem->_notifyZOrder(mZOrder + 1);
87            elem->_notifyWorldTransforms(mXForm);
88            elem->_notifyViewport();
89
90    }
91    //---------------------------------------------------------------------
92    void OverlayContainer::addChildImpl(OverlayContainer* cont)
93    {
94        // Add to main map first
95        // This will pick up duplicates
96        OverlayElement* pElem = cont;
97        addChildImpl(pElem);
98
99        /*
100        cont->_notifyParent(this, mOverlay);
101        cont->_notifyZOrder(mZOrder + 1);
102            cont->_notifyWorldTransforms(mXForm);
103
104                // tell children of new container the current overlay
105        ChildIterator it = cont->getChildIterator();
106        while (it.hasMoreElements())
107        {
108            // Give children ZOrder 1 higher than this
109            GuiElement* pElemChild = it.getNext();
110                        pElemChild->_notifyParent(cont, mOverlay);
111            pElemChild->_notifyZOrder(cont->getZOrder() + 1);
112            pElemChild->_notifyWorldTransforms(mXForm);
113        }
114        */
115
116        // Now add to specific map too
117        mChildContainers.insert(ChildContainerMap::value_type(cont->getName(), cont));
118
119    }
120    //---------------------------------------------------------------------
121    void OverlayContainer::removeChild(const String& name)
122    {
123        ChildMap::iterator i = mChildren.find(name);
124        if (i == mChildren.end())
125        {
126            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Child with name " + name + 
127                " not found.", "OverlayContainer::removeChild");
128        }
129
130        OverlayElement* element = i->second;
131        mChildren.erase(i);
132
133            // remove from container list (if found)
134        ChildContainerMap::iterator j = mChildContainers.find(name);
135        if (j != mChildContainers.end())
136            mChildContainers.erase(j);
137
138        element->_setParent(0);
139    }
140    //---------------------------------------------------------------------
141    void OverlayContainer::_addChild(OverlayElement* elem)
142    {
143        if (elem->isContainer())
144                {
145                        addChildImpl(static_cast<OverlayContainer*>(elem));
146                }
147                else
148                {
149                        addChildImpl(elem);
150                }
151        }
152    //---------------------------------------------------------------------
153    void OverlayContainer::_removeChild(const String& name)
154    {
155        ChildMap::iterator i = mChildren.find(name);
156        if (i == mChildren.end())
157        {
158            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Child with name " + name + 
159                " not found.", "OverlayContainer::removeChild");
160        }
161
162        OverlayElement* element = i->second;
163        mChildren.erase(i);
164
165            // remove from container list (if found)
166        ChildContainerMap::iterator j = mChildContainers.find(name);
167        if (j != mChildContainers.end())
168            mChildContainers.erase(j);
169
170        element->_setParent(0);
171    }
172    //---------------------------------------------------------------------
173    OverlayElement* OverlayContainer::getChild(const String& name)
174    {
175        ChildMap::iterator i = mChildren.find(name);
176        if (i == mChildren.end())
177        {
178            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Child with name " + name + 
179                " not found.", "OverlayContainer::getChild");
180        }
181
182        return i->second;
183    }
184    //---------------------------------------------------------------------
185    OverlayContainer::ChildIterator OverlayContainer::getChildIterator(void)
186    {
187        return ChildIterator(mChildren.begin(), mChildren.end());
188    }
189    //---------------------------------------------------------------------
190    OverlayContainer::ChildContainerIterator OverlayContainer::getChildContainerIterator(void)
191    {
192        return ChildContainerIterator(mChildContainers.begin(), mChildContainers.end());
193    }
194        //---------------------------------------------------------------------
195        void OverlayContainer::initialise(void)
196        {
197                ChildContainerMap::iterator coni;
198                for (coni =  mChildContainers.begin(); coni != mChildContainers.end(); ++coni)
199                {
200                        coni->second->initialise();
201                }
202                ChildMap::iterator ci;
203                for (ci =  mChildren.begin(); ci != mChildren.end(); ++ci)
204                {
205                        ci->second->initialise();
206                }
207        }
208    //---------------------------------------------------------------------
209        void OverlayContainer::_positionsOutOfDate(void)
210        {
211                OverlayElement::_positionsOutOfDate();
212
213        ChildIterator it = getChildIterator();
214        while (it.hasMoreElements())
215        {
216                        it.getNext()->_positionsOutOfDate();
217        }
218        }
219
220    //---------------------------------------------------------------------
221    void OverlayContainer::_update(void)
222    {
223        // call superclass
224        OverlayElement::_update();
225
226        // Update children
227        ChildIterator it = getChildIterator();
228        while (it.hasMoreElements())
229        {
230            it.getNext()->_update();
231        }
232
233
234    }
235    //---------------------------------------------------------------------
236    void OverlayContainer::_notifyZOrder(ushort newZOrder)
237    {
238        OverlayElement::_notifyZOrder(newZOrder);
239
240        // Update children
241        ChildIterator it = getChildIterator();
242        while (it.hasMoreElements())
243        {
244            // Give children ZOrder 1 higher than this
245            it.getNext()->_notifyZOrder(newZOrder + 1);
246        }
247    }
248    //---------------------------------------------------------------------
249    void OverlayContainer::_notifyWorldTransforms(const Matrix4& xform)
250    {
251        OverlayElement::_notifyWorldTransforms(xform);
252
253        // Update children
254        ChildIterator it = getChildIterator();
255        while (it.hasMoreElements())
256        {
257            it.getNext()->_notifyWorldTransforms(xform);
258        }
259    }
260    //---------------------------------------------------------------------
261    void OverlayContainer::_notifyViewport()
262    {
263        OverlayElement::_notifyViewport();
264
265        // Update children
266        ChildIterator it = getChildIterator();
267        while (it.hasMoreElements())
268        {
269            it.getNext()->_notifyViewport();
270        }
271    }
272    //---------------------------------------------------------------------
273    void OverlayContainer::_notifyParent(OverlayContainer* parent, Overlay* overlay)
274    {
275        OverlayElement::_notifyParent(parent, overlay);
276
277        // Update children
278        ChildIterator it = getChildIterator();
279        while (it.hasMoreElements())
280        {
281            // Notify the children of the overlay
282            it.getNext()->_notifyParent(this, overlay);
283        }
284    }
285
286    //---------------------------------------------------------------------
287    void OverlayContainer::_updateRenderQueue(RenderQueue* queue)
288    {
289        if (mVisible)
290        {
291
292            OverlayElement::_updateRenderQueue(queue);
293
294            // Also add children
295            ChildIterator it = getChildIterator();
296            while (it.hasMoreElements())
297            {
298                // Give children ZOrder 1 higher than this
299                it.getNext()->_updateRenderQueue(queue);
300            }
301        }
302
303    }
304
305
306        OverlayElement* OverlayContainer::findElementAt(Real x, Real y)                 // relative to parent
307        {
308
309                OverlayElement* ret = NULL;
310
311                int currZ = -1;
312
313                if (mVisible)
314                {
315                        ret = OverlayElement::findElementAt(x,y);       //default to the current container if no others are found
316                        if (ret && mChildrenProcessEvents)
317                        {
318                                ChildIterator it = getChildIterator();
319                                while (it.hasMoreElements())
320                                {
321                                        OverlayElement* currentOverlayElement = it.getNext();
322                                        if (currentOverlayElement->isVisible() && currentOverlayElement->isEnabled())
323                                        {
324                                                int z = currentOverlayElement->getZOrder();
325                                                if (z > currZ)
326                                                {
327                                                        OverlayElement* elementFound = currentOverlayElement->findElementAt(x ,y );
328                                                        if (elementFound)
329                                                        {
330                                                                currZ = z;
331                                                                ret = elementFound;
332                                                        }
333                                                }
334                                        }
335                                }
336                        }
337                }
338                return ret;
339        }
340
341    void OverlayContainer::copyFromTemplate(OverlayElement* templateOverlay)
342    {
343        OverlayElement::copyFromTemplate(templateOverlay);
344
345                    if (templateOverlay->isContainer() && isContainer())
346                    {
347             OverlayContainer::ChildIterator it = static_cast<OverlayContainer*>(templateOverlay)->getChildIterator();
348                         while (it.hasMoreElements())
349                         {
350                                 OverlayElement* oldChildElement = it.getNext();
351                                 if (oldChildElement->isCloneable())
352                                 {
353                                         OverlayElement* newChildElement = 
354                                                 OverlayManager::getSingleton().createOverlayElement(
355                                                        oldChildElement->getTypeName(), 
356                                                        mName+"/"+oldChildElement->getName());
357                                         newChildElement->copyFromTemplate(oldChildElement);
358                                         addChild((OverlayContainer*)newChildElement);
359                                 }
360                         }
361        }
362    }
363
364    OverlayElement* OverlayContainer::clone(const String& instanceName)
365    {
366        OverlayContainer *newContainer;
367
368        newContainer = static_cast<OverlayContainer*>(OverlayElement::clone(instanceName));
369
370          ChildIterator it = getChildIterator();
371                  while (it.hasMoreElements())
372                          {
373                                    OverlayElement* oldChildElement = it.getNext();
374                                    if (oldChildElement->isCloneable())
375                                    {
376                OverlayElement* newChildElement = oldChildElement->clone(instanceName);
377                newContainer->_addChild(newChildElement);
378            }
379        }
380
381        return newContainer;
382    }
383
384}
385
Note: See TracBrowser for help on using the repository browser.