Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(253)

Side by Side Diff: Source/platform/scroll/ScrollView.cpp

Issue 641733004: Merge FrameView and ScrollView. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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/ScrollbarTheme.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_scrollbarsAvoidingResizer(0)
43 , m_scrollbarsSuppressed(false)
44 , m_inUpdateScrollbars(false)
45 , m_drawPanScrollIcon(false)
46 , m_clipsRepaints(true)
47 {
48 }
49
50 ScrollView::~ScrollView()
51 {
52 }
53
54 void ScrollView::addChild(PassRefPtr<Widget> prpChild)
55 {
56 Widget* child = prpChild.get();
57 ASSERT(child != this && !child->parent());
58 child->setParent(this);
59 m_children.add(prpChild);
60 }
61
62 void ScrollView::removeChild(Widget* child)
63 {
64 ASSERT(child->parent() == this);
65 child->setParent(0);
66 m_children.remove(child);
67 }
68
69 void ScrollView::setHasHorizontalScrollbar(bool hasBar)
70 {
71 if (hasBar && !m_horizontalScrollbar) {
72 m_horizontalScrollbar = createScrollbar(HorizontalScrollbar);
73 addChild(m_horizontalScrollbar.get());
74 didAddScrollbar(m_horizontalScrollbar.get(), HorizontalScrollbar);
75 m_horizontalScrollbar->styleChanged();
76 } else if (!hasBar && m_horizontalScrollbar) {
77 willRemoveScrollbar(m_horizontalScrollbar.get(), HorizontalScrollbar);
78 // If the scrollbar has been marked as overlapping the window resizer,
79 // then its removal should reduce the count.
80 if (m_horizontalScrollbar->overlapsResizer())
81 adjustScrollbarsAvoidingResizerCount(-1);
82 removeChild(m_horizontalScrollbar.get());
83 m_horizontalScrollbar = nullptr;
84 }
85 }
86
87 void ScrollView::setHasVerticalScrollbar(bool hasBar)
88 {
89 if (hasBar && !m_verticalScrollbar) {
90 m_verticalScrollbar = createScrollbar(VerticalScrollbar);
91 addChild(m_verticalScrollbar.get());
92 didAddScrollbar(m_verticalScrollbar.get(), VerticalScrollbar);
93 m_verticalScrollbar->styleChanged();
94 } else if (!hasBar && m_verticalScrollbar) {
95 willRemoveScrollbar(m_verticalScrollbar.get(), VerticalScrollbar);
96 // If the scrollbar has been marked as overlapping the window resizer,
97 // then its removal should reduce the count.
98 if (m_verticalScrollbar->overlapsResizer())
99 adjustScrollbarsAvoidingResizerCount(-1);
100 removeChild(m_verticalScrollbar.get());
101 m_verticalScrollbar = nullptr;
102 }
103 }
104
105 PassRefPtr<Scrollbar> ScrollView::createScrollbar(ScrollbarOrientation orientati on)
106 {
107 return Scrollbar::create(this, orientation, RegularScrollbar);
108 }
109
110 void ScrollView::setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode v erticalMode,
111 bool horizontalLock, bool verticalLock)
112 {
113 bool needsUpdate = false;
114
115 if (horizontalMode != horizontalScrollbarMode() && !m_horizontalScrollbarLoc k) {
116 m_horizontalScrollbarMode = horizontalMode;
117 needsUpdate = true;
118 }
119
120 if (verticalMode != verticalScrollbarMode() && !m_verticalScrollbarLock) {
121 m_verticalScrollbarMode = verticalMode;
122 needsUpdate = true;
123 }
124
125 if (horizontalLock)
126 setHorizontalScrollbarLock();
127
128 if (verticalLock)
129 setVerticalScrollbarLock();
130
131 if (!needsUpdate)
132 return;
133
134 updateScrollbars(scrollOffset());
135
136 if (!layerForScrolling())
137 return;
138 blink::WebLayer* layer = layerForScrolling()->platformLayer();
139 if (!layer)
140 return;
141 layer->setUserScrollable(userInputScrollable(HorizontalScrollbar), userInput Scrollable(VerticalScrollbar));
142 }
143
144 void ScrollView::scrollbarModes(ScrollbarMode& horizontalMode, ScrollbarMode& ve rticalMode) const
145 {
146 horizontalMode = m_horizontalScrollbarMode;
147 verticalMode = m_verticalScrollbarMode;
148 }
149
150 void ScrollView::setCanHaveScrollbars(bool canScroll)
151 {
152 ScrollbarMode newHorizontalMode;
153 ScrollbarMode newVerticalMode;
154
155 scrollbarModes(newHorizontalMode, newVerticalMode);
156
157 if (canScroll && newVerticalMode == ScrollbarAlwaysOff)
158 newVerticalMode = ScrollbarAuto;
159 else if (!canScroll)
160 newVerticalMode = ScrollbarAlwaysOff;
161
162 if (canScroll && newHorizontalMode == ScrollbarAlwaysOff)
163 newHorizontalMode = ScrollbarAuto;
164 else if (!canScroll)
165 newHorizontalMode = ScrollbarAlwaysOff;
166
167 setScrollbarModes(newHorizontalMode, newVerticalMode);
168 }
169
170 void ScrollView::setClipsRepaints(bool clipsRepaints)
171 {
172 m_clipsRepaints = clipsRepaints;
173 }
174
175 IntSize ScrollView::unscaledVisibleContentSize(IncludeScrollbarsInRect scrollbar Inclusion) const
176 {
177 return scrollbarInclusion == ExcludeScrollbars ? excludeScrollbars(frameRect ().size()) : frameRect().size();
178 }
179
180 IntSize ScrollView::excludeScrollbars(const IntSize& size) const
181 {
182 int verticalScrollbarWidth = 0;
183 int horizontalScrollbarHeight = 0;
184
185 if (Scrollbar* verticalBar = verticalScrollbar())
186 verticalScrollbarWidth = !verticalBar->isOverlayScrollbar() ? verticalBa r->width() : 0;
187 if (Scrollbar* horizontalBar = horizontalScrollbar())
188 horizontalScrollbarHeight = !horizontalBar->isOverlayScrollbar() ? horiz ontalBar->height() : 0;
189
190 return IntSize(std::max(0, size.width() - verticalScrollbarWidth),
191 std::max(0, size.height() - horizontalScrollbarHeight));
192
193 }
194
195 IntRect ScrollView::visibleContentRect(IncludeScrollbarsInRect scollbarInclusion ) const
196 {
197 FloatSize visibleContentSize = unscaledVisibleContentSize(scollbarInclusion) ;
198 visibleContentSize.scale(1 / visibleContentScaleFactor());
199 return IntRect(flooredIntPoint(m_scrollPosition), expandedIntSize(visibleCon tentSize));
200 }
201
202 IntSize ScrollView::contentsSize() const
203 {
204 return m_contentsSize;
205 }
206
207 void ScrollView::setContentsSize(const IntSize& newSize)
208 {
209 if (contentsSize() == newSize)
210 return;
211 m_contentsSize = newSize;
212 updateScrollbars(scrollOffset());
213 updateOverhangAreas();
214 }
215
216 IntPoint ScrollView::maximumScrollPosition() const
217 {
218 IntPoint maximumOffset(contentsWidth() - visibleWidth() - scrollOrigin().x() , contentsHeight() - visibleHeight() - scrollOrigin().y());
219 maximumOffset.clampNegativeToZero();
220 return maximumOffset;
221 }
222
223 IntPoint ScrollView::minimumScrollPosition() const
224 {
225 return IntPoint(-scrollOrigin().x(), -scrollOrigin().y());
226 }
227
228 IntPoint ScrollView::adjustScrollPositionWithinRange(const IntPoint& scrollPoint ) const
229 {
230 if (!constrainsScrollingToContentEdge())
231 return scrollPoint;
232
233 IntPoint newScrollPosition = scrollPoint.shrunkTo(maximumScrollPosition());
234 newScrollPosition = newScrollPosition.expandedTo(minimumScrollPosition());
235 return newScrollPosition;
236 }
237
238 DoublePoint ScrollView::adjustScrollPositionWithinRange(const DoublePoint& scrol lPoint) const
239 {
240 if (!constrainsScrollingToContentEdge())
241 return scrollPoint;
242 DoublePoint newScrollPosition = scrollPoint.shrunkTo(
243 maximumScrollPosition().x(), maximumScrollPosition().y());
244 newScrollPosition = newScrollPosition.expandedTo(
245 minimumScrollPosition().x(), minimumScrollPosition().y());
246 return newScrollPosition;
247 }
248
249 void ScrollView::adjustScrollbarOpacity()
250 {
251 if (m_horizontalScrollbar && layerForHorizontalScrollbar()) {
252 bool isOpaqueScrollbar = !m_horizontalScrollbar->isOverlayScrollbar();
253 layerForHorizontalScrollbar()->setContentsOpaque(isOpaqueScrollbar);
254 }
255 if (m_verticalScrollbar && layerForVerticalScrollbar()) {
256 bool isOpaqueScrollbar = !m_verticalScrollbar->isOverlayScrollbar();
257 layerForVerticalScrollbar()->setContentsOpaque(isOpaqueScrollbar);
258 }
259 }
260
261 int ScrollView::scrollSize(ScrollbarOrientation orientation) const
262 {
263 Scrollbar* scrollbar = ((orientation == HorizontalScrollbar) ? m_horizontalS crollbar : m_verticalScrollbar).get();
264
265 // If no scrollbars are present, the content may still be scrollable.
266 if (!scrollbar) {
267 IntSize scrollSize = m_contentsSize - visibleContentRect().size();
268 scrollSize.clampNegativeToZero();
269 return orientation == HorizontalScrollbar ? scrollSize.width() : scrollS ize.height();
270 }
271
272 return scrollbar->totalSize() - scrollbar->visibleSize();
273 }
274
275 void ScrollView::notifyPageThatContentAreaWillPaint() const
276 {
277 }
278
279 void ScrollView::setScrollOffset(const IntPoint& offset)
280 {
281 scrollTo(DoublePoint(adjustScrollPositionWithinRange(offset)));
282 }
283
284 void ScrollView::setScrollOffset(const DoublePoint& offset)
285 {
286 scrollTo(adjustScrollPositionWithinRange(offset));
287 }
288
289 void ScrollView::scrollTo(const DoublePoint& newPosition)
290 {
291 DoubleSize scrollDelta = newPosition - m_scrollPosition;
292 if (scrollDelta.isZero())
293 return;
294 m_scrollPosition = newPosition;
295
296 if (scrollbarsSuppressed())
297 return;
298
299 // FIXME: Change scrollContents() to take DoubleSize. crbug.com/414283.
300 if (isFrameView())
301 m_pendingScrollDelta += scrollDelta;
302 else
303 scrollContents(flooredIntSize(scrollDelta));
304 }
305
306 void ScrollView::setScrollPosition(const IntPoint& scrollPoint, ScrollBehavior s crollBehavior)
307 {
308 IntPoint newScrollPosition = adjustScrollPositionWithinRange(scrollPoint);
309
310 if (newScrollPosition == scrollPosition())
311 return;
312
313 if (scrollBehavior == ScrollBehaviorInstant)
314 updateScrollbars(IntSize(newScrollPosition.x(), newScrollPosition.y()));
315 else
316 programmaticallyScrollSmoothlyToOffset(newScrollPosition);
317 }
318
319 bool ScrollView::scroll(ScrollDirection direction, ScrollGranularity granularity )
320 {
321 ScrollDirection physicalDirection =
322 toPhysicalDirection(direction, isVerticalDocument(), isFlippedDocument() );
323
324 return ScrollableArea::scroll(physicalDirection, granularity);
325 }
326
327 IntSize ScrollView::overhangAmount() const
328 {
329 IntSize stretch;
330
331 IntPoint currentScrollPosition = scrollPosition();
332 IntPoint minScrollPosition = minimumScrollPosition();
333 IntPoint maxScrollPosition = maximumScrollPosition();
334
335 if (currentScrollPosition.x() < minScrollPosition.x())
336 stretch.setWidth(currentScrollPosition.x() - minScrollPosition.x());
337 if (currentScrollPosition.x() > maxScrollPosition.x())
338 stretch.setWidth(currentScrollPosition.x() - maxScrollPosition.x());
339
340 if (currentScrollPosition.y() < minScrollPosition.y())
341 stretch.setHeight(currentScrollPosition.y() - minScrollPosition.y());
342 if (currentScrollPosition.y() > maxScrollPosition.y())
343 stretch.setHeight(currentScrollPosition.y() - maxScrollPosition.y());
344
345 return stretch;
346 }
347
348 void ScrollView::windowResizerRectChanged()
349 {
350 updateScrollbars(scrollOffset());
351 }
352
353 static bool useOverlayScrollbars()
354 {
355 // FIXME: Need to detect the presence of CSS custom scrollbars, which are no n-overlay regardless the ScrollbarTheme.
356 return ScrollbarTheme::theme()->usesOverlayScrollbars();
357 }
358
359 void ScrollView::computeScrollbarExistence(bool& newHasHorizontalScrollbar, bool & newHasVerticalScrollbar, const IntSize& docSize, ComputeScrollbarExistenceOpti on option) const
360 {
361 bool hasHorizontalScrollbar = m_horizontalScrollbar;
362 bool hasVerticalScrollbar = m_verticalScrollbar;
363
364 newHasHorizontalScrollbar = hasHorizontalScrollbar;
365 newHasVerticalScrollbar = hasVerticalScrollbar;
366
367 ScrollbarMode hScroll = m_horizontalScrollbarMode;
368 ScrollbarMode vScroll = m_verticalScrollbarMode;
369
370 if (hScroll != ScrollbarAuto)
371 newHasHorizontalScrollbar = (hScroll == ScrollbarAlwaysOn);
372 if (vScroll != ScrollbarAuto)
373 newHasVerticalScrollbar = (vScroll == ScrollbarAlwaysOn);
374
375 if (m_scrollbarsSuppressed || (hScroll != ScrollbarAuto && vScroll != Scroll barAuto))
376 return;
377
378 if (hScroll == ScrollbarAuto)
379 newHasHorizontalScrollbar = docSize.width() > visibleWidth();
380 if (vScroll == ScrollbarAuto)
381 newHasVerticalScrollbar = docSize.height() > visibleHeight();
382
383 if (useOverlayScrollbars())
384 return;
385
386 IntSize fullVisibleSize = visibleContentRect(IncludeScrollbars).size();
387
388 bool attemptToRemoveScrollbars = (option == FirstPass
389 && docSize.width() <= fullVisibleSize.width() && docSize.height() <= ful lVisibleSize.height());
390 if (attemptToRemoveScrollbars) {
391 if (hScroll == ScrollbarAuto)
392 newHasHorizontalScrollbar = false;
393 if (vScroll == ScrollbarAuto)
394 newHasVerticalScrollbar = false;
395 }
396
397 // If we ever turn one scrollbar off, always turn the other one off too.
398 // Never ever try to both gain/lose a scrollbar in the same pass.
399 if (!newHasHorizontalScrollbar && hasHorizontalScrollbar && vScroll != Scrol lbarAlwaysOn)
400 newHasVerticalScrollbar = false;
401 if (!newHasVerticalScrollbar && hasVerticalScrollbar && hScroll != Scrollbar AlwaysOn)
402 newHasHorizontalScrollbar = false;
403 }
404
405 void ScrollView::updateScrollbarGeometry()
406 {
407 if (m_horizontalScrollbar) {
408 int clientWidth = visibleWidth();
409 IntRect oldRect(m_horizontalScrollbar->frameRect());
410 IntRect hBarRect((shouldPlaceVerticalScrollbarOnLeft() && m_verticalScro llbar) ? m_verticalScrollbar->width() : 0,
411 height() - m_horizontalScrollbar->height(),
412 width() - (m_verticalScrollbar ? m_verticalScrollbar->wi dth() : 0),
413 m_horizontalScrollbar->height());
414 m_horizontalScrollbar->setFrameRect(adjustScrollbarRectForResizer(hBarRe ct, m_horizontalScrollbar.get()));
415 if (!m_scrollbarsSuppressed && oldRect != m_horizontalScrollbar->frameRe ct())
416 m_horizontalScrollbar->invalidate();
417
418 if (m_scrollbarsSuppressed)
419 m_horizontalScrollbar->setSuppressInvalidation(true);
420 m_horizontalScrollbar->setEnabled(contentsWidth() > clientWidth);
421 m_horizontalScrollbar->setProportion(clientWidth, contentsWidth());
422 m_horizontalScrollbar->offsetDidChange();
423 if (m_scrollbarsSuppressed)
424 m_horizontalScrollbar->setSuppressInvalidation(false);
425 }
426
427 if (m_verticalScrollbar) {
428 int clientHeight = visibleHeight();
429 IntRect oldRect(m_verticalScrollbar->frameRect());
430 IntRect vBarRect(shouldPlaceVerticalScrollbarOnLeft() ? 0 : (width() - m _verticalScrollbar->width()),
431 0,
432 m_verticalScrollbar->width(),
433 height() - (m_horizontalScrollbar ? m_horizontalScrollb ar->height() : 0));
434 m_verticalScrollbar->setFrameRect(adjustScrollbarRectForResizer(vBarRect , m_verticalScrollbar.get()));
435 if (!m_scrollbarsSuppressed && oldRect != m_verticalScrollbar->frameRect ())
436 m_verticalScrollbar->invalidate();
437
438 if (m_scrollbarsSuppressed)
439 m_verticalScrollbar->setSuppressInvalidation(true);
440 m_verticalScrollbar->setEnabled(contentsHeight() > clientHeight);
441 m_verticalScrollbar->setProportion(clientHeight, contentsHeight());
442 m_verticalScrollbar->offsetDidChange();
443 if (m_scrollbarsSuppressed)
444 m_verticalScrollbar->setSuppressInvalidation(false);
445 }
446 }
447
448 IntRect ScrollView::adjustScrollbarRectForResizer(const IntRect& rect, Scrollbar * scrollbar)
449 {
450 // Get our window resizer rect and see if we overlap. Adjust to avoid the ov erlap
451 // if necessary.
452 IntRect adjustedRect(rect);
453 bool overlapsResizer = false;
454 if (!rect.isEmpty() && !windowResizerRect().isEmpty()) {
455 IntRect resizerRect = convertFromContainingWindow(windowResizerRect());
456 if (rect.intersects(resizerRect)) {
457 if (scrollbar->orientation() == HorizontalScrollbar) {
458 int overlap = rect.maxX() - resizerRect.x();
459 if (overlap > 0 && resizerRect.maxX() >= rect.maxX()) {
460 adjustedRect.setWidth(rect.width() - overlap);
461 overlapsResizer = true;
462 }
463 } else {
464 int overlap = rect.maxY() - resizerRect.y();
465 if (overlap > 0 && resizerRect.maxY() >= rect.maxY()) {
466 adjustedRect.setHeight(rect.height() - overlap);
467 overlapsResizer = true;
468 }
469 }
470 }
471 }
472 if (overlapsResizer != scrollbar->overlapsResizer()) {
473 scrollbar->setOverlapsResizer(overlapsResizer);
474 adjustScrollbarsAvoidingResizerCount(overlapsResizer ? 1 : -1);
475 }
476 return adjustedRect;
477 }
478
479 bool ScrollView::adjustScrollbarExistence(ComputeScrollbarExistenceOption option )
480 {
481 ASSERT(m_inUpdateScrollbars);
482
483 // If we came in here with the view already needing a layout, then go ahead and do that
484 // first. (This will be the common case, e.g., when the page changes due to window resizing for example).
485 // This layout will not re-enter updateScrollbars and does not count towards our max layout pass total.
486 if (!m_scrollbarsSuppressed)
487 scrollbarExistenceDidChange();
488
489 bool hasHorizontalScrollbar = m_horizontalScrollbar;
490 bool hasVerticalScrollbar = m_verticalScrollbar;
491
492 bool newHasHorizontalScrollbar = false;
493 bool newHasVerticalScrollbar = false;
494 computeScrollbarExistence(newHasHorizontalScrollbar, newHasVerticalScrollbar , contentsSize(), option);
495
496 bool scrollbarExistenceChanged = hasHorizontalScrollbar != newHasHorizontalS crollbar || hasVerticalScrollbar != newHasVerticalScrollbar;
497 if (!scrollbarExistenceChanged)
498 return false;
499
500 setHasHorizontalScrollbar(newHasHorizontalScrollbar);
501 setHasVerticalScrollbar(newHasVerticalScrollbar);
502
503 if (m_scrollbarsSuppressed)
504 return true;
505
506 if (!useOverlayScrollbars())
507 contentsResized();
508 scrollbarExistenceDidChange();
509 return true;
510 }
511
512 void ScrollView::updateScrollbars(const IntSize& desiredOffset)
513 {
514 if (scrollbarsDisabled()) {
515 setScrollOffsetFromUpdateScrollbars(desiredOffset);
516 return;
517 }
518
519 if (m_inUpdateScrollbars)
520 return;
521 InUpdateScrollbarsScope inUpdateScrollbarsScope(this);
522
523 IntSize oldVisibleSize = visibleSize();
524
525 bool scrollbarExistenceChanged = false;
526 int maxUpdateScrollbarsPass = useOverlayScrollbars() || m_scrollbarsSuppress ed ? 1 : 3;
527 for (int updateScrollbarsPass = 0; updateScrollbarsPass < maxUpdateScrollbar sPass; updateScrollbarsPass++) {
528 if (!adjustScrollbarExistence(updateScrollbarsPass ? Incremental : First Pass))
529 break;
530 scrollbarExistenceChanged = true;
531 }
532
533 updateScrollbarGeometry();
534
535 if (scrollbarExistenceChanged) {
536 // FIXME: Is frameRectsChanged really necessary here? Have any frame rec ts changed?
537 frameRectsChanged();
538 positionScrollbarLayers();
539 updateScrollCorner();
540 }
541
542 // FIXME: We don't need to do this if we are composited.
543 IntSize newVisibleSize = visibleSize();
544 if (newVisibleSize.width() > oldVisibleSize.width()) {
545 if (shouldPlaceVerticalScrollbarOnLeft())
546 invalidateRect(IntRect(0, 0, newVisibleSize.width() - oldVisibleSize .width(), newVisibleSize.height()));
547 else
548 invalidateRect(IntRect(oldVisibleSize.width(), 0, newVisibleSize.wid th() - oldVisibleSize.width(), newVisibleSize.height()));
549 }
550 if (newVisibleSize.height() > oldVisibleSize.height())
551 invalidateRect(IntRect(0, oldVisibleSize.height(), newVisibleSize.width( ), newVisibleSize.height() - oldVisibleSize.height()));
552
553 setScrollOffsetFromUpdateScrollbars(desiredOffset);
554 }
555
556 void ScrollView::setScrollOffsetFromUpdateScrollbars(const IntSize& offset)
557 {
558 IntPoint adjustedScrollPosition = IntPoint(offset);
559
560 if (!isRubberBandInProgress())
561 adjustedScrollPosition = adjustScrollPositionWithinRange(adjustedScrollP osition);
562
563 if (adjustedScrollPosition != scrollPosition() || scrollOriginChanged()) {
564 ScrollableArea::scrollToOffsetWithoutAnimation(adjustedScrollPosition);
565 resetScrollOriginChanged();
566 }
567 }
568
569 const int panIconSizeLength = 16;
570
571 IntRect ScrollView::rectToCopyOnScroll() const
572 {
573 IntRect scrollViewRect = convertToContainingWindow(IntRect((shouldPlaceVerti calScrollbarOnLeft() && verticalScrollbar()) ? verticalScrollbar()->width() : 0, 0, visibleWidth(), visibleHeight()));
574 if (hasOverlayScrollbars()) {
575 int verticalScrollbarWidth = (verticalScrollbar() && !hasLayerForVertica lScrollbar()) ? verticalScrollbar()->width() : 0;
576 int horizontalScrollbarHeight = (horizontalScrollbar() && !hasLayerForHo rizontalScrollbar()) ? horizontalScrollbar()->height() : 0;
577
578 scrollViewRect.setWidth(scrollViewRect.width() - verticalScrollbarWidth) ;
579 scrollViewRect.setHeight(scrollViewRect.height() - horizontalScrollbarHe ight);
580 }
581 return scrollViewRect;
582 }
583
584 void ScrollView::scrollContentsIfNeeded()
585 {
586 if (m_pendingScrollDelta.isZero())
587 return;
588 DoubleSize scrollDelta = m_pendingScrollDelta;
589 m_pendingScrollDelta = DoubleSize();
590 // FIXME: Change scrollContents() to take DoubleSize. crbug.com/414283.
591 scrollContents(flooredIntSize(scrollDelta));
592 }
593
594 void ScrollView::scrollContents(const IntSize& scrollDelta)
595 {
596 HostWindow* window = hostWindow();
597 if (!window)
598 return;
599
600 IntRect clipRect = windowClipRect();
601 IntRect updateRect = clipRect;
602 updateRect.intersect(rectToCopyOnScroll());
603
604 if (m_drawPanScrollIcon) {
605 // FIXME: the pan icon is broken when accelerated compositing is on, sin ce it will draw under the compositing layers.
606 // https://bugs.webkit.org/show_bug.cgi?id=47837
607 int panIconDirtySquareSizeLength = 2 * (panIconSizeLength + std::max(abs (scrollDelta.width()), abs(scrollDelta.height()))); // We only want to repaint w hat's necessary
608 IntPoint panIconDirtySquareLocation = IntPoint(m_panScrollIconPoint.x() - (panIconDirtySquareSizeLength / 2), m_panScrollIconPoint.y() - (panIconDirtySq uareSizeLength / 2));
609 IntRect panScrollIconDirtyRect = IntRect(panIconDirtySquareLocation, Int Size(panIconDirtySquareSizeLength, panIconDirtySquareSizeLength));
610 panScrollIconDirtyRect.intersect(clipRect);
611 window->invalidateContentsAndRootView(panScrollIconDirtyRect);
612 }
613
614 if (!scrollContentsFastPath(-scrollDelta))
615 scrollContentsSlowPath(updateRect);
616
617 // Invalidate the overhang areas if they are visible.
618 updateOverhangAreas();
619
620 // This call will move children with native widgets (plugins) and invalidate them as well.
621 frameRectsChanged();
622 }
623
624 void ScrollView::scrollContentsSlowPath(const IntRect& updateRect)
625 {
626 hostWindow()->invalidateContentsForSlowScroll(updateRect);
627 }
628
629 IntPoint ScrollView::rootViewToContents(const IntPoint& rootViewPoint) const
630 {
631 IntPoint viewPoint = convertFromContainingWindow(rootViewPoint);
632 return viewPoint + scrollOffset();
633 }
634
635 IntPoint ScrollView::contentsToRootView(const IntPoint& contentsPoint) const
636 {
637 IntPoint viewPoint = contentsPoint - scrollOffset();
638 return convertToContainingWindow(viewPoint);
639 }
640
641 IntRect ScrollView::rootViewToContents(const IntRect& rootViewRect) const
642 {
643 IntRect viewRect = convertFromContainingWindow(rootViewRect);
644 viewRect.move(scrollOffset());
645 return viewRect;
646 }
647
648 IntRect ScrollView::contentsToRootView(const IntRect& contentsRect) const
649 {
650 IntRect viewRect = contentsRect;
651 viewRect.move(-scrollOffset());
652 return convertToContainingWindow(viewRect);
653 }
654
655 IntPoint ScrollView::windowToContents(const IntPoint& windowPoint) const
656 {
657 IntPoint viewPoint = convertFromContainingWindow(windowPoint);
658 return viewPoint + scrollOffset();
659 }
660
661 FloatPoint ScrollView::windowToContents(const FloatPoint& windowPoint) const
662 {
663 FloatPoint viewPoint = convertFromContainingWindow(windowPoint);
664 return viewPoint + scrollOffset();
665 }
666
667 IntPoint ScrollView::contentsToWindow(const IntPoint& contentsPoint) const
668 {
669 IntPoint viewPoint = contentsPoint - scrollOffset();
670 return convertToContainingWindow(viewPoint);
671 }
672
673 IntRect ScrollView::windowToContents(const IntRect& windowRect) const
674 {
675 IntRect viewRect = convertFromContainingWindow(windowRect);
676 viewRect.move(scrollOffset());
677 return viewRect;
678 }
679
680 IntRect ScrollView::contentsToWindow(const IntRect& contentsRect) const
681 {
682 IntRect viewRect = contentsRect;
683 viewRect.move(-scrollOffset());
684 return convertToContainingWindow(viewRect);
685 }
686
687 IntRect ScrollView::contentsToScreen(const IntRect& rect) const
688 {
689 HostWindow* window = hostWindow();
690 if (!window)
691 return IntRect();
692 return window->rootViewToScreen(contentsToRootView(rect));
693 }
694
695 bool ScrollView::containsScrollbarsAvoidingResizer() const
696 {
697 return !m_scrollbarsAvoidingResizer;
698 }
699
700 void ScrollView::adjustScrollbarsAvoidingResizerCount(int overlapDelta)
701 {
702 int oldCount = m_scrollbarsAvoidingResizer;
703 m_scrollbarsAvoidingResizer += overlapDelta;
704 if (parent())
705 toScrollView(parent())->adjustScrollbarsAvoidingResizerCount(overlapDelt a);
706 else if (!scrollbarsSuppressed()) {
707 // If we went from n to 0 or from 0 to n and we're the outermost view,
708 // we need to invalidate the windowResizerRect(), since it will now need to paint
709 // differently.
710 if ((oldCount > 0 && m_scrollbarsAvoidingResizer == 0) ||
711 (oldCount == 0 && m_scrollbarsAvoidingResizer > 0))
712 invalidateRect(windowResizerRect());
713 }
714 }
715
716 void ScrollView::setParent(Widget* parentView)
717 {
718 if (parentView == parent())
719 return;
720
721 if (m_scrollbarsAvoidingResizer && parent())
722 toScrollView(parent())->adjustScrollbarsAvoidingResizerCount(-m_scrollba rsAvoidingResizer);
723
724 Widget::setParent(parentView);
725
726 if (m_scrollbarsAvoidingResizer && parent())
727 toScrollView(parent())->adjustScrollbarsAvoidingResizerCount(m_scrollbar sAvoidingResizer);
728 }
729
730 void ScrollView::setScrollbarsSuppressed(bool suppressed, bool repaintOnUnsuppre ss)
731 {
732 if (suppressed == m_scrollbarsSuppressed)
733 return;
734
735 m_scrollbarsSuppressed = suppressed;
736
737 if (repaintOnUnsuppress && !suppressed) {
738 if (m_horizontalScrollbar)
739 m_horizontalScrollbar->invalidate();
740 if (m_verticalScrollbar)
741 m_verticalScrollbar->invalidate();
742
743 // Invalidate the scroll corner too on unsuppress.
744 invalidateRect(scrollCornerRect());
745 }
746 }
747
748 Scrollbar* ScrollView::scrollbarAtWindowPoint(const IntPoint& windowPoint)
749 {
750 IntPoint viewPoint = convertFromContainingWindow(windowPoint);
751 return scrollbarAtViewPoint(viewPoint);
752 }
753
754 Scrollbar* ScrollView::scrollbarAtViewPoint(const IntPoint& viewPoint)
755 {
756 if (m_horizontalScrollbar && m_horizontalScrollbar->shouldParticipateInHitTe sting() && m_horizontalScrollbar->frameRect().contains(viewPoint))
757 return m_horizontalScrollbar.get();
758 if (m_verticalScrollbar && m_verticalScrollbar->shouldParticipateInHitTestin g() && m_verticalScrollbar->frameRect().contains(viewPoint))
759 return m_verticalScrollbar.get();
760 return 0;
761 }
762
763 void ScrollView::setFrameRect(const IntRect& newRect)
764 {
765 IntRect oldRect = frameRect();
766
767 if (newRect == oldRect)
768 return;
769
770 Widget::setFrameRect(newRect);
771
772 updateScrollbars(scrollOffset());
773
774 frameRectsChanged();
775 }
776
777 void ScrollView::frameRectsChanged()
778 {
779 HashSet<RefPtr<Widget> >::const_iterator end = m_children.end();
780 for (HashSet<RefPtr<Widget> >::const_iterator current = m_children.begin(); current != end; ++current)
781 (*current)->frameRectsChanged();
782 }
783
784 static void positionScrollbarLayer(GraphicsLayer* graphicsLayer, Scrollbar* scro llbar)
785 {
786 if (!graphicsLayer || !scrollbar)
787 return;
788
789 IntRect scrollbarRect = scrollbar->frameRect();
790 graphicsLayer->setPosition(scrollbarRect.location());
791
792 if (scrollbarRect.size() == graphicsLayer->size())
793 return;
794
795 graphicsLayer->setSize(scrollbarRect.size());
796
797 if (graphicsLayer->hasContentsLayer()) {
798 graphicsLayer->setContentsRect(IntRect(0, 0, scrollbarRect.width(), scro llbarRect.height()));
799 return;
800 }
801
802 graphicsLayer->setDrawsContent(true);
803 graphicsLayer->setNeedsDisplay();
804 }
805
806 static void positionScrollCornerLayer(GraphicsLayer* graphicsLayer, const IntRec t& cornerRect)
807 {
808 if (!graphicsLayer)
809 return;
810 graphicsLayer->setDrawsContent(!cornerRect.isEmpty());
811 graphicsLayer->setPosition(cornerRect.location());
812 if (cornerRect.size() != graphicsLayer->size())
813 graphicsLayer->setNeedsDisplay();
814 graphicsLayer->setSize(cornerRect.size());
815 }
816
817 void ScrollView::positionScrollbarLayers()
818 {
819 positionScrollbarLayer(layerForHorizontalScrollbar(), horizontalScrollbar()) ;
820 positionScrollbarLayer(layerForVerticalScrollbar(), verticalScrollbar());
821 positionScrollCornerLayer(layerForScrollCorner(), scrollCornerRect());
822 }
823
824 bool ScrollView::userInputScrollable(ScrollbarOrientation orientation) const
825 {
826 ScrollbarMode mode = (orientation == HorizontalScrollbar) ?
827 m_horizontalScrollbarMode : m_verticalScrollbarMode;
828
829 return mode == ScrollbarAuto || mode == ScrollbarAlwaysOn;
830 }
831
832 bool ScrollView::shouldPlaceVerticalScrollbarOnLeft() const
833 {
834 return false;
835 }
836
837 void ScrollView::contentRectangleForPaintInvalidation(const IntRect& rect)
838 {
839 IntRect paintRect = rect;
840 if (clipsPaintInvalidations())
841 paintRect.intersect(visibleContentRect());
842 if (paintRect.isEmpty())
843 return;
844
845 if (HostWindow* window = hostWindow())
846 window->invalidateContentsAndRootView(contentsToWindow(paintRect));
847 }
848
849 IntRect ScrollView::scrollCornerRect() const
850 {
851 IntRect cornerRect;
852
853 if (hasOverlayScrollbars())
854 return cornerRect;
855
856 if (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0) {
857 cornerRect.unite(IntRect(shouldPlaceVerticalScrollbarOnLeft() ? 0 : m_ho rizontalScrollbar->width(),
858 height() - m_horizontalScrollbar->height(),
859 width() - m_horizontalScrollbar->width(),
860 m_horizontalScrollbar->height()));
861 }
862
863 if (m_verticalScrollbar && height() - m_verticalScrollbar->height() > 0) {
864 cornerRect.unite(IntRect(shouldPlaceVerticalScrollbarOnLeft() ? 0 : (wid th() - m_verticalScrollbar->width()),
865 m_verticalScrollbar->height(),
866 m_verticalScrollbar->width(),
867 height() - m_verticalScrollbar->height()));
868 }
869
870 return cornerRect;
871 }
872
873 bool ScrollView::isScrollCornerVisible() const
874 {
875 return !scrollCornerRect().isEmpty();
876 }
877
878 void ScrollView::scrollbarStyleChanged()
879 {
880 adjustScrollbarOpacity();
881 contentsResized();
882 updateScrollbars(scrollOffset());
883 positionScrollbarLayers();
884 }
885
886 void ScrollView::updateScrollCorner()
887 {
888 }
889
890 void ScrollView::paintScrollCorner(GraphicsContext* context, const IntRect& corn erRect)
891 {
892 ScrollbarTheme::theme()->paintScrollCorner(context, cornerRect);
893 }
894
895 void ScrollView::paintScrollbar(GraphicsContext* context, Scrollbar* bar, const IntRect& rect)
896 {
897 bar->paint(context, rect);
898 }
899
900 void ScrollView::invalidateScrollCornerRect(const IntRect& rect)
901 {
902 invalidateRect(rect);
903 }
904
905 void ScrollView::paintScrollbars(GraphicsContext* context, const IntRect& rect)
906 {
907 if (m_horizontalScrollbar && !layerForHorizontalScrollbar())
908 paintScrollbar(context, m_horizontalScrollbar.get(), rect);
909 if (m_verticalScrollbar && !layerForVerticalScrollbar())
910 paintScrollbar(context, m_verticalScrollbar.get(), rect);
911
912 if (layerForScrollCorner())
913 return;
914 paintScrollCorner(context, scrollCornerRect());
915 }
916
917 void ScrollView::paintPanScrollIcon(GraphicsContext* context)
918 {
919 DEFINE_STATIC_REF(Image, panScrollIcon, (Image::loadPlatformResource("panIco n")));
920 IntPoint iconGCPoint = m_panScrollIconPoint;
921 if (parent())
922 iconGCPoint = toScrollView(parent())->windowToContents(iconGCPoint);
923 context->drawImage(panScrollIcon, iconGCPoint);
924 }
925
926 void ScrollView::paint(GraphicsContext* context, const IntRect& rect)
927 {
928 notifyPageThatContentAreaWillPaint();
929
930 IntRect documentDirtyRect = rect;
931 IntRect visibleAreaWithoutScrollbars(location(), visibleContentRect().size() );
932 documentDirtyRect.intersect(visibleAreaWithoutScrollbars);
933
934 if (!documentDirtyRect.isEmpty()) {
935 GraphicsContextStateSaver stateSaver(*context);
936
937 context->translate(x() - scrollX(), y() - scrollY());
938 context->clip(visibleContentRect());
939
940 documentDirtyRect.moveBy(-location() + scrollPosition());
941 paintContents(context, documentDirtyRect);
942 }
943
944 calculateAndPaintOverhangAreas(context, rect);
945
946 // Now paint the scrollbars.
947 if (!m_scrollbarsSuppressed && (m_horizontalScrollbar || m_verticalScrollbar )) {
948 GraphicsContextStateSaver stateSaver(*context);
949 IntRect scrollViewDirtyRect = rect;
950 IntRect visibleAreaWithScrollbars(location(), visibleContentRect(Include Scrollbars).size());
951 scrollViewDirtyRect.intersect(visibleAreaWithScrollbars);
952 context->translate(x(), y());
953 scrollViewDirtyRect.moveBy(-location());
954 context->clip(IntRect(IntPoint(), visibleAreaWithScrollbars.size()));
955
956 paintScrollbars(context, scrollViewDirtyRect);
957 }
958
959 // Paint the panScroll Icon
960 if (m_drawPanScrollIcon)
961 paintPanScrollIcon(context);
962 }
963
964 void ScrollView::calculateOverhangAreasForPainting(IntRect& horizontalOverhangRe ct, IntRect& verticalOverhangRect)
965 {
966 int verticalScrollbarWidth = (verticalScrollbar() && !verticalScrollbar()->i sOverlayScrollbar())
967 ? verticalScrollbar()->width() : 0;
968 int horizontalScrollbarHeight = (horizontalScrollbar() && !horizontalScrollb ar()->isOverlayScrollbar())
969 ? horizontalScrollbar()->height() : 0;
970
971 int physicalScrollY = scrollPosition().y() + scrollOrigin().y();
972 if (physicalScrollY < 0) {
973 horizontalOverhangRect = frameRect();
974 horizontalOverhangRect.setHeight(-physicalScrollY);
975 horizontalOverhangRect.setWidth(horizontalOverhangRect.width() - vertica lScrollbarWidth);
976 } else if (contentsHeight() && physicalScrollY > contentsHeight() - visibleH eight()) {
977 int height = physicalScrollY - (contentsHeight() - visibleHeight());
978 horizontalOverhangRect = frameRect();
979 horizontalOverhangRect.setY(frameRect().maxY() - height - horizontalScro llbarHeight);
980 horizontalOverhangRect.setHeight(height);
981 horizontalOverhangRect.setWidth(horizontalOverhangRect.width() - vertica lScrollbarWidth);
982 }
983
984 int physicalScrollX = scrollPosition().x() + scrollOrigin().x();
985 if (physicalScrollX < 0) {
986 verticalOverhangRect.setWidth(-physicalScrollX);
987 verticalOverhangRect.setHeight(frameRect().height() - horizontalOverhang Rect.height() - horizontalScrollbarHeight);
988 verticalOverhangRect.setX(frameRect().x());
989 if (horizontalOverhangRect.y() == frameRect().y())
990 verticalOverhangRect.setY(frameRect().y() + horizontalOverhangRect.h eight());
991 else
992 verticalOverhangRect.setY(frameRect().y());
993 } else if (contentsWidth() && physicalScrollX > contentsWidth() - visibleWid th()) {
994 int width = physicalScrollX - (contentsWidth() - visibleWidth());
995 verticalOverhangRect.setWidth(width);
996 verticalOverhangRect.setHeight(frameRect().height() - horizontalOverhang Rect.height() - horizontalScrollbarHeight);
997 verticalOverhangRect.setX(frameRect().maxX() - width - verticalScrollbar Width);
998 if (horizontalOverhangRect.y() == frameRect().y())
999 verticalOverhangRect.setY(frameRect().y() + horizontalOverhangRect.h eight());
1000 else
1001 verticalOverhangRect.setY(frameRect().y());
1002 }
1003 }
1004
1005 void ScrollView::updateOverhangAreas()
1006 {
1007 HostWindow* window = hostWindow();
1008 if (!window)
1009 return;
1010
1011 IntRect horizontalOverhangRect;
1012 IntRect verticalOverhangRect;
1013 calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRe ct);
1014 if (!horizontalOverhangRect.isEmpty())
1015 window->invalidateContentsAndRootView(horizontalOverhangRect);
1016 if (!verticalOverhangRect.isEmpty())
1017 window->invalidateContentsAndRootView(verticalOverhangRect);
1018 }
1019
1020 void ScrollView::paintOverhangAreas(GraphicsContext* context, const IntRect& hor izontalOverhangRect, const IntRect& verticalOverhangRect, const IntRect& dirtyRe ct)
1021 {
1022 ScrollbarTheme::theme()->paintOverhangBackground(context, horizontalOverhang Rect, verticalOverhangRect, dirtyRect);
1023 ScrollbarTheme::theme()->paintOverhangShadows(context, scrollOffset(), horiz ontalOverhangRect, verticalOverhangRect, dirtyRect);
1024 }
1025
1026 void ScrollView::calculateAndPaintOverhangAreas(GraphicsContext* context, const IntRect& dirtyRect)
1027 {
1028 IntRect horizontalOverhangRect;
1029 IntRect verticalOverhangRect;
1030 calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRe ct);
1031
1032 if (dirtyRect.intersects(horizontalOverhangRect) || dirtyRect.intersects(ver ticalOverhangRect))
1033 paintOverhangAreas(context, horizontalOverhangRect, verticalOverhangRect , dirtyRect);
1034 }
1035
1036 void ScrollView::calculateAndPaintOverhangBackground(GraphicsContext* context, c onst IntRect& dirtyRect)
1037 {
1038 IntRect horizontalOverhangRect;
1039 IntRect verticalOverhangRect;
1040 calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRe ct);
1041
1042 if (dirtyRect.intersects(horizontalOverhangRect) || dirtyRect.intersects(ver ticalOverhangRect))
1043 ScrollbarTheme::theme()->paintOverhangBackground(context, horizontalOver hangRect, verticalOverhangRect, dirtyRect);
1044 }
1045
1046 bool ScrollView::isPointInScrollbarCorner(const IntPoint& windowPoint)
1047 {
1048 if (!scrollbarCornerPresent())
1049 return false;
1050
1051 IntPoint viewPoint = convertFromContainingWindow(windowPoint);
1052
1053 if (m_horizontalScrollbar) {
1054 int horizontalScrollbarYMin = m_horizontalScrollbar->frameRect().y();
1055 int horizontalScrollbarYMax = m_horizontalScrollbar->frameRect().y() + m _horizontalScrollbar->frameRect().height();
1056 int horizontalScrollbarXMin = m_horizontalScrollbar->frameRect().x() + m _horizontalScrollbar->frameRect().width();
1057
1058 return viewPoint.y() > horizontalScrollbarYMin && viewPoint.y() < horizo ntalScrollbarYMax && viewPoint.x() > horizontalScrollbarXMin;
1059 }
1060
1061 int verticalScrollbarXMin = m_verticalScrollbar->frameRect().x();
1062 int verticalScrollbarXMax = m_verticalScrollbar->frameRect().x() + m_vertica lScrollbar->frameRect().width();
1063 int verticalScrollbarYMin = m_verticalScrollbar->frameRect().y() + m_vertica lScrollbar->frameRect().height();
1064
1065 return viewPoint.x() > verticalScrollbarXMin && viewPoint.x() < verticalScro llbarXMax && viewPoint.y() > verticalScrollbarYMin;
1066 }
1067
1068 bool ScrollView::scrollbarCornerPresent() const
1069 {
1070 return (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0)
1071 || (m_verticalScrollbar && height() - m_verticalScrollbar->height() > 0) ;
1072 }
1073
1074 IntRect ScrollView::convertFromScrollbarToContainingView(const Scrollbar* scroll bar, const IntRect& localRect) const
1075 {
1076 // Scrollbars won't be transformed within us
1077 IntRect newRect = localRect;
1078 newRect.moveBy(scrollbar->location());
1079 return newRect;
1080 }
1081
1082 IntRect ScrollView::convertFromContainingViewToScrollbar(const Scrollbar* scroll bar, const IntRect& parentRect) const
1083 {
1084 IntRect newRect = parentRect;
1085 // Scrollbars won't be transformed within us
1086 newRect.moveBy(-scrollbar->location());
1087 return newRect;
1088 }
1089
1090 // FIXME: test these on windows
1091 IntPoint ScrollView::convertFromScrollbarToContainingView(const Scrollbar* scrol lbar, const IntPoint& localPoint) const
1092 {
1093 // Scrollbars won't be transformed within us
1094 IntPoint newPoint = localPoint;
1095 newPoint.moveBy(scrollbar->location());
1096 return newPoint;
1097 }
1098
1099 IntPoint ScrollView::convertFromContainingViewToScrollbar(const Scrollbar* scrol lbar, const IntPoint& parentPoint) const
1100 {
1101 IntPoint newPoint = parentPoint;
1102 // Scrollbars won't be transformed within us
1103 newPoint.moveBy(-scrollbar->location());
1104 return newPoint;
1105 }
1106
1107 void ScrollView::setParentVisible(bool visible)
1108 {
1109 if (isParentVisible() == visible)
1110 return;
1111
1112 Widget::setParentVisible(visible);
1113
1114 if (!isSelfVisible())
1115 return;
1116
1117 HashSet<RefPtr<Widget> >::iterator end = m_children.end();
1118 for (HashSet<RefPtr<Widget> >::iterator it = m_children.begin(); it != end; ++it)
1119 (*it)->setParentVisible(visible);
1120 }
1121
1122 void ScrollView::show()
1123 {
1124 if (!isSelfVisible()) {
1125 setSelfVisible(true);
1126 if (isParentVisible()) {
1127 HashSet<RefPtr<Widget> >::iterator end = m_children.end();
1128 for (HashSet<RefPtr<Widget> >::iterator it = m_children.begin(); it != end; ++it)
1129 (*it)->setParentVisible(true);
1130 }
1131 }
1132
1133 Widget::show();
1134 }
1135
1136 void ScrollView::hide()
1137 {
1138 if (isSelfVisible()) {
1139 if (isParentVisible()) {
1140 HashSet<RefPtr<Widget> >::iterator end = m_children.end();
1141 for (HashSet<RefPtr<Widget> >::iterator it = m_children.begin(); it != end; ++it)
1142 (*it)->setParentVisible(false);
1143 }
1144 setSelfVisible(false);
1145 }
1146
1147 Widget::hide();
1148 }
1149
1150 void ScrollView::addPanScrollIcon(const IntPoint& iconPosition)
1151 {
1152 HostWindow* window = hostWindow();
1153 if (!window)
1154 return;
1155 m_drawPanScrollIcon = true;
1156 m_panScrollIconPoint = IntPoint(iconPosition.x() - panIconSizeLength / 2 , i conPosition.y() - panIconSizeLength / 2) ;
1157 window->invalidateContentsAndRootView(IntRect(m_panScrollIconPoint, IntSize( panIconSizeLength, panIconSizeLength)));
1158 }
1159
1160 void ScrollView::removePanScrollIcon()
1161 {
1162 HostWindow* window = hostWindow();
1163 if (!window)
1164 return;
1165 m_drawPanScrollIcon = false;
1166 window->invalidateContentsAndRootView(IntRect(m_panScrollIconPoint, IntSize( panIconSizeLength, panIconSizeLength)));
1167 }
1168
1169 void ScrollView::setScrollOrigin(const IntPoint& origin, bool updatePositionAtAl l, bool updatePositionSynchronously)
1170 {
1171 if (scrollOrigin() == origin)
1172 return;
1173
1174 ScrollableArea::setScrollOrigin(origin);
1175
1176 // Update if the scroll origin changes, since our position will be different if the content size did not change.
1177 if (updatePositionAtAll && updatePositionSynchronously)
1178 updateScrollbars(scrollOffset());
1179 }
1180
1181 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698