MyGUI  3.0.1
MyGUI_ControllerEdgeHide.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_ControllerEdgeHide.h"
00025 #include "MyGUI_Gui.h"
00026 #include "MyGUI_InputManager.h"
00027 #include "MyGUI_WidgetManager.h"
00028 #include "MyGUI_Widget.h"
00029 
00030 namespace MyGUI
00031 {
00032 
00033 #ifndef M_PI
00034     const float M_PI = 3.141593f;
00035 #endif
00036 
00037     ControllerEdgeHide::ControllerEdgeHide() :
00038         mTime(1.0),
00039         mRemainPixels(0),
00040         mShadowSize(0),
00041         mElapsedTime(0)
00042     {
00043     }
00044 
00045     void ControllerEdgeHide::prepareItem(Widget* _widget)
00046     {
00047         recalculateTime(_widget);
00048         // вызываем пользовательский делегат для подготовки
00049         eventPreAction(_widget);
00050     }
00051 
00052     bool ControllerEdgeHide::addTime(Widget* _widget, float _time)
00053     {
00054         Widget* keyFocus = InputManager::getInstance().getKeyFocusWidget();
00055         Widget* mouseFocus = InputManager::getInstance().getMouseFocusWidget();
00056 
00057         while ((keyFocus != nullptr) && (_widget != keyFocus))
00058             keyFocus = keyFocus->getParent();
00059         while ((mouseFocus != nullptr) && (_widget != mouseFocus))
00060             mouseFocus = mouseFocus->getParent();
00061 
00062         // if our widget or its children have focus
00063         bool haveFocus = ((keyFocus != nullptr) || (mouseFocus != nullptr)) || (_widget->isVisible() == false);
00064 
00065         mElapsedTime += (1 - 2*haveFocus) * _time;
00066 
00067         if (mElapsedTime >= mTime)
00068         {
00069             mElapsedTime = mTime;
00070         }
00071         if (mElapsedTime <= 0)
00072         {
00073             mElapsedTime = 0.0f;
00074             return true;
00075         }
00076 
00077         float k = sin(M_PI * mElapsedTime/mTime - M_PI/2);
00078         if (k<0) k = (-pow(-k, 0.7f) + 1)/2;
00079         else k = (pow(k, 0.7f) + 1)/2;
00080 
00081         MyGUI::IntCoord coord = _widget->getCoord();
00082         // if widget was moved
00083         if (coord != mLastCoord)
00084         {
00085             // if still moving - leave it alone
00086             if (haveFocus)
00087                 return true;
00088             else
00089                 recalculateTime(_widget);
00090         }
00091 
00092         IntSize view_size;
00093         if (_widget->getCroppedParent() == nullptr)
00094             view_size = _widget->getLayer()->getSize();
00095         else
00096             view_size = ((Widget*)_widget->getCroppedParent())->getSize();
00097 
00098         bool nearBorder = false;
00099 
00100         if ((coord.left <= 0) && !(coord.right() >= view_size.width - 1))
00101         {
00102             coord.left = - int( float(coord.width - mRemainPixels - mShadowSize) * k);
00103             nearBorder = true;
00104         }
00105         else if ((coord.top <= 0) && !(coord.bottom() >= view_size.height - 1))
00106         {
00107             coord.top = - int( float(coord.height - mRemainPixels - mShadowSize) * k);
00108             nearBorder = true;
00109         }
00110         else if ((coord.right() >= view_size.width - 1) && !(coord.left <= 0))
00111         {
00112             coord.left = int(float(view_size.width - 1) - float(mRemainPixels)*k - float(coord.width) * (1.f - k));
00113             nearBorder = true;
00114         }
00115         else if ((coord.bottom() >= view_size.height-1) && !(coord.top <= 0))
00116         {
00117             coord.top = int(float(view_size.height-1) - float(mRemainPixels)*k - float(coord.height) * (1.f - k));
00118             nearBorder = true;
00119         }
00120 
00121         if (nearBorder)
00122         {
00123             _widget->setCoord(coord);
00124         }
00125         else
00126         {
00127             mElapsedTime = 0;
00128         }
00129         mLastCoord = coord;
00130 
00131         eventUpdateAction(_widget);
00132 
00133         return true;
00134     }
00135 
00136     void ControllerEdgeHide::setProperty(const std::string& _key, const std::string& _value)
00137     {
00138         if (_key == "Time") setTime(utility::parseValue<float>(_value));
00139         else if (_key == "RemainPixels") setRemainPixels(utility::parseValue<int>(_value));
00140         else if (_key == "ShadowSize") setShadowSize(utility::parseValue<int>(_value));
00141     }
00142 
00143     void ControllerEdgeHide::recalculateTime(Widget* _widget)
00144     {
00145         float k = 0;
00146         const MyGUI::IntCoord& coord = _widget->getCoord();     IntSize view_size;
00147         if (_widget->getCroppedParent() == nullptr)
00148             view_size = _widget->getLayer()->getSize();
00149         else
00150             view_size = ((Widget*)_widget->getCroppedParent())->getSize();
00151 
00152 
00153         // check if widget is near any border and not near opposite borders at same time
00154         if ((coord.left <= 0) && !(coord.right() >= view_size.width - 1))
00155         {
00156             k = - (float) coord.left / (coord.width - mRemainPixels - mShadowSize);
00157         }
00158         else if ((coord.top <= 0) && !(coord.bottom() >= view_size.height - 1))
00159         {
00160             k = - (float)coord.top / (coord.height - mRemainPixels - mShadowSize);
00161         }
00162         else if ((coord.right() >= view_size.width - 1) && !(coord.left <= 0))
00163         {
00164             k = (float)(coord.right() - view_size.width + 1 ) / (coord.width - mRemainPixels);
00165         }
00166         else if ((coord.bottom() >= view_size.height - 1) && !(coord.top <= 0))
00167         {
00168             k = (float)(coord.bottom() - view_size.height + 1 ) / (coord.height - mRemainPixels);
00169         }
00170 
00171         //mElapsedTime = (asin(k)/M_PI + 1./2) * mTime;
00172         // this is reversed formula from ControllerEdgeHide::addTime k calculation
00173         if (k > 0.5f)
00174             mElapsedTime = (asin( pow( 2*k - 1, 1/0.7f))/M_PI + 1.f/2) * mTime;
00175         else
00176             mElapsedTime = (asin(-pow(-2*k + 1, 1/0.7f))/M_PI + 1.f/2) * mTime;
00177     }
00178 
00179 } // namespace MyGUI