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

Side by Side Diff: third_party/WebKit/Source/platform/scroll/Scrollbar.cpp

Issue 1406133005: Calculate paint invalidation rect for scrollbars (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month 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
1 /* 1 /*
2 * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 16 matching lines...) Expand all
27 #include "platform/scroll/Scrollbar.h" 27 #include "platform/scroll/Scrollbar.h"
28 28
29 #include <algorithm> 29 #include <algorithm>
30 #include "platform/PlatformGestureEvent.h" 30 #include "platform/PlatformGestureEvent.h"
31 #include "platform/PlatformMouseEvent.h" 31 #include "platform/PlatformMouseEvent.h"
32 #include "platform/graphics/paint/CullRect.h" 32 #include "platform/graphics/paint/CullRect.h"
33 #include "platform/scroll/ScrollAnimatorBase.h" 33 #include "platform/scroll/ScrollAnimatorBase.h"
34 #include "platform/scroll/ScrollableArea.h" 34 #include "platform/scroll/ScrollableArea.h"
35 #include "platform/scroll/ScrollbarTheme.h" 35 #include "platform/scroll/ScrollbarTheme.h"
36 36
37 #if ((OS(POSIX) && !OS(MACOSX)) || OS(WIN))
38 // The position of the scrollbar thumb affects the appearance of the steppers, s o
39 // when the thumb moves, we have to invalidate them for painting.
40 #define THUMB_POSITION_AFFECTS_BUTTONS
41 #endif
42
43 namespace blink { 37 namespace blink {
44 38
45 PassRefPtrWillBeRawPtr<Scrollbar> Scrollbar::create(ScrollableArea* scrollableAr ea, ScrollbarOrientation orientation, ScrollbarControlSize size) 39 PassRefPtrWillBeRawPtr<Scrollbar> Scrollbar::create(ScrollableArea* scrollableAr ea, ScrollbarOrientation orientation, ScrollbarControlSize size)
46 { 40 {
47 return adoptRefWillBeNoop(new Scrollbar(scrollableArea, orientation, size)); 41 return adoptRefWillBeNoop(new Scrollbar(scrollableArea, orientation, size));
48 } 42 }
49 43
50 Scrollbar::Scrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orient ation, ScrollbarControlSize controlSize, ScrollbarTheme* theme) 44 Scrollbar::Scrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orient ation, ScrollbarControlSize controlSize, ScrollbarTheme* theme)
51 : m_scrollableArea(scrollableArea) 45 : m_scrollableArea(scrollableArea)
52 , m_orientation(orientation) 46 , m_orientation(orientation)
53 , m_controlSize(controlSize) 47 , m_controlSize(controlSize)
54 , m_theme(theme) 48 , m_theme(theme)
55 , m_visibleSize(0) 49 , m_visibleSize(0)
56 , m_totalSize(0) 50 , m_totalSize(0)
57 , m_currentPos(0) 51 , m_currentPos(0)
58 , m_dragOrigin(0) 52 , m_dragOrigin(0)
59 , m_hoveredPart(NoPart) 53 , m_hoveredPart(NoPart)
60 , m_pressedPart(NoPart) 54 , m_pressedPart(NoPart)
61 , m_pressedPos(0) 55 , m_pressedPos(0)
62 , m_scrollPos(0) 56 , m_scrollPos(0)
63 , m_draggingDocument(false) 57 , m_draggingDocument(false)
64 , m_documentDragPos(0) 58 , m_documentDragPos(0)
65 , m_enabled(true) 59 , m_enabled(true)
66 , m_scrollTimer(this, &Scrollbar::autoscrollTimerFired) 60 , m_scrollTimer(this, &Scrollbar::autoscrollTimerFired)
67 , m_overlapsResizer(false) 61 , m_overlapsResizer(false)
68 , m_suppressInvalidation(false)
69 , m_isAlphaLocked(false) 62 , m_isAlphaLocked(false)
70 , m_elasticOverscroll(0) 63 , m_elasticOverscroll(0)
71 { 64 {
72 if (!m_theme) 65 if (!m_theme)
73 m_theme = ScrollbarTheme::theme(); 66 m_theme = ScrollbarTheme::theme();
74 67
75 m_theme->registerScrollbar(this); 68 m_theme->registerScrollbar(this);
76 69
77 // FIXME: This is ugly and would not be necessary if we fix cross-platform c ode to actually query for 70 // FIXME: This is ugly and would not be necessary if we fix cross-platform c ode to actually query for
78 // scrollbar thickness and use it when sizing scrollbars (rather than leavin g one dimension of the scrollbar 71 // scrollbar thickness and use it when sizing scrollbars (rather than leavin g one dimension of the scrollbar
(...skipping 13 matching lines...) Expand all
92 { 85 {
93 visitor->trace(m_scrollableArea); 86 visitor->trace(m_scrollableArea);
94 Widget::trace(visitor); 87 Widget::trace(visitor);
95 } 88 }
96 89
97 void Scrollbar::setFrameRect(const IntRect& frameRect) 90 void Scrollbar::setFrameRect(const IntRect& frameRect)
98 { 91 {
99 if (frameRect == this->frameRect()) 92 if (frameRect == this->frameRect())
100 return; 93 return;
101 94
102 invalidate();
103 Widget::setFrameRect(frameRect); 95 Widget::setFrameRect(frameRect);
104 invalidate(); 96 setNeedsPaintInvalidation();
105 } 97 }
106 98
107 ScrollbarOverlayStyle Scrollbar::scrollbarOverlayStyle() const 99 ScrollbarOverlayStyle Scrollbar::scrollbarOverlayStyle() const
108 { 100 {
109 return m_scrollableArea ? m_scrollableArea->scrollbarOverlayStyle() : Scroll barOverlayStyleDefault; 101 return m_scrollableArea ? m_scrollableArea->scrollbarOverlayStyle() : Scroll barOverlayStyleDefault;
110 } 102 }
111 103
112 void Scrollbar::getTickmarks(Vector<IntRect>& tickmarks) const 104 void Scrollbar::getTickmarks(Vector<IntRect>& tickmarks) const
113 { 105 {
114 if (m_scrollableArea) 106 if (m_scrollableArea)
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 return; 145 return;
154 146
155 m_visibleSize = visibleSize; 147 m_visibleSize = visibleSize;
156 m_totalSize = totalSize; 148 m_totalSize = totalSize;
157 149
158 updateThumbProportion(); 150 updateThumbProportion();
159 } 151 }
160 152
161 void Scrollbar::updateThumb() 153 void Scrollbar::updateThumb()
162 { 154 {
163 #ifdef THUMB_POSITION_AFFECTS_BUTTONS 155 setNeedsPaintInvalidation();
164 invalidate();
165 #else
166 theme()->invalidateParts(this, ForwardTrackPart | BackTrackPart | ThumbPart) ;
167 #endif
168 } 156 }
169 157
170 void Scrollbar::updateThumbPosition() 158 void Scrollbar::updateThumbPosition()
171 { 159 {
172 updateThumb(); 160 updateThumb();
173 } 161 }
174 162
175 void Scrollbar::updateThumbProportion() 163 void Scrollbar::updateThumbProportion()
176 { 164 {
177 updateThumb(); 165 updateThumb();
(...skipping 21 matching lines...) Expand all
199 } 187 }
200 188
201 void Scrollbar::autoscrollPressedPart(double delay) 189 void Scrollbar::autoscrollPressedPart(double delay)
202 { 190 {
203 // Don't do anything for the thumb or if nothing was pressed. 191 // Don't do anything for the thumb or if nothing was pressed.
204 if (m_pressedPart == ThumbPart || m_pressedPart == NoPart) 192 if (m_pressedPart == ThumbPart || m_pressedPart == NoPart)
205 return; 193 return;
206 194
207 // Handle the track. 195 // Handle the track.
208 if ((m_pressedPart == BackTrackPart || m_pressedPart == ForwardTrackPart) && thumbUnderMouse(this)) { 196 if ((m_pressedPart == BackTrackPart || m_pressedPart == ForwardTrackPart) && thumbUnderMouse(this)) {
209 theme()->invalidatePart(this, m_pressedPart); 197 setNeedsPaintInvalidation();
210 setHoveredPart(ThumbPart); 198 setHoveredPart(ThumbPart);
211 return; 199 return;
212 } 200 }
213 201
214 // Handle the arrows and track. 202 // Handle the arrows and track.
215 if (m_scrollableArea && m_scrollableArea->userScroll(pressedPartScrollDirect ionPhysical(), pressedPartScrollGranularity()).didScroll) 203 if (m_scrollableArea && m_scrollableArea->userScroll(pressedPartScrollDirect ionPhysical(), pressedPartScrollGranularity()).didScroll)
216 startTimerIfNeeded(delay); 204 startTimerIfNeeded(delay);
217 } 205 }
218 206
219 void Scrollbar::startTimerIfNeeded(double delay) 207 void Scrollbar::startTimerIfNeeded(double delay)
220 { 208 {
221 // Don't do anything for the thumb. 209 // Don't do anything for the thumb.
222 if (m_pressedPart == ThumbPart) 210 if (m_pressedPart == ThumbPart)
223 return; 211 return;
224 212
225 // Handle the track. We halt track scrolling once the thumb is level 213 // Handle the track. We halt track scrolling once the thumb is level
226 // with us. 214 // with us.
227 if ((m_pressedPart == BackTrackPart || m_pressedPart == ForwardTrackPart) && thumbUnderMouse(this)) { 215 if ((m_pressedPart == BackTrackPart || m_pressedPart == ForwardTrackPart) && thumbUnderMouse(this)) {
228 theme()->invalidatePart(this, m_pressedPart); 216 setNeedsPaintInvalidation();
229 setHoveredPart(ThumbPart); 217 setHoveredPart(ThumbPart);
230 return; 218 return;
231 } 219 }
232 220
233 // We can't scroll if we've hit the beginning or end. 221 // We can't scroll if we've hit the beginning or end.
234 ScrollDirectionPhysical dir = pressedPartScrollDirectionPhysical(); 222 ScrollDirectionPhysical dir = pressedPartScrollDirectionPhysical();
235 if (dir == ScrollUp || dir == ScrollLeft) { 223 if (dir == ScrollUp || dir == ScrollLeft) {
236 if (m_currentPos == 0) 224 if (m_currentPos == 0)
237 return; 225 return;
238 } else { 226 } else {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 float newPosition = static_cast<float>(thumbPos + delta) * (maxPos - min Pos) / (trackLen - thumbLen) + minPos; 300 float newPosition = static_cast<float>(thumbPos + delta) * (maxPos - min Pos) / (trackLen - thumbLen) + minPos;
313 m_scrollableArea->setScrollPositionSingleAxis(m_orientation, newPosition , UserScroll); 301 m_scrollableArea->setScrollPositionSingleAxis(m_orientation, newPosition , UserScroll);
314 } 302 }
315 } 303 }
316 304
317 void Scrollbar::setHoveredPart(ScrollbarPart part) 305 void Scrollbar::setHoveredPart(ScrollbarPart part)
318 { 306 {
319 if (part == m_hoveredPart) 307 if (part == m_hoveredPart)
320 return; 308 return;
321 309
322 if ((m_hoveredPart == NoPart || part == NoPart) && theme()->invalidateOnMous eEnterExit()) 310 if (((m_hoveredPart == NoPart || part == NoPart) && theme()->invalidateOnMou seEnterExit())
323 invalidate(); // Just invalidate the whole scrollbar, since the buttons at either end change anyway. 311 // When there's a pressed part, we don't draw a hovered state, so there' s no reason to invalidate.
324 else if (m_pressedPart == NoPart) { // When there's a pressed part, we don' t draw a hovered state, so there's no reason to invalidate. 312 || m_pressedPart == NoPart)
325 theme()->invalidatePart(this, part); 313 setNeedsPaintInvalidation();
326 theme()->invalidatePart(this, m_hoveredPart); 314
327 }
328 m_hoveredPart = part; 315 m_hoveredPart = part;
329 } 316 }
330 317
331 void Scrollbar::setPressedPart(ScrollbarPart part) 318 void Scrollbar::setPressedPart(ScrollbarPart part)
332 { 319 {
333 if (m_pressedPart != NoPart) 320 if (m_pressedPart != NoPart
334 theme()->invalidatePart(this, m_pressedPart); 321 // When we no longer have a pressed part, we can start drawing a hovered state on the hovered part.
322 || m_hoveredPart != NoPart)
323 setNeedsPaintInvalidation();
335 m_pressedPart = part; 324 m_pressedPart = part;
336 if (m_pressedPart != NoPart)
337 theme()->invalidatePart(this, m_pressedPart);
338 else if (m_hoveredPart != NoPart) // When we no longer have a pressed part, we can start drawing a hovered state on the hovered part.
339 theme()->invalidatePart(this, m_hoveredPart);
340 } 325 }
341 326
342 bool Scrollbar::gestureEvent(const PlatformGestureEvent& evt) 327 bool Scrollbar::gestureEvent(const PlatformGestureEvent& evt)
343 { 328 {
344 switch (evt.type()) { 329 switch (evt.type()) {
345 case PlatformEvent::GestureTapDown: 330 case PlatformEvent::GestureTapDown:
346 setPressedPart(theme()->hitTest(this, evt.position())); 331 setPressedPart(theme()->hitTest(this, evt.position()));
347 m_pressedPos = orientation() == HorizontalScrollbar ? convertFromContain ingWindow(evt.position()).x() : convertFromContainingWindow(evt.position()).y(); 332 m_pressedPos = orientation() == HorizontalScrollbar ? convertFromContain ingWindow(evt.position()).x() : convertFromContainingWindow(evt.position()).y();
348 return true; 333 return true;
349 case PlatformEvent::GestureTapDownCancel: 334 case PlatformEvent::GestureTapDownCancel:
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 if (m_pressedPart != NoPart) 384 if (m_pressedPart != NoPart)
400 m_pressedPos = orientation() == HorizontalScrollbar ? convertFromContain ingWindow(evt.position()).x() : convertFromContainingWindow(evt.position()).y(); 385 m_pressedPos = orientation() == HorizontalScrollbar ? convertFromContain ingWindow(evt.position()).x() : convertFromContainingWindow(evt.position()).y();
401 386
402 ScrollbarPart part = theme()->hitTest(this, evt.position()); 387 ScrollbarPart part = theme()->hitTest(this, evt.position());
403 if (part != m_hoveredPart) { 388 if (part != m_hoveredPart) {
404 if (m_pressedPart != NoPart) { 389 if (m_pressedPart != NoPart) {
405 if (part == m_pressedPart) { 390 if (part == m_pressedPart) {
406 // The mouse is moving back over the pressed part. We 391 // The mouse is moving back over the pressed part. We
407 // need to start up the timer action again. 392 // need to start up the timer action again.
408 startTimerIfNeeded(theme()->autoscrollTimerDelay()); 393 startTimerIfNeeded(theme()->autoscrollTimerDelay());
409 theme()->invalidatePart(this, m_pressedPart); 394 setNeedsPaintInvalidation();
410 } else if (m_hoveredPart == m_pressedPart) { 395 } else if (m_hoveredPart == m_pressedPart) {
411 // The mouse is leaving the pressed part. Kill our timer 396 // The mouse is leaving the pressed part. Kill our timer
412 // if needed. 397 // if needed.
413 stopTimerIfNeeded(); 398 stopTimerIfNeeded();
414 theme()->invalidatePart(this, m_pressedPart); 399 setNeedsPaintInvalidation();
415 } 400 }
416 } 401 }
417 402
418 setHoveredPart(part); 403 setHoveredPart(part);
419 } 404 }
420 405
421 return; 406 return;
422 } 407 }
423 408
424 void Scrollbar::mouseEntered() 409 void Scrollbar::mouseEntered()
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 if (m_scrollableArea) 468 if (m_scrollableArea)
484 m_scrollableArea->scrollbarVisibilityChanged(); 469 m_scrollableArea->scrollbarVisibilityChanged();
485 } 470 }
486 471
487 void Scrollbar::setEnabled(bool e) 472 void Scrollbar::setEnabled(bool e)
488 { 473 {
489 if (m_enabled == e) 474 if (m_enabled == e)
490 return; 475 return;
491 m_enabled = e; 476 m_enabled = e;
492 theme()->updateEnabledState(this); 477 theme()->updateEnabledState(this);
493 invalidate(); 478 setNeedsPaintInvalidation();
494 } 479 }
495 480
496 bool Scrollbar::isOverlayScrollbar() const 481 bool Scrollbar::isOverlayScrollbar() const
497 { 482 {
498 return m_theme->usesOverlayScrollbars(); 483 return m_theme->usesOverlayScrollbars();
499 } 484 }
500 485
501 bool Scrollbar::shouldParticipateInHitTesting() 486 bool Scrollbar::shouldParticipateInHitTesting()
502 { 487 {
503 // Non-overlay scrollbars should always participate in hit testing. 488 // Non-overlay scrollbars should always participate in hit testing.
504 if (!isOverlayScrollbar()) 489 if (!isOverlayScrollbar())
505 return true; 490 return true;
506 return m_scrollableArea->scrollAnimator()->shouldScrollbarParticipateInHitTe sting(this); 491 return m_scrollableArea->scrollAnimator()->shouldScrollbarParticipateInHitTe sting(this);
507 } 492 }
508 493
509 bool Scrollbar::isWindowActive() const 494 bool Scrollbar::isWindowActive() const
510 { 495 {
511 return m_scrollableArea && m_scrollableArea->isActive(); 496 return m_scrollableArea && m_scrollableArea->isActive();
512 } 497 }
513 498
514 void Scrollbar::invalidateRect(const IntRect& rect)
515 {
516 if (suppressInvalidation())
517 return;
518
519 if (m_scrollableArea)
520 m_scrollableArea->invalidateScrollbar(this, rect);
521 }
522
523 IntRect Scrollbar::convertToContainingView(const IntRect& localRect) const 499 IntRect Scrollbar::convertToContainingView(const IntRect& localRect) const
524 { 500 {
525 if (m_scrollableArea) 501 if (m_scrollableArea)
526 return m_scrollableArea->convertFromScrollbarToContainingView(this, loca lRect); 502 return m_scrollableArea->convertFromScrollbarToContainingView(this, loca lRect);
527 503
528 return Widget::convertToContainingView(localRect); 504 return Widget::convertToContainingView(localRect);
529 } 505 }
530 506
531 IntRect Scrollbar::convertFromContainingView(const IntRect& parentRect) const 507 IntRect Scrollbar::convertFromContainingView(const IntRect& parentRect) const
532 { 508 {
(...skipping 23 matching lines...) Expand all
556 { 532 {
557 if (!m_scrollableArea) 533 if (!m_scrollableArea)
558 return 0; 534 return 0;
559 535
560 if (m_orientation == HorizontalScrollbar) 536 if (m_orientation == HorizontalScrollbar)
561 return m_scrollableArea->scrollPosition().x() - m_scrollableArea->minimu mScrollPosition().x(); 537 return m_scrollableArea->scrollPosition().x() - m_scrollableArea->minimu mScrollPosition().x();
562 538
563 return m_scrollableArea->scrollPosition().y() - m_scrollableArea->minimumScr ollPosition().y(); 539 return m_scrollableArea->scrollPosition().y() - m_scrollableArea->minimumScr ollPosition().y();
564 } 540 }
565 541
542 void Scrollbar::setNeedsPaintInvalidation()
543 {
544 if (m_scrollableArea)
545 m_scrollableArea->setScrollbarNeedsPaintInvalidation(this);
546 }
547
566 } // namespace blink 548 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/scroll/Scrollbar.h ('k') | third_party/WebKit/Source/platform/scroll/ScrollbarTheme.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698