MyGUI  3.2.0
MyGUI_ControllerEdgeHide.cpp
Go to the documentation of this file.
00001 
00006 /*
00007     This file is part of MyGUI.
00008 
00009     MyGUI is free software: you can redistribute it and/or modify
00010     it under the terms of the GNU Lesser General Public License as published by
00011     the Free Software Foundation, either version 3 of the License, or
00012     (at your option) any later version.
00013 
00014     MyGUI is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017     GNU Lesser General Public License for more details.
00018 
00019     You should have received a copy of the GNU Lesser General Public License
00020     along with MyGUI.  If not, see <http://www.gnu.org/licenses/>.
00021 */
00022 #include "MyGUI_Precompiled.h"
00023 #include "MyGUI_ControllerEdgeHide.h"
00024 #include "MyGUI_Gui.h"
00025 #include "MyGUI_InputManager.h"
00026 #include "MyGUI_WidgetManager.h"
00027 #include "MyGUI_Widget.h"
00028 
00029 namespace MyGUI
00030 {
00031 
00032 #ifndef M_PI
00033     const float M_PI = 3.141593f;
00034 #endif
00035 
00036     ControllerEdgeHide::ControllerEdgeHide() :
00037         mTime(1.0),
00038         mRemainPixels(0),
00039         mShadowSize(0),
00040         mElapsedTime(0)
00041     {
00042     }
00043 
00044     ControllerEdgeHide::~ControllerEdgeHide()
00045     {
00046     }
00047 
00048     void ControllerEdgeHide::prepareItem(Widget* _widget)
00049     {
00050         recalculateTime(_widget);
00051         // вызываем пользовательский делегат для подготовки
00052         eventPreAction(_widget);
00053     }
00054 
00055     bool ControllerEdgeHide::addTime(Widget* _widget, float _time)
00056     {
00057         const IntSize& view_size = _widget->getParentSize();
00058         // do nothing if we have minimized window
00059         if (view_size.width <= 1 && view_size.height <= 1)
00060             return true;
00061 
00062         Widget* keyFocus = InputManager::getInstance().getKeyFocusWidget();
00063         Widget* mouseFocus = InputManager::getInstance().getMouseFocusWidget();
00064 
00065         while ((keyFocus != nullptr) && (_widget != keyFocus))
00066             keyFocus = keyFocus->getParent();
00067         while ((mouseFocus != nullptr) && (_widget != mouseFocus))
00068             mouseFocus = mouseFocus->getParent();
00069 
00070         // if our widget or its children have focus
00071         bool haveFocus = ((keyFocus != nullptr) || (mouseFocus != nullptr)) || (_widget->getVisible() == false);
00072 
00073         mElapsedTime += haveFocus ? -_time : _time;
00074 
00075         if (mElapsedTime >= mTime)
00076         {
00077             mElapsedTime = mTime;
00078         }
00079         if (mElapsedTime <= 0)
00080         {
00081             mElapsedTime = 0.0f;
00082             return true;
00083         }
00084 
00085         float k = sin(M_PI * mElapsedTime / mTime - M_PI / 2);
00086         if (k < 0) k = (-pow(-k, 0.7f) + 1) / 2;
00087         else k = (pow(k, 0.7f) + 1) / 2;
00088 
00089         MyGUI::IntCoord coord = _widget->getCoord();
00090         // if widget was moved
00091         if (coord != mLastCoord)
00092         {
00093             // if still moving - leave it alone
00094             if (haveFocus)
00095                 return true;
00096             else
00097                 recalculateTime(_widget);
00098         }
00099 
00100         bool nearBorder = false;
00101 
00102         if ((coord.left <= 0) && !(coord.right() >= view_size.width - 1))
00103         {
00104             coord.left = - int( float(coord.width - mRemainPixels - mShadowSize) * k);
00105             nearBorder = true;
00106         }
00107         if ((coord.top <= 0) && !(coord.bottom() >= view_size.height - 1))
00108         {
00109             coord.top = - int( float(coord.height - mRemainPixels - mShadowSize) * k);
00110             nearBorder = true;
00111         }
00112         if ((coord.right() >= view_size.width - 1) && !(coord.left <= 0))
00113         {
00114             coord.left = int(float(view_size.width - 1) - float(mRemainPixels) * k - float(coord.width) * (1.f - k));
00115             nearBorder = true;
00116         }
00117         if ((coord.bottom() >= view_size.height - 1) && !(coord.top <= 0))
00118         {
00119             coord.top = int(float(view_size.height - 1) - float(mRemainPixels) * k - float(coord.height) * (1.f - k));
00120             nearBorder = true;
00121         }
00122 
00123         if (nearBorder)
00124         {
00125             _widget->setCoord(coord);
00126         }
00127         else
00128         {
00129             mElapsedTime = 0;
00130         }
00131         mLastCoord = coord;
00132 
00133         eventUpdateAction(_widget);
00134 
00135         return true;
00136     }
00137 
00138     void ControllerEdgeHide::setProperty(const std::string& _key, const std::string& _value)
00139     {
00140         if (_key == "Time")
00141             setTime(utility::parseValue<float>(_value));
00142         else if (_key == "RemainPixels")
00143             setRemainPixels(utility::parseValue<int>(_value));
00144         else if (_key == "ShadowSize")
00145             setShadowSize(utility::parseValue<int>(_value));
00146     }
00147 
00148     void ControllerEdgeHide::recalculateTime(Widget* _widget)
00149     {
00150         float k = 0;
00151         const MyGUI::IntCoord& coord = _widget->getCoord();
00152         const MyGUI::IntSize& view_size = _widget->getParentSize();
00153 
00154         // check if widget is near any border and not near opposite borders at same time
00155         if ((coord.left <= 0) && !(coord.right() >= view_size.width - 1))
00156         {
00157             k = - (float) coord.left / (coord.width - mRemainPixels - mShadowSize);
00158         }
00159         else if ((coord.top <= 0) && !(coord.bottom() >= view_size.height - 1))
00160         {
00161             k = - (float)coord.top / (coord.height - mRemainPixels - mShadowSize);
00162         }
00163         else if ((coord.right() >= view_size.width - 1) && !(coord.left <= 0))
00164         {
00165             k = (float)(coord.right() - view_size.width + 1 ) / (coord.width - mRemainPixels);
00166         }
00167         else if ((coord.bottom() >= view_size.height - 1) && !(coord.top <= 0))
00168         {
00169             k = (float)(coord.bottom() - view_size.height + 1 ) / (coord.height - mRemainPixels);
00170         }
00171 
00172         //mElapsedTime = (asin(k)/M_PI + 1./2) * mTime;
00173         // this is reversed formula from ControllerEdgeHide::addTime k calculation
00174         if (k > 0.5f)
00175             mElapsedTime = (asin( pow( 2 * k - 1, 1 / 0.7f)) / M_PI + 1.f / 2) * mTime;
00176         else
00177             mElapsedTime = (asin(-pow(-2 * k + 1, 1 / 0.7f)) / M_PI + 1.f / 2) * mTime;
00178     }
00179 
00180     void ControllerEdgeHide::setTime(float _value)
00181     {
00182         mTime = _value;
00183     }
00184 
00185     void ControllerEdgeHide::setRemainPixels(int _value)
00186     {
00187         mRemainPixels = _value;
00188     }
00189 
00190     void ControllerEdgeHide::setShadowSize(int _value)
00191     {
00192         mShadowSize = _value;
00193     }
00194 
00195 } // namespace MyGUI