Scroll-snap points needs to be updated during programmatic scrolls
authorbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 May 2015 19:37:50 +0000 (19:37 +0000)
committerbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 May 2015 19:37:50 +0000 (19:37 +0000)
https://bugs.webkit.org/show_bug.cgi?id=145216
<rdar://problem/21051039>

Reviewed by Dean Jackson.

Whenever we adjust the current scroll position, make sure we also update the current
active scroll snap offset index (if applicable).

* platform/ScrollAnimator.cpp:
(WebCore::ScrollAnimator::scrollToOffsetWithoutAnimation): Call the new 'updateActiveScrollSnapIndexForOffset'
method after moving to a new position.
(WebCore::ScrollAnimator::setCurrentPosition): Ditto.
(WebCore::ScrollAnimator::updateActiveScrollSnapIndexForOffset): New method. Asks the scroll controller to
identify the closest scroll snap offset index. If it finds something relevant, update the ScrollableArea state
to track these new values.
* platform/ScrollAnimator.h:
* platform/cocoa/ScrollController.h:
(WebCore::ScrollController::activeScrollSnapIndexDidChange):
(WebCore::ScrollController::setScrollSnapIndexDidChange):
* platform/cocoa/ScrollController.mm:
(WebCore::ScrollController::setNearestScrollSnapIndexForAxisAndOffset): Added. Find the closest relevant scroll snap offset
index for the given scroll offset, and update the internal scroll snap state to reflect it.
(WebCore::ScrollController::setActiveScrollSnapIndicesForOffset): Given the x and y offset for a scroll,
set the relevant scroll snap offset indices.
* platform/mac/ScrollAnimatorMac.mm:
(WebCore::ScrollAnimatorMac::immediateScrollTo): Call the new 'updateActiveScrollSnapIndexForOffset' method
after moving to a new position.
(WebCore::ScrollAnimatorMac::immediateScrollBy): Ditto.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@184728 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/ScrollAnimator.cpp
Source/WebCore/platform/ScrollAnimator.h
Source/WebCore/platform/cocoa/ScrollController.h
Source/WebCore/platform/cocoa/ScrollController.mm
Source/WebCore/platform/mac/ScrollAnimatorMac.mm

index 2213cac..acbf9a1 100644 (file)
@@ -1,3 +1,35 @@
+2015-05-21  Brent Fulgham  <bfulgham@apple.com>
+
+        Scroll-snap points needs to be updated during programmatic scrolls
+        https://bugs.webkit.org/show_bug.cgi?id=145216
+        <rdar://problem/21051039>
+
+        Reviewed by Dean Jackson.
+
+        Whenever we adjust the current scroll position, make sure we also update the current
+        active scroll snap offset index (if applicable).
+
+        * platform/ScrollAnimator.cpp:
+        (WebCore::ScrollAnimator::scrollToOffsetWithoutAnimation): Call the new 'updateActiveScrollSnapIndexForOffset'
+        method after moving to a new position.
+        (WebCore::ScrollAnimator::setCurrentPosition): Ditto.
+        (WebCore::ScrollAnimator::updateActiveScrollSnapIndexForOffset): New method. Asks the scroll controller to
+        identify the closest scroll snap offset index. If it finds something relevant, update the ScrollableArea state
+        to track these new values.
+        * platform/ScrollAnimator.h:
+        * platform/cocoa/ScrollController.h:
+        (WebCore::ScrollController::activeScrollSnapIndexDidChange):
+        (WebCore::ScrollController::setScrollSnapIndexDidChange):
+        * platform/cocoa/ScrollController.mm:
+        (WebCore::ScrollController::setNearestScrollSnapIndexForAxisAndOffset): Added. Find the closest relevant scroll snap offset
+        index for the given scroll offset, and update the internal scroll snap state to reflect it.
+        (WebCore::ScrollController::setActiveScrollSnapIndicesForOffset): Given the x and y offset for a scroll,
+        set the relevant scroll snap offset indices.
+        * platform/mac/ScrollAnimatorMac.mm:
+        (WebCore::ScrollAnimatorMac::immediateScrollTo): Call the new 'updateActiveScrollSnapIndexForOffset' method
+        after moving to a new position.
+        (WebCore::ScrollAnimatorMac::immediateScrollBy): Ditto.
+
 2015-05-21  Matt Baker  <mattbaker@apple.com>
 
         Unreviewed build fix.
index 66b11cf..c9dac12 100644 (file)
@@ -80,6 +80,7 @@ void ScrollAnimator::scrollToOffsetWithoutAnimation(const FloatPoint& offset)
     m_currentPosX = offset.x();
     m_currentPosY = offset.y();
     notifyPositionChanged(delta);
+    updateActiveScrollSnapIndexForOffset();
 }
 
 #if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
@@ -168,6 +169,7 @@ void ScrollAnimator::setCurrentPosition(const FloatPoint& position)
 {
     m_currentPosX = position.x();
     m_currentPosY = position.y();
+    updateActiveScrollSnapIndexForOffset();
 }
 
 FloatPoint ScrollAnimator::currentPosition() const
@@ -175,6 +177,17 @@ FloatPoint ScrollAnimator::currentPosition() const
     return FloatPoint(m_currentPosX, m_currentPosY);
 }
 
+void ScrollAnimator::updateActiveScrollSnapIndexForOffset()
+{
+#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
+    m_scrollController.setActiveScrollSnapIndicesForOffset(m_currentPosX, m_currentPosY);
+    if (m_scrollController.activeScrollSnapIndexDidChange()) {
+        m_scrollableArea.setCurrentHorizontalSnapPointIndex(m_scrollController.activeScrollSnapIndexForAxis(ScrollEventAxis::Horizontal));
+        m_scrollableArea.setCurrentVerticalSnapPointIndex(m_scrollController.activeScrollSnapIndexForAxis(ScrollEventAxis::Vertical));
+    }
+#endif
+}
+
 void ScrollAnimator::notifyPositionChanged(const FloatSize& delta)
 {
     UNUSED_PARAM(delta);
index aec89dd..38635d0 100644 (file)
@@ -137,6 +137,7 @@ public:
 
 protected:
     virtual void notifyPositionChanged(const FloatSize& delta);
+    void updateActiveScrollSnapIndexForOffset();
 
     ScrollableArea& m_scrollableArea;
     RefPtr<WheelEventTestTrigger> m_wheelEventTestTrigger;
index 0fb7351..e5cf421 100644 (file)
@@ -122,6 +122,7 @@ public:
     void updateScrollSnapPoints(ScrollEventAxis, const Vector<LayoutUnit>&);
     unsigned activeScrollSnapIndexForAxis(ScrollEventAxis) const;
     void setActiveScrollSnapIndexForAxis(ScrollEventAxis, unsigned);
+    void setActiveScrollSnapIndicesForOffset(int x, int y);
     bool activeScrollSnapIndexDidChange() const { return m_activeScrollSnapIndexDidChange; }
     void setScrollSnapIndexDidChange(bool state) { m_activeScrollSnapIndexDidChange = state; }
     bool hasActiveScrollSnapTimerForAxis(ScrollEventAxis) const;
@@ -144,6 +145,7 @@ private:
     LayoutUnit scrollOffsetOnAxis(ScrollEventAxis) const;
     void processWheelEventForScrollSnapOnAxis(ScrollEventAxis, const PlatformWheelEvent&);
     bool shouldOverrideWheelEvent(ScrollEventAxis, const PlatformWheelEvent&) const;
+    void setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis, int);
 
     void beginScrollSnapAnimation(ScrollEventAxis, ScrollSnapState);
     void scrollSnapAnimationUpdate(ScrollEventAxis);
index 1182afd..6feffa9 100644 (file)
@@ -719,6 +719,31 @@ void ScrollController::setActiveScrollSnapIndexForAxis(ScrollEventAxis axis, uns
     snapState->m_activeSnapIndex = index;
 }
 
+void ScrollController::setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis axis, int offset)
+{
+    float scaleFactor = m_client.pageScaleFactor();
+    ScrollSnapAnimatorState& snapState = scrollSnapPointState(axis);
+    
+    LayoutUnit clampedOffset = std::min(std::max(LayoutUnit(offset / scaleFactor), snapState.m_snapOffsets.first()), snapState.m_snapOffsets.last());
+
+    unsigned activeIndex = 0;
+    (void)closestSnapOffset<LayoutUnit, float>(snapState.m_snapOffsets, clampedOffset, 0, activeIndex);
+
+    if (activeIndex == snapState.m_activeSnapIndex)
+        return;
+
+    m_activeScrollSnapIndexDidChange = true;
+    snapState.m_activeSnapIndex = activeIndex;
+}
+
+void ScrollController::setActiveScrollSnapIndicesForOffset(int x, int y)
+{
+    if (m_horizontalScrollSnapState)
+        setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis::Horizontal, x);
+    if (m_verticalScrollSnapState)
+        setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis::Vertical, y);
+}
+
 void ScrollController::beginScrollSnapAnimation(ScrollEventAxis axis, ScrollSnapState newState)
 {
     ASSERT(newState == ScrollSnapState::Gliding || newState == ScrollSnapState::Snapping);
index 7263cec..77cd06d 100644 (file)
@@ -758,6 +758,7 @@ void ScrollAnimatorMac::immediateScrollTo(const FloatPoint& newPosition)
     m_currentPosX = adjustedPosition.x();
     m_currentPosY = adjustedPosition.y();
     notifyPositionChanged(delta);
+    updateActiveScrollSnapIndexForOffset();
 }
 
 bool ScrollAnimatorMac::isRubberBandInProgress() const
@@ -1278,6 +1279,7 @@ void ScrollAnimatorMac::immediateScrollBy(const FloatSize& delta)
     m_currentPosX = newPos.x();
     m_currentPosY = newPos.y();
     notifyPositionChanged(adjustedDelta);
+    updateActiveScrollSnapIndexForOffset();
 }
 #endif