00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "MyGUI_Precompiled.h"
00024 #include "MyGUI_Window.h"
00025 #include "MyGUI_Macros.h"
00026 #include "MyGUI_Gui.h"
00027 #include "MyGUI_ControllerManager.h"
00028 #include "MyGUI_InputManager.h"
00029 #include "MyGUI_WidgetManager.h"
00030 #include "MyGUI_ResourceSkin.h"
00031
00032 namespace MyGUI
00033 {
00034
00035 const float WINDOW_ALPHA_ACTIVE = ALPHA_MAX;
00036 const float WINDOW_ALPHA_FOCUS = 0.7f;
00037 const float WINDOW_ALPHA_DEACTIVE = 0.3f;
00038 const float WINDOW_SPEED_COEF = 3.0f;
00039
00040 const int WINDOW_SNAP_DISTANSE = 10;
00041
00042 Window::Window() :
00043 mWidgetCaption(nullptr),
00044 mMouseRootFocus(false),
00045 mKeyRootFocus(false),
00046 mIsAutoAlpha(false),
00047 mSnap(false),
00048 mAnimateSmooth(false)
00049 {
00050 }
00051
00052 void Window::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name)
00053 {
00054 Base::_initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name);
00055
00056 initialiseWidgetSkin(_info);
00057 }
00058
00059 Window::~Window()
00060 {
00061 shutdownWidgetSkin();
00062 }
00063
00064 void Window::baseChangeWidgetSkin(ResourceSkin* _info)
00065 {
00066 shutdownWidgetSkin();
00067 Base::baseChangeWidgetSkin(_info);
00068 initialiseWidgetSkin(_info);
00069 }
00070
00071 void Window::initialiseWidgetSkin(ResourceSkin* _info)
00072 {
00073
00074 mNeedKeyFocus = true;
00075
00076
00077 mMinmax.set(0, 0, 3000, 3000);
00078
00079 bool main_move = false;
00080
00081 const MapString& properties = _info->getProperties();
00082 if (!properties.empty())
00083 {
00084 MapString::const_iterator iter = properties.find("Snap");
00085 if (iter != properties.end()) mSnap = utility::parseBool(iter->second);
00086 iter = properties.find("MainMove");
00087 if (iter != properties.end())
00088 {
00089 setUserString("Scale", "1 1 0 0");
00090 main_move = true;
00091 }
00092 }
00093
00094 for (VectorWidgetPtr::iterator iter=mWidgetChildSkin.begin(); iter!=mWidgetChildSkin.end(); ++iter)
00095 {
00096 if (*(*iter)->_getInternalData<std::string>() == "Client")
00097 {
00098 MYGUI_DEBUG_ASSERT( ! mWidgetClient, "widget already assigned");
00099 mWidgetClient = (*iter);
00100 if (main_move)
00101 {
00102 (*iter)->setUserString("Scale", "1 1 0 0");
00103 (*iter)->eventMouseButtonPressed = newDelegate(this, &Window::notifyMousePressed);
00104 (*iter)->eventMouseDrag = newDelegate(this, &Window::notifyMouseDrag);
00105 }
00106 }
00107 else if (*(*iter)->_getInternalData<std::string>() == "Caption")
00108 {
00109 MYGUI_DEBUG_ASSERT( ! mWidgetCaption, "widget already assigned");
00110 mWidgetCaption = (*iter);
00111 mWidgetCaption->eventMouseButtonPressed = newDelegate(this, &Window::notifyMousePressed);
00112 mWidgetCaption->eventMouseDrag = newDelegate(this, &Window::notifyMouseDrag);
00113 }
00114 else if (*(*iter)->_getInternalData<std::string>() == "Button")
00115 {
00116 (*iter)->eventMouseButtonClick = newDelegate(this, &Window::notifyPressedButtonEvent);
00117 }
00118 else if (*(*iter)->_getInternalData<std::string>() == "Action")
00119 {
00120 (*iter)->eventMouseButtonPressed = newDelegate(this, &Window::notifyMousePressed);
00121 (*iter)->eventMouseDrag = newDelegate(this, &Window::notifyMouseDrag);
00122 }
00123 }
00124
00125 }
00126
00127 void Window::shutdownWidgetSkin()
00128 {
00129 mWidgetClient = nullptr;
00130 mWidgetCaption = nullptr;
00131 }
00132
00133
00134 Widget* Window::baseCreateWidget(WidgetStyle _style, const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _layer, const std::string& _name)
00135 {
00136 MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
00137 if (mWidgetClient != nullptr) return mWidgetClient->createWidgetT(_style, _type, _skin, _coord, _align, _layer, _name);
00138 return Base::baseCreateWidget(_style, _type, _skin, _coord, _align, _layer, _name);
00139 }
00140
00141 void Window::onMouseChangeRootFocus(bool _focus)
00142 {
00143 mMouseRootFocus = _focus;
00144 updateAlpha();
00145
00146 Base::onMouseChangeRootFocus(_focus);
00147 }
00148
00149 void Window::onKeyChangeRootFocus(bool _focus)
00150 {
00151 mKeyRootFocus = _focus;
00152 updateAlpha();
00153
00154 Base::onKeyChangeRootFocus(_focus);
00155 }
00156
00157 void Window::onMouseDrag(int _left, int _top)
00158 {
00159
00160 notifyMouseDrag(this, _left, _top);
00161
00162 Base::onMouseDrag(_left, _top);
00163 }
00164
00165 void Window::onMouseButtonPressed(int _left, int _top, MouseButton _id)
00166 {
00167 notifyMousePressed(this, _left, _top, _id);
00168
00169 Base::onMouseButtonPressed(_left, _top, _id);
00170 }
00171
00172 void Window::notifyMousePressed(MyGUI::Widget* _sender, int _left, int _top, MouseButton _id)
00173 {
00174 if (MouseButton::Left == _id)
00175 {
00176 mPreActionCoord = mCoord;
00177 mCurrentActionScale = IntCoord::parse(_sender->getUserString("Scale"));
00178 }
00179 }
00180
00181 void Window::notifyPressedButtonEvent(MyGUI::Widget* _sender)
00182 {
00183 eventWindowButtonPressed(this, _sender->getUserString("Event"));
00184 }
00185
00186 void Window::notifyMouseDrag(MyGUI::Widget* _sender, int _left, int _top)
00187 {
00188 const IntPoint& point = InputManager::getInstance().getLastLeftPressed();
00189
00190 IntCoord coord = mCurrentActionScale;
00191 coord.left *= (_left - point.left);
00192 coord.top *= (_top - point.top);
00193 coord.width *= (_left - point.left);
00194 coord.height *= (_top - point.top);
00195
00196 if (coord.left == 0 && coord.top == 0)
00197 setSize((mPreActionCoord + coord).size());
00198 else if (coord.width == 0 && coord.height == 0)
00199 setPosition((mPreActionCoord + coord).point());
00200 else
00201 setCoord(mPreActionCoord + coord);
00202
00203
00204 eventWindowChangeCoord(this);
00205 }
00206
00207 void Window::updateAlpha()
00208 {
00209 if (!mIsAutoAlpha) return;
00210
00211 float alpha;
00212 if (mKeyRootFocus) alpha = WINDOW_ALPHA_ACTIVE;
00213 else if (mMouseRootFocus) alpha = WINDOW_ALPHA_FOCUS;
00214 else alpha = WINDOW_ALPHA_DEACTIVE;
00215
00216 ControllerFadeAlpha * controller = createControllerFadeAlpha(alpha, WINDOW_SPEED_COEF, true);
00217 ControllerManager::getInstance().addItem(this, controller);
00218 }
00219
00220 void Window::setAutoAlpha(bool _auto)
00221 {
00222 mIsAutoAlpha = _auto;
00223 if (!_auto) setAlpha(ALPHA_MAX);
00224 else
00225 {
00226 if (mKeyRootFocus) setAlpha(WINDOW_ALPHA_ACTIVE);
00227 else if (mMouseRootFocus) setAlpha(WINDOW_ALPHA_FOCUS);
00228 else setAlpha(WINDOW_ALPHA_DEACTIVE);
00229 }
00230 }
00231
00232 void Window::setPosition(const IntPoint& _point)
00233 {
00234 IntPoint point = _point;
00235
00236 if (mSnap)
00237 {
00238 IntCoord coord(point, mCoord.size());
00239 getSnappedCoord(coord);
00240 point = coord.point();
00241 }
00242
00243 Base::setPosition(point);
00244 }
00245
00246 void Window::setSize(const IntSize& _size)
00247 {
00248 IntSize size = _size;
00249
00250
00251 if (size.width < mMinmax.left) size.width = mMinmax.left;
00252 else if (size.width > mMinmax.right) size.width = mMinmax.right;
00253 if (size.height < mMinmax.top) size.height = mMinmax.top;
00254 else if (size.height > mMinmax.bottom) size.height = mMinmax.bottom;
00255 if ((size.width == mCoord.width) && (size.height == mCoord.height) ) return;
00256
00257 if (mSnap)
00258 {
00259 IntCoord coord(mCoord.point(), size);
00260 getSnappedCoord(coord);
00261 size = coord.size();
00262 }
00263
00264 Base::setSize(size);
00265 }
00266
00267 void Window::setCoord(const IntCoord& _coord)
00268 {
00269 IntPoint pos = _coord.point();
00270 IntSize size = _coord.size();
00271
00272 if (size.width < mMinmax.left)
00273 {
00274 int offset = mMinmax.left - size.width;
00275 size.width = mMinmax.left;
00276 if ((pos.left - mCoord.left) > offset) pos.left -= offset;
00277 else pos.left = mCoord.left;
00278 }
00279 else if (size.width > mMinmax.right)
00280 {
00281 int offset = mMinmax.right - size.width;
00282 size.width = mMinmax.right;
00283 if ((pos.left - mCoord.left) < offset) pos.left -= offset;
00284 else pos.left = mCoord.left;
00285 }
00286 if (size.height < mMinmax.top)
00287 {
00288 int offset = mMinmax.top - size.height;
00289 size.height = mMinmax.top;
00290 if ((pos.top - mCoord.top) > offset) pos.top -= offset;
00291 else pos.top = mCoord.top;
00292 }
00293 else if (size.height > mMinmax.bottom)
00294 {
00295 int offset = mMinmax.bottom - size.height;
00296 size.height = mMinmax.bottom;
00297 if ((pos.top - mCoord.top) < offset) pos.top -= offset;
00298 else pos.top = mCoord.top;
00299 }
00300
00301
00302 if (mSnap)
00303 {
00304 IntCoord coord(pos, size);
00305 getSnappedCoord(coord);
00306 size = coord.size();
00307 }
00308
00309 IntCoord coord(pos, size);
00310 if (coord == mCoord) return;
00311
00312 Base::setCoord(coord);
00313 }
00314
00315 void Window::setCaption(const UString& _caption)
00316 {
00317 if (mWidgetCaption != nullptr) mWidgetCaption->setCaption(_caption);
00318 else Base::setCaption(_caption);
00319 }
00320
00321 const UString& Window::getCaption()
00322 {
00323 if (mWidgetCaption != nullptr) return mWidgetCaption->getCaption();
00324 return Base::getCaption();
00325 }
00326
00327 void Window::destroySmooth()
00328 {
00329 ControllerFadeAlpha * controller = createControllerFadeAlpha(ALPHA_MIN, WINDOW_SPEED_COEF, false);
00330 controller->eventPostAction = newDelegate(action::actionWidgetDestroy);
00331 ControllerManager::getInstance().addItem(this, controller);
00332 }
00333
00334 void Window::animateStop(Widget* _widget)
00335 {
00336 if (mAnimateSmooth)
00337 {
00338 ControllerManager::getInstance().removeItem(this);
00339 mAnimateSmooth = false;
00340 }
00341 }
00342
00343 void Window::setVisible(bool _visible)
00344 {
00345
00346 if (mAnimateSmooth)
00347 {
00348 ControllerManager::getInstance().removeItem(this);
00349 setAlpha(getAlphaVisible());
00350 setEnabledSilent(true);
00351 mAnimateSmooth = false;
00352 }
00353
00354 Base::setVisible(_visible);
00355 }
00356
00357 float Window::getAlphaVisible()
00358 {
00359 return (mIsAutoAlpha && !mKeyRootFocus) ? WINDOW_ALPHA_DEACTIVE : ALPHA_MAX;
00360 }
00361
00362 void Window::getSnappedCoord(IntCoord& _coord)
00363 {
00364 if (abs(_coord.left) <= WINDOW_SNAP_DISTANSE) _coord.left = 0;
00365 if (abs(_coord.top) <= WINDOW_SNAP_DISTANSE) _coord.top = 0;
00366
00367 IntSize view_size;
00368 if (getCroppedParent() == nullptr)
00369 view_size = this->getLayer()->getSize();
00370 else
00371 view_size = ((Widget*)getCroppedParent())->getSize();
00372
00373 if ( abs(_coord.left + _coord.width - view_size.width) < WINDOW_SNAP_DISTANSE) _coord.left = view_size.width - _coord.width;
00374 if ( abs(_coord.top + _coord.height - view_size.height) < WINDOW_SNAP_DISTANSE) _coord.top = view_size.height - _coord.height;
00375 }
00376
00377 void Window::setVisibleSmooth(bool _visible)
00378 {
00379 mAnimateSmooth = true;
00380 ControllerManager::getInstance().removeItem(this);
00381
00382 if (_visible)
00383 {
00384 setEnabledSilent(true);
00385 if ( ! isVisible() )
00386 {
00387 setAlpha(ALPHA_MIN);
00388 Base::setVisible(true);
00389 }
00390 ControllerFadeAlpha * controller = createControllerFadeAlpha(getAlphaVisible(), WINDOW_SPEED_COEF, true);
00391 controller->eventPostAction = newDelegate(this, &Window::animateStop);
00392 ControllerManager::getInstance().addItem(this, controller);
00393 }
00394 else
00395 {
00396 setEnabledSilent(false);
00397 ControllerFadeAlpha * controller = createControllerFadeAlpha(ALPHA_MIN, WINDOW_SPEED_COEF, false);
00398 controller->eventPostAction = newDelegate(action::actionWidgetHide);
00399 ControllerManager::getInstance().addItem(this, controller);
00400 }
00401 }
00402
00403 ControllerFadeAlpha* Window::createControllerFadeAlpha(float _alpha, float _coef, bool _enable)
00404 {
00405 ControllerItem* item = ControllerManager::getInstance().createItem(ControllerFadeAlpha::getClassTypeName());
00406 ControllerFadeAlpha* controller = item->castType<ControllerFadeAlpha>();
00407
00408 controller->setAlpha(_alpha);
00409 controller->setCoef(_coef);
00410 controller->setEnabled(_enable);
00411
00412 return controller;
00413 }
00414
00415 void Window::setMinSize(const IntSize& _value)
00416 {
00417 mMinmax.left = _value.width;
00418 mMinmax.top = _value.height;
00419 }
00420
00421 IntSize Window::getMinSize()
00422 {
00423 return IntSize(mMinmax.left, mMinmax.top);
00424 }
00425
00426 void Window::setMaxSize(const IntSize& _value)
00427 {
00428 mMinmax.right = _value.width;
00429 mMinmax.bottom = _value.height;
00430 }
00431
00432 IntSize Window::getMaxSize()
00433 {
00434 return IntSize(mMinmax.right, mMinmax.bottom);
00435 }
00436
00437 void Window::setProperty(const std::string& _key, const std::string& _value)
00438 {
00439 if (_key == "Window_AutoAlpha") setAutoAlpha(utility::parseValue<bool>(_value));
00440 else if (_key == "Window_Snap") setSnap(utility::parseValue<bool>(_value));
00441 else if (_key == "Window_MinSize") setMinSize(utility::parseValue<IntSize>(_value));
00442 else if (_key == "Window_MaxSize") setMaxSize(utility::parseValue<IntSize>(_value));
00443
00444 #ifndef MYGUI_DONT_USE_OBSOLETE
00445 else if (_key == "Window_MinMax")
00446 {
00447 IntRect rect = IntRect::parse(_value);
00448 setMinSize(rect.left, rect.top);
00449 setMaxSize(rect.right, rect.bottom);
00450 MYGUI_LOG(Warning, "Window_MinMax is obsolete, use Window_MinSize or Window_MaxSize");
00451 }
00452 #endif // MYGUI_DONT_USE_OBSOLETE
00453
00454 else
00455 {
00456 Base::setProperty(_key, _value);
00457 return;
00458 }
00459 eventChangeProperty(this, _key, _value);
00460 }
00461
00462 }