CGUIModalScreen.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. // Copyright (C) 2002-2012 Nikolaus Gebhardt
  2. // This file is part of the "Irrlicht Engine".
  3. // For conditions of distribution and use, see copyright notice in irrlicht.h
  4. #include "CGUIModalScreen.h"
  5. #ifdef _IRR_COMPILE_WITH_GUI_
  6. #include "IGUIEnvironment.h"
  7. #include "os.h"
  8. #include "IVideoDriver.h"
  9. #include "IGUISkin.h"
  10. namespace irr
  11. {
  12. namespace gui
  13. {
  14. //! constructor
  15. CGUIModalScreen::CGUIModalScreen(IGUIEnvironment* environment, IGUIElement* parent, s32 id)
  16. : IGUIElement(EGUIET_MODAL_SCREEN, environment, parent, id, core::recti(0, 0, parent->getAbsolutePosition().getWidth(), parent->getAbsolutePosition().getHeight()) ),
  17. MouseDownTime(0)
  18. {
  19. #ifdef _DEBUG
  20. setDebugName("CGUIModalScreen");
  21. #endif
  22. setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
  23. // this element is a tab group
  24. setTabGroup(true);
  25. }
  26. bool CGUIModalScreen::canTakeFocus(IGUIElement* target) const
  27. {
  28. return (target && ((const IGUIElement*)target == this // this element can take it
  29. || isMyChild(target) // own children also
  30. || (target->getType() == EGUIET_MODAL_SCREEN ) // other modals also fine (is now on top or explicitely requested)
  31. || (target->getParent() && target->getParent()->getType() == EGUIET_MODAL_SCREEN ))) // children of other modals will do
  32. ;
  33. }
  34. bool CGUIModalScreen::isVisible() const
  35. {
  36. // any parent invisible?
  37. IGUIElement * parentElement = getParent();
  38. while ( parentElement )
  39. {
  40. if ( !parentElement->isVisible() )
  41. return false;
  42. parentElement = parentElement->getParent();
  43. }
  44. // if we have no children then the modal is probably abused as a way to block input
  45. if ( Children.empty() )
  46. {
  47. return IGUIElement::isVisible();
  48. }
  49. // any child visible?
  50. bool visible = false;
  51. core::list<IGUIElement*>::ConstIterator it = Children.begin();
  52. for (; it != Children.end(); ++it)
  53. {
  54. if ( (*it)->isVisible() )
  55. {
  56. visible = true;
  57. break;
  58. }
  59. }
  60. return visible;
  61. }
  62. bool CGUIModalScreen::isPointInside(const core::position2d<s32>& point) const
  63. {
  64. return true;
  65. }
  66. //! called if an event happened.
  67. bool CGUIModalScreen::OnEvent(const SEvent& event)
  68. {
  69. if (!isEnabled() || !isVisible() )
  70. return IGUIElement::OnEvent(event);
  71. switch(event.EventType)
  72. {
  73. case EET_GUI_EVENT:
  74. switch(event.GUIEvent.EventType)
  75. {
  76. case EGET_ELEMENT_FOCUSED:
  77. if ( event.GUIEvent.Caller == this && isMyChild(event.GUIEvent.Element) )
  78. {
  79. Environment->removeFocus(0); // can't setFocus otherwise at it still has focus here
  80. Environment->setFocus(event.GUIEvent.Element);
  81. MouseDownTime = os::Timer::getTime();
  82. return true;
  83. }
  84. if ( !canTakeFocus(event.GUIEvent.Caller))
  85. {
  86. if ( !Children.empty() )
  87. Environment->setFocus(*(Children.begin()));
  88. else
  89. Environment->setFocus(this);
  90. }
  91. IGUIElement::OnEvent(event);
  92. return false;
  93. case EGET_ELEMENT_FOCUS_LOST:
  94. if ( !canTakeFocus(event.GUIEvent.Element))
  95. {
  96. if ( isMyChild(event.GUIEvent.Caller) )
  97. {
  98. if ( !Children.empty() )
  99. Environment->setFocus(*(Children.begin()));
  100. else
  101. Environment->setFocus(this);
  102. }
  103. else
  104. {
  105. MouseDownTime = os::Timer::getTime();
  106. }
  107. return true;
  108. }
  109. else
  110. {
  111. return IGUIElement::OnEvent(event);
  112. }
  113. case EGET_ELEMENT_CLOSED:
  114. // do not interfere with children being removed
  115. return IGUIElement::OnEvent(event);
  116. default:
  117. break;
  118. }
  119. break;
  120. case EET_MOUSE_INPUT_EVENT:
  121. if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
  122. {
  123. MouseDownTime = os::Timer::getTime();
  124. }
  125. default:
  126. break;
  127. }
  128. IGUIElement::OnEvent(event); // anyone knows why events are passed on here? Causes p.e. problems when this is child of a CGUIWindow.
  129. return true; // absorb everything else
  130. }
  131. //! draws the element and its children
  132. void CGUIModalScreen::draw()
  133. {
  134. IGUISkin *skin = Environment->getSkin();
  135. if (!skin)
  136. return;
  137. u32 now = os::Timer::getTime();
  138. if (now - MouseDownTime < 300 && (now / 70)%2)
  139. {
  140. core::list<IGUIElement*>::Iterator it = Children.begin();
  141. core::rect<s32> r;
  142. video::SColor c = Environment->getSkin()->getColor(gui::EGDC_3D_HIGH_LIGHT);
  143. for (; it != Children.end(); ++it)
  144. {
  145. if ((*it)->isVisible())
  146. {
  147. r = (*it)->getAbsolutePosition();
  148. r.LowerRightCorner.X += 1;
  149. r.LowerRightCorner.Y += 1;
  150. r.UpperLeftCorner.X -= 1;
  151. r.UpperLeftCorner.Y -= 1;
  152. skin->draw2DRectangle(this, c, r, &AbsoluteClippingRect);
  153. }
  154. }
  155. }
  156. IGUIElement::draw();
  157. }
  158. //! Removes a child.
  159. void CGUIModalScreen::removeChild(IGUIElement* child)
  160. {
  161. IGUIElement::removeChild(child);
  162. if (Children.empty())
  163. {
  164. remove();
  165. }
  166. }
  167. //! adds a child
  168. void CGUIModalScreen::addChild(IGUIElement* child)
  169. {
  170. IGUIElement::addChild(child);
  171. Environment->setFocus(child);
  172. }
  173. void CGUIModalScreen::updateAbsolutePosition()
  174. {
  175. core::rect<s32> parentRect(0,0,0,0);
  176. if (Parent)
  177. {
  178. parentRect = Parent->getAbsolutePosition();
  179. RelativeRect.UpperLeftCorner.X = 0;
  180. RelativeRect.UpperLeftCorner.Y = 0;
  181. RelativeRect.LowerRightCorner.X = parentRect.getWidth();
  182. RelativeRect.LowerRightCorner.Y = parentRect.getHeight();
  183. }
  184. IGUIElement::updateAbsolutePosition();
  185. }
  186. //! Writes attributes of the element.
  187. void CGUIModalScreen::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const
  188. {
  189. IGUIElement::serializeAttributes(out,options);
  190. }
  191. //! Reads attributes of the element
  192. void CGUIModalScreen::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)
  193. {
  194. IGUIElement::deserializeAttributes(in, options);
  195. }
  196. } // end namespace gui
  197. } // end namespace irr
  198. #endif // _IRR_COMPILE_WITH_GUI_