PageRenderTime 27ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/Ogre-1.8rc/OgreMain/src/OgreOverlayContainer.cpp

http://gamekit.googlecode.com/
C++ | 388 lines | 264 code | 44 blank | 80 comment | 43 complexity | 9d3b171053e641d5117e4bcf30ebaadf MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-2.0, AGPL-3.0, BSD-3-Clause, GPL-2.0, LGPL-3.0, MPL-2.0-no-copyleft-exception, LGPL-2.1, MIT
  1. /*
  2. -----------------------------------------------------------------------------
  3. This source file is part of OGRE
  4. (Object-oriented Graphics Rendering Engine)
  5. For the latest info, see http://www.ogre3d.org/
  6. Copyright (c) 2000-2012 Torus Knot Software Ltd
  7. Permission is hereby granted, free of charge, to any person obtaining a copy
  8. of this software and associated documentation files (the "Software"), to deal
  9. in the Software without restriction, including without limitation the rights
  10. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. copies of the Software, and to permit persons to whom the Software is
  12. furnished to do so, subject to the following conditions:
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. THE SOFTWARE.
  22. -----------------------------------------------------------------------------
  23. */
  24. #include "OgreStableHeaders.h"
  25. #include "OgreOverlayContainer.h"
  26. #include "OgreException.h"
  27. #include "OgreOverlayManager.h"
  28. namespace Ogre {
  29. //---------------------------------------------------------------------
  30. OverlayContainer::OverlayContainer(const String& name)
  31. : OverlayElement(name),
  32. mChildrenProcessEvents(true)
  33. {
  34. }
  35. //---------------------------------------------------------------------
  36. OverlayContainer::~OverlayContainer()
  37. {
  38. // remove from parent overlay if root
  39. if (mOverlay && !mParent)
  40. {
  41. mOverlay->remove2D(this);
  42. }
  43. OverlayContainer::ChildIterator ci = getChildIterator();
  44. while (ci.hasMoreElements())
  45. {
  46. OverlayElement* child = ci.getNext();
  47. child->_notifyParent(0, 0);
  48. }
  49. }
  50. //---------------------------------------------------------------------
  51. void OverlayContainer::addChild(OverlayElement* elem)
  52. {
  53. if (elem->isContainer())
  54. {
  55. addChildImpl(static_cast<OverlayContainer*>(elem));
  56. }
  57. else
  58. {
  59. addChildImpl(elem);
  60. }
  61. }
  62. //---------------------------------------------------------------------
  63. void OverlayContainer::addChildImpl(OverlayElement* elem)
  64. {
  65. String name = elem->getName();
  66. ChildMap::iterator i = mChildren.find(name);
  67. if (i != mChildren.end())
  68. {
  69. OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Child with name " + name +
  70. " already defined.", "OverlayContainer::addChild");
  71. }
  72. mChildren.insert(ChildMap::value_type(name, elem));
  73. // tell child about parent & ZOrder
  74. elem->_notifyParent(this, mOverlay);
  75. elem->_notifyZOrder(mZOrder + 1);
  76. elem->_notifyWorldTransforms(mXForm);
  77. elem->_notifyViewport();
  78. }
  79. //---------------------------------------------------------------------
  80. void OverlayContainer::addChildImpl(OverlayContainer* cont)
  81. {
  82. // Add to main map first
  83. // This will pick up duplicates
  84. OverlayElement* pElem = cont;
  85. addChildImpl(pElem);
  86. /*
  87. cont->_notifyParent(this, mOverlay);
  88. cont->_notifyZOrder(mZOrder + 1);
  89. cont->_notifyWorldTransforms(mXForm);
  90. // tell children of new container the current overlay
  91. ChildIterator it = cont->getChildIterator();
  92. while (it.hasMoreElements())
  93. {
  94. // Give children ZOrder 1 higher than this
  95. GuiElement* pElemChild = it.getNext();
  96. pElemChild->_notifyParent(cont, mOverlay);
  97. pElemChild->_notifyZOrder(cont->getZOrder() + 1);
  98. pElemChild->_notifyWorldTransforms(mXForm);
  99. }
  100. */
  101. // Now add to specific map too
  102. mChildContainers.insert(ChildContainerMap::value_type(cont->getName(), cont));
  103. }
  104. //---------------------------------------------------------------------
  105. void OverlayContainer::removeChild(const String& name)
  106. {
  107. ChildMap::iterator i = mChildren.find(name);
  108. if (i == mChildren.end())
  109. {
  110. OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Child with name " + name +
  111. " not found.", "OverlayContainer::removeChild");
  112. }
  113. OverlayElement* element = i->second;
  114. mChildren.erase(i);
  115. // remove from container list (if found)
  116. ChildContainerMap::iterator j = mChildContainers.find(name);
  117. if (j != mChildContainers.end())
  118. mChildContainers.erase(j);
  119. element->_setParent(0);
  120. }
  121. //---------------------------------------------------------------------
  122. void OverlayContainer::_addChild(OverlayElement* elem)
  123. {
  124. if (elem->isContainer())
  125. {
  126. addChildImpl(static_cast<OverlayContainer*>(elem));
  127. }
  128. else
  129. {
  130. addChildImpl(elem);
  131. }
  132. }
  133. //---------------------------------------------------------------------
  134. void OverlayContainer::_removeChild(const String& name)
  135. {
  136. ChildMap::iterator i = mChildren.find(name);
  137. if (i == mChildren.end())
  138. {
  139. OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Child with name " + name +
  140. " not found.", "OverlayContainer::removeChild");
  141. }
  142. OverlayElement* element = i->second;
  143. mChildren.erase(i);
  144. // remove from container list (if found)
  145. ChildContainerMap::iterator j = mChildContainers.find(name);
  146. if (j != mChildContainers.end())
  147. mChildContainers.erase(j);
  148. element->_setParent(0);
  149. }
  150. //---------------------------------------------------------------------
  151. OverlayElement* OverlayContainer::getChild(const String& name)
  152. {
  153. ChildMap::iterator i = mChildren.find(name);
  154. if (i == mChildren.end())
  155. {
  156. OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Child with name " + name +
  157. " not found.", "OverlayContainer::getChild");
  158. }
  159. return i->second;
  160. }
  161. //---------------------------------------------------------------------
  162. OverlayContainer::ChildIterator OverlayContainer::getChildIterator(void)
  163. {
  164. return ChildIterator(mChildren.begin(), mChildren.end());
  165. }
  166. //---------------------------------------------------------------------
  167. OverlayContainer::ChildContainerIterator OverlayContainer::getChildContainerIterator(void)
  168. {
  169. return ChildContainerIterator(mChildContainers.begin(), mChildContainers.end());
  170. }
  171. //---------------------------------------------------------------------
  172. void OverlayContainer::initialise(void)
  173. {
  174. ChildContainerMap::iterator coni;
  175. for (coni = mChildContainers.begin(); coni != mChildContainers.end(); ++coni)
  176. {
  177. coni->second->initialise();
  178. }
  179. ChildMap::iterator ci;
  180. for (ci = mChildren.begin(); ci != mChildren.end(); ++ci)
  181. {
  182. ci->second->initialise();
  183. }
  184. }
  185. //---------------------------------------------------------------------
  186. void OverlayContainer::_positionsOutOfDate(void)
  187. {
  188. OverlayElement::_positionsOutOfDate();
  189. ChildIterator it = getChildIterator();
  190. while (it.hasMoreElements())
  191. {
  192. it.getNext()->_positionsOutOfDate();
  193. }
  194. }
  195. //---------------------------------------------------------------------
  196. void OverlayContainer::_update(void)
  197. {
  198. // call superclass
  199. OverlayElement::_update();
  200. // Update children
  201. ChildIterator it = getChildIterator();
  202. while (it.hasMoreElements())
  203. {
  204. it.getNext()->_update();
  205. }
  206. }
  207. //---------------------------------------------------------------------
  208. ushort OverlayContainer::_notifyZOrder(ushort newZOrder)
  209. {
  210. OverlayElement::_notifyZOrder(newZOrder);
  211. // One for us
  212. newZOrder++;
  213. // Update children
  214. ChildIterator it = getChildIterator();
  215. while (it.hasMoreElements())
  216. {
  217. // Children "consume" ZOrder values, so keep track of them
  218. newZOrder = it.getNext()->_notifyZOrder(newZOrder);
  219. }
  220. return newZOrder;
  221. }
  222. //---------------------------------------------------------------------
  223. void OverlayContainer::_notifyWorldTransforms(const Matrix4& xform)
  224. {
  225. OverlayElement::_notifyWorldTransforms(xform);
  226. // Update children
  227. ChildIterator it = getChildIterator();
  228. while (it.hasMoreElements())
  229. {
  230. it.getNext()->_notifyWorldTransforms(xform);
  231. }
  232. }
  233. //---------------------------------------------------------------------
  234. void OverlayContainer::_notifyViewport()
  235. {
  236. OverlayElement::_notifyViewport();
  237. // Update children
  238. ChildIterator it = getChildIterator();
  239. while (it.hasMoreElements())
  240. {
  241. it.getNext()->_notifyViewport();
  242. }
  243. }
  244. //---------------------------------------------------------------------
  245. void OverlayContainer::_notifyParent(OverlayContainer* parent, Overlay* overlay)
  246. {
  247. OverlayElement::_notifyParent(parent, overlay);
  248. // Update children
  249. ChildIterator it = getChildIterator();
  250. while (it.hasMoreElements())
  251. {
  252. // Notify the children of the overlay
  253. it.getNext()->_notifyParent(this, overlay);
  254. }
  255. }
  256. //---------------------------------------------------------------------
  257. void OverlayContainer::_updateRenderQueue(RenderQueue* queue)
  258. {
  259. if (mVisible)
  260. {
  261. OverlayElement::_updateRenderQueue(queue);
  262. // Also add children
  263. ChildIterator it = getChildIterator();
  264. while (it.hasMoreElements())
  265. {
  266. // Give children ZOrder 1 higher than this
  267. it.getNext()->_updateRenderQueue(queue);
  268. }
  269. }
  270. }
  271. OverlayElement* OverlayContainer::findElementAt(Real x, Real y) // relative to parent
  272. {
  273. OverlayElement* ret = NULL;
  274. int currZ = -1;
  275. if (mVisible)
  276. {
  277. ret = OverlayElement::findElementAt(x,y); //default to the current container if no others are found
  278. if (ret && mChildrenProcessEvents)
  279. {
  280. ChildIterator it = getChildIterator();
  281. while (it.hasMoreElements())
  282. {
  283. OverlayElement* currentOverlayElement = it.getNext();
  284. if (currentOverlayElement->isVisible() && currentOverlayElement->isEnabled())
  285. {
  286. int z = currentOverlayElement->getZOrder();
  287. if (z > currZ)
  288. {
  289. OverlayElement* elementFound = currentOverlayElement->findElementAt(x ,y );
  290. if (elementFound)
  291. {
  292. currZ = z;
  293. ret = elementFound;
  294. }
  295. }
  296. }
  297. }
  298. }
  299. }
  300. return ret;
  301. }
  302. void OverlayContainer::copyFromTemplate(OverlayElement* templateOverlay)
  303. {
  304. OverlayElement::copyFromTemplate(templateOverlay);
  305. if (templateOverlay->isContainer() && isContainer())
  306. {
  307. OverlayContainer::ChildIterator it = static_cast<OverlayContainer*>(templateOverlay)->getChildIterator();
  308. while (it.hasMoreElements())
  309. {
  310. OverlayElement* oldChildElement = it.getNext();
  311. if (oldChildElement->isCloneable())
  312. {
  313. OverlayElement* newChildElement =
  314. OverlayManager::getSingleton().createOverlayElement(
  315. oldChildElement->getTypeName(),
  316. mName+"/"+oldChildElement->getName());
  317. newChildElement->copyFromTemplate(oldChildElement);
  318. addChild((OverlayContainer*)newChildElement);
  319. }
  320. }
  321. }
  322. }
  323. OverlayElement* OverlayContainer::clone(const String& instanceName)
  324. {
  325. OverlayContainer *newContainer;
  326. newContainer = static_cast<OverlayContainer*>(OverlayElement::clone(instanceName));
  327. ChildIterator it = getChildIterator();
  328. while (it.hasMoreElements())
  329. {
  330. OverlayElement* oldChildElement = it.getNext();
  331. if (oldChildElement->isCloneable())
  332. {
  333. OverlayElement* newChildElement = oldChildElement->clone(instanceName);
  334. newContainer->_addChild(newChildElement);
  335. }
  336. }
  337. return newContainer;
  338. }
  339. }