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