MyGUI  3.0.1
MyGUI_ScrollView.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_ScrollView.h"
00025 #include "MyGUI_SkinManager.h"
00026 #include "MyGUI_ISubWidgetText.h"
00027 #include "MyGUI_VScroll.h"
00028 #include "MyGUI_HScroll.h"
00029 
00030 namespace MyGUI
00031 {
00032 
00033     const int SCROLL_VIEW_MOUSE_WHEEL = 50; // колличество пикселей для колеса мыши
00034     const int SCROLL_VIEW_SCROLL_PAGE = 16; // колличество пикселей для кнопок скрола
00035 
00036     ScrollView::ScrollView() :
00037         mIsFocus(false),
00038         mIsPressed(false),
00039         mScrollClient(nullptr),
00040         mContentAlign(Align::Center)
00041     {
00042         mChangeContentByResize = false;
00043         mContentAlign = Align::Center;
00044     }
00045 
00046     void ScrollView::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name)
00047     {
00048         Base::_initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name);
00049 
00050         initialiseWidgetSkin(_info);
00051     }
00052 
00053     ScrollView::~ScrollView()
00054     {
00055         shutdownWidgetSkin();
00056     }
00057 
00058     void ScrollView::baseChangeWidgetSkin(ResourceSkin* _info)
00059     {
00060         shutdownWidgetSkin();
00061         Base::baseChangeWidgetSkin(_info);
00062         initialiseWidgetSkin(_info);
00063     }
00064 
00065     void ScrollView::initialiseWidgetSkin(ResourceSkin* _info)
00066     {
00067         // нам нужен фокус клавы
00068         mNeedKeyFocus = true;
00069 
00070         for (VectorWidgetPtr::iterator iter=mWidgetChildSkin.begin(); iter!=mWidgetChildSkin.end(); ++iter)
00071         {
00072             if (*(*iter)->_getInternalData<std::string>() == "Client")
00073             {
00074                 MYGUI_DEBUG_ASSERT( ! mScrollClient, "widget already assigned");
00075                 mScrollClient = (*iter);
00076                 mScrollClient->eventMouseSetFocus = newDelegate(this, &ScrollView::notifyMouseSetFocus);
00077                 mScrollClient->eventMouseLostFocus = newDelegate(this, &ScrollView::notifyMouseLostFocus);
00078                 mScrollClient->eventMouseWheel = newDelegate(this, &ScrollView::notifyMouseWheel);
00079                 mClient = mScrollClient;
00080 
00081                 // создаем холcт, реальный владелец детей
00082                 mWidgetClient = mScrollClient->createWidget<Widget>("Default", IntCoord(), Align::Default);
00083                 mWidgetClient->eventMouseWheel = newDelegate(this, &ScrollView::notifyMouseWheel);
00084                 mWidgetClient->eventMouseSetFocus = newDelegate(this, &ScrollView::notifyMouseSetFocus);
00085                 mWidgetClient->eventMouseLostFocus = newDelegate(this, &ScrollView::notifyMouseLostFocus);
00086             }
00087             else if (*(*iter)->_getInternalData<std::string>() == "VScroll")
00088             {
00089                 MYGUI_DEBUG_ASSERT( ! mVScroll, "widget already assigned");
00090                 mVScroll = (*iter)->castType<VScroll>();
00091                 mVScroll->eventScrollChangePosition = newDelegate(this, &ScrollView::notifyScrollChangePosition);
00092             }
00093             else if (*(*iter)->_getInternalData<std::string>() == "HScroll")
00094             {
00095                 MYGUI_DEBUG_ASSERT( ! mHScroll, "widget already assigned");
00096                 mHScroll = (*iter)->castType<HScroll>();
00097                 mHScroll->eventScrollChangePosition = newDelegate(this, &ScrollView::notifyScrollChangePosition);
00098             }
00099         }
00100 
00101         //MYGUI_ASSERT(nullptr != mScrollClient, "Child Widget Client not found in skin (ScrollView must have Client)");
00102 
00103         updateView();
00104     }
00105 
00106     void ScrollView::shutdownWidgetSkin()
00107     {
00108         mWidgetClient = nullptr;
00109         mVScroll = nullptr;
00110         mHScroll = nullptr;
00111         mScrollClient = nullptr;
00112     }
00113 
00114     void ScrollView::notifyMouseSetFocus(Widget* _sender, Widget* _old)
00115     {
00116         if ((_old == mScrollClient) || (mIsFocus))
00117             return;
00118 
00119         mIsFocus = true;
00120         updateScrollViewState();
00121     }
00122 
00123     void ScrollView::notifyMouseLostFocus(Widget* _sender, Widget* _new)
00124     {
00125         if ((_new == mScrollClient) || (!mIsFocus))
00126             return;
00127 
00128         mIsFocus = false;
00129         updateScrollViewState();
00130     }
00131 
00132     void ScrollView::onKeySetFocus(Widget* _old)
00133     {
00134         if (!mIsPressed)
00135         {
00136             mIsPressed = true;
00137             updateScrollViewState();
00138         }
00139 
00140         Base::onKeySetFocus(_old);
00141     }
00142 
00143     void ScrollView::onKeyLostFocus(Widget* _new)
00144     {
00145         if (mIsPressed)
00146         {
00147             mIsPressed = false;
00148             updateScrollViewState();
00149         }
00150 
00151         Base::onKeyLostFocus(_new);
00152     }
00153 
00154     void ScrollView::updateScrollViewState()
00155     {
00156         if (!mEnabled) setState("disabled");
00157         else if (mIsPressed)
00158         {
00159             if (mIsFocus) setState("pushed");
00160             else setState("normal_checked");
00161         }
00162         else if (mIsFocus) setState("highlighted");
00163         else setState("normal");
00164     }
00165 
00166     void ScrollView::setPosition(const IntPoint& _point)
00167     {
00168         Base::setPosition(_point);
00169     }
00170 
00171     void ScrollView::setSize(const IntSize& _size)
00172     {
00173         Base::setSize(_size);
00174 
00175         updateView();
00176     }
00177 
00178     void ScrollView::setCoord(const IntCoord& _coord)
00179     {
00180         Base::setCoord(_coord);
00181 
00182         updateView();
00183     }
00184 
00185     void ScrollView::notifyScrollChangePosition(VScroll* _sender, size_t _position)
00186     {
00187         if (mWidgetClient == nullptr)
00188             return;
00189 
00190         if (_sender == mVScroll)
00191         {
00192             IntPoint point = mWidgetClient->getPosition();
00193             point.top = -(int)_position;
00194             mWidgetClient->setPosition(point);
00195         }
00196         else if (_sender == mHScroll)
00197         {
00198             IntPoint point = mWidgetClient->getPosition();
00199             point.left = -(int)_position;
00200             mWidgetClient->setPosition(point);
00201         }
00202     }
00203 
00204     void ScrollView::notifyMouseWheel(Widget* _sender, int _rel)
00205     {
00206         if (mWidgetClient == nullptr)
00207             return;
00208 
00209         if (mVRange != 0)
00210         {
00211             IntPoint point = mWidgetClient->getPosition();
00212             int offset = -point.top;
00213             if (_rel < 0) offset += SCROLL_VIEW_MOUSE_WHEEL;
00214             else  offset -= SCROLL_VIEW_MOUSE_WHEEL;
00215 
00216             if (offset < 0) offset = 0;
00217             else if (offset > (int)mVRange) offset = mVRange;
00218 
00219             if (offset != point.top)
00220             {
00221                 point.top = -offset;
00222                 if (mVScroll != nullptr)
00223                 {
00224                     mVScroll->setScrollPosition(offset);
00225                 }
00226                 mWidgetClient->setPosition(point);
00227             }
00228         }
00229         else if (mHRange != 0)
00230         {
00231             IntPoint point = mWidgetClient->getPosition();
00232             int offset = -point.left;
00233             if (_rel < 0) offset += SCROLL_VIEW_MOUSE_WHEEL;
00234             else  offset -= SCROLL_VIEW_MOUSE_WHEEL;
00235 
00236             if (offset < 0) offset = 0;
00237             else if (offset > (int)mHRange) offset = mHRange;
00238 
00239             if (offset != point.left)
00240             {
00241                 point.left = -offset;
00242                 if (mHScroll != nullptr)
00243                 {
00244                     mHScroll->setScrollPosition(offset);
00245                 }
00246                 mWidgetClient->setPosition(point);
00247             }
00248         }
00249     }
00250 
00251     Widget* ScrollView::baseCreateWidget(WidgetStyle _style, const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _layer, const std::string& _name)
00252     {
00253         if (mWidgetClient == nullptr)
00254             return Base::baseCreateWidget(_style, _type, _skin, _coord, _align, _layer, _name);
00255         return mWidgetClient->createWidgetT(_style, _type, _skin, _coord, _align, _layer, _name);
00256     }
00257 
00258     IntSize ScrollView::getContentSize()
00259     {
00260         return mWidgetClient == nullptr ? IntSize() : mWidgetClient->getSize();
00261     }
00262 
00263     IntPoint ScrollView::getContentPosition()
00264     {
00265         return mWidgetClient == nullptr ? IntPoint() : (IntPoint() - mWidgetClient->getPosition());
00266     }
00267 
00268     void ScrollView::setContentPosition(const IntPoint& _point)
00269     {
00270         if (mWidgetClient != nullptr)
00271             mWidgetClient->setPosition(IntPoint() - _point);
00272     }
00273 
00274     IntSize ScrollView::getViewSize() const
00275     {
00276         return mScrollClient == nullptr ? IntSize() : mScrollClient->getSize();
00277     }
00278 
00279     size_t ScrollView::getVScrollPage()
00280     {
00281         return SCROLL_VIEW_SCROLL_PAGE;
00282     }
00283 
00284     size_t ScrollView::getHScrollPage()
00285     {
00286         return SCROLL_VIEW_SCROLL_PAGE;
00287     }
00288 
00289     void ScrollView::updateView()
00290     {
00291         updateScrollSize();
00292         updateScrollPosition();
00293     }
00294 
00295     void ScrollView::setVisibleVScroll(bool _value)
00296     {
00297         mVisibleVScroll = _value;
00298         updateView();
00299     }
00300 
00301     void ScrollView::setVisibleHScroll(bool _value)
00302     {
00303         mVisibleHScroll = _value;
00304         updateView();
00305     }
00306 
00307     void ScrollView::setCanvasAlign(Align _value)
00308     {
00309         mContentAlign = _value;
00310         updateView();
00311     }
00312 
00313     void ScrollView::setCanvasSize(const IntSize& _value)
00314     {
00315         if (mWidgetClient != nullptr)
00316             mWidgetClient->setSize(_value); updateView();
00317     }
00318 
00319     void ScrollView::setProperty(const std::string& _key, const std::string& _value)
00320     {
00321         if (_key == "ScrollView_VisibleVScroll") setVisibleVScroll(utility::parseValue<bool>(_value));
00322         else if (_key == "ScrollView_VisibleHScroll") setVisibleHScroll(utility::parseValue<bool>(_value));
00323         else if (_key == "ScrollView_CanvasAlign") setCanvasAlign(utility::parseValue<Align>(_value));
00324         else if (_key == "ScrollView_CanvasSize") setCanvasSize(utility::parseValue<IntSize>(_value));
00325 
00326 #ifndef MYGUI_DONT_USE_OBSOLETE
00327         else if (_key == "ScrollView_VScroll")
00328         {
00329             MYGUI_LOG(Warning, "ScrollView_VScroll is obsolete, use ScrollView_VisibleVScroll");
00330             setVisibleVScroll(utility::parseValue<bool>(_value));
00331         }
00332         else if (_key == "ScrollView_HScroll")
00333         {
00334             MYGUI_LOG(Warning, "ScrollView_HScroll is obsolete, use ScrollView_VisibleHScroll");
00335             setVisibleHScroll(utility::parseValue<bool>(_value));
00336         }
00337 #endif // MYGUI_DONT_USE_OBSOLETE
00338 
00339         else
00340         {
00341             Base::setProperty(_key, _value);
00342             return;
00343         }
00344         eventChangeProperty(this, _key, _value);
00345     }
00346 
00347     const IntCoord& ScrollView::getClientCoord()
00348     {
00349         return mScrollClient == nullptr ? getCoord() : mScrollClient->getCoord();
00350     }
00351 
00352     IntSize ScrollView::getCanvasSize()
00353     {
00354         return mWidgetClient == nullptr ? IntSize() : mWidgetClient->getSize();
00355     }
00356 
00357 } // namespace MyGUI