1 /* 2 * This source file is part of MyGUI. For the latest info, see http://mygui.info/ 3 * Distributed under the MIT License 4 * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT) 5 */ 6 7 #include "MyGUI_Precompiled.h" 8 #include "MyGUI_ScrollViewBase.h" 9 #include "MyGUI_ScrollBar.h" 10 11 namespace MyGUI 12 { 13 ScrollViewBase()14 ScrollViewBase::ScrollViewBase() : 15 mVScroll(nullptr), 16 mHScroll(nullptr), 17 mScrollViewClient(nullptr), 18 mVisibleHScroll(true), 19 mVisibleVScroll(true), 20 mVRange(0), 21 mHRange(0), 22 mChangeContentByResize(false) 23 { 24 } 25 updateScrollSize()26 void ScrollViewBase::updateScrollSize() 27 { 28 if (mScrollViewClient == nullptr) 29 return; 30 31 eraseContent(); 32 IntSize contentSize = getContentSize(); 33 IntSize viewSize = getViewSize(); 34 35 // вертикальный контент не помещается 36 if (contentSize.height > viewSize.height) 37 { 38 if (mVScroll != nullptr) 39 { 40 if (!mVScroll->getVisible() && mVisibleVScroll) 41 { 42 mVScroll->setVisible(true); 43 mScrollViewClient->setSize(mScrollViewClient->getWidth() - mVScroll->getWidth(), mScrollViewClient->getHeight()); 44 45 // размер может измениться 46 if (mChangeContentByResize) 47 { 48 eraseContent(); 49 contentSize = getContentSize(); 50 viewSize = getViewSize(); 51 } 52 53 if (mHScroll != nullptr) 54 { 55 mHScroll->setSize(mHScroll->getWidth() - mVScroll->getWidth(), mHScroll->getHeight()); 56 57 // если показали вертикальный скрол бар, уменьшилось вью по горизонтали, 58 // пересчитываем горизонтальный скрол на предмет показа 59 if ((contentSize.width > viewSize.width) && ( ! mHScroll->getVisible()) && (mVisibleHScroll)) 60 { 61 mHScroll->setVisible(true); 62 mScrollViewClient->setSize(mScrollViewClient->getWidth(), mScrollViewClient->getHeight() - mHScroll->getHeight()); 63 mVScroll->setSize(mVScroll->getWidth(), mVScroll->getHeight() - mHScroll->getHeight()); 64 65 // размер может измениться 66 if (mChangeContentByResize) 67 { 68 eraseContent(); 69 contentSize = getContentSize(); 70 viewSize = getViewSize(); 71 } 72 73 } 74 } 75 } 76 } 77 } 78 // вертикальный контент помещается 79 else 80 { 81 if (mVScroll != nullptr) 82 { 83 if (mVScroll->getVisible()) 84 { 85 mVScroll->setVisible(false); 86 mScrollViewClient->setSize(mScrollViewClient->getWidth() + mVScroll->getWidth(), mScrollViewClient->getHeight()); 87 88 // размер может измениться 89 if (mChangeContentByResize) 90 { 91 eraseContent(); 92 contentSize = getContentSize(); 93 viewSize = getViewSize(); 94 } 95 96 if (mHScroll != nullptr) 97 { 98 mHScroll->setSize(mHScroll->getWidth() + mVScroll->getWidth(), mHScroll->getHeight()); 99 100 // если скрыли вертикальный скрол бар, увеличилось вью по горизонтали, 101 // пересчитываем горизонтальный скрол на предмет скрытия 102 if ((contentSize.width <= viewSize.width) && (mHScroll->getVisible())) 103 { 104 mHScroll->setVisible(false); 105 mScrollViewClient->setSize(mScrollViewClient->getWidth(), mScrollViewClient->getHeight() + mHScroll->getHeight()); 106 mVScroll->setSize(mVScroll->getWidth(), mVScroll->getHeight() + mHScroll->getHeight()); 107 108 // размер может измениться 109 if (mChangeContentByResize) 110 { 111 eraseContent(); 112 contentSize = getContentSize(); 113 viewSize = getViewSize(); 114 } 115 116 } 117 } 118 } 119 } 120 } 121 122 123 // горизонтальный контент не помещается 124 if (contentSize.width > viewSize.width) 125 { 126 if (mHScroll != nullptr) 127 { 128 if (!mHScroll->getVisible() && mVisibleHScroll) 129 { 130 mHScroll->setVisible(true); 131 mScrollViewClient->setSize(mScrollViewClient->getWidth(), mScrollViewClient->getHeight() - mHScroll->getHeight()); 132 133 // размер может измениться 134 if (mChangeContentByResize) 135 { 136 eraseContent(); 137 contentSize = getContentSize(); 138 viewSize = getViewSize(); 139 } 140 141 if (mVScroll != nullptr) 142 { 143 mVScroll->setSize(mVScroll->getWidth(), mVScroll->getHeight() - mHScroll->getHeight()); 144 145 // если показали горизонтальный скрол бар, уменьшилось вью по вертикали, 146 // пересчитываем вертикальный скрол на предмет показа 147 if ((contentSize.height > viewSize.height) && ( ! mVScroll->getVisible()) && (mVisibleVScroll)) 148 { 149 mVScroll->setVisible(true); 150 mScrollViewClient->setSize(mScrollViewClient->getWidth() - mVScroll->getWidth(), mScrollViewClient->getHeight()); 151 mHScroll->setSize(mHScroll->getWidth() - mVScroll->getWidth(), mHScroll->getHeight()); 152 153 // размер может измениться 154 if (mChangeContentByResize) 155 { 156 eraseContent(); 157 contentSize = getContentSize(); 158 viewSize = getViewSize(); 159 } 160 161 } 162 } 163 } 164 } 165 } 166 // горизонтальный контент помещается 167 else 168 { 169 if (mHScroll != nullptr) 170 { 171 if (mHScroll->getVisible()) 172 { 173 mHScroll->setVisible(false); 174 mScrollViewClient->setSize(mScrollViewClient->getWidth(), mScrollViewClient->getHeight() + mHScroll->getHeight()); 175 176 // размер может измениться 177 if (mChangeContentByResize) 178 { 179 eraseContent(); 180 contentSize = getContentSize(); 181 viewSize = getViewSize(); 182 } 183 184 if (mVScroll != nullptr) 185 { 186 mVScroll->setSize(mVScroll->getWidth(), mVScroll->getHeight() + mHScroll->getHeight()); 187 188 // если скрыли горизонтальный скрол бар, увеличилось вью по вертикали, 189 // пересчитываем вертикальный скрол на предмет скрытия 190 if ((contentSize.height <= viewSize.height) && (mVScroll->getVisible())) 191 { 192 mVScroll->setVisible(false); 193 mScrollViewClient->setSize(mScrollViewClient->getWidth() + mVScroll->getWidth(), mScrollViewClient->getHeight()); 194 mHScroll->setSize(mHScroll->getWidth() + mVScroll->getWidth(), mHScroll->getHeight()); 195 196 // размер может измениться 197 if (mChangeContentByResize) 198 { 199 eraseContent(); 200 contentSize = getContentSize(); 201 viewSize = getViewSize(); 202 } 203 } 204 } 205 } 206 } 207 } 208 209 mVRange = (viewSize.height >= contentSize.height) ? 0 : contentSize.height - viewSize.height; 210 mHRange = (viewSize.width >= contentSize.width) ? 0 : contentSize.width - viewSize.width; 211 212 if (mVScroll != nullptr) 213 { 214 size_t page = getVScrollPage(); 215 mVScroll->setScrollPage(page); 216 mVScroll->setScrollViewPage(viewSize.height > (int)page ? viewSize.height : page); 217 mVScroll->setScrollRange(mVRange + 1); 218 if (contentSize.height) mVScroll->setTrackSize(int (float(mVScroll->getLineSize() * viewSize.height) / float(contentSize.height))); 219 } 220 if (mHScroll != nullptr) 221 { 222 size_t page = getHScrollPage(); 223 mHScroll->setScrollPage(page); 224 mHScroll->setScrollViewPage(viewSize.width > (int)page ? viewSize.width : page); 225 mHScroll->setScrollRange(mHRange + 1); 226 if (contentSize.width) mHScroll->setTrackSize(int (float(mHScroll->getLineSize() * viewSize.width) / float(contentSize.width))); 227 } 228 } 229 updateScrollPosition()230 void ScrollViewBase::updateScrollPosition() 231 { 232 // размер контекста 233 IntSize contentSize = getContentSize(); 234 // текущее смещение контекста 235 IntPoint contentPoint = getContentPosition(); 236 // расчетное смещение 237 IntPoint offset = contentPoint; 238 239 IntSize viewSize = getViewSize(); 240 241 Align align = getContentAlign(); 242 243 if (contentSize.width > viewSize.width) 244 { 245 // максимальный выход влево 246 if ((offset.left + viewSize.width) > contentSize.width) 247 { 248 offset.left = contentSize.width - viewSize.width; 249 } 250 // максимальный выход вправо 251 else if (offset.left < 0) 252 { 253 offset.left = 0; 254 } 255 } 256 else 257 { 258 if (align.isLeft()) 259 { 260 offset.left = 0; 261 } 262 else if (align.isRight()) 263 { 264 offset.left = contentSize.width - viewSize.width; 265 } 266 else 267 { 268 offset.left = (contentSize.width - viewSize.width) / 2; 269 } 270 } 271 272 if (contentSize.height > viewSize.height) 273 { 274 // максимальный выход вверх 275 if ((offset.top + viewSize.height) > contentSize.height) 276 { 277 offset.top = contentSize.height - viewSize.height; 278 } 279 // максимальный выход вниз 280 else if (offset.top < 0) 281 { 282 offset.top = 0; 283 } 284 } 285 else 286 { 287 if (align.isTop()) 288 { 289 offset.top = 0; 290 } 291 else if (align.isBottom()) 292 { 293 offset.top = contentSize.height - viewSize.height; 294 } 295 else 296 { 297 offset.top = (contentSize.height - viewSize.height) / 2; 298 } 299 } 300 301 if (offset != contentPoint) 302 { 303 if (nullptr != mVScroll) mVScroll->setScrollPosition(offset.top); 304 if (nullptr != mHScroll) mHScroll->setScrollPosition(offset.left); 305 setContentPosition(offset); 306 } 307 } 308 getContentSize()309 IntSize ScrollViewBase::getContentSize() 310 { 311 return IntSize(); 312 } 313 getContentPosition()314 IntPoint ScrollViewBase::getContentPosition() 315 { 316 return IntPoint(); 317 } 318 setContentPosition(const IntPoint & _value)319 void ScrollViewBase::setContentPosition(const IntPoint& _value) 320 { 321 } 322 getViewSize()323 IntSize ScrollViewBase::getViewSize() 324 { 325 return IntSize(); 326 } 327 getHScrollPage()328 size_t ScrollViewBase::getHScrollPage() 329 { 330 return 1; 331 } 332 getVScrollPage()333 size_t ScrollViewBase::getVScrollPage() 334 { 335 return 1; 336 } 337 getContentAlign()338 Align ScrollViewBase::getContentAlign() 339 { 340 return Align::Center; 341 } 342 eraseContent()343 void ScrollViewBase::eraseContent() 344 { 345 } 346 347 } // namespace MyGUI 348