MyGUI  3.2.1
MyGUI_ScrollViewBase.cpp
Go to the documentation of this file.
00001 /*
00002  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
00003  * Distributed under the MIT License
00004  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
00005  */
00006 
00007 #include "MyGUI_Precompiled.h"
00008 #include "MyGUI_ScrollViewBase.h"
00009 #include "MyGUI_ScrollBar.h"
00010 
00011 namespace MyGUI
00012 {
00013 
00014     ScrollViewBase::ScrollViewBase() :
00015         mVScroll(nullptr),
00016         mHScroll(nullptr),
00017         mClient(nullptr),
00018         mVisibleHScroll(true),
00019         mVisibleVScroll(true),
00020         mVRange(0),
00021         mHRange(0),
00022         mChangeContentByResize(false)
00023     {
00024     }
00025 
00026     ScrollViewBase::~ScrollViewBase()
00027     {
00028     }
00029 
00030     void ScrollViewBase::updateScrollSize()
00031     {
00032         if (mClient == nullptr)
00033             return;
00034 
00035         eraseContent();
00036         IntSize contentSize = getContentSize();
00037         IntSize viewSize = getViewSize();
00038 
00039         // вертикальный контент не помещается
00040         if (contentSize.height > viewSize.height)
00041         {
00042             if (mVScroll != nullptr)
00043             {
00044                 if (!mVScroll->getVisible() && mVisibleVScroll)
00045                 {
00046                     mVScroll->setVisible(true);
00047                     mClient->setSize(mClient->getWidth() - mVScroll->getWidth(), mClient->getHeight());
00048 
00049                     // размер может измениться
00050                     if (mChangeContentByResize)
00051                     {
00052                         eraseContent();
00053                         contentSize = getContentSize();
00054                         viewSize = getViewSize();
00055                     }
00056 
00057                     if (mHScroll != nullptr)
00058                     {
00059                         mHScroll->setSize(mHScroll->getWidth() - mVScroll->getWidth(), mHScroll->getHeight());
00060 
00061                         // если показали вертикальный скрол бар, уменьшилось вью по горизонтали,
00062                         // пересчитываем горизонтальный скрол на предмет показа
00063                         if ((contentSize.width > viewSize.width) && ( ! mHScroll->getVisible()) && (mVisibleHScroll))
00064                         {
00065                             mHScroll->setVisible(true);
00066                             mClient->setSize(mClient->getWidth(), mClient->getHeight() - mHScroll->getHeight());
00067                             mVScroll->setSize(mVScroll->getWidth(), mVScroll->getHeight() - mHScroll->getHeight());
00068 
00069                             // размер может измениться
00070                             if (mChangeContentByResize)
00071                             {
00072                                 eraseContent();
00073                                 contentSize = getContentSize();
00074                                 viewSize = getViewSize();
00075                             }
00076 
00077                         }
00078                     }
00079                 }
00080             }
00081         }
00082         // вертикальный контент помещается
00083         else
00084         {
00085             if (mVScroll != nullptr)
00086             {
00087                 if (mVScroll->getVisible())
00088                 {
00089                     mVScroll->setVisible(false);
00090                     mClient->setSize(mClient->getWidth() + mVScroll->getWidth(), mClient->getHeight());
00091 
00092                     // размер может измениться
00093                     if (mChangeContentByResize)
00094                     {
00095                         eraseContent();
00096                         contentSize = getContentSize();
00097                         viewSize = getViewSize();
00098                     }
00099 
00100                     if (mHScroll != nullptr)
00101                     {
00102                         mHScroll->setSize(mHScroll->getWidth() + mVScroll->getWidth(), mHScroll->getHeight());
00103 
00104                         // если скрыли вертикальный скрол бар, увеличилось вью по горизонтали,
00105                         // пересчитываем горизонтальный скрол на предмет скрытия
00106                         if ((contentSize.width <= viewSize.width) && (mHScroll->getVisible()))
00107                         {
00108                             mHScroll->setVisible(false);
00109                             mClient->setSize(mClient->getWidth(), mClient->getHeight() + mHScroll->getHeight());
00110                             mVScroll->setSize(mVScroll->getWidth(), mVScroll->getHeight() + mHScroll->getHeight());
00111 
00112                             // размер может измениться
00113                             if (mChangeContentByResize)
00114                             {
00115                                 eraseContent();
00116                                 contentSize = getContentSize();
00117                                 viewSize = getViewSize();
00118                             }
00119 
00120                         }
00121                     }
00122                 }
00123             }
00124         }
00125 
00126 
00127         // горизонтальный контент не помещается
00128         if (contentSize.width > viewSize.width)
00129         {
00130             if (mHScroll != nullptr)
00131             {
00132                 if (!mHScroll->getVisible() && mVisibleHScroll)
00133                 {
00134                     mHScroll->setVisible(true);
00135                     mClient->setSize(mClient->getWidth(), mClient->getHeight() - mHScroll->getHeight());
00136 
00137                     // размер может измениться
00138                     if (mChangeContentByResize)
00139                     {
00140                         eraseContent();
00141                         contentSize = getContentSize();
00142                         viewSize = getViewSize();
00143                     }
00144 
00145                     if (mVScroll != nullptr)
00146                     {
00147                         mVScroll->setSize(mVScroll->getWidth(), mVScroll->getHeight() - mHScroll->getHeight());
00148 
00149                         // если показали горизонтальный скрол бар, уменьшилось вью по вертикали,
00150                         // пересчитываем вертикальный скрол на предмет показа
00151                         if ((contentSize.height > viewSize.height) && ( ! mVScroll->getVisible()) && (mVisibleVScroll))
00152                         {
00153                             mVScroll->setVisible(true);
00154                             mClient->setSize(mClient->getWidth() - mVScroll->getWidth(), mClient->getHeight());
00155                             mHScroll->setSize(mHScroll->getWidth() - mVScroll->getWidth(), mHScroll->getHeight());
00156 
00157                             // размер может измениться
00158                             if (mChangeContentByResize)
00159                             {
00160                                 eraseContent();
00161                                 contentSize = getContentSize();
00162                                 viewSize = getViewSize();
00163                             }
00164 
00165                         }
00166                     }
00167                 }
00168             }
00169         }
00170         // горизонтальный контент помещается
00171         else
00172         {
00173             if (mHScroll != nullptr)
00174             {
00175                 if (mHScroll->getVisible())
00176                 {
00177                     mHScroll->setVisible(false);
00178                     mClient->setSize(mClient->getWidth(), mClient->getHeight() + mHScroll->getHeight());
00179 
00180                     // размер может измениться
00181                     if (mChangeContentByResize)
00182                     {
00183                         eraseContent();
00184                         contentSize = getContentSize();
00185                         viewSize = getViewSize();
00186                     }
00187 
00188                     if (mVScroll != nullptr)
00189                     {
00190                         mVScroll->setSize(mVScroll->getWidth(), mVScroll->getHeight() + mHScroll->getHeight());
00191 
00192                         // если скрыли горизонтальный скрол бар, увеличилось вью по вертикали,
00193                         // пересчитываем вертикальный скрол на предмет скрытия
00194                         if ((contentSize.height <= viewSize.height) && (mVScroll->getVisible()))
00195                         {
00196                             mVScroll->setVisible(false);
00197                             mClient->setSize(mClient->getWidth() + mVScroll->getWidth(), mClient->getHeight());
00198                             mHScroll->setSize(mHScroll->getWidth() + mVScroll->getWidth(), mHScroll->getHeight());
00199 
00200                             // размер может измениться
00201                             if (mChangeContentByResize)
00202                             {
00203                                 eraseContent();
00204                                 contentSize = getContentSize();
00205                                 viewSize = getViewSize();
00206                             }
00207                         }
00208                     }
00209                 }
00210             }
00211         }
00212 
00213         mVRange = (viewSize.height >= contentSize.height) ? 0 : contentSize.height - viewSize.height;
00214         mHRange = (viewSize.width >= contentSize.width) ? 0 : contentSize.width - viewSize.width;
00215 
00216         if (mVScroll != nullptr)
00217         {
00218             size_t page = getVScrollPage();
00219             mVScroll->setScrollPage(page);
00220             mVScroll->setScrollViewPage(viewSize.width > (int)page ? viewSize.width : page);
00221             mVScroll->setScrollRange(mVRange + 1);
00222             if (contentSize.height) mVScroll->setTrackSize(int (float(mVScroll->getLineSize() * viewSize.height) / float(contentSize.height)));
00223         }
00224         if (mHScroll != nullptr)
00225         {
00226             size_t page = getHScrollPage();
00227             mHScroll->setScrollPage(page);
00228             mHScroll->setScrollViewPage(viewSize.height > (int)page ? viewSize.height : page);
00229             mHScroll->setScrollRange(mHRange + 1);
00230             if (contentSize.width) mHScroll->setTrackSize(int (float(mHScroll->getLineSize() * viewSize.width) / float(contentSize.width)));
00231         }
00232     }
00233 
00234     void ScrollViewBase::updateScrollPosition()
00235     {
00236         // размер контекста
00237         IntSize contentSize = getContentSize();
00238         // текущее смещение контекста
00239         IntPoint contentPoint = getContentPosition();
00240         // расчетное смещение
00241         IntPoint offset = contentPoint;
00242 
00243         IntSize viewSize = getViewSize();
00244 
00245         Align align = getContentAlign();
00246 
00247         if (contentSize.width > viewSize.width)
00248         {
00249             // максимальный выход влево
00250             if ((offset.left + viewSize.width) > contentSize.width)
00251             {
00252                 offset.left = contentSize.width - viewSize.width;
00253             }
00254             // максимальный выход вправо
00255             else if (offset.left < 0)
00256             {
00257                 offset.left = 0;
00258             }
00259         }
00260         else
00261         {
00262             if (align.isLeft())
00263             {
00264                 offset.left = 0;
00265             }
00266             else if (align.isRight())
00267             {
00268                 offset.left = contentSize.width - viewSize.width;
00269             }
00270             else
00271             {
00272                 offset.left = (contentSize.width - viewSize.width) / 2;
00273             }
00274         }
00275 
00276         if (contentSize.height > viewSize.height)
00277         {
00278             // максимальный выход вверх
00279             if ((offset.top + viewSize.height) > contentSize.height)
00280             {
00281                 offset.top = contentSize.height - viewSize.height;
00282             }
00283             // максимальный выход вниз
00284             else if (offset.top < 0)
00285             {
00286                 offset.top = 0;
00287             }
00288         }
00289         else
00290         {
00291             if (align.isTop())
00292             {
00293                 offset.top = 0;
00294             }
00295             else if (align.isBottom())
00296             {
00297                 offset.top = contentSize.height - viewSize.height;
00298             }
00299             else
00300             {
00301                 offset.top = (contentSize.height - viewSize.height) / 2;
00302             }
00303         }
00304 
00305         if (offset != contentPoint)
00306         {
00307             if (nullptr != mVScroll) mVScroll->setScrollPosition(offset.top);
00308             if (nullptr != mHScroll) mHScroll->setScrollPosition(offset.left);
00309             setContentPosition(offset);
00310         }
00311     }
00312 
00313     IntSize ScrollViewBase::getContentSize()
00314     {
00315         return IntSize();
00316     }
00317 
00318     IntPoint ScrollViewBase::getContentPosition()
00319     {
00320         return IntPoint();
00321     }
00322 
00323     void ScrollViewBase::setContentPosition(const IntPoint& _value)
00324     {
00325     }
00326 
00327     IntSize ScrollViewBase::getViewSize()
00328     {
00329         return IntSize();
00330     }
00331 
00332     size_t ScrollViewBase::getHScrollPage()
00333     {
00334         return 1;
00335     }
00336 
00337     size_t ScrollViewBase::getVScrollPage()
00338     {
00339         return 1;
00340     }
00341 
00342     Align ScrollViewBase::getContentAlign()
00343     {
00344         return Align::Center;
00345     }
00346 
00347     void ScrollViewBase::eraseContent()
00348     {
00349     }
00350 
00351 } // namespace MyGUI