MyGUI  3.2.0
MyGUI_ScrollView.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_ScrollView.h"
00024 #include "MyGUI_SkinManager.h"
00025 #include "MyGUI_ISubWidgetText.h"
00026 #include "MyGUI_ScrollBar.h"
00027 
00028 namespace MyGUI
00029 {
00030 
00031     const int SCROLL_VIEW_MOUSE_WHEEL = 50; // колличество пикселей для колеса мыши
00032     const int SCROLL_VIEW_SCROLL_PAGE = 16; // колличество пикселей для кнопок скрола
00033 
00034     ScrollView::ScrollView() :
00035         mContentAlign(Align::Center),
00036         mRealClient(nullptr)
00037     {
00038         mChangeContentByResize = false;
00039         mContentAlign = Align::Center;
00040     }
00041 
00042     void ScrollView::initialiseOverride()
00043     {
00044         Base::initialiseOverride();
00045 
00046         // FIXME нам нужен фокус клавы
00047         setNeedKeyFocus(true);
00048 
00049         assignWidget(mClient, "Client");
00050         MyGUI::Widget* realClientOwner = this;
00051         if (mClient != nullptr)
00052         {
00053             mClient->eventMouseWheel += newDelegate(this, &ScrollView::notifyMouseWheel);
00054             realClientOwner = mClient;
00055         }
00056 
00057         // создаем холcт, реальный владелец детей
00058         mRealClient = realClientOwner->createWidget<Widget>("Default", IntCoord(), Align::Default);
00059         mRealClient->eventMouseWheel += newDelegate(this, &ScrollView::notifyMouseWheel);
00060         setWidgetClient(mRealClient);
00061 
00062         assignWidget(mVScroll, "VScroll");
00063         if (mVScroll != nullptr)
00064         {
00065             mVScroll->eventScrollChangePosition += newDelegate(this, &ScrollView::notifyScrollChangePosition);
00066         }
00067 
00068         assignWidget(mHScroll, "HScroll");
00069         if (mHScroll != nullptr)
00070         {
00071             mHScroll->eventScrollChangePosition += newDelegate(this, &ScrollView::notifyScrollChangePosition);
00072         }
00073 
00074         updateView();
00075     }
00076 
00077     void ScrollView::shutdownOverride()
00078     {
00079         mVScroll = nullptr;
00080         mHScroll = nullptr;
00081         mClient = nullptr;
00082         mRealClient = nullptr;
00083 
00084         Base::shutdownOverride();
00085     }
00086 
00087     void ScrollView::setPosition(const IntPoint& _point)
00088     {
00089         Base::setPosition(_point);
00090     }
00091 
00092     void ScrollView::setSize(const IntSize& _size)
00093     {
00094         Base::setSize(_size);
00095 
00096         updateView();
00097     }
00098 
00099     void ScrollView::setCoord(const IntCoord& _coord)
00100     {
00101         Base::setCoord(_coord);
00102 
00103         updateView();
00104     }
00105 
00106     void ScrollView::notifyScrollChangePosition(ScrollBar* _sender, size_t _position)
00107     {
00108         if (mRealClient == nullptr)
00109             return;
00110 
00111         if (_sender == mVScroll)
00112         {
00113             IntPoint point = mRealClient->getPosition();
00114             point.top = -(int)_position;
00115             mRealClient->setPosition(point);
00116         }
00117         else if (_sender == mHScroll)
00118         {
00119             IntPoint point = mRealClient->getPosition();
00120             point.left = -(int)_position;
00121             mRealClient->setPosition(point);
00122         }
00123     }
00124 
00125     void ScrollView::notifyMouseWheel(Widget* _sender, int _rel)
00126     {
00127         if (mRealClient == nullptr)
00128             return;
00129 
00130         if (mVRange != 0)
00131         {
00132             IntPoint point = mRealClient->getPosition();
00133             int offset = -point.top;
00134             if (_rel < 0) offset += SCROLL_VIEW_MOUSE_WHEEL;
00135             else  offset -= SCROLL_VIEW_MOUSE_WHEEL;
00136 
00137             if (offset < 0) offset = 0;
00138             else if (offset > (int)mVRange) offset = mVRange;
00139 
00140             if (offset != point.top)
00141             {
00142                 point.top = -offset;
00143                 if (mVScroll != nullptr)
00144                 {
00145                     mVScroll->setScrollPosition(offset);
00146                 }
00147                 mRealClient->setPosition(point);
00148             }
00149         }
00150         else if (mHRange != 0)
00151         {
00152             IntPoint point = mRealClient->getPosition();
00153             int offset = -point.left;
00154             if (_rel < 0) offset += SCROLL_VIEW_MOUSE_WHEEL;
00155             else  offset -= SCROLL_VIEW_MOUSE_WHEEL;
00156 
00157             if (offset < 0) offset = 0;
00158             else if (offset > (int)mHRange) offset = mHRange;
00159 
00160             if (offset != point.left)
00161             {
00162                 point.left = -offset;
00163                 if (mHScroll != nullptr)
00164                 {
00165                     mHScroll->setScrollPosition(offset);
00166                 }
00167                 mRealClient->setPosition(point);
00168             }
00169         }
00170     }
00171 
00172     IntSize ScrollView::getContentSize()
00173     {
00174         return mRealClient == nullptr ? IntSize() : mRealClient->getSize();
00175     }
00176 
00177     IntPoint ScrollView::getContentPosition()
00178     {
00179         return mRealClient == nullptr ? IntPoint() : (IntPoint() - mRealClient->getPosition());
00180     }
00181 
00182     void ScrollView::setContentPosition(const IntPoint& _point)
00183     {
00184         if (mRealClient != nullptr)
00185             mRealClient->setPosition(IntPoint() - _point);
00186     }
00187 
00188     IntSize ScrollView::getViewSize()
00189     {
00190         return mClient == nullptr ? getSize() : mClient->getSize();
00191     }
00192 
00193     size_t ScrollView::getVScrollPage()
00194     {
00195         return SCROLL_VIEW_SCROLL_PAGE;
00196     }
00197 
00198     size_t ScrollView::getHScrollPage()
00199     {
00200         return SCROLL_VIEW_SCROLL_PAGE;
00201     }
00202 
00203     void ScrollView::updateView()
00204     {
00205         updateScrollSize();
00206         updateScrollPosition();
00207     }
00208 
00209     void ScrollView::setVisibleVScroll(bool _value)
00210     {
00211         mVisibleVScroll = _value;
00212         updateView();
00213     }
00214 
00215     void ScrollView::setVisibleHScroll(bool _value)
00216     {
00217         mVisibleHScroll = _value;
00218         updateView();
00219     }
00220 
00221     void ScrollView::setCanvasAlign(Align _value)
00222     {
00223         mContentAlign = _value;
00224         updateView();
00225     }
00226 
00227     void ScrollView::setCanvasSize(const IntSize& _value)
00228     {
00229         if (mRealClient != nullptr)
00230             mRealClient->setSize(_value);
00231         updateView();
00232     }
00233 
00234     IntSize ScrollView::getCanvasSize()
00235     {
00236         return mRealClient == nullptr ? IntSize() : mRealClient->getSize();
00237     }
00238 
00239     void ScrollView::setPropertyOverride(const std::string& _key, const std::string& _value)
00240     {
00241         if (_key == "VisibleVScroll")
00242             setVisibleVScroll(utility::parseValue<bool>(_value));
00243         else if (_key == "VisibleHScroll")
00244             setVisibleHScroll(utility::parseValue<bool>(_value));
00245         else if (_key == "CanvasAlign")
00246             setCanvasAlign(utility::parseValue<Align>(_value));
00247         else if (_key == "CanvasSize")
00248             setCanvasSize(utility::parseValue<IntSize>(_value));
00249         else
00250         {
00251             Base::setPropertyOverride(_key, _value);
00252             return;
00253         }
00254         eventChangeProperty(this, _key, _value);
00255     }
00256 
00257     void ScrollView::setPosition(int _left, int _top)
00258     {
00259         setPosition(IntPoint(_left, _top));
00260     }
00261 
00262     void ScrollView::setSize(int _width, int _height)
00263     {
00264         setSize(IntSize(_width, _height));
00265     }
00266 
00267     void ScrollView::setCoord(int _left, int _top, int _width, int _height)
00268     {
00269         setCoord(IntCoord(_left, _top, _width, _height));
00270     }
00271 
00272     bool ScrollView::isVisibleVScroll() const
00273     {
00274         return mVisibleVScroll;
00275     }
00276 
00277     bool ScrollView::isVisibleHScroll() const
00278     {
00279         return mVisibleHScroll;
00280     }
00281 
00282     Align ScrollView::getCanvasAlign() const
00283     {
00284         return mContentAlign;
00285     }
00286 
00287     void ScrollView::setCanvasSize(int _width, int _height)
00288     {
00289         setCanvasSize(IntSize(_width, _height));
00290     }
00291 
00292     Align ScrollView::getContentAlign()
00293     {
00294         return mContentAlign;
00295     }
00296 
00297     void ScrollView::setViewOffset(const IntPoint& _value)
00298     {
00299         IntPoint value = _value;
00300         IntPoint currentOffset = mRealClient->getPosition();
00301 
00302         if (mHRange != 0)
00303         {
00304             if (value.left > 0)
00305                 value.left = 0;
00306             else if (value.left < -(int)mHRange)
00307                 value.left = -(int)mHRange;
00308         }
00309         else
00310         {
00311             value.left = currentOffset.left;
00312         }
00313 
00314         if (mVRange != 0)
00315         {
00316             if (value.top > 0)
00317                 value.top = 0;
00318             else if (value.top < -(int)mVRange)
00319                 value.top = -(int)mVRange;
00320         }
00321         else
00322         {
00323             value.top = currentOffset.top;
00324         }
00325 
00326         if (mHScroll != nullptr)
00327             mHScroll->setScrollPosition(-value.left);
00328 
00329         if (mVScroll != nullptr)
00330             mVScroll->setScrollPosition(-value.top);
00331 
00332         mRealClient->setPosition(value);
00333     }
00334 
00335     IntPoint ScrollView::getViewOffset() const
00336     {
00337         return mRealClient->getPosition();
00338     }
00339 
00340     IntCoord ScrollView::getViewCoord() const
00341     {
00342         return mClient == nullptr ? getCoord() : mClient->getCoord();
00343     }
00344 
00345     ScrollBar* ScrollView::getVScroll()
00346     {
00347         return mVScroll;
00348     }
00349 
00350 } // namespace MyGUI