Changeset 76956 in webkit
- Timestamp:
- Jan 28, 2011 11:05:43 AM (13 years ago)
- Location:
- trunk/Source
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r76925 r76956 1 2011-01-28 Sam Weinig <sam@webkit.org> 2 3 Reviewed by Maciej Stachowiak. 4 5 Add basic rubber banding support 6 <rdar://problem/8219429> 7 https://bugs.webkit.org/show_bug.cgi?id=53277 8 9 * wtf/Platform.h: Add ENABLE for rubber banding. 10 1 11 2011-01-28 Sheriff Bot <webkit.review.bot@gmail.com> 2 12 -
trunk/Source/JavaScriptCore/wtf/Platform.h
r76745 r76956 606 606 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 607 607 #define ENABLE_GESTURE_EVENTS 1 608 #define ENABLE_RUBBER_BANDING 1 608 609 #endif 609 610 #if !defined(ENABLE_JAVA_BRIDGE) -
trunk/Source/WebCore/ChangeLog
r76954 r76956 1 2011-01-28 Sam Weinig <sam@webkit.org> 2 3 Reviewed by Maciej Stachowiak. 4 5 Add basic rubber banding support 6 <rdar://problem/8219429> 7 https://bugs.webkit.org/show_bug.cgi?id=53277 8 9 * page/EventHandler.cpp: 10 (WebCore::EventHandler::handleGestureEvent): 11 Pass gesture events to the FrameView. 12 13 * platform/ScrollAnimator.cpp: 14 (WebCore::ScrollAnimator::handleGestureEvent): 15 * platform/ScrollAnimator.h: 16 Add stubbed out implementation. 17 18 * platform/ScrollView.cpp: 19 (WebCore::ScrollView::ScrollView): 20 (WebCore::ScrollView::overhangAmount): 21 (WebCore::ScrollView::wheelEvent): 22 * platform/ScrollView.h: 23 * platform/ScrollableArea.cpp: 24 (WebCore::ScrollableArea::ScrollableArea): 25 (WebCore::ScrollableArea::handleGestureEvent): 26 * platform/ScrollableArea.h: 27 (WebCore::ScrollableArea::constrainsScrollingToContentEdge): 28 (WebCore::ScrollableArea::setConstrainsScrollingToContentEdge): 29 Move constrains scrolling bit to ScrollableArea from ScrollView. 30 31 (WebCore::ScrollableArea::contentsSize): 32 (WebCore::ScrollableArea::overhangAmount): 33 Add additional virtual functions for information needed by the animator. 34 35 * platform/mac/ScrollAnimatorMac.h: 36 * platform/mac/ScrollAnimatorMac.mm: 37 (WebCore::ScrollAnimatorMac::ScrollAnimatorMac): 38 (WebCore::ScrollAnimatorMac::immediateScrollByDeltaX): 39 (WebCore::ScrollAnimatorMac::immediateScrollByDeltaY): 40 (WebCore::elasticDeltaForTimeDelta): 41 (WebCore::elasticDeltaForReboundDelta): 42 (WebCore::reboundDeltaForElasticDelta): 43 (WebCore::scrollWheelMultiplier): 44 (WebCore::ScrollAnimatorMac::handleWheelEvent): 45 (WebCore::ScrollAnimatorMac::handleGestureEvent): 46 (WebCore::ScrollAnimatorMac::pinnedInDirection): 47 (WebCore::ScrollAnimatorMac::allowsVerticalStretching): 48 (WebCore::ScrollAnimatorMac::allowsHorizontalStretching): 49 (WebCore::ScrollAnimatorMac::smoothScrollWithEvent): 50 (WebCore::ScrollAnimatorMac::beginScrollGesture): 51 (WebCore::ScrollAnimatorMac::endScrollGesture): 52 (WebCore::ScrollAnimatorMac::snapRubberBand): 53 (WebCore::roundTowardZero): 54 (WebCore::roundToDevicePixelTowardZero): 55 (WebCore::ScrollAnimatorMac::snapRubberBandTimerFired): 56 Implement basic rubber banding. 57 1 58 2011-01-28 Dan Bernstein <mitz@apple.com> 2 59 -
trunk/Source/WebCore/page/EventHandler.cpp
r76912 r76956 2041 2041 2042 2042 #if ENABLE(GESTURE_EVENTS) 2043 bool EventHandler::handleGestureEvent(const PlatformGestureEvent&) 2044 { 2045 // FIXME: Handle gesture events. 2043 bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent) 2044 { 2045 // FIXME: This should hit test and go to the correct subframe rather than 2046 // always sending gestures to the main frame only. We should also ensure 2047 // that if a frame gets a gesture begin gesture, it gets the corresponding 2048 // end gesture as well. 2049 2050 FrameView* view = m_frame->view(); 2051 if (!view) 2052 return false; 2053 2054 view->handleGestureEvent(gestureEvent); 2046 2055 return true; 2047 2056 } -
trunk/Source/WebCore/platform/ScrollAnimator.cpp
r76757 r76956 114 114 } 115 115 116 #if ENABLE(GESTURE_EVENTS) 117 void ScrollAnimator::handleGestureEvent(const PlatformGestureEvent&) 118 { 119 } 120 #endif 121 116 122 FloatPoint ScrollAnimator::currentPosition() const 117 123 { -
trunk/Source/WebCore/platform/ScrollAnimator.h
r76757 r76956 41 41 class ScrollableArea; 42 42 43 #if ENABLE(GESTURE_EVENTS) 44 class PlatformGestureEvent; 45 #endif 46 43 47 class ScrollAnimator { 44 48 public: … … 56 60 57 61 virtual void handleWheelEvent(PlatformWheelEvent&); 62 #if ENABLE(GESTURE_EVENTS) 63 virtual void handleGestureEvent(const PlatformGestureEvent&); 64 #endif 58 65 59 66 FloatPoint currentPosition() const; -
trunk/Source/WebCore/platform/ScrollView.cpp
r76832 r76956 56 56 , m_clipsRepaints(true) 57 57 , m_delegatesScrolling(false) 58 , m_constrainsScrollingToContentEdge(true)59 58 { 60 59 platformInit(); … … 398 397 { 399 398 return scroll(logicalToPhysical(direction, isVerticalDocument(), isFlippedDocument()), granularity); 399 } 400 401 IntSize ScrollView::overhangAmount() const 402 { 403 IntSize stretch; 404 if (scrollY() < 0) 405 stretch.setHeight(scrollY()); 406 else if (scrollY() > contentsHeight() - visibleContentRect().height()) 407 stretch.setHeight(scrollY() - (contentsHeight() - visibleContentRect().height())); 408 409 if (scrollX() < 0) 410 stretch.setWidth(scrollX()); 411 else if (scrollX() > contentsWidth() - visibleContentRect().width()) 412 stretch.setWidth(scrollX() - (contentsWidth() - visibleContentRect().width())); 413 414 return stretch; 400 415 } 401 416 … … 738 753 ScrollableArea::handleWheelEvent(e); 739 754 } 755 756 #if ENABLE(GESTURE_EVENTS) 757 void ScrollView::gestureEvent(const PlatformGestureEvent& gestureEvent) 758 { 759 if (platformWidget()) 760 return; 761 762 ScrollableArea::handleGestureEvent(gestureEvent); 763 } 764 #endif 740 765 741 766 void ScrollView::setFrameRect(const IntRect& newRect) -
trunk/Source/WebCore/platform/ScrollView.h
r76831 r76956 52 52 53 53 class HostWindow; 54 class PlatformWheelEvent;55 54 class Scrollbar; 56 55 … … 164 163 virtual void setContentsSize(const IntSize&); 165 164 166 // Functions for controlling if you can scroll past the end of the document.167 bool constrainsScrollingToContentEdge() const { return m_constrainsScrollingToContentEdge; }168 void setConstrainsScrollingToContentEdge(bool constrainsScrollingToContentEdge) { m_constrainsScrollingToContentEdge = constrainsScrollingToContentEdge; }169 170 165 // Functions for querying the current scrolled position (both as a point, a size, or as individual X and Y values). 171 166 IntPoint scrollPosition() const { return visibleContentRect().location(); } … … 177 172 int scrollX() const { return scrollPosition().x(); } 178 173 int scrollY() const { return scrollPosition().y(); } 179 174 175 IntSize overhangAmount() const; 176 180 177 // Functions for scrolling the view. 181 178 void setScrollPosition(const IntPoint&); … … 233 230 // (like Windows), we need this function in order to do the scroll ourselves. 234 231 void wheelEvent(PlatformWheelEvent&); 232 #if ENABLE(GESTURE_EVENTS) 233 void gestureEvent(const PlatformGestureEvent&); 234 #endif 235 235 236 236 IntPoint convertChildToSelf(const Widget* child, const IntPoint& point) const … … 339 339 bool m_clipsRepaints; 340 340 bool m_delegatesScrolling; 341 342 bool m_constrainsScrollingToContentEdge;343 341 344 342 // There are 8 possible combinations of writing mode and direction. Scroll origin will be non-zero in the x or y axis -
trunk/Source/WebCore/platform/ScrollableArea.cpp
r76757 r76956 42 42 ScrollableArea::ScrollableArea() 43 43 : m_scrollAnimator(ScrollAnimator::create(this)) 44 , m_constrainsScrollingToContentEdge(true) 44 45 { 45 46 } … … 114 115 } 115 116 117 #if ENABLE(GESTURE_EVENTS) 118 void ScrollableArea::handleGestureEvent(const PlatformGestureEvent& gestureEvent) 119 { 120 m_scrollAnimator->handleGestureEvent(gestureEvent); 121 } 122 #endif 123 116 124 void ScrollableArea::setScrollOffsetFromAnimation(const IntPoint& offset) 117 125 { -
trunk/Source/WebCore/platform/ScrollableArea.h
r76757 r76956 37 37 class ScrollAnimator; 38 38 39 #if ENABLE(GESTURE_EVENTS) 40 class PlatformGestureEvent; 41 #endif 42 39 43 class ScrollableArea { 40 44 public: … … 49 53 50 54 void handleWheelEvent(PlatformWheelEvent&); 55 #if ENABLE(GESTURE_EVENTS) 56 void handleGestureEvent(const PlatformGestureEvent&); 57 #endif 58 59 // Functions for controlling if you can scroll past the end of the document. 60 bool constrainsScrollingToContentEdge() const { return m_constrainsScrollingToContentEdge; } 61 void setConstrainsScrollingToContentEdge(bool constrainsScrollingToContentEdge) { m_constrainsScrollingToContentEdge = constrainsScrollingToContentEdge; } 51 62 52 63 virtual int scrollSize(ScrollbarOrientation) const = 0; … … 93 104 virtual int visibleWidth() const { ASSERT_NOT_REACHED(); return 0; } 94 105 106 virtual IntSize contentsSize() const { ASSERT_NOT_REACHED(); return IntSize(); } 107 108 virtual IntSize overhangAmount() const { ASSERT_NOT_REACHED(); return IntSize(); } 109 95 110 private: 96 111 // NOTE: Only called from the ScrollAnimator. … … 99 114 100 115 OwnPtr<ScrollAnimator> m_scrollAnimator; 116 bool m_constrainsScrollingToContentEdge; 101 117 }; 102 118 -
trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.h
r76378 r76956 1 1 /* 2 * Copyright (C) 2010 Apple Inc. All rights reserved.2 * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 #if ENABLE(SMOOTH_SCROLLING) 30 30 31 #include "FloatPoint.h" 32 #include "FloatSize.h" 31 33 #include "ScrollAnimator.h" 34 #include "Timer.h" 32 35 #include <wtf/RetainPtr.h> 33 36 … … 48 51 virtual void scrollToOffsetWithoutAnimation(const FloatPoint&); 49 52 50 // Called by the ScrollAnimationHelperDelegate. 53 #if ENABLE(RUBBER_BANDING) 54 virtual void handleWheelEvent(PlatformWheelEvent&); 55 #if ENABLE(GESTURE_EVENTS) 56 virtual void handleGestureEvent(const PlatformGestureEvent&); 57 #endif 58 #endif 59 51 60 void immediateScrollToPoint(const FloatPoint& newPosition); 61 void immediateScrollByDeltaX(float deltaX); 62 void immediateScrollByDeltaY(float deltaY); 52 63 53 64 private: 54 65 RetainPtr<id> m_scrollAnimationHelper; 55 66 RetainPtr<ScrollAnimationHelperDelegate> m_scrollAnimationHelperDelegate; 67 68 #if ENABLE(RUBBER_BANDING) 69 bool allowsVerticalStretching() const; 70 bool allowsHorizontalStretching() const; 71 bool pinnedInDirection(float deltaX, float deltaY); 72 void snapRubberBand(); 73 void snapRubberBandTimerFired(Timer<ScrollAnimatorMac>*); 74 void smoothScrollWithEvent(PlatformWheelEvent&); 75 void beginScrollGesture(); 76 void endScrollGesture(); 77 78 bool m_inScrollGesture; 79 bool m_momentumScrollInProgress; 80 bool m_ignoreMomentumScrolls; 81 CFTimeInterval m_lastMomemtumScrollTimestamp; 82 FloatSize m_overflowScrollDelta; 83 FloatSize m_stretchScrollForce; 84 FloatSize m_momentumVelocity; 85 86 // Rubber band state. 87 CFTimeInterval m_startTime; 88 FloatSize m_startStretch; 89 FloatPoint m_origOrigin; 90 FloatSize m_origVelocity; 91 Timer<ScrollAnimatorMac> m_snapRubberBandTimer; 92 #endif 56 93 }; 57 94 -
trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm
r76378 r76956 1 1 /* 2 * Copyright (C) 2010 Apple Inc. All rights reserved.2 * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 31 31 32 32 #include "FloatPoint.h" 33 #include "PlatformWheelEvent.h" 34 #include "PlatformGestureEvent.h" 33 35 #include "ScrollableArea.h" 34 36 #include <wtf/PassOwnPtr.h> … … 123 125 @end 124 126 127 125 128 namespace WebCore { 126 129 … … 132 135 ScrollAnimatorMac::ScrollAnimatorMac(ScrollableArea* scrollableArea) 133 136 : ScrollAnimator(scrollableArea) 137 #if ENABLE(RUBBER_BANDING) 138 , m_inScrollGesture(false) 139 , m_momentumScrollInProgress(false) 140 , m_ignoreMomentumScrolls(false) 141 , m_lastMomemtumScrollTimestamp(0) 142 , m_startTime(0) 143 , m_snapRubberBandTimer(this, &ScrollAnimatorMac::snapRubberBandTimerFired) 144 #endif 134 145 { 135 146 m_scrollAnimationHelperDelegate.adoptNS([[ScrollAnimationHelperDelegate alloc] initWithScrollAnimator:this]); … … 178 189 } 179 190 191 void ScrollAnimatorMac::immediateScrollByDeltaX(float deltaX) 192 { 193 m_currentPosX += deltaX; 194 notityPositionChanged(); 195 } 196 197 void ScrollAnimatorMac::immediateScrollByDeltaY(float deltaY) 198 { 199 m_currentPosY += deltaY; 200 notityPositionChanged(); 201 } 202 203 #if ENABLE(RUBBER_BANDING) 204 205 static const double scrollVelocityZeroingTimeout = 0.10; 206 static const double rubberbandStiffness = 20.0; 207 static const double rubberbandDirectionLockStretchRatio = 1.0; 208 static const double rubberbandMinimumRequiredDeltaBeforeStretch = 10.0; 209 static const double rubberbandAmplitude = 0.31; 210 static const double rubberbandPeriod = 1.6; 211 212 static float elasticDeltaForTimeDelta(float initialPosition, float initialVelocity, float elapsedTime) 213 { 214 float amplitude = rubberbandAmplitude; 215 float period = rubberbandPeriod; 216 float criticalDampeningFactor = exp((-elapsedTime * rubberbandStiffness) / period); 217 218 return (initialPosition + (-initialVelocity * elapsedTime * amplitude)) * criticalDampeningFactor; 219 } 220 221 static float elasticDeltaForReboundDelta(float delta) 222 { 223 float stiffness = std::max(rubberbandStiffness, 1.0); 224 return delta / stiffness; 225 } 226 227 static float reboundDeltaForElasticDelta(float delta) 228 { 229 return delta * rubberbandStiffness; 230 } 231 232 static float scrollWheelMultiplier() 233 { 234 static float multiplier = -1.0; 235 if (multiplier < 0) { 236 multiplier = [[NSUserDefaults standardUserDefaults] floatForKey:@"NSScrollWheelMultiplier"]; 237 if (multiplier <= 0) 238 multiplier = 1; 239 } 240 return multiplier; 241 } 242 243 void ScrollAnimatorMac::handleWheelEvent(PlatformWheelEvent& wheelEvent) 244 { 245 if (!wheelEvent.hasPreciseScrollingDeltas()) { 246 ScrollAnimator::handleWheelEvent(wheelEvent); 247 return; 248 } 249 250 wheelEvent.accept(); 251 252 bool isMometumScrollEvent = (wheelEvent.phase() != PlatformWheelEventPhaseNone); 253 if (m_ignoreMomentumScrolls && (isMometumScrollEvent || m_snapRubberBandTimer.isActive())) { 254 if (wheelEvent.phase() == PlatformWheelEventPhaseEnded) 255 m_ignoreMomentumScrolls = false; 256 return; 257 } 258 259 smoothScrollWithEvent(wheelEvent); 260 } 261 262 void ScrollAnimatorMac::handleGestureEvent(const PlatformGestureEvent& gestureEvent) 263 { 264 if (gestureEvent.type() == PlatformGestureEvent::ScrollBeginType) 265 beginScrollGesture(); 266 else 267 endScrollGesture(); 268 } 269 270 bool ScrollAnimatorMac::pinnedInDirection(float deltaX, float deltaY) 271 { 272 FloatSize limitDelta; 273 if (fabsf(deltaY) >= fabsf(deltaX)) { 274 if (deltaY < 0) { 275 // We are trying to scroll up. Make sure we are not pinned to the top 276 limitDelta.setHeight(m_scrollableArea->visibleContentRect().y()); 277 } else { 278 // We are trying to scroll down. Make sure we are not pinned to the bottom 279 limitDelta.setHeight(m_scrollableArea->contentsSize().height() - m_scrollableArea->visibleContentRect().bottom()); 280 } 281 } else if (deltaX != 0) { 282 if (deltaX < 0) { 283 // We are trying to scroll left. Make sure we are not pinned to the left 284 limitDelta.setWidth(m_scrollableArea->visibleContentRect().x()); 285 } else { 286 // We are trying to scroll right. Make sure we are not pinned to the right 287 limitDelta.setWidth(m_scrollableArea->contentsSize().width() - m_scrollableArea->visibleContentRect().right()); 288 } 289 } 290 291 if ((deltaX != 0 || deltaY != 0) && (limitDelta.width() < 1 && limitDelta.height() < 1)) 292 return true; 293 return false; 294 } 295 296 bool ScrollAnimatorMac::allowsVerticalStretching() const 297 { 298 Scrollbar* hScroller = m_scrollableArea->horizontalScrollbar(); 299 Scrollbar* vScroller = m_scrollableArea->verticalScrollbar(); 300 if (((vScroller && vScroller->enabled()) || (!hScroller || !hScroller->enabled()))) 301 return true; 302 303 return false; 304 } 305 306 bool ScrollAnimatorMac::allowsHorizontalStretching() const 307 { 308 Scrollbar* hScroller = m_scrollableArea->horizontalScrollbar(); 309 Scrollbar* vScroller = m_scrollableArea->verticalScrollbar(); 310 if (((hScroller && hScroller->enabled()) || (!vScroller || !vScroller->enabled()))) 311 return true; 312 313 return false; 314 } 315 316 void ScrollAnimatorMac::smoothScrollWithEvent(PlatformWheelEvent& wheelEvent) 317 { 318 float deltaX = m_overflowScrollDelta.width(); 319 float deltaY = m_overflowScrollDelta.height(); 320 321 // Reset overflow values because we may decide to remove delta at various points and put it into overflow. 322 m_overflowScrollDelta = FloatSize(); 323 324 float eventCoallescedDeltaX = -wheelEvent.deltaX(); 325 float eventCoallescedDeltaY = -wheelEvent.deltaY(); 326 327 deltaX += eventCoallescedDeltaX; 328 deltaY += eventCoallescedDeltaY; 329 330 // Slightly prefer scrolling vertically by applying the = case to deltaY 331 if (fabsf(deltaY) >= fabsf(deltaX)) 332 deltaX = 0.0; 333 else 334 deltaY = 0.0; 335 336 bool isVerticallyStretched = false; 337 bool isHorizontallyStretched = false; 338 bool shouldStretch = false; 339 340 IntSize stretchAmount = m_scrollableArea->overhangAmount(); 341 342 isHorizontallyStretched = (stretchAmount.width() == 0.0) ? false : true; 343 isVerticallyStretched = (stretchAmount.height() == 0.0) ? false : true; 344 345 PlatformWheelEventPhase phase = wheelEvent.phase(); 346 347 // If we are starting momentum scrolling then do some setup. 348 if (!m_momentumScrollInProgress && (phase == PlatformWheelEventPhaseBegan || phase == PlatformWheelEventPhaseChanged)) 349 m_momentumScrollInProgress = true; 350 351 CFTimeInterval timeDelta = wheelEvent.timestamp() - m_lastMomemtumScrollTimestamp; 352 if (m_inScrollGesture || m_momentumScrollInProgress) { 353 if (m_lastMomemtumScrollTimestamp && timeDelta > 0.0 && timeDelta < scrollVelocityZeroingTimeout) { 354 m_momentumVelocity.setWidth(eventCoallescedDeltaX / timeDelta); 355 m_momentumVelocity.setHeight(eventCoallescedDeltaY / timeDelta); 356 m_lastMomemtumScrollTimestamp = wheelEvent.timestamp(); 357 } else { 358 m_lastMomemtumScrollTimestamp = wheelEvent.timestamp(); 359 m_momentumVelocity = FloatSize(); 360 } 361 362 if (isVerticallyStretched) { 363 if (!isHorizontallyStretched && pinnedInDirection(deltaX, 0)) { 364 // Stretching only in the vertical. 365 if (deltaY != 0.0 && (fabsf(deltaX / deltaY) < rubberbandDirectionLockStretchRatio)) 366 deltaX = 0.0; 367 else if (fabsf(deltaX) < rubberbandMinimumRequiredDeltaBeforeStretch) { 368 m_overflowScrollDelta.setWidth(m_overflowScrollDelta.width() + deltaX); 369 deltaX = 0.0; 370 } else 371 m_overflowScrollDelta.setWidth(m_overflowScrollDelta.width() + deltaX); 372 } 373 } else if (isHorizontallyStretched) { 374 // Stretching only in the horizontal. 375 if (pinnedInDirection(0, deltaY)) { 376 if (deltaX != 0.0 && (fabsf(deltaY / deltaX) < rubberbandDirectionLockStretchRatio)) 377 deltaY = 0.0; 378 else if (fabsf(deltaY) < rubberbandMinimumRequiredDeltaBeforeStretch) { 379 m_overflowScrollDelta.setHeight(m_overflowScrollDelta.height() + deltaY); 380 deltaY = 0.0; 381 } else 382 m_overflowScrollDelta.setHeight(m_overflowScrollDelta.height() + deltaY); 383 } 384 } else { 385 // Not stretching at all yet. 386 if (pinnedInDirection(deltaX, deltaY)) { 387 if (fabsf(deltaY) >= fabsf(deltaX)) { 388 if (fabsf(deltaX) < rubberbandMinimumRequiredDeltaBeforeStretch) { 389 m_overflowScrollDelta.setWidth(m_overflowScrollDelta.width() + deltaX); 390 deltaX = 0.0; 391 } else 392 m_overflowScrollDelta.setWidth(m_overflowScrollDelta.width() + deltaX); 393 } 394 shouldStretch = true; 395 } 396 } 397 } 398 399 if (deltaX != 0.0 || deltaY != 0.0) { 400 if (!(shouldStretch || isVerticallyStretched || isHorizontallyStretched)) { 401 if (deltaY != 0) { 402 deltaY *= scrollWheelMultiplier(); 403 immediateScrollByDeltaY(deltaY); 404 } 405 if (deltaX != 0) { 406 deltaX *= scrollWheelMultiplier(); 407 immediateScrollByDeltaX(deltaX); 408 } 409 } else { 410 if (!allowsHorizontalStretching()) { 411 deltaX = 0.0; 412 eventCoallescedDeltaX = 0.0; 413 } else if ((deltaX != 0) && !isHorizontallyStretched && !pinnedInDirection(deltaX, 0)) { 414 deltaX *= scrollWheelMultiplier(); 415 416 m_scrollableArea->setConstrainsScrollingToContentEdge(false); 417 immediateScrollByDeltaX(deltaX); 418 m_scrollableArea->setConstrainsScrollingToContentEdge(true); 419 420 deltaX = 0.0; 421 } 422 423 if (!allowsVerticalStretching()) { 424 deltaY = 0.0; 425 eventCoallescedDeltaY = 0.0; 426 } else if ((deltaY != 0) && !isVerticallyStretched && !pinnedInDirection(0, deltaY)) { 427 deltaY *= scrollWheelMultiplier(); 428 429 m_scrollableArea->setConstrainsScrollingToContentEdge(false); 430 immediateScrollByDeltaY(deltaY); 431 m_scrollableArea->setConstrainsScrollingToContentEdge(true); 432 433 deltaY = 0.0; 434 } 435 436 IntSize stretchAmount = m_scrollableArea->overhangAmount(); 437 438 if (m_momentumScrollInProgress) { 439 if ((pinnedInDirection(eventCoallescedDeltaX, eventCoallescedDeltaY) || (fabsf(eventCoallescedDeltaX) + fabsf(eventCoallescedDeltaY) <= 0)) && m_lastMomemtumScrollTimestamp) { 440 m_ignoreMomentumScrolls = true; 441 m_momentumScrollInProgress = false; 442 snapRubberBand(); 443 } 444 } 445 446 m_stretchScrollForce.setWidth(m_stretchScrollForce.width() + deltaX); 447 m_stretchScrollForce.setHeight(m_stretchScrollForce.height() + deltaY); 448 449 FloatSize dampedDelta(ceil(elasticDeltaForReboundDelta(m_stretchScrollForce.width())), ceil(elasticDeltaForReboundDelta(m_stretchScrollForce.height()))); 450 FloatPoint origOrigin = m_scrollableArea->visibleContentRect().location() - stretchAmount; 451 FloatPoint newOrigin = origOrigin + dampedDelta; 452 453 if (origOrigin != newOrigin) { 454 m_scrollableArea->setConstrainsScrollingToContentEdge(false); 455 immediateScrollToPoint(newOrigin); 456 m_scrollableArea->setConstrainsScrollingToContentEdge(true); 457 } 458 } 459 } 460 461 if (m_momentumScrollInProgress && phase == PlatformWheelEventPhaseEnded) { 462 m_momentumScrollInProgress = false; 463 m_ignoreMomentumScrolls = false; 464 m_lastMomemtumScrollTimestamp = 0.0; 465 } 466 } 467 468 void ScrollAnimatorMac::beginScrollGesture() 469 { 470 m_inScrollGesture = true; 471 m_momentumScrollInProgress = false; 472 m_ignoreMomentumScrolls = false; 473 m_lastMomemtumScrollTimestamp = 0.0; 474 m_momentumVelocity = FloatSize(); 475 476 IntSize stretchAmount = m_scrollableArea->overhangAmount(); 477 m_stretchScrollForce.setWidth(reboundDeltaForElasticDelta(stretchAmount.width())); 478 m_stretchScrollForce.setHeight(reboundDeltaForElasticDelta(stretchAmount.height())); 479 480 m_overflowScrollDelta = FloatSize(); 481 482 if (m_snapRubberBandTimer.isActive()) 483 m_snapRubberBandTimer.stop(); 484 } 485 486 void ScrollAnimatorMac::endScrollGesture() 487 { 488 snapRubberBand(); 489 } 490 491 void ScrollAnimatorMac::snapRubberBand() 492 { 493 CFTimeInterval timeDelta = [[NSProcessInfo processInfo] systemUptime] - m_lastMomemtumScrollTimestamp; 494 if (m_lastMomemtumScrollTimestamp && timeDelta >= scrollVelocityZeroingTimeout) 495 m_momentumVelocity = FloatSize(); 496 497 m_inScrollGesture = false; 498 499 if (m_snapRubberBandTimer.isActive()) 500 return; 501 502 m_startTime = [NSDate timeIntervalSinceReferenceDate]; 503 m_startStretch = FloatSize(); 504 m_origOrigin = FloatPoint(); 505 m_origVelocity = FloatSize(); 506 507 m_snapRubberBandTimer.startRepeating(1.0/60.0); 508 } 509 510 static inline double roundTowardZero(double num) 511 { 512 return num > 0.0 ? ceil(num - 0.5) : floor(num + 0.5); 513 } 514 515 static inline double roundToDevicePixelTowardZero(double num) 516 { 517 double roundedNum = round(num); 518 if (fabs(num - roundedNum) < 0.125) { 519 num = roundedNum; 520 } 521 522 return roundTowardZero(num); 523 } 524 525 void ScrollAnimatorMac::snapRubberBandTimerFired(Timer<ScrollAnimatorMac>*) 526 { 527 if (!m_momentumScrollInProgress || m_ignoreMomentumScrolls) { 528 CFTimeInterval timeDelta = [NSDate timeIntervalSinceReferenceDate] - m_startTime; 529 530 if (m_startStretch == FloatSize()) { 531 m_startStretch = m_scrollableArea->overhangAmount(); 532 if (m_startStretch == FloatSize()) { 533 m_snapRubberBandTimer.stop(); 534 m_stretchScrollForce = FloatSize(); 535 m_startTime = 0; 536 m_startStretch = FloatSize(); 537 m_origOrigin = FloatPoint(); 538 m_origVelocity = FloatSize(); 539 540 return; 541 } 542 543 m_origOrigin = m_scrollableArea->visibleContentRect().location() - m_startStretch; 544 m_origVelocity = m_momentumVelocity; 545 546 // Just like normal scrolling, prefer vertical rubberbanding 547 if (fabsf(m_origVelocity.height()) >= fabsf(m_origVelocity.width())) 548 m_origVelocity.setWidth(0); 549 550 // Don't rubber-band horizontally if it's not possible to scroll horizontally 551 Scrollbar* hScroller = m_scrollableArea->horizontalScrollbar(); 552 if (!hScroller || !hScroller->enabled()) 553 m_origVelocity.setWidth(0); 554 555 // Don't rubber-band vertically if it's not possible to scroll horizontally 556 Scrollbar* vScroller = m_scrollableArea->verticalScrollbar(); 557 if (!vScroller || !vScroller->enabled()) 558 m_origVelocity.setHeight(0); 559 } 560 561 FloatPoint delta(roundToDevicePixelTowardZero(elasticDeltaForTimeDelta(m_startStretch.width(), -m_origVelocity.width(), timeDelta)), 562 roundToDevicePixelTowardZero(elasticDeltaForTimeDelta(m_startStretch.height(), -m_origVelocity.height(), timeDelta))); 563 564 if (fabs(delta.x()) >= 1.0 || fabs(delta.y()) >= 1.0) { 565 FloatPoint newOrigin = m_origOrigin + delta; 566 567 m_scrollableArea->setConstrainsScrollingToContentEdge(false); 568 immediateScrollToPoint(newOrigin); 569 m_scrollableArea->setConstrainsScrollingToContentEdge(true); 570 571 FloatSize newStretch = m_scrollableArea->overhangAmount(); 572 573 m_stretchScrollForce.setWidth(reboundDeltaForElasticDelta(newStretch.width())); 574 m_stretchScrollForce.setHeight(reboundDeltaForElasticDelta(newStretch.height())); 575 } else { 576 immediateScrollToPoint(m_origOrigin); 577 578 m_snapRubberBandTimer.stop(); 579 m_stretchScrollForce = FloatSize(); 580 581 m_startTime = 0; 582 m_startStretch = FloatSize(); 583 m_origOrigin = FloatPoint(); 584 m_origVelocity = FloatSize(); 585 } 586 } else { 587 m_startTime = [NSDate timeIntervalSinceReferenceDate]; 588 m_startStretch = FloatSize(); 589 } 590 } 591 #endif 592 180 593 } // namespace WebCore 181 594
Note: See TracChangeset
for help on using the changeset viewer.