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

Side by Side Diff: sky/engine/platform/scroll/ScrollView.cpp

Issue 646273006: Get rid of ScrollView. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: merge to ToT 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
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/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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698