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