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

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

Issue 2387883002: Use float for scroll offset. (Closed)
Patch Set: Fix README.md 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/tracing/TraceEvent.h" 40 #include "platform/tracing/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 220 // TODO(bokan): Note, this doesn't use the derived class versions since this
227 // method is currently used exclusively by code that adjusts the position by 221 // method is currently used exclusively by code that adjusts the position by
228 // the scroll origin and the derived class versions differ on whether they 222 // the scroll origin and the derived class versions differ on whether they
229 // take that into account or not. 223 // take that into account or not.
230 ScrollableArea::setScrollPosition(newPosition, scrollType, behavior); 224 ScrollableArea::setScrollOffset(newOffset, scrollType, behavior);
231 } 225 }
232 226
233 void ScrollableArea::programmaticScrollHelper(const DoublePoint& position, 227 void ScrollableArea::programmaticScrollHelper(const ScrollOffset& offset,
234 ScrollBehavior scrollBehavior) { 228 ScrollBehavior scrollBehavior) {
235 cancelScrollAnimation(); 229 cancelScrollAnimation();
236 230
237 if (scrollBehavior == ScrollBehaviorSmooth) 231 if (scrollBehavior == ScrollBehaviorSmooth)
238 programmaticScrollAnimator().animateToOffset(toFloatPoint(position)); 232 programmaticScrollAnimator().animateToOffset(offset);
239 else 233 else
240 programmaticScrollAnimator().scrollToOffsetWithoutAnimation( 234 programmaticScrollAnimator().scrollToOffsetWithoutAnimation(offset);
241 toFloatPoint(position));
242 } 235 }
243 236
244 void ScrollableArea::userScrollHelper(const DoublePoint& position, 237 void ScrollableArea::userScrollHelper(const ScrollOffset& offset,
245 ScrollBehavior scrollBehavior) { 238 ScrollBehavior scrollBehavior) {
246 cancelProgrammaticScrollAnimation(); 239 cancelProgrammaticScrollAnimation();
247 240
248 double x = userInputScrollable(HorizontalScrollbar) 241 float x = userInputScrollable(HorizontalScrollbar)
249 ? position.x() 242 ? offset.width()
250 : scrollAnimator().currentPosition().x(); 243 : scrollAnimator().currentOffset().width();
251 double y = userInputScrollable(VerticalScrollbar) 244 float y = userInputScrollable(VerticalScrollbar)
252 ? position.y() 245 ? offset.height()
253 : scrollAnimator().currentPosition().y(); 246 : scrollAnimator().currentOffset().height();
254 247
255 // Smooth user scrolls (keyboard, wheel clicks) are handled via the userScroll 248 // Smooth user scrolls (keyboard, wheel clicks) are handled via the userScroll
256 // method. 249 // method.
257 // TODO(bokan): The userScroll method should probably be modified to call this 250 // TODO(bokan): The userScroll method should probably be modified to call this
258 // method and ScrollAnimatorBase to have a simpler 251 // method and ScrollAnimatorBase to have a simpler
259 // animateToOffset method like the ProgrammaticScrollAnimator. 252 // animateToOffset method like the ProgrammaticScrollAnimator.
260 ASSERT(scrollBehavior == ScrollBehaviorInstant); 253 ASSERT(scrollBehavior == ScrollBehaviorInstant);
261 scrollAnimator().scrollToOffsetWithoutAnimation(FloatPoint(x, y)); 254 scrollAnimator().scrollToOffsetWithoutAnimation(ScrollOffset(x, y));
262 } 255 }
263 256
264 LayoutRect ScrollableArea::scrollIntoView(const LayoutRect& rectInContent, 257 LayoutRect ScrollableArea::scrollIntoView(const LayoutRect& rectInContent,
265 const ScrollAlignment& alignX, 258 const ScrollAlignment& alignX,
266 const ScrollAlignment& alignY, 259 const ScrollAlignment& alignY,
267 ScrollType) { 260 ScrollType) {
268 // TODO(bokan): This should really be implemented here but ScrollAlignment is 261 // TODO(bokan): This should really be implemented here but ScrollAlignment is
269 // in Core which is a dependency violation. 262 // in Core which is a dependency violation.
270 ASSERT_NOT_REACHED(); 263 ASSERT_NOT_REACHED();
271 return LayoutRect(); 264 return LayoutRect();
272 } 265 }
273 266
274 void ScrollableArea::scrollPositionChanged(const DoublePoint& position, 267 void ScrollableArea::scrollOffsetChanged(const ScrollOffset& offset,
275 ScrollType scrollType) { 268 ScrollType scrollType) {
276 TRACE_EVENT0("blink", "ScrollableArea::scrollPositionChanged"); 269 TRACE_EVENT0("blink", "ScrollableArea::scrollOffsetChanged");
277 270
278 DoublePoint oldPosition = scrollPositionDouble(); 271 ScrollOffset oldOffset = scrollOffset();
279 DoublePoint truncatedPosition = 272 ScrollOffset truncatedOffset = shouldUseIntegerScrollOffset()
280 shouldUseIntegerScrollOffset() ? flooredIntPoint(position) : position; 273 ? ScrollOffset(flooredIntSize(offset))
274 : offset;
281 275
282 // Tell the derived class to scroll its contents. 276 // Tell the derived class to scroll its contents.
283 setScrollOffset(truncatedPosition, scrollType); 277 updateScrollOffset(truncatedOffset, scrollType);
284 278
285 // Tell the scrollbars to update their thumb postions. 279 // Tell the scrollbars to update their thumb postions.
286 // If the scrollbar does not have its own layer, it must always be 280 // If the scrollbar does not have its own layer, it must always be
287 // invalidated to reflect the new thumb position, even if the theme did not 281 // invalidated to reflect the new thumb offset, even if the theme did not
288 // invalidate any individual part. 282 // invalidate any individual part.
289 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) 283 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar())
290 horizontalScrollbar->offsetDidChange(); 284 horizontalScrollbar->offsetDidChange();
291 if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) 285 if (Scrollbar* verticalScrollbar = this->verticalScrollbar())
292 verticalScrollbar->offsetDidChange(); 286 verticalScrollbar->offsetDidChange();
293 287
294 if (scrollPositionDouble() != oldPosition) { 288 if (scrollOffset() != oldOffset)
295 // FIXME: Pass in DoubleSize. crbug.com/414283. 289 scrollAnimator().notifyContentAreaScrolled(scrollOffset() - oldOffset);
296 scrollAnimator().notifyContentAreaScrolled(
297 toFloatSize(scrollPositionDouble() - oldPosition));
298 }
299 290
300 scrollAnimator().setCurrentPosition(toFloatPoint(position)); 291 scrollAnimator().setCurrentOffset(offset);
301 } 292 }
302 293
303 bool ScrollableArea::scrollBehaviorFromString(const String& behaviorString, 294 bool ScrollableArea::scrollBehaviorFromString(const String& behaviorString,
304 ScrollBehavior& behavior) { 295 ScrollBehavior& behavior) {
305 if (behaviorString == "auto") 296 if (behaviorString == "auto")
306 behavior = ScrollBehaviorAuto; 297 behavior = ScrollBehaviorAuto;
307 else if (behaviorString == "instant") 298 else if (behaviorString == "instant")
308 behavior = ScrollBehaviorInstant; 299 behavior = ScrollBehaviorInstant;
309 else if (behaviorString == "smooth") 300 else if (behaviorString == "smooth")
310 behavior = ScrollBehaviorSmooth; 301 behavior = ScrollBehaviorSmooth;
311 else 302 else
312 return false; 303 return false;
313 304
314 return true; 305 return true;
315 } 306 }
316 307
317 // NOTE: Only called from Internals for testing. 308 // NOTE: Only called from Internals for testing.
318 void ScrollableArea::setScrollOffsetFromInternals(const IntPoint& offset) { 309 void ScrollableArea::updateScrollOffsetFromInternals(const IntSize& offset) {
319 scrollPositionChanged(DoublePoint(offset), ProgrammaticScroll); 310 scrollOffsetChanged(ScrollOffset(offset), ProgrammaticScroll);
320 } 311 }
321 312
322 void ScrollableArea::contentAreaWillPaint() const { 313 void ScrollableArea::contentAreaWillPaint() const {
323 if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator()) 314 if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator())
324 scrollAnimator->contentAreaWillPaint(); 315 scrollAnimator->contentAreaWillPaint();
325 } 316 }
326 317
327 void ScrollableArea::mouseEnteredContentArea() const { 318 void ScrollableArea::mouseEnteredContentArea() const {
328 if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator()) 319 if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator())
329 scrollAnimator->mouseEnteredContentArea(); 320 scrollAnimator->mouseEnteredContentArea();
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 // scheduled on the compositor. 521 // scheduled on the compositor.
531 // TODO(ymalik): We have a non-transient "main thread scrolling reason" 522 // TODO(ymalik): We have a non-transient "main thread scrolling reason"
532 // that doesn't actually cause shouldScrollOnMainThread() to be true. 523 // that doesn't actually cause shouldScrollOnMainThread() to be true.
533 // This is confusing and should be cleaned up. 524 // This is confusing and should be cleaned up.
534 return !!(reasons & 525 return !!(reasons &
535 ~MainThreadScrollingReason::kHandlingScrollFromMainThread); 526 ~MainThreadScrollingReason::kHandlingScrollFromMainThread);
536 } 527 }
537 return true; 528 return true;
538 } 529 }
539 530
540 DoubleRect ScrollableArea::visibleContentRectDouble(
541 IncludeScrollbarsInRect scrollbarInclusion) const {
542 return visibleContentRect(scrollbarInclusion);
543 }
544
545 IntRect ScrollableArea::visibleContentRect( 531 IntRect ScrollableArea::visibleContentRect(
546 IncludeScrollbarsInRect scrollbarInclusion) const { 532 IncludeScrollbarsInRect scrollbarInclusion) const {
547 int scrollbarWidth = 533 int scrollbarWidth =
548 scrollbarInclusion == IncludeScrollbars ? verticalScrollbarWidth() : 0; 534 scrollbarInclusion == IncludeScrollbars ? verticalScrollbarWidth() : 0;
549 int scrollbarHeight = 535 int scrollbarHeight =
550 scrollbarInclusion == IncludeScrollbars ? horizontalScrollbarHeight() : 0; 536 scrollbarInclusion == IncludeScrollbars ? horizontalScrollbarHeight() : 0;
551 537
552 return IntRect(scrollPosition().x(), scrollPosition().y(), 538 return enclosingIntRect(
553 std::max(0, visibleWidth() + scrollbarWidth), 539 IntRect(scrollOffset().width(), scrollOffset().height(),
554 std::max(0, visibleHeight() + scrollbarHeight)); 540 std::max(0, visibleWidth() + scrollbarWidth),
541 std::max(0, visibleHeight() + scrollbarHeight)));
555 } 542 }
556 543
557 IntPoint ScrollableArea::clampScrollPosition( 544 IntSize ScrollableArea::clampScrollOffset(const IntSize& scrollOffset) const {
558 const IntPoint& scrollPosition) const { 545 return scrollOffset.shrunkTo(maximumScrollOffsetInt())
559 return scrollPosition.shrunkTo(maximumScrollPosition()) 546 .expandedTo(minimumScrollOffsetInt());
560 .expandedTo(minimumScrollPosition());
561 } 547 }
562 548
563 DoublePoint ScrollableArea::clampScrollPosition( 549 ScrollOffset ScrollableArea::clampScrollOffset(
564 const DoublePoint& scrollPosition) const { 550 const ScrollOffset& scrollOffset) const {
565 return scrollPosition.shrunkTo(maximumScrollPositionDouble()) 551 return scrollOffset.shrunkTo(maximumScrollOffset())
566 .expandedTo(minimumScrollPositionDouble()); 552 .expandedTo(minimumScrollOffset());
567 } 553 }
568 554
569 int ScrollableArea::lineStep(ScrollbarOrientation) const { 555 int ScrollableArea::lineStep(ScrollbarOrientation) const {
570 return pixelsPerLineStep(getHostWindow()); 556 return pixelsPerLineStep(getHostWindow());
571 } 557 }
572 558
573 int ScrollableArea::pageStep(ScrollbarOrientation orientation) const { 559 int ScrollableArea::pageStep(ScrollbarOrientation orientation) const {
574 IntRect visibleRect = visibleContentRect(IncludeScrollbars); 560 IntRect visibleRect = visibleContentRect(IncludeScrollbars);
575 int length = (orientation == HorizontalScrollbar) ? visibleRect.width() 561 int length = (orientation == HorizontalScrollbar) ? visibleRect.width()
576 : visibleRect.height(); 562 : visibleRect.height();
(...skipping 27 matching lines...) Expand all
604 return IntSize(std::max(0, size.width() - verticalScrollbarWidth()), 590 return IntSize(std::max(0, size.width() - verticalScrollbarWidth()),
605 std::max(0, size.height() - horizontalScrollbarHeight())); 591 std::max(0, size.height() - horizontalScrollbarHeight()));
606 } 592 }
607 593
608 DEFINE_TRACE(ScrollableArea) { 594 DEFINE_TRACE(ScrollableArea) {
609 visitor->trace(m_scrollAnimator); 595 visitor->trace(m_scrollAnimator);
610 visitor->trace(m_programmaticScrollAnimator); 596 visitor->trace(m_programmaticScrollAnimator);
611 } 597 }
612 598
613 } // namespace blink 599 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698