| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. | |
| 3 * | |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions | |
| 6 * are met: | |
| 7 * 1. Redistributions of source code must retain the above copyright | |
| 8 * notice, this list of conditions and the following disclaimer. | |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | |
| 10 * notice, this list of conditions and the following disclaimer in the | |
| 11 * documentation and/or other materials provided with the distribution. | |
| 12 * | |
| 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | |
| 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | |
| 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
| 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
| 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
| 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
| 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 24 */ | |
| 25 | |
| 26 #include "config.h" | |
| 27 #include "platform/scroll/ScrollView.h" | |
| 28 | |
| 29 #include "platform/graphics/GraphicsContextStateSaver.h" | |
| 30 #include "platform/graphics/GraphicsLayer.h" | |
| 31 #include "platform/HostWindow.h" | |
| 32 #include "platform/scroll/Scrollbar.h" | |
| 33 #include "wtf/StdLibExtras.h" | |
| 34 | |
| 35 namespace blink { | |
| 36 | |
| 37 ScrollView::ScrollView() | |
| 38 : m_horizontalScrollbarMode(ScrollbarAuto) | |
| 39 , m_verticalScrollbarMode(ScrollbarAuto) | |
| 40 , m_horizontalScrollbarLock(false) | |
| 41 , m_verticalScrollbarLock(false) | |
| 42 , m_scrollbarsSuppressed(false) | |
| 43 , m_inUpdateScrollbars(false) | |
| 44 , m_paintsEntireContents(false) | |
| 45 , m_clipsRepaints(true) | |
| 46 { | |
| 47 } | |
| 48 | |
| 49 ScrollView::~ScrollView() | |
| 50 { | |
| 51 } | |
| 52 | |
| 53 void ScrollView::addChild(PassRefPtr<Widget> prpChild) | |
| 54 { | |
| 55 Widget* child = prpChild.get(); | |
| 56 ASSERT(child != this && !child->parent()); | |
| 57 child->setParent(this); | |
| 58 m_children.add(prpChild); | |
| 59 } | |
| 60 | |
| 61 void ScrollView::removeChild(Widget* child) | |
| 62 { | |
| 63 ASSERT(child->parent() == this); | |
| 64 child->setParent(0); | |
| 65 m_children.remove(child); | |
| 66 } | |
| 67 | |
| 68 void ScrollView::setHasHorizontalScrollbar(bool hasBar) | |
| 69 { | |
| 70 if (hasBar && !m_horizontalScrollbar) { | |
| 71 m_horizontalScrollbar = createScrollbar(HorizontalScrollbar); | |
| 72 addChild(m_horizontalScrollbar.get()); | |
| 73 didAddScrollbar(m_horizontalScrollbar.get(), HorizontalScrollbar); | |
| 74 m_horizontalScrollbar->styleChanged(); | |
| 75 } else if (!hasBar && m_horizontalScrollbar) { | |
| 76 willRemoveScrollbar(m_horizontalScrollbar.get(), HorizontalScrollbar); | |
| 77 removeChild(m_horizontalScrollbar.get()); | |
| 78 m_horizontalScrollbar = nullptr; | |
| 79 } | |
| 80 } | |
| 81 | |
| 82 void ScrollView::setHasVerticalScrollbar(bool hasBar) | |
| 83 { | |
| 84 if (hasBar && !m_verticalScrollbar) { | |
| 85 m_verticalScrollbar = createScrollbar(VerticalScrollbar); | |
| 86 addChild(m_verticalScrollbar.get()); | |
| 87 didAddScrollbar(m_verticalScrollbar.get(), VerticalScrollbar); | |
| 88 m_verticalScrollbar->styleChanged(); | |
| 89 } else if (!hasBar && m_verticalScrollbar) { | |
| 90 willRemoveScrollbar(m_verticalScrollbar.get(), VerticalScrollbar); | |
| 91 removeChild(m_verticalScrollbar.get()); | |
| 92 m_verticalScrollbar = nullptr; | |
| 93 } | |
| 94 } | |
| 95 | |
| 96 PassRefPtr<Scrollbar> ScrollView::createScrollbar(ScrollbarOrientation orientati
on) | |
| 97 { | |
| 98 return Scrollbar::create(this, orientation); | |
| 99 } | |
| 100 | |
| 101 void ScrollView::setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode v
erticalMode, | |
| 102 bool horizontalLock, bool verticalLock) | |
| 103 { | |
| 104 bool needsUpdate = false; | |
| 105 | |
| 106 if (horizontalMode != horizontalScrollbarMode() && !m_horizontalScrollbarLoc
k) { | |
| 107 m_horizontalScrollbarMode = horizontalMode; | |
| 108 needsUpdate = true; | |
| 109 } | |
| 110 | |
| 111 if (verticalMode != verticalScrollbarMode() && !m_verticalScrollbarLock) { | |
| 112 m_verticalScrollbarMode = verticalMode; | |
| 113 needsUpdate = true; | |
| 114 } | |
| 115 | |
| 116 if (horizontalLock) | |
| 117 setHorizontalScrollbarLock(); | |
| 118 | |
| 119 if (verticalLock) | |
| 120 setVerticalScrollbarLock(); | |
| 121 | |
| 122 if (!needsUpdate) | |
| 123 return; | |
| 124 | |
| 125 updateScrollbars(scrollOffset()); | |
| 126 | |
| 127 if (!layerForScrolling()) | |
| 128 return; | |
| 129 blink::WebLayer* layer = layerForScrolling()->platformLayer(); | |
| 130 if (!layer) | |
| 131 return; | |
| 132 layer->setUserScrollable(userInputScrollable(HorizontalScrollbar), userInput
Scrollable(VerticalScrollbar)); | |
| 133 } | |
| 134 | |
| 135 void ScrollView::scrollbarModes(ScrollbarMode& horizontalMode, ScrollbarMode& ve
rticalMode) const | |
| 136 { | |
| 137 horizontalMode = m_horizontalScrollbarMode; | |
| 138 verticalMode = m_verticalScrollbarMode; | |
| 139 } | |
| 140 | |
| 141 void ScrollView::setCanHaveScrollbars(bool canScroll) | |
| 142 { | |
| 143 ScrollbarMode newHorizontalMode; | |
| 144 ScrollbarMode newVerticalMode; | |
| 145 | |
| 146 scrollbarModes(newHorizontalMode, newVerticalMode); | |
| 147 | |
| 148 if (canScroll && newVerticalMode == ScrollbarAlwaysOff) | |
| 149 newVerticalMode = ScrollbarAuto; | |
| 150 else if (!canScroll) | |
| 151 newVerticalMode = ScrollbarAlwaysOff; | |
| 152 | |
| 153 if (canScroll && newHorizontalMode == ScrollbarAlwaysOff) | |
| 154 newHorizontalMode = ScrollbarAuto; | |
| 155 else if (!canScroll) | |
| 156 newHorizontalMode = ScrollbarAlwaysOff; | |
| 157 | |
| 158 setScrollbarModes(newHorizontalMode, newVerticalMode); | |
| 159 } | |
| 160 | |
| 161 void ScrollView::setPaintsEntireContents(bool paintsEntireContents) | |
| 162 { | |
| 163 m_paintsEntireContents = paintsEntireContents; | |
| 164 } | |
| 165 | |
| 166 void ScrollView::setClipsRepaints(bool clipsRepaints) | |
| 167 { | |
| 168 m_clipsRepaints = clipsRepaints; | |
| 169 } | |
| 170 | |
| 171 IntSize ScrollView::unscaledVisibleContentSize(IncludeScrollbarsInRect scrollbar
Inclusion) const | |
| 172 { | |
| 173 return scrollbarInclusion == ExcludeScrollbars ? excludeScrollbars(frameRect
().size()) : frameRect().size(); | |
| 174 } | |
| 175 | |
| 176 IntSize ScrollView::excludeScrollbars(const IntSize& size) const | |
| 177 { | |
| 178 int verticalScrollbarWidth = 0; | |
| 179 int horizontalScrollbarHeight = 0; | |
| 180 | |
| 181 if (Scrollbar* verticalBar = verticalScrollbar()) | |
| 182 verticalScrollbarWidth = !verticalBar->isOverlayScrollbar() ? verticalBa
r->width() : 0; | |
| 183 if (Scrollbar* horizontalBar = horizontalScrollbar()) | |
| 184 horizontalScrollbarHeight = !horizontalBar->isOverlayScrollbar() ? horiz
ontalBar->height() : 0; | |
| 185 | |
| 186 return IntSize(std::max(0, size.width() - verticalScrollbarWidth), | |
| 187 std::max(0, size.height() - horizontalScrollbarHeight)); | |
| 188 | |
| 189 } | |
| 190 | |
| 191 IntRect ScrollView::visibleContentRect(IncludeScrollbarsInRect scollbarInclusion
) const | |
| 192 { | |
| 193 FloatSize visibleContentSize = unscaledVisibleContentSize(scollbarInclusion)
; | |
| 194 visibleContentSize.scale(1 / visibleContentScaleFactor()); | |
| 195 return IntRect(IntPoint(m_scrollOffset), expandedIntSize(visibleContentSize)
); | |
| 196 } | |
| 197 | |
| 198 IntSize ScrollView::contentsSize() const | |
| 199 { | |
| 200 return m_contentsSize; | |
| 201 } | |
| 202 | |
| 203 void ScrollView::setContentsSize(const IntSize& newSize) | |
| 204 { | |
| 205 if (contentsSize() == newSize) | |
| 206 return; | |
| 207 m_contentsSize = newSize; | |
| 208 updateScrollbars(scrollOffset()); | |
| 209 updateOverhangAreas(); | |
| 210 } | |
| 211 | |
| 212 IntPoint ScrollView::maximumScrollPosition() const | |
| 213 { | |
| 214 IntPoint maximumOffset(contentsWidth() - visibleWidth() - scrollOrigin().x()
, contentsHeight() - visibleHeight() - scrollOrigin().y()); | |
| 215 maximumOffset.clampNegativeToZero(); | |
| 216 return maximumOffset; | |
| 217 } | |
| 218 | |
| 219 IntPoint ScrollView::minimumScrollPosition() const | |
| 220 { | |
| 221 return IntPoint(-scrollOrigin().x(), -scrollOrigin().y()); | |
| 222 } | |
| 223 | |
| 224 IntPoint ScrollView::adjustScrollPositionWithinRange(const IntPoint& scrollPoint
) const | |
| 225 { | |
| 226 if (!constrainsScrollingToContentEdge()) | |
| 227 return scrollPoint; | |
| 228 | |
| 229 IntPoint newScrollPosition = scrollPoint.shrunkTo(maximumScrollPosition()); | |
| 230 newScrollPosition = newScrollPosition.expandedTo(minimumScrollPosition()); | |
| 231 return newScrollPosition; | |
| 232 } | |
| 233 | |
| 234 void ScrollView::adjustScrollbarOpacity() | |
| 235 { | |
| 236 if (m_horizontalScrollbar && layerForHorizontalScrollbar()) { | |
| 237 bool isOpaqueScrollbar = !m_horizontalScrollbar->isOverlayScrollbar(); | |
| 238 layerForHorizontalScrollbar()->setContentsOpaque(isOpaqueScrollbar); | |
| 239 } | |
| 240 if (m_verticalScrollbar && layerForVerticalScrollbar()) { | |
| 241 bool isOpaqueScrollbar = !m_verticalScrollbar->isOverlayScrollbar(); | |
| 242 layerForVerticalScrollbar()->setContentsOpaque(isOpaqueScrollbar); | |
| 243 } | |
| 244 } | |
| 245 | |
| 246 int ScrollView::scrollSize(ScrollbarOrientation orientation) const | |
| 247 { | |
| 248 Scrollbar* scrollbar = ((orientation == HorizontalScrollbar) ? m_horizontalS
crollbar : m_verticalScrollbar).get(); | |
| 249 | |
| 250 // If no scrollbars are present, the content may still be scrollable. | |
| 251 if (!scrollbar) { | |
| 252 IntSize scrollSize = m_contentsSize - visibleContentRect().size(); | |
| 253 scrollSize.clampNegativeToZero(); | |
| 254 return orientation == HorizontalScrollbar ? scrollSize.width() : scrollS
ize.height(); | |
| 255 } | |
| 256 | |
| 257 return scrollbar->totalSize() - scrollbar->visibleSize(); | |
| 258 } | |
| 259 | |
| 260 void ScrollView::notifyPageThatContentAreaWillPaint() const | |
| 261 { | |
| 262 } | |
| 263 | |
| 264 void ScrollView::setScrollOffset(const IntPoint& offset) | |
| 265 { | |
| 266 scrollTo(toIntSize(adjustScrollPositionWithinRange(offset))); | |
| 267 } | |
| 268 | |
| 269 void ScrollView::scrollTo(const IntSize& newOffset) | |
| 270 { | |
| 271 IntSize scrollDelta = newOffset - m_scrollOffset; | |
| 272 if (scrollDelta == IntSize()) | |
| 273 return; | |
| 274 m_scrollOffset = newOffset; | |
| 275 | |
| 276 if (scrollbarsSuppressed()) | |
| 277 return; | |
| 278 | |
| 279 if (isFrameView()) | |
| 280 m_pendingScrollDelta += scrollDelta; | |
| 281 else | |
| 282 scrollContents(scrollDelta); | |
| 283 } | |
| 284 | |
| 285 void ScrollView::setScrollPosition(const IntPoint& scrollPoint, ScrollBehavior s
crollBehavior) | |
| 286 { | |
| 287 IntPoint newScrollPosition = adjustScrollPositionWithinRange(scrollPoint); | |
| 288 | |
| 289 if (newScrollPosition == scrollPosition()) | |
| 290 return; | |
| 291 | |
| 292 if (scrollBehavior == ScrollBehaviorInstant) | |
| 293 updateScrollbars(IntSize(newScrollPosition.x(), newScrollPosition.y())); | |
| 294 else | |
| 295 programmaticallyScrollSmoothlyToOffset(newScrollPosition); | |
| 296 } | |
| 297 | |
| 298 bool ScrollView::scroll(ScrollDirection direction, ScrollGranularity granularity
) | |
| 299 { | |
| 300 return ScrollableArea::scroll(direction, granularity); | |
| 301 } | |
| 302 | |
| 303 IntSize ScrollView::overhangAmount() const | |
| 304 { | |
| 305 IntSize stretch; | |
| 306 | |
| 307 IntPoint currentScrollPosition = scrollPosition(); | |
| 308 IntPoint minScrollPosition = minimumScrollPosition(); | |
| 309 IntPoint maxScrollPosition = maximumScrollPosition(); | |
| 310 | |
| 311 if (currentScrollPosition.x() < minScrollPosition.x()) | |
| 312 stretch.setWidth(currentScrollPosition.x() - minScrollPosition.x()); | |
| 313 if (currentScrollPosition.x() > maxScrollPosition.x()) | |
| 314 stretch.setWidth(currentScrollPosition.x() - maxScrollPosition.x()); | |
| 315 | |
| 316 if (currentScrollPosition.y() < minScrollPosition.y()) | |
| 317 stretch.setHeight(currentScrollPosition.y() - minScrollPosition.y()); | |
| 318 if (currentScrollPosition.y() > maxScrollPosition.y()) | |
| 319 stretch.setHeight(currentScrollPosition.y() - maxScrollPosition.y()); | |
| 320 | |
| 321 return stretch; | |
| 322 } | |
| 323 | |
| 324 void ScrollView::computeScrollbarExistence(bool& newHasHorizontalScrollbar, bool
& newHasVerticalScrollbar, const IntSize& docSize, ComputeScrollbarExistenceOpti
on option) const | |
| 325 { | |
| 326 bool hasHorizontalScrollbar = m_horizontalScrollbar; | |
| 327 bool hasVerticalScrollbar = m_verticalScrollbar; | |
| 328 | |
| 329 newHasHorizontalScrollbar = hasHorizontalScrollbar; | |
| 330 newHasVerticalScrollbar = hasVerticalScrollbar; | |
| 331 | |
| 332 ScrollbarMode hScroll = m_horizontalScrollbarMode; | |
| 333 ScrollbarMode vScroll = m_verticalScrollbarMode; | |
| 334 | |
| 335 if (hScroll != ScrollbarAuto) | |
| 336 newHasHorizontalScrollbar = (hScroll == ScrollbarAlwaysOn); | |
| 337 if (vScroll != ScrollbarAuto) | |
| 338 newHasVerticalScrollbar = (vScroll == ScrollbarAlwaysOn); | |
| 339 | |
| 340 if (m_scrollbarsSuppressed || (hScroll != ScrollbarAuto && vScroll != Scroll
barAuto)) | |
| 341 return; | |
| 342 | |
| 343 if (hScroll == ScrollbarAuto) | |
| 344 newHasHorizontalScrollbar = docSize.width() > visibleWidth(); | |
| 345 if (vScroll == ScrollbarAuto) | |
| 346 newHasVerticalScrollbar = docSize.height() > visibleHeight(); | |
| 347 } | |
| 348 | |
| 349 void ScrollView::updateScrollbarGeometry() | |
| 350 { | |
| 351 if (m_horizontalScrollbar) { | |
| 352 int clientWidth = visibleWidth(); | |
| 353 IntRect oldRect(m_horizontalScrollbar->frameRect()); | |
| 354 IntRect hBarRect((shouldPlaceVerticalScrollbarOnLeft() && m_verticalScro
llbar) ? m_verticalScrollbar->width() : 0, | |
| 355 height() - m_horizontalScrollbar->height(), | |
| 356 width() - (m_verticalScrollbar ? m_verticalScrollbar->wi
dth() : 0), | |
| 357 m_horizontalScrollbar->height()); | |
| 358 m_horizontalScrollbar->setFrameRect(hBarRect); | |
| 359 if (!m_scrollbarsSuppressed && oldRect != m_horizontalScrollbar->frameRe
ct()) | |
| 360 m_horizontalScrollbar->invalidate(); | |
| 361 | |
| 362 if (m_scrollbarsSuppressed) | |
| 363 m_horizontalScrollbar->setSuppressInvalidation(true); | |
| 364 m_horizontalScrollbar->setEnabled(contentsWidth() > clientWidth); | |
| 365 m_horizontalScrollbar->setProportion(clientWidth, contentsWidth()); | |
| 366 m_horizontalScrollbar->offsetDidChange(); | |
| 367 if (m_scrollbarsSuppressed) | |
| 368 m_horizontalScrollbar->setSuppressInvalidation(false); | |
| 369 } | |
| 370 | |
| 371 if (m_verticalScrollbar) { | |
| 372 int clientHeight = visibleHeight(); | |
| 373 IntRect oldRect(m_verticalScrollbar->frameRect()); | |
| 374 IntRect vBarRect(shouldPlaceVerticalScrollbarOnLeft() ? 0 : (width() - m
_verticalScrollbar->width()), | |
| 375 0, | |
| 376 m_verticalScrollbar->width(), | |
| 377 height() - (m_horizontalScrollbar ? m_horizontalScrollb
ar->height() : 0)); | |
| 378 m_verticalScrollbar->setFrameRect(vBarRect); | |
| 379 if (!m_scrollbarsSuppressed && oldRect != m_verticalScrollbar->frameRect
()) | |
| 380 m_verticalScrollbar->invalidate(); | |
| 381 | |
| 382 if (m_scrollbarsSuppressed) | |
| 383 m_verticalScrollbar->setSuppressInvalidation(true); | |
| 384 m_verticalScrollbar->setEnabled(contentsHeight() > clientHeight); | |
| 385 m_verticalScrollbar->setProportion(clientHeight, contentsHeight()); | |
| 386 m_verticalScrollbar->offsetDidChange(); | |
| 387 if (m_scrollbarsSuppressed) | |
| 388 m_verticalScrollbar->setSuppressInvalidation(false); | |
| 389 } | |
| 390 } | |
| 391 | |
| 392 bool ScrollView::adjustScrollbarExistence(ComputeScrollbarExistenceOption option
) | |
| 393 { | |
| 394 ASSERT(m_inUpdateScrollbars); | |
| 395 | |
| 396 // If we came in here with the view already needing a layout, then go ahead
and do that | |
| 397 // first. (This will be the common case, e.g., when the page changes due to
window resizing for example). | |
| 398 // This layout will not re-enter updateScrollbars and does not count towards
our max layout pass total. | |
| 399 if (!m_scrollbarsSuppressed) | |
| 400 scrollbarExistenceDidChange(); | |
| 401 | |
| 402 bool hasHorizontalScrollbar = m_horizontalScrollbar; | |
| 403 bool hasVerticalScrollbar = m_verticalScrollbar; | |
| 404 | |
| 405 bool newHasHorizontalScrollbar = false; | |
| 406 bool newHasVerticalScrollbar = false; | |
| 407 computeScrollbarExistence(newHasHorizontalScrollbar, newHasVerticalScrollbar
, contentsSize(), option); | |
| 408 | |
| 409 bool scrollbarExistenceChanged = hasHorizontalScrollbar != newHasHorizontalS
crollbar || hasVerticalScrollbar != newHasVerticalScrollbar; | |
| 410 if (!scrollbarExistenceChanged) | |
| 411 return false; | |
| 412 | |
| 413 setHasHorizontalScrollbar(newHasHorizontalScrollbar); | |
| 414 setHasVerticalScrollbar(newHasVerticalScrollbar); | |
| 415 | |
| 416 if (m_scrollbarsSuppressed) | |
| 417 return true; | |
| 418 | |
| 419 scrollbarExistenceDidChange(); | |
| 420 return true; | |
| 421 } | |
| 422 | |
| 423 void ScrollView::updateScrollbars(const IntSize& desiredOffset) | |
| 424 { | |
| 425 if (m_inUpdateScrollbars) | |
| 426 return; | |
| 427 InUpdateScrollbarsScope inUpdateScrollbarsScope(this); | |
| 428 | |
| 429 IntSize oldVisibleSize = visibleSize(); | |
| 430 | |
| 431 bool scrollbarExistenceChanged = false; | |
| 432 int maxUpdateScrollbarsPass = 1; | |
| 433 for (int updateScrollbarsPass = 0; updateScrollbarsPass < maxUpdateScrollbar
sPass; updateScrollbarsPass++) { | |
| 434 if (!adjustScrollbarExistence(updateScrollbarsPass ? Incremental : First
Pass)) | |
| 435 break; | |
| 436 scrollbarExistenceChanged = true; | |
| 437 } | |
| 438 | |
| 439 updateScrollbarGeometry(); | |
| 440 | |
| 441 if (scrollbarExistenceChanged) { | |
| 442 // FIXME: Is frameRectsChanged really necessary here? Have any frame rec
ts changed? | |
| 443 frameRectsChanged(); | |
| 444 positionScrollbarLayers(); | |
| 445 updateScrollCorner(); | |
| 446 } | |
| 447 | |
| 448 // FIXME: We don't need to do this if we are composited. | |
| 449 IntSize newVisibleSize = visibleSize(); | |
| 450 if (newVisibleSize.width() > oldVisibleSize.width()) { | |
| 451 if (shouldPlaceVerticalScrollbarOnLeft()) | |
| 452 invalidateRect(IntRect(0, 0, newVisibleSize.width() - oldVisibleSize
.width(), newVisibleSize.height())); | |
| 453 else | |
| 454 invalidateRect(IntRect(oldVisibleSize.width(), 0, newVisibleSize.wid
th() - oldVisibleSize.width(), newVisibleSize.height())); | |
| 455 } | |
| 456 if (newVisibleSize.height() > oldVisibleSize.height()) | |
| 457 invalidateRect(IntRect(0, oldVisibleSize.height(), newVisibleSize.width(
), newVisibleSize.height() - oldVisibleSize.height())); | |
| 458 | |
| 459 IntPoint adjustedScrollPosition = IntPoint(desiredOffset); | |
| 460 if (!isRubberBandInProgress()) | |
| 461 adjustedScrollPosition = adjustScrollPositionWithinRange(adjustedScrollP
osition); | |
| 462 if (adjustedScrollPosition != scrollPosition() || scrollOriginChanged()) { | |
| 463 ScrollableArea::scrollToOffsetWithoutAnimation(adjustedScrollPosition); | |
| 464 resetScrollOriginChanged(); | |
| 465 } | |
| 466 } | |
| 467 | |
| 468 IntRect ScrollView::rectToCopyOnScroll() const | |
| 469 { | |
| 470 IntRect scrollViewRect = convertToRootView(IntRect((shouldPlaceVerticalScrol
lbarOnLeft() && verticalScrollbar()) ? verticalScrollbar()->width() : 0, 0, visi
bleWidth(), visibleHeight())); | |
| 471 if (hasOverlayScrollbars()) { | |
| 472 int verticalScrollbarWidth = (verticalScrollbar() && !hasLayerForVertica
lScrollbar()) ? verticalScrollbar()->width() : 0; | |
| 473 int horizontalScrollbarHeight = (horizontalScrollbar() && !hasLayerForHo
rizontalScrollbar()) ? horizontalScrollbar()->height() : 0; | |
| 474 | |
| 475 scrollViewRect.setWidth(scrollViewRect.width() - verticalScrollbarWidth)
; | |
| 476 scrollViewRect.setHeight(scrollViewRect.height() - horizontalScrollbarHe
ight); | |
| 477 } | |
| 478 return scrollViewRect; | |
| 479 } | |
| 480 | |
| 481 void ScrollView::scrollContentsIfNeeded() | |
| 482 { | |
| 483 if (m_pendingScrollDelta.isZero()) | |
| 484 return; | |
| 485 IntSize scrollDelta = m_pendingScrollDelta; | |
| 486 m_pendingScrollDelta = IntSize(); | |
| 487 scrollContents(scrollDelta); | |
| 488 } | |
| 489 | |
| 490 void ScrollView::scrollContents(const IntSize& scrollDelta) | |
| 491 { | |
| 492 HostWindow* window = hostWindow(); | |
| 493 if (!window) | |
| 494 return; | |
| 495 | |
| 496 IntRect clipRect = windowClipRect(); | |
| 497 IntRect updateRect = clipRect; | |
| 498 updateRect.intersect(rectToCopyOnScroll()); | |
| 499 | |
| 500 if (!scrollContentsFastPath(-scrollDelta)) | |
| 501 scrollContentsSlowPath(updateRect); | |
| 502 | |
| 503 // Invalidate the overhang areas if they are visible. | |
| 504 updateOverhangAreas(); | |
| 505 | |
| 506 // This call will move children with native widgets (plugins) and invalidate
them as well. | |
| 507 frameRectsChanged(); | |
| 508 } | |
| 509 | |
| 510 void ScrollView::scrollContentsSlowPath(const IntRect& updateRect) | |
| 511 { | |
| 512 hostWindow()->invalidateContentsForSlowScroll(updateRect); | |
| 513 } | |
| 514 | |
| 515 IntPoint ScrollView::rootViewToContents(const IntPoint& rootViewPoint) const | |
| 516 { | |
| 517 IntPoint viewPoint = convertFromRootView(rootViewPoint); | |
| 518 return viewPoint + scrollOffset(); | |
| 519 } | |
| 520 | |
| 521 IntPoint ScrollView::contentsToRootView(const IntPoint& contentsPoint) const | |
| 522 { | |
| 523 IntPoint viewPoint = contentsPoint - scrollOffset(); | |
| 524 return convertToRootView(viewPoint); | |
| 525 } | |
| 526 | |
| 527 IntRect ScrollView::rootViewToContents(const IntRect& rootViewRect) const | |
| 528 { | |
| 529 IntRect viewRect = convertFromRootView(rootViewRect); | |
| 530 viewRect.move(scrollOffset()); | |
| 531 return viewRect; | |
| 532 } | |
| 533 | |
| 534 IntRect ScrollView::contentsToRootView(const IntRect& contentsRect) const | |
| 535 { | |
| 536 IntRect viewRect = contentsRect; | |
| 537 viewRect.move(-scrollOffset()); | |
| 538 return convertToRootView(viewRect); | |
| 539 } | |
| 540 | |
| 541 IntPoint ScrollView::windowToContents(const IntPoint& windowPoint) const | |
| 542 { | |
| 543 IntPoint viewPoint = convertFromContainingWindow(windowPoint); | |
| 544 return viewPoint + scrollOffset(); | |
| 545 } | |
| 546 | |
| 547 FloatPoint ScrollView::windowToContents(const FloatPoint& windowPoint) const | |
| 548 { | |
| 549 FloatPoint viewPoint = convertFromContainingWindow(windowPoint); | |
| 550 return viewPoint + scrollOffset(); | |
| 551 } | |
| 552 | |
| 553 IntPoint ScrollView::contentsToWindow(const IntPoint& contentsPoint) const | |
| 554 { | |
| 555 IntPoint viewPoint = contentsPoint - scrollOffset(); | |
| 556 return convertToContainingWindow(viewPoint); | |
| 557 } | |
| 558 | |
| 559 IntRect ScrollView::windowToContents(const IntRect& windowRect) const | |
| 560 { | |
| 561 IntRect viewRect = convertFromContainingWindow(windowRect); | |
| 562 viewRect.move(scrollOffset()); | |
| 563 return viewRect; | |
| 564 } | |
| 565 | |
| 566 IntRect ScrollView::contentsToWindow(const IntRect& contentsRect) const | |
| 567 { | |
| 568 IntRect viewRect = contentsRect; | |
| 569 viewRect.move(-scrollOffset()); | |
| 570 return convertToContainingWindow(viewRect); | |
| 571 } | |
| 572 | |
| 573 IntRect ScrollView::contentsToScreen(const IntRect& rect) const | |
| 574 { | |
| 575 HostWindow* window = hostWindow(); | |
| 576 if (!window) | |
| 577 return IntRect(); | |
| 578 return window->rootViewToScreen(contentsToRootView(rect)); | |
| 579 } | |
| 580 | |
| 581 void ScrollView::setScrollbarsSuppressed(bool suppressed, bool repaintOnUnsuppre
ss) | |
| 582 { | |
| 583 if (suppressed == m_scrollbarsSuppressed) | |
| 584 return; | |
| 585 | |
| 586 m_scrollbarsSuppressed = suppressed; | |
| 587 | |
| 588 if (repaintOnUnsuppress && !suppressed) { | |
| 589 if (m_horizontalScrollbar) | |
| 590 m_horizontalScrollbar->invalidate(); | |
| 591 if (m_verticalScrollbar) | |
| 592 m_verticalScrollbar->invalidate(); | |
| 593 | |
| 594 // Invalidate the scroll corner too on unsuppress. | |
| 595 invalidateRect(scrollCornerRect()); | |
| 596 } | |
| 597 } | |
| 598 | |
| 599 Scrollbar* ScrollView::scrollbarAtPoint(const IntPoint& windowPoint) | |
| 600 { | |
| 601 IntPoint viewPoint = convertFromContainingWindow(windowPoint); | |
| 602 if (m_horizontalScrollbar && m_horizontalScrollbar->shouldParticipateInHitTe
sting() && m_horizontalScrollbar->frameRect().contains(viewPoint)) | |
| 603 return m_horizontalScrollbar.get(); | |
| 604 if (m_verticalScrollbar && m_verticalScrollbar->shouldParticipateInHitTestin
g() && m_verticalScrollbar->frameRect().contains(viewPoint)) | |
| 605 return m_verticalScrollbar.get(); | |
| 606 return 0; | |
| 607 } | |
| 608 | |
| 609 void ScrollView::setFrameRect(const IntRect& newRect) | |
| 610 { | |
| 611 IntRect oldRect = frameRect(); | |
| 612 | |
| 613 if (newRect == oldRect) | |
| 614 return; | |
| 615 | |
| 616 Widget::setFrameRect(newRect); | |
| 617 | |
| 618 updateScrollbars(scrollOffset()); | |
| 619 | |
| 620 frameRectsChanged(); | |
| 621 } | |
| 622 | |
| 623 void ScrollView::frameRectsChanged() | |
| 624 { | |
| 625 HashSet<RefPtr<Widget> >::const_iterator end = m_children.end(); | |
| 626 for (HashSet<RefPtr<Widget> >::const_iterator current = m_children.begin();
current != end; ++current) | |
| 627 (*current)->frameRectsChanged(); | |
| 628 } | |
| 629 | |
| 630 static void positionScrollbarLayer(GraphicsLayer* graphicsLayer, Scrollbar* scro
llbar) | |
| 631 { | |
| 632 if (!graphicsLayer || !scrollbar) | |
| 633 return; | |
| 634 | |
| 635 IntRect scrollbarRect = scrollbar->frameRect(); | |
| 636 graphicsLayer->setPosition(scrollbarRect.location()); | |
| 637 | |
| 638 if (scrollbarRect.size() == graphicsLayer->size()) | |
| 639 return; | |
| 640 | |
| 641 graphicsLayer->setSize(scrollbarRect.size()); | |
| 642 | |
| 643 if (graphicsLayer->hasContentsLayer()) { | |
| 644 graphicsLayer->setContentsRect(IntRect(0, 0, scrollbarRect.width(), scro
llbarRect.height())); | |
| 645 return; | |
| 646 } | |
| 647 | |
| 648 graphicsLayer->setDrawsContent(true); | |
| 649 graphicsLayer->setNeedsDisplay(); | |
| 650 } | |
| 651 | |
| 652 static void positionScrollCornerLayer(GraphicsLayer* graphicsLayer, const IntRec
t& cornerRect) | |
| 653 { | |
| 654 if (!graphicsLayer) | |
| 655 return; | |
| 656 graphicsLayer->setDrawsContent(!cornerRect.isEmpty()); | |
| 657 graphicsLayer->setPosition(cornerRect.location()); | |
| 658 if (cornerRect.size() != graphicsLayer->size()) | |
| 659 graphicsLayer->setNeedsDisplay(); | |
| 660 graphicsLayer->setSize(cornerRect.size()); | |
| 661 } | |
| 662 | |
| 663 void ScrollView::positionScrollbarLayers() | |
| 664 { | |
| 665 positionScrollbarLayer(layerForHorizontalScrollbar(), horizontalScrollbar())
; | |
| 666 positionScrollbarLayer(layerForVerticalScrollbar(), verticalScrollbar()); | |
| 667 positionScrollCornerLayer(layerForScrollCorner(), scrollCornerRect()); | |
| 668 } | |
| 669 | |
| 670 bool ScrollView::userInputScrollable(ScrollbarOrientation orientation) const | |
| 671 { | |
| 672 ScrollbarMode mode = (orientation == HorizontalScrollbar) ? | |
| 673 m_horizontalScrollbarMode : m_verticalScrollbarMode; | |
| 674 | |
| 675 return mode == ScrollbarAuto || mode == ScrollbarAlwaysOn; | |
| 676 } | |
| 677 | |
| 678 bool ScrollView::shouldPlaceVerticalScrollbarOnLeft() const | |
| 679 { | |
| 680 return false; | |
| 681 } | |
| 682 | |
| 683 void ScrollView::contentRectangleForPaintInvalidation(const IntRect& rect) | |
| 684 { | |
| 685 IntRect paintRect = rect; | |
| 686 if (clipsPaintInvalidations() && !paintsEntireContents()) | |
| 687 paintRect.intersect(visibleContentRect()); | |
| 688 if (paintRect.isEmpty()) | |
| 689 return; | |
| 690 | |
| 691 if (HostWindow* window = hostWindow()) | |
| 692 window->invalidateContentsAndRootView(contentsToWindow(paintRect)); | |
| 693 } | |
| 694 | |
| 695 IntRect ScrollView::scrollCornerRect() const | |
| 696 { | |
| 697 IntRect cornerRect; | |
| 698 | |
| 699 if (hasOverlayScrollbars()) | |
| 700 return cornerRect; | |
| 701 | |
| 702 if (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0) { | |
| 703 cornerRect.unite(IntRect(shouldPlaceVerticalScrollbarOnLeft() ? 0 : m_ho
rizontalScrollbar->width(), | |
| 704 height() - m_horizontalScrollbar->height(), | |
| 705 width() - m_horizontalScrollbar->width(), | |
| 706 m_horizontalScrollbar->height())); | |
| 707 } | |
| 708 | |
| 709 if (m_verticalScrollbar && height() - m_verticalScrollbar->height() > 0) { | |
| 710 cornerRect.unite(IntRect(shouldPlaceVerticalScrollbarOnLeft() ? 0 : (wid
th() - m_verticalScrollbar->width()), | |
| 711 m_verticalScrollbar->height(), | |
| 712 m_verticalScrollbar->width(), | |
| 713 height() - m_verticalScrollbar->height())); | |
| 714 } | |
| 715 | |
| 716 return cornerRect; | |
| 717 } | |
| 718 | |
| 719 bool ScrollView::isScrollCornerVisible() const | |
| 720 { | |
| 721 return !scrollCornerRect().isEmpty(); | |
| 722 } | |
| 723 | |
| 724 void ScrollView::updateScrollCorner() | |
| 725 { | |
| 726 } | |
| 727 | |
| 728 void ScrollView::paintScrollCorner(GraphicsContext* context, const IntRect& corn
erRect) | |
| 729 { | |
| 730 Scrollbar::paintScrollCorner(context, cornerRect); | |
| 731 } | |
| 732 | |
| 733 void ScrollView::paintScrollbar(GraphicsContext* context, Scrollbar* bar, const
IntRect& rect) | |
| 734 { | |
| 735 bar->paint(context, rect); | |
| 736 } | |
| 737 | |
| 738 void ScrollView::invalidateScrollCornerRect(const IntRect& rect) | |
| 739 { | |
| 740 invalidateRect(rect); | |
| 741 } | |
| 742 | |
| 743 void ScrollView::paintScrollbars(GraphicsContext* context, const IntRect& rect) | |
| 744 { | |
| 745 if (m_horizontalScrollbar && !layerForHorizontalScrollbar()) | |
| 746 paintScrollbar(context, m_horizontalScrollbar.get(), rect); | |
| 747 if (m_verticalScrollbar && !layerForVerticalScrollbar()) | |
| 748 paintScrollbar(context, m_verticalScrollbar.get(), rect); | |
| 749 | |
| 750 if (layerForScrollCorner()) | |
| 751 return; | |
| 752 paintScrollCorner(context, scrollCornerRect()); | |
| 753 } | |
| 754 | |
| 755 void ScrollView::paint(GraphicsContext* context, const IntRect& rect) | |
| 756 { | |
| 757 notifyPageThatContentAreaWillPaint(); | |
| 758 | |
| 759 IntRect documentDirtyRect = rect; | |
| 760 if (!paintsEntireContents()) { | |
| 761 IntRect visibleAreaWithoutScrollbars(location(), visibleContentRect().si
ze()); | |
| 762 documentDirtyRect.intersect(visibleAreaWithoutScrollbars); | |
| 763 } | |
| 764 | |
| 765 if (!documentDirtyRect.isEmpty()) { | |
| 766 GraphicsContextStateSaver stateSaver(*context); | |
| 767 | |
| 768 context->translate(x(), y()); | |
| 769 documentDirtyRect.moveBy(-location()); | |
| 770 | |
| 771 if (!paintsEntireContents()) { | |
| 772 context->translate(-scrollX(), -scrollY()); | |
| 773 documentDirtyRect.moveBy(scrollPosition()); | |
| 774 | |
| 775 context->clip(visibleContentRect()); | |
| 776 } | |
| 777 | |
| 778 paintContents(context, documentDirtyRect); | |
| 779 } | |
| 780 | |
| 781 calculateAndPaintOverhangAreas(context, rect); | |
| 782 | |
| 783 // Now paint the scrollbars. | |
| 784 if (!m_scrollbarsSuppressed && (m_horizontalScrollbar || m_verticalScrollbar
)) { | |
| 785 GraphicsContextStateSaver stateSaver(*context); | |
| 786 IntRect scrollViewDirtyRect = rect; | |
| 787 IntRect visibleAreaWithScrollbars(location(), visibleContentRect(Include
Scrollbars).size()); | |
| 788 scrollViewDirtyRect.intersect(visibleAreaWithScrollbars); | |
| 789 context->translate(x(), y()); | |
| 790 scrollViewDirtyRect.moveBy(-location()); | |
| 791 context->clip(IntRect(IntPoint(), visibleAreaWithScrollbars.size())); | |
| 792 | |
| 793 paintScrollbars(context, scrollViewDirtyRect); | |
| 794 } | |
| 795 } | |
| 796 | |
| 797 void ScrollView::calculateOverhangAreasForPainting(IntRect& horizontalOverhangRe
ct, IntRect& verticalOverhangRect) | |
| 798 { | |
| 799 int verticalScrollbarWidth = (verticalScrollbar() && !verticalScrollbar()->i
sOverlayScrollbar()) | |
| 800 ? verticalScrollbar()->width() : 0; | |
| 801 int horizontalScrollbarHeight = (horizontalScrollbar() && !horizontalScrollb
ar()->isOverlayScrollbar()) | |
| 802 ? horizontalScrollbar()->height() : 0; | |
| 803 | |
| 804 int physicalScrollY = scrollPosition().y() + scrollOrigin().y(); | |
| 805 if (physicalScrollY < 0) { | |
| 806 horizontalOverhangRect = frameRect(); | |
| 807 horizontalOverhangRect.setHeight(-physicalScrollY); | |
| 808 horizontalOverhangRect.setWidth(horizontalOverhangRect.width() - vertica
lScrollbarWidth); | |
| 809 } else if (contentsHeight() && physicalScrollY > contentsHeight() - visibleH
eight()) { | |
| 810 int height = physicalScrollY - (contentsHeight() - visibleHeight()); | |
| 811 horizontalOverhangRect = frameRect(); | |
| 812 horizontalOverhangRect.setY(frameRect().maxY() - height - horizontalScro
llbarHeight); | |
| 813 horizontalOverhangRect.setHeight(height); | |
| 814 horizontalOverhangRect.setWidth(horizontalOverhangRect.width() - vertica
lScrollbarWidth); | |
| 815 } | |
| 816 | |
| 817 int physicalScrollX = scrollPosition().x() + scrollOrigin().x(); | |
| 818 if (physicalScrollX < 0) { | |
| 819 verticalOverhangRect.setWidth(-physicalScrollX); | |
| 820 verticalOverhangRect.setHeight(frameRect().height() - horizontalOverhang
Rect.height() - horizontalScrollbarHeight); | |
| 821 verticalOverhangRect.setX(frameRect().x()); | |
| 822 if (horizontalOverhangRect.y() == frameRect().y()) | |
| 823 verticalOverhangRect.setY(frameRect().y() + horizontalOverhangRect.h
eight()); | |
| 824 else | |
| 825 verticalOverhangRect.setY(frameRect().y()); | |
| 826 } else if (contentsWidth() && physicalScrollX > contentsWidth() - visibleWid
th()) { | |
| 827 int width = physicalScrollX - (contentsWidth() - visibleWidth()); | |
| 828 verticalOverhangRect.setWidth(width); | |
| 829 verticalOverhangRect.setHeight(frameRect().height() - horizontalOverhang
Rect.height() - horizontalScrollbarHeight); | |
| 830 verticalOverhangRect.setX(frameRect().maxX() - width - verticalScrollbar
Width); | |
| 831 if (horizontalOverhangRect.y() == frameRect().y()) | |
| 832 verticalOverhangRect.setY(frameRect().y() + horizontalOverhangRect.h
eight()); | |
| 833 else | |
| 834 verticalOverhangRect.setY(frameRect().y()); | |
| 835 } | |
| 836 } | |
| 837 | |
| 838 void ScrollView::updateOverhangAreas() | |
| 839 { | |
| 840 HostWindow* window = hostWindow(); | |
| 841 if (!window) | |
| 842 return; | |
| 843 | |
| 844 IntRect horizontalOverhangRect; | |
| 845 IntRect verticalOverhangRect; | |
| 846 calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRe
ct); | |
| 847 if (!horizontalOverhangRect.isEmpty()) | |
| 848 window->invalidateContentsAndRootView(horizontalOverhangRect); | |
| 849 if (!verticalOverhangRect.isEmpty()) | |
| 850 window->invalidateContentsAndRootView(verticalOverhangRect); | |
| 851 } | |
| 852 | |
| 853 void ScrollView::paintOverhangAreas(GraphicsContext* context, const IntRect& hor
izontalOverhangRect, const IntRect& verticalOverhangRect, const IntRect& dirtyRe
ct) | |
| 854 { | |
| 855 Scrollbar::paintOverhangBackground(context, horizontalOverhangRect, vertical
OverhangRect, dirtyRect); | |
| 856 } | |
| 857 | |
| 858 void ScrollView::calculateAndPaintOverhangAreas(GraphicsContext* context, const
IntRect& dirtyRect) | |
| 859 { | |
| 860 IntRect horizontalOverhangRect; | |
| 861 IntRect verticalOverhangRect; | |
| 862 calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRe
ct); | |
| 863 | |
| 864 if (dirtyRect.intersects(horizontalOverhangRect) || dirtyRect.intersects(ver
ticalOverhangRect)) | |
| 865 paintOverhangAreas(context, horizontalOverhangRect, verticalOverhangRect
, dirtyRect); | |
| 866 } | |
| 867 | |
| 868 void ScrollView::calculateAndPaintOverhangBackground(GraphicsContext* context, c
onst IntRect& dirtyRect) | |
| 869 { | |
| 870 IntRect horizontalOverhangRect; | |
| 871 IntRect verticalOverhangRect; | |
| 872 calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRe
ct); | |
| 873 | |
| 874 if (dirtyRect.intersects(horizontalOverhangRect) || dirtyRect.intersects(ver
ticalOverhangRect)) | |
| 875 Scrollbar::paintOverhangBackground(context, horizontalOverhangRect, vert
icalOverhangRect, dirtyRect); | |
| 876 } | |
| 877 | |
| 878 bool ScrollView::isPointInScrollbarCorner(const IntPoint& windowPoint) | |
| 879 { | |
| 880 if (!scrollbarCornerPresent()) | |
| 881 return false; | |
| 882 | |
| 883 IntPoint viewPoint = convertFromContainingWindow(windowPoint); | |
| 884 | |
| 885 if (m_horizontalScrollbar) { | |
| 886 int horizontalScrollbarYMin = m_horizontalScrollbar->frameRect().y(); | |
| 887 int horizontalScrollbarYMax = m_horizontalScrollbar->frameRect().y() + m
_horizontalScrollbar->frameRect().height(); | |
| 888 int horizontalScrollbarXMin = m_horizontalScrollbar->frameRect().x() + m
_horizontalScrollbar->frameRect().width(); | |
| 889 | |
| 890 return viewPoint.y() > horizontalScrollbarYMin && viewPoint.y() < horizo
ntalScrollbarYMax && viewPoint.x() > horizontalScrollbarXMin; | |
| 891 } | |
| 892 | |
| 893 int verticalScrollbarXMin = m_verticalScrollbar->frameRect().x(); | |
| 894 int verticalScrollbarXMax = m_verticalScrollbar->frameRect().x() + m_vertica
lScrollbar->frameRect().width(); | |
| 895 int verticalScrollbarYMin = m_verticalScrollbar->frameRect().y() + m_vertica
lScrollbar->frameRect().height(); | |
| 896 | |
| 897 return viewPoint.x() > verticalScrollbarXMin && viewPoint.x() < verticalScro
llbarXMax && viewPoint.y() > verticalScrollbarYMin; | |
| 898 } | |
| 899 | |
| 900 bool ScrollView::scrollbarCornerPresent() const | |
| 901 { | |
| 902 return (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() >
0) | |
| 903 || (m_verticalScrollbar && height() - m_verticalScrollbar->height() > 0)
; | |
| 904 } | |
| 905 | |
| 906 IntRect ScrollView::convertFromScrollbarToContainingView(const Scrollbar* scroll
bar, const IntRect& localRect) const | |
| 907 { | |
| 908 // Scrollbars won't be transformed within us | |
| 909 IntRect newRect = localRect; | |
| 910 newRect.moveBy(scrollbar->location()); | |
| 911 return newRect; | |
| 912 } | |
| 913 | |
| 914 IntRect ScrollView::convertFromContainingViewToScrollbar(const Scrollbar* scroll
bar, const IntRect& parentRect) const | |
| 915 { | |
| 916 IntRect newRect = parentRect; | |
| 917 // Scrollbars won't be transformed within us | |
| 918 newRect.moveBy(-scrollbar->location()); | |
| 919 return newRect; | |
| 920 } | |
| 921 | |
| 922 // FIXME: test these on windows | |
| 923 IntPoint ScrollView::convertFromScrollbarToContainingView(const Scrollbar* scrol
lbar, const IntPoint& localPoint) const | |
| 924 { | |
| 925 // Scrollbars won't be transformed within us | |
| 926 IntPoint newPoint = localPoint; | |
| 927 newPoint.moveBy(scrollbar->location()); | |
| 928 return newPoint; | |
| 929 } | |
| 930 | |
| 931 IntPoint ScrollView::convertFromContainingViewToScrollbar(const Scrollbar* scrol
lbar, const IntPoint& parentPoint) const | |
| 932 { | |
| 933 IntPoint newPoint = parentPoint; | |
| 934 // Scrollbars won't be transformed within us | |
| 935 newPoint.moveBy(-scrollbar->location()); | |
| 936 return newPoint; | |
| 937 } | |
| 938 | |
| 939 void ScrollView::setParentVisible(bool visible) | |
| 940 { | |
| 941 if (isParentVisible() == visible) | |
| 942 return; | |
| 943 | |
| 944 Widget::setParentVisible(visible); | |
| 945 | |
| 946 if (!isSelfVisible()) | |
| 947 return; | |
| 948 | |
| 949 HashSet<RefPtr<Widget> >::iterator end = m_children.end(); | |
| 950 for (HashSet<RefPtr<Widget> >::iterator it = m_children.begin(); it != end;
++it) | |
| 951 (*it)->setParentVisible(visible); | |
| 952 } | |
| 953 | |
| 954 void ScrollView::show() | |
| 955 { | |
| 956 if (!isSelfVisible()) { | |
| 957 setSelfVisible(true); | |
| 958 if (isParentVisible()) { | |
| 959 HashSet<RefPtr<Widget> >::iterator end = m_children.end(); | |
| 960 for (HashSet<RefPtr<Widget> >::iterator it = m_children.begin(); it
!= end; ++it) | |
| 961 (*it)->setParentVisible(true); | |
| 962 } | |
| 963 } | |
| 964 | |
| 965 Widget::show(); | |
| 966 } | |
| 967 | |
| 968 void ScrollView::hide() | |
| 969 { | |
| 970 if (isSelfVisible()) { | |
| 971 if (isParentVisible()) { | |
| 972 HashSet<RefPtr<Widget> >::iterator end = m_children.end(); | |
| 973 for (HashSet<RefPtr<Widget> >::iterator it = m_children.begin(); it
!= end; ++it) | |
| 974 (*it)->setParentVisible(false); | |
| 975 } | |
| 976 setSelfVisible(false); | |
| 977 } | |
| 978 | |
| 979 Widget::hide(); | |
| 980 } | |
| 981 | |
| 982 void ScrollView::setScrollOrigin(const IntPoint& origin, bool updatePositionAtAl
l, bool updatePositionSynchronously) | |
| 983 { | |
| 984 if (scrollOrigin() == origin) | |
| 985 return; | |
| 986 | |
| 987 ScrollableArea::setScrollOrigin(origin); | |
| 988 | |
| 989 // Update if the scroll origin changes, since our position will be different
if the content size did not change. | |
| 990 if (updatePositionAtAll && updatePositionSynchronously) | |
| 991 updateScrollbars(scrollOffset()); | |
| 992 } | |
| 993 | |
| 994 } // namespace blink | |
| OLD | NEW |