• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

MyGUI_Window.cpp

Go to the documentation of this file.
00001 
00007 /*
00008     This file is part of MyGUI.
00009     
00010     MyGUI is free software: you can redistribute it and/or modify
00011     it under the terms of the GNU Lesser General Public License as published by
00012     the Free Software Foundation, either version 3 of the License, or
00013     (at your option) any later version.
00014     
00015     MyGUI is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018     GNU Lesser General Public License for more details.
00019     
00020     You should have received a copy of the GNU Lesser General Public License
00021     along with MyGUI.  If not, see <http://www.gnu.org/licenses/>.
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, WidgetPtr _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 (false == 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     WidgetPtr 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::WidgetPtr _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::WidgetPtr _sender)
00182     {
00183         eventWindowButtonPressed(this, _sender->getUserString("Event"));
00184     }
00185 
00186     void Window::notifyMouseDrag(MyGUI::WidgetPtr _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         setCoord(mPreActionCoord + coord);
00197 
00198         // посылаем событие о изменении позиции и размере
00199         eventWindowChangeCoord(this);
00200     }
00201 
00202     void Window::updateAlpha()
00203     {
00204         if (false == mIsAutoAlpha) return;
00205 
00206         float alpha;
00207         if (mKeyRootFocus) alpha = WINDOW_ALPHA_ACTIVE;
00208         else if (mMouseRootFocus) alpha = WINDOW_ALPHA_FOCUS;
00209         else alpha = WINDOW_ALPHA_DEACTIVE;
00210 
00211         ControllerFadeAlpha * controller = createControllerFadeAlpha(alpha, WINDOW_SPEED_COEF, true);
00212         ControllerManager::getInstance().addItem(this, controller);
00213     }
00214 
00215     void Window::setAutoAlpha(bool _auto)
00216     {
00217         mIsAutoAlpha = _auto;
00218         if (false == _auto) setAlpha(ALPHA_MAX);
00219         else
00220         {
00221             if (mKeyRootFocus) setAlpha(WINDOW_ALPHA_ACTIVE);
00222             else if (mMouseRootFocus) setAlpha(WINDOW_ALPHA_FOCUS);
00223             else setAlpha(WINDOW_ALPHA_DEACTIVE);
00224         }
00225     }
00226 
00227     void Window::setPosition(const IntPoint& _point)
00228     {
00229         IntPoint pos = _point;
00230         // прилепляем к краям
00231         if (mSnap)
00232         {
00233             if (abs(pos.left) <= WINDOW_SNAP_DISTANSE) pos.left = 0;
00234             if (abs(pos.top) <= WINDOW_SNAP_DISTANSE) pos.top = 0;
00235 
00236             const IntSize& view_size = Gui::getInstance().getViewSize();
00237 
00238             if ( abs(pos.left + mCoord.width - view_size.width) < WINDOW_SNAP_DISTANSE) pos.left = view_size.width - mCoord.width;
00239             if ( abs(pos.top + mCoord.height - view_size.height) < WINDOW_SNAP_DISTANSE) pos.top = view_size.height - mCoord.height;
00240         }
00241 
00242         Base::setPosition(_point);
00243     }
00244 
00245     void Window::setSize(const IntSize& _size)
00246     {
00247         IntSize size = _size;
00248         // прилепляем к краям
00249         if (mSnap)
00250         {
00251             const IntSize& view_size = Gui::getInstance().getViewSize();
00252 
00253             if ( abs(mCoord.left + size.width - view_size.width) < WINDOW_SNAP_DISTANSE) size.width = view_size.width - mCoord.left;
00254             if ( abs(mCoord.top + size.height - view_size.height) < WINDOW_SNAP_DISTANSE) size.height = view_size.height - mCoord.top;
00255         }
00256 
00257         if (size.width < mMinmax.left) size.width = mMinmax.left;
00258         else if (size.width > mMinmax.right) size.width = mMinmax.right;
00259         if (size.height < mMinmax.top) size.height = mMinmax.top;
00260         else if (size.height > mMinmax.bottom) size.height = mMinmax.bottom;
00261         if ((size.width == mCoord.width) && (size.height == mCoord.height) ) return;
00262 
00263         Base::setSize(size);
00264     }
00265 
00266     void Window::setCoord(const IntCoord& _coord)
00267     {
00268         IntPoint pos = _coord.point();
00269         IntSize size = _coord.size();
00270         // прилепляем к краям
00271         if (mSnap)
00272         {
00273             if (abs(pos.left) <= WINDOW_SNAP_DISTANSE) pos.left = 0;
00274             if (abs(pos.top) <= WINDOW_SNAP_DISTANSE) pos.top = 0;
00275 
00276             const IntSize& view_size = Gui::getInstance().getViewSize();
00277 
00278             if ( abs(pos.left + mCoord.width - view_size.width) < WINDOW_SNAP_DISTANSE) pos.left = view_size.width - mCoord.width;
00279             if ( abs(pos.top + mCoord.height - view_size.height) < WINDOW_SNAP_DISTANSE) pos.top = view_size.height - mCoord.height;
00280 
00281             if ( abs(mCoord.left + size.width - view_size.width) < WINDOW_SNAP_DISTANSE) size.width = view_size.width - mCoord.left;
00282             if ( abs(mCoord.top + size.height - view_size.height) < WINDOW_SNAP_DISTANSE) size.height = view_size.height - mCoord.top;
00283         }
00284 
00285         if (size.width < mMinmax.left)
00286         {
00287             int offset = mMinmax.left - size.width;
00288             size.width = mMinmax.left;
00289             if ((pos.left - mCoord.left) > offset) pos.left -= offset;
00290             else pos.left = mCoord.left;
00291         }
00292         else if (size.width > mMinmax.right)
00293         {
00294             int offset = mMinmax.right - size.width;
00295             size.width = mMinmax.right;
00296             if ((pos.left - mCoord.left) < offset) pos.left -= offset;
00297             else pos.left = mCoord.left;
00298         }
00299         if (size.height < mMinmax.top)
00300         {
00301             int offset = mMinmax.top - size.height;
00302             size.height = mMinmax.top;
00303             if ((pos.top - mCoord.top) > offset) pos.top -= offset;
00304             else pos.top = mCoord.top;
00305         }
00306         else if (size.height > mMinmax.bottom)
00307         {
00308             int offset = mMinmax.bottom - size.height;
00309             size.height = mMinmax.bottom;
00310             if ((pos.top - mCoord.top) < offset) pos.top -= offset;
00311             else pos.top = mCoord.top;
00312         }
00313 
00314         IntCoord coord(pos, size);
00315         if (coord == mCoord) return;
00316 
00317         Base::setCoord(coord);
00318     }
00319 
00320     void Window::setCaption(const UString& _caption)
00321     {
00322         if (mWidgetCaption != nullptr) mWidgetCaption->setCaption(_caption);
00323         else Base::setCaption(_caption);
00324     }
00325 
00326     const UString& Window::getCaption()
00327     {
00328         if (mWidgetCaption != nullptr) return mWidgetCaption->getCaption();
00329         return Base::getCaption();
00330     }
00331 
00332     void Window::destroySmooth()
00333     {
00334         ControllerFadeAlpha * controller = createControllerFadeAlpha(ALPHA_MIN, WINDOW_SPEED_COEF, false);
00335         controller->eventPostAction = newDelegate(action::actionWidgetDestroy);
00336         ControllerManager::getInstance().addItem(this, controller);
00337     }
00338 
00339     void Window::animateStop(WidgetPtr _widget)
00340     {
00341         if (mAnimateSmooth)
00342         {
00343             ControllerManager::getInstance().removeItem(this);
00344             mAnimateSmooth = false;
00345         }
00346     }
00347 
00348     void Window::setVisible(bool _visible)
00349     {
00350 
00351         if (mAnimateSmooth)
00352         {
00353             ControllerManager::getInstance().removeItem(this);
00354             setAlpha(getAlphaVisible());
00355             setEnabledSilent(true);
00356             mAnimateSmooth = false;
00357         }
00358 
00359         Base::setVisible(_visible);
00360     }
00361 
00362     float Window::getAlphaVisible()
00363     {
00364         return (mIsAutoAlpha && !mKeyRootFocus) ? WINDOW_ALPHA_DEACTIVE : ALPHA_MAX;
00365     }
00366 
00367     void Window::setVisibleSmooth(bool _visible)
00368     {
00369         mAnimateSmooth = true;
00370         ControllerManager::getInstance().removeItem(this);
00371 
00372         if (_visible)
00373         {
00374             setEnabledSilent(true);
00375             if ( ! isVisible() )
00376             {
00377                 setAlpha(ALPHA_MIN);
00378                 Base::setVisible(true);
00379             }
00380             ControllerFadeAlpha * controller = createControllerFadeAlpha(getAlphaVisible(), WINDOW_SPEED_COEF, true);
00381             controller->eventPostAction = newDelegate(this, &Window::animateStop);
00382             ControllerManager::getInstance().addItem(this, controller);
00383         }
00384         else
00385         {
00386             setEnabledSilent(false);
00387             ControllerFadeAlpha * controller = createControllerFadeAlpha(ALPHA_MIN, WINDOW_SPEED_COEF, false);
00388             controller->eventPostAction = newDelegate(action::actionWidgetHide);
00389             ControllerManager::getInstance().addItem(this, controller);
00390         }
00391     }
00392 
00393     ControllerFadeAlpha* Window::createControllerFadeAlpha(float _alpha, float _coef, bool _enable)
00394     {
00395         ControllerItem* item = ControllerManager::getInstance().createItem(ControllerFadeAlpha::getClassTypeName());
00396         ControllerFadeAlpha* controller = item->castType<ControllerFadeAlpha>();
00397 
00398         controller->setAlpha(_alpha);
00399         controller->setCoef(_coef);
00400         controller->setEnabled(_enable);
00401 
00402         return controller;
00403     }
00404 
00405     void Window::setMinSize(const IntSize& _value)
00406     {
00407         mMinmax.left = _value.width;
00408         mMinmax.top = _value.height;
00409     }
00410 
00411     IntSize Window::getMinSize()
00412     {
00413         return IntSize(mMinmax.left, mMinmax.top);
00414     }
00415 
00416     void Window::setMaxSize(const IntSize& _value)
00417     {
00418         mMinmax.right = _value.width;
00419         mMinmax.bottom = _value.height;
00420     }
00421 
00422     IntSize Window::getMaxSize()
00423     {
00424         return IntSize(mMinmax.right, mMinmax.bottom);
00425     }
00426 
00427     void Window::setProperty(const std::string& _key, const std::string& _value)
00428     {
00429         if (_key == "Window_AutoAlpha") setAutoAlpha(utility::parseValue<bool>(_value));
00430         else if (_key == "Window_Snap") setSnap(utility::parseValue<bool>(_value));
00431         else if (_key == "Window_MinSize") setMinSize(utility::parseValue<IntSize>(_value));
00432         else if (_key == "Window_MaxSize") setMaxSize(utility::parseValue<IntSize>(_value));
00433 
00434 #ifndef MYGUI_DONT_USE_OBSOLETE
00435         else if (_key == "Window_MinMax")
00436         {
00437             IntRect rect = IntRect::parse(_value);
00438             setMinSize(rect.left, rect.top);
00439             setMaxSize(rect.right, rect.bottom);
00440             MYGUI_LOG(Warning, "Window_MinMax is obsolete, use Window_MinSize or Window_MaxSize");
00441         }
00442 #endif // MYGUI_DONT_USE_OBSOLETE
00443 
00444         else Base::setProperty(_key, _value);
00445     }
00446 
00447 } // namespace MyGUI

Generated on Sun Jan 30 2011 for MyGUI by  doxygen 1.7.1