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

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

Issue 2387883002: Use float for scroll offset. (Closed)
Patch Set: Created 4 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
1 /* 1 /*
2 * Copyright (c) 2010, Google Inc. All rights reserved. 2 * Copyright (c) 2010, Google Inc. All rights reserved.
3 * Copyright (C) 2008, 2011 Apple Inc. All Rights Reserved. 3 * Copyright (C) 2008, 2011 Apple Inc. All Rights Reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are 6 * modification, are permitted provided that the following conditions are
7 * met: 7 * met:
8 * 8 *
9 * * Redistributions of source code must retain the above copyright 9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 14 matching lines...) Expand all
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32 #include "platform/scroll/ScrollableArea.h" 32 #include "platform/scroll/ScrollableArea.h"
33 33
34 #include "platform/HostWindow.h" 34 #include "platform/HostWindow.h"
35 #include "platform/geometry/DoubleRect.h"
36 #include "platform/geometry/FloatPoint.h"
37 #include "platform/geometry/LayoutRect.h"
38 #include "platform/graphics/GraphicsLayer.h" 35 #include "platform/graphics/GraphicsLayer.h"
39 #include "platform/scroll/MainThreadScrollingReason.h" 36 #include "platform/scroll/MainThreadScrollingReason.h"
40 #include "platform/scroll/ProgrammaticScrollAnimator.h" 37 #include "platform/scroll/ProgrammaticScrollAnimator.h"
41 #include "platform/scroll/ScrollbarTheme.h" 38 #include "platform/scroll/ScrollbarTheme.h"
42 39
43 #include "platform/TraceEvent.h" 40 #include "platform/TraceEvent.h"
44 41
45 static const int kPixelsPerLineStep = 40; 42 static const int kPixelsPerLineStep = 40;
46 static const float kMinFractionToStepWhenPaging = 0.875f; 43 static const float kMinFractionToStepWhenPaging = 0.875f;
47 44
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 case ScrollByPixel: 137 case ScrollByPixel:
141 case ScrollByPrecisePixel: 138 case ScrollByPrecisePixel:
142 return pixelStep(orientation); 139 return pixelStep(orientation);
143 default: 140 default:
144 ASSERT_NOT_REACHED(); 141 ASSERT_NOT_REACHED();
145 return 0.0f; 142 return 0.0f;
146 } 143 }
147 } 144 }
148 145
149 ScrollResult ScrollableArea::userScroll(ScrollGranularity granularity, 146 ScrollResult ScrollableArea::userScroll(ScrollGranularity granularity,
150 const FloatSize& delta) { 147 const ScrollOffset& delta) {
151 float stepX = scrollStep(granularity, HorizontalScrollbar); 148 float stepX = scrollStep(granularity, HorizontalScrollbar);
152 float stepY = scrollStep(granularity, VerticalScrollbar); 149 float stepY = scrollStep(granularity, VerticalScrollbar);
153 150
154 FloatSize pixelDelta(delta); 151 ScrollOffset pixelDelta(delta);
155 pixelDelta.scale(stepX, stepY); 152 pixelDelta.scale(stepX, stepY);
156 153
157 FloatSize scrollableAxisDelta( 154 ScrollOffset scrollableAxisDelta(
158 userInputScrollable(HorizontalScrollbar) ? pixelDelta.width() : 0, 155 userInputScrollable(HorizontalScrollbar) ? pixelDelta.width() : 0,
159 userInputScrollable(VerticalScrollbar) ? pixelDelta.height() : 0); 156 userInputScrollable(VerticalScrollbar) ? pixelDelta.height() : 0);
160 157
161 if (scrollableAxisDelta.isZero()) { 158 if (scrollableAxisDelta.isZero()) {
162 return ScrollResult(false, false, pixelDelta.width(), pixelDelta.height()); 159 return ScrollResult(false, false, pixelDelta.width(), pixelDelta.height());
163 } 160 }
164 161
165 cancelProgrammaticScrollAnimation(); 162 cancelProgrammaticScrollAnimation();
166 163
167 ScrollResult result = scrollAnimator().userScroll(granularity, pixelDelta); 164 ScrollResult result = scrollAnimator().userScroll(granularity, pixelDelta);
168 165
169 // Delta that wasn't scrolled because the axis is !userInputScrollable 166 // Delta that wasn't scrolled because the axis is !userInputScrollable
170 // should count as unusedScrollDelta. 167 // should count as unusedScrollDelta.
171 FloatSize unscrollableAxisDelta = pixelDelta - scrollableAxisDelta; 168 ScrollOffset unscrollableAxisDelta = pixelDelta - scrollableAxisDelta;
172 result.unusedScrollDeltaX += unscrollableAxisDelta.width(); 169 result.unusedScrollDeltaX += unscrollableAxisDelta.width();
173 result.unusedScrollDeltaY += unscrollableAxisDelta.height(); 170 result.unusedScrollDeltaY += unscrollableAxisDelta.height();
174 171
175 return result; 172 return result;
176 } 173 }
177 174
178 void ScrollableArea::setScrollPosition(const DoublePoint& position, 175 void ScrollableArea::setScrollOffset(const ScrollOffset& offset,
179 ScrollType scrollType, 176 ScrollType scrollType,
180 ScrollBehavior behavior) { 177 ScrollBehavior behavior) {
181 DoublePoint clampedPosition = clampScrollPosition(position); 178 ScrollOffset clampedOffset = clampScrollOffset(offset);
182 if (shouldUseIntegerScrollOffset()) 179 if (clampedOffset == scrollOffset())
183 clampedPosition = flooredIntPoint(clampedPosition);
184 if (clampedPosition == scrollPositionDouble())
185 return; 180 return;
186 181
187 if (behavior == ScrollBehaviorAuto) 182 if (behavior == ScrollBehaviorAuto)
188 behavior = scrollBehaviorStyle(); 183 behavior = scrollBehaviorStyle();
189 184
190 switch (scrollType) { 185 switch (scrollType) {
191 case CompositorScroll: 186 case CompositorScroll:
192 scrollPositionChanged(clampedPosition, scrollType); 187 scrollOffsetChanged(clampedOffset, scrollType);
193 break; 188 break;
194 case AnchoringScroll: 189 case AnchoringScroll:
195 scrollAnimator().adjustAnimationAndSetScrollPosition(clampedPosition, 190 scrollAnimator().adjustAnimationAndSetScrollOffset(clampedOffset,
196 scrollType); 191 scrollType);
197 break; 192 break;
198 case ProgrammaticScroll: 193 case ProgrammaticScroll:
199 programmaticScrollHelper(clampedPosition, behavior); 194 programmaticScrollHelper(clampedOffset, behavior);
200 break; 195 break;
201 case UserScroll: 196 case UserScroll:
202 userScrollHelper(clampedPosition, behavior); 197 userScrollHelper(clampedOffset, behavior);
203 break; 198 break;
204 default: 199 default:
205 ASSERT_NOT_REACHED(); 200 ASSERT_NOT_REACHED();
206 } 201 }
207 } 202 }
208 203
209 void ScrollableArea::scrollBy(const DoubleSize& delta, 204 void ScrollableArea::scrollBy(const ScrollOffset& delta,
210 ScrollType type, 205 ScrollType type,
211 ScrollBehavior behavior) { 206 ScrollBehavior behavior) {
212 setScrollPosition(scrollPositionDouble() + delta, type, behavior); 207 setScrollOffset(scrollOffset() + delta, type, behavior);
213 } 208 }
214 209
215 void ScrollableArea::setScrollPositionSingleAxis( 210 void ScrollableArea::setScrollOffsetSingleAxis(ScrollbarOrientation orientation,
216 ScrollbarOrientation orientation, 211 float offset,
217 double position, 212 ScrollType scrollType,
218 ScrollType scrollType, 213 ScrollBehavior behavior) {
219 ScrollBehavior behavior) { 214 ScrollOffset newOffset;
220 DoublePoint newPosition;
221 if (orientation == HorizontalScrollbar) 215 if (orientation == HorizontalScrollbar)
222 newPosition = DoublePoint(position, scrollAnimator().currentPosition().y()); 216 newOffset = ScrollOffset(offset, scrollAnimator().currentOffset().height());
223 else 217 else
224 newPosition = DoublePoint(scrollAnimator().currentPosition().x(), position); 218 newOffset = ScrollOffset(scrollAnimator().currentOffset().width(), offset);
225 219
226 // TODO(bokan): Note, this doesn't use the derived class versions since this m ethod is currently used 220 // TODO(bokan): Note, this doesn't use the derived class versions since this m ethod is currently used
227 // exclusively by code that adjusts the position by the scroll origin and the derived class versions 221 // exclusively by code that adjusts the offset by the scroll origin and the de rived class versions
228 // differ on whether they take that into account or not. 222 // differ on whether they take that into account or not.
229 ScrollableArea::setScrollPosition(newPosition, scrollType, behavior); 223 ScrollableArea::setScrollOffset(newOffset, scrollType, behavior);
230 } 224 }
231 225
232 void ScrollableArea::programmaticScrollHelper(const DoublePoint& position, 226 void ScrollableArea::programmaticScrollHelper(const ScrollOffset& offset,
233 ScrollBehavior scrollBehavior) { 227 ScrollBehavior scrollBehavior) {
234 cancelScrollAnimation(); 228 cancelScrollAnimation();
235 229
236 if (scrollBehavior == ScrollBehaviorSmooth) 230 if (scrollBehavior == ScrollBehaviorSmooth)
237 programmaticScrollAnimator().animateToOffset(toFloatPoint(position)); 231 programmaticScrollAnimator().animateToOffset(offset);
238 else 232 else
239 programmaticScrollAnimator().scrollToOffsetWithoutAnimation( 233 programmaticScrollAnimator().scrollToOffsetWithoutAnimation(offset);
240 toFloatPoint(position));
241 } 234 }
242 235
243 void ScrollableArea::userScrollHelper(const DoublePoint& position, 236 void ScrollableArea::userScrollHelper(const ScrollOffset& offset,
244 ScrollBehavior scrollBehavior) { 237 ScrollBehavior scrollBehavior) {
245 cancelProgrammaticScrollAnimation(); 238 cancelProgrammaticScrollAnimation();
246 239
247 double x = userInputScrollable(HorizontalScrollbar) 240 float x = userInputScrollable(HorizontalScrollbar)
248 ? position.x() 241 ? offset.width()
249 : scrollAnimator().currentPosition().x(); 242 : scrollAnimator().currentOffset().width();
250 double y = userInputScrollable(VerticalScrollbar) 243 float y = userInputScrollable(VerticalScrollbar)
251 ? position.y() 244 ? offset.height()
252 : scrollAnimator().currentPosition().y(); 245 : scrollAnimator().currentOffset().height();
253 246
254 // Smooth user scrolls (keyboard, wheel clicks) are handled via the userScroll method. 247 // Smooth user scrolls (keyboard, wheel clicks) are handled via the userScroll method.
255 // TODO(bokan): The userScroll method should probably be modified to call this method 248 // TODO(bokan): The userScroll method should probably be modified to call this method
256 // and ScrollAnimatorBase to have a simpler animateToOffset metho d like the 249 // and ScrollAnimatorBase to have a simpler animateToOffset metho d like the
257 // ProgrammaticScrollAnimator. 250 // ProgrammaticScrollAnimator.
258 ASSERT(scrollBehavior == ScrollBehaviorInstant); 251 ASSERT(scrollBehavior == ScrollBehaviorInstant);
259 scrollAnimator().scrollToOffsetWithoutAnimation(FloatPoint(x, y)); 252 scrollAnimator().scrollToOffsetWithoutAnimation(ScrollOffset(x, y));
260 } 253 }
261 254
262 LayoutRect ScrollableArea::scrollIntoView(const LayoutRect& rectInContent, 255 LayoutRect ScrollableArea::scrollIntoView(const LayoutRect& rectInContent,
263 const ScrollAlignment& alignX, 256 const ScrollAlignment& alignX,
264 const ScrollAlignment& alignY, 257 const ScrollAlignment& alignY,
265 ScrollType) { 258 ScrollType) {
266 // TODO(bokan): This should really be implemented here but ScrollAlignment is in Core which is a dependency violation. 259 // TODO(bokan): This should really be implemented here but ScrollAlignment is in Core which is a dependency violation.
267 ASSERT_NOT_REACHED(); 260 ASSERT_NOT_REACHED();
268 return LayoutRect(); 261 return LayoutRect();
269 } 262 }
270 263
271 void ScrollableArea::scrollPositionChanged(const DoublePoint& position, 264 void ScrollableArea::scrollOffsetChanged(const ScrollOffset& offset,
272 ScrollType scrollType) { 265 ScrollType scrollType) {
273 TRACE_EVENT0("blink", "ScrollableArea::scrollPositionChanged"); 266 TRACE_EVENT0("blink", "ScrollableArea::scrollOffsetChanged");
274 267
275 DoublePoint oldPosition = scrollPositionDouble(); 268 ScrollOffset oldOffset = scrollOffset();
276 DoublePoint truncatedPosition = 269 ScrollOffset truncatedOffset = shouldUseIntegerScrollOffset()
277 shouldUseIntegerScrollOffset() ? flooredIntPoint(position) : position; 270 ? ScrollOffset(flooredIntSize(offset))
271 : offset;
278 272
279 // Tell the derived class to scroll its contents. 273 // Tell the derived class to scroll its contents.
280 updateScrollPosition(truncatedPosition, scrollType); 274 updateScrollOffset(truncatedOffset, scrollType);
281 275
282 // Tell the scrollbars to update their thumb postions. 276 // Tell the scrollbars to update their thumb postions.
283 // If the scrollbar does not have its own layer, it must always be 277 // If the scrollbar does not have its own layer, it must always be
284 // invalidated to reflect the new thumb position, even if the theme did not 278 // invalidated to reflect the new thumb offset, even if the theme did not
285 // invalidate any individual part. 279 // invalidate any individual part.
286 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) 280 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar())
287 horizontalScrollbar->offsetDidChange(); 281 horizontalScrollbar->offsetDidChange();
288 if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) 282 if (Scrollbar* verticalScrollbar = this->verticalScrollbar())
289 verticalScrollbar->offsetDidChange(); 283 verticalScrollbar->offsetDidChange();
290 284
291 if (scrollPositionDouble() != oldPosition) { 285 if (scrollOffset() != oldOffset)
292 // FIXME: Pass in DoubleSize. crbug.com/414283. 286 scrollAnimator().notifyContentAreaScrolled(scrollOffset() - oldOffset);
293 scrollAnimator().notifyContentAreaScrolled(
294 toFloatSize(scrollPositionDouble() - oldPosition));
295 }
296 287
297 scrollAnimator().setCurrentPosition(toFloatPoint(position)); 288 scrollAnimator().setCurrentOffset(offset);
298 } 289 }
299 290
300 bool ScrollableArea::scrollBehaviorFromString(const String& behaviorString, 291 bool ScrollableArea::scrollBehaviorFromString(const String& behaviorString,
301 ScrollBehavior& behavior) { 292 ScrollBehavior& behavior) {
302 if (behaviorString == "auto") 293 if (behaviorString == "auto")
303 behavior = ScrollBehaviorAuto; 294 behavior = ScrollBehaviorAuto;
304 else if (behaviorString == "instant") 295 else if (behaviorString == "instant")
305 behavior = ScrollBehaviorInstant; 296 behavior = ScrollBehaviorInstant;
306 else if (behaviorString == "smooth") 297 else if (behaviorString == "smooth")
307 behavior = ScrollBehaviorSmooth; 298 behavior = ScrollBehaviorSmooth;
308 else 299 else
309 return false; 300 return false;
310 301
311 return true; 302 return true;
312 } 303 }
313 304
314 // NOTE: Only called from Internals for testing. 305 // NOTE: Only called from Internals for testing.
315 void ScrollableArea::updateScrollPositionFromInternals( 306 void ScrollableArea::updateScrollOffsetFromInternals(const IntSize& offset) {
316 const IntPoint& position) { 307 scrollOffsetChanged(ScrollOffset(offset), ProgrammaticScroll);
317 scrollPositionChanged(DoublePoint(position), ProgrammaticScroll);
318 } 308 }
319 309
320 void ScrollableArea::contentAreaWillPaint() const { 310 void ScrollableArea::contentAreaWillPaint() const {
321 if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator()) 311 if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator())
322 scrollAnimator->contentAreaWillPaint(); 312 scrollAnimator->contentAreaWillPaint();
323 } 313 }
324 314
325 void ScrollableArea::mouseEnteredContentArea() const { 315 void ScrollableArea::mouseEnteredContentArea() const {
326 if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator()) 316 if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator())
327 scrollAnimator->mouseEnteredContentArea(); 317 scrollAnimator->mouseEnteredContentArea();
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 // scheduled on the compositor. 517 // scheduled on the compositor.
528 // TODO(ymalik): We have a non-transient "main thread scrolling reason" 518 // TODO(ymalik): We have a non-transient "main thread scrolling reason"
529 // that doesn't actually cause shouldScrollOnMainThread() to be true. 519 // that doesn't actually cause shouldScrollOnMainThread() to be true.
530 // This is confusing and should be cleaned up. 520 // This is confusing and should be cleaned up.
531 return !!(reasons & 521 return !!(reasons &
532 ~MainThreadScrollingReason::kHandlingScrollFromMainThread); 522 ~MainThreadScrollingReason::kHandlingScrollFromMainThread);
533 } 523 }
534 return true; 524 return true;
535 } 525 }
536 526
537 DoubleRect ScrollableArea::visibleContentRectDouble(
538 IncludeScrollbarsInRect scrollbarInclusion) const {
539 return visibleContentRect(scrollbarInclusion);
540 }
541
542 IntRect ScrollableArea::visibleContentRect( 527 IntRect ScrollableArea::visibleContentRect(
543 IncludeScrollbarsInRect scrollbarInclusion) const { 528 IncludeScrollbarsInRect scrollbarInclusion) const {
544 int scrollbarWidth = 529 int scrollbarWidth =
545 scrollbarInclusion == IncludeScrollbars ? verticalScrollbarWidth() : 0; 530 scrollbarInclusion == IncludeScrollbars ? verticalScrollbarWidth() : 0;
546 int scrollbarHeight = 531 int scrollbarHeight =
547 scrollbarInclusion == IncludeScrollbars ? horizontalScrollbarHeight() : 0; 532 scrollbarInclusion == IncludeScrollbars ? horizontalScrollbarHeight() : 0;
548 533
549 return IntRect(scrollPosition().x(), scrollPosition().y(), 534 return enclosingIntRect(
550 std::max(0, visibleWidth() + scrollbarWidth), 535 IntRect(scrollOffset().width(), scrollOffset().height(),
551 std::max(0, visibleHeight() + scrollbarHeight)); 536 std::max(0, visibleWidth() + scrollbarWidth),
537 std::max(0, visibleHeight() + scrollbarHeight)));
552 } 538 }
553 539
554 IntPoint ScrollableArea::clampScrollPosition( 540 IntSize ScrollableArea::clampScrollOffset(const IntSize& scrollOffset) const {
555 const IntPoint& scrollPosition) const { 541 return scrollOffset.shrunkTo(maximumScrollOffsetInt())
556 return scrollPosition.shrunkTo(maximumScrollPosition()) 542 .expandedTo(minimumScrollOffsetInt());
557 .expandedTo(minimumScrollPosition());
558 } 543 }
559 544
560 DoublePoint ScrollableArea::clampScrollPosition( 545 ScrollOffset ScrollableArea::clampScrollOffset(
561 const DoublePoint& scrollPosition) const { 546 const ScrollOffset& scrollOffset) const {
562 return scrollPosition.shrunkTo(maximumScrollPositionDouble()) 547 return scrollOffset.shrunkTo(maximumScrollOffset())
563 .expandedTo(minimumScrollPositionDouble()); 548 .expandedTo(minimumScrollOffset());
564 } 549 }
565 550
566 int ScrollableArea::lineStep(ScrollbarOrientation) const { 551 int ScrollableArea::lineStep(ScrollbarOrientation) const {
567 return pixelsPerLineStep(getHostWindow()); 552 return pixelsPerLineStep(getHostWindow());
568 } 553 }
569 554
570 int ScrollableArea::pageStep(ScrollbarOrientation orientation) const { 555 int ScrollableArea::pageStep(ScrollbarOrientation orientation) const {
571 IntRect visibleRect = visibleContentRect(IncludeScrollbars); 556 IntRect visibleRect = visibleContentRect(IncludeScrollbars);
572 int length = (orientation == HorizontalScrollbar) ? visibleRect.width() 557 int length = (orientation == HorizontalScrollbar) ? visibleRect.width()
573 : visibleRect.height(); 558 : visibleRect.height();
(...skipping 27 matching lines...) Expand all
601 return IntSize(std::max(0, size.width() - verticalScrollbarWidth()), 586 return IntSize(std::max(0, size.width() - verticalScrollbarWidth()),
602 std::max(0, size.height() - horizontalScrollbarHeight())); 587 std::max(0, size.height() - horizontalScrollbarHeight()));
603 } 588 }
604 589
605 DEFINE_TRACE(ScrollableArea) { 590 DEFINE_TRACE(ScrollableArea) {
606 visitor->trace(m_scrollAnimator); 591 visitor->trace(m_scrollAnimator);
607 visitor->trace(m_programmaticScrollAnimator); 592 visitor->trace(m_programmaticScrollAnimator);
608 } 593 }
609 594
610 } // namespace blink 595 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698