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