Index: Source/platform/scroll/ScrollableArea.cpp |
diff --git a/Source/platform/scroll/ScrollableArea.cpp b/Source/platform/scroll/ScrollableArea.cpp |
index e5c157112e9bd4d49893d9e125a1f9a402d5d1f8..b0a8541838bbb8fb5572ff6015f1338d1bb37e89 100644 |
--- a/Source/platform/scroll/ScrollableArea.cpp |
+++ b/Source/platform/scroll/ScrollableArea.cpp |
@@ -34,6 +34,7 @@ |
#include "platform/graphics/GraphicsLayer.h" |
#include "platform/geometry/FloatPoint.h" |
+#include "platform/scroll/ProgrammaticScrollAnimator.h" |
#include "platform/scroll/ScrollbarTheme.h" |
#include "wtf/PassOwnPtr.h" |
@@ -48,7 +49,7 @@ struct SameSizeAsScrollableArea { |
virtual ~SameSizeAsScrollableArea(); |
unsigned damageBits : 2; |
IntRect scrollbarDamage[2]; |
- void* pointer; |
+ void* pointer[2]; |
unsigned bitfields : 16; |
IntPoint origin; |
}; |
@@ -95,6 +96,14 @@ ScrollAnimator* ScrollableArea::scrollAnimator() const |
return m_scrollAnimator.get(); |
} |
+ProgrammaticScrollAnimator* ScrollableArea::programmaticScrollAnimator() const |
+{ |
+ if (!m_programmaticScrollAnimator) |
+ m_programmaticScrollAnimator = ProgrammaticScrollAnimator::create(const_cast<ScrollableArea*>(this)); |
+ |
+ return m_programmaticScrollAnimator.get(); |
+} |
+ |
void ScrollableArea::setScrollOrigin(const IntPoint& origin) |
{ |
if (m_scrollOrigin != origin) { |
@@ -115,6 +124,8 @@ bool ScrollableArea::scroll(ScrollDirection direction, ScrollGranularity granula |
if (!userInputScrollable(orientation)) |
return false; |
+ cancelProgrammaticScrollAnimation(); |
+ |
float step = 0; |
switch (granularity) { |
case ScrollByLine: |
@@ -140,6 +151,7 @@ bool ScrollableArea::scroll(ScrollDirection direction, ScrollGranularity granula |
void ScrollableArea::scrollToOffsetWithoutAnimation(const FloatPoint& offset) |
{ |
+ cancelProgrammaticScrollAnimation(); |
scrollAnimator()->scrollToOffsetWithoutAnimation(offset); |
} |
@@ -151,6 +163,14 @@ void ScrollableArea::scrollToOffsetWithoutAnimation(ScrollbarOrientation orienta |
scrollToOffsetWithoutAnimation(FloatPoint(scrollAnimator()->currentPosition().x(), offset)); |
} |
+void ScrollableArea::programmaticallyScrollSmoothlyToOffset(const FloatPoint& offset) |
+{ |
+ if (ScrollAnimator* scrollAnimator = existingScrollAnimator()) |
+ scrollAnimator->cancelAnimations(); |
+ cancelProgrammaticScrollAnimation(); |
+ programmaticScrollAnimator()->animateToOffset(offset); |
+} |
+ |
void ScrollableArea::notifyScrollPositionChanged(const IntPoint& position) |
{ |
scrollPositionChanged(position); |
@@ -208,6 +228,7 @@ bool ScrollableArea::scrollBehaviorFromString(const String& behaviorString, Scro |
bool ScrollableArea::handleWheelEvent(const PlatformWheelEvent& wheelEvent) |
{ |
+ cancelProgrammaticScrollAnimation(); |
return scrollAnimator()->handleWheelEvent(wheelEvent); |
} |
@@ -222,6 +243,12 @@ void ScrollableArea::setScrollOffsetFromAnimation(const IntPoint& offset) |
scrollPositionChanged(offset); |
} |
+void ScrollableArea::setScrollOffsetFromProgrammaticAnimation(const IntPoint& offset) |
+{ |
+ scrollPositionChanged(offset); |
+ scrollAnimator()->setCurrentPosition(offset); |
+} |
+ |
void ScrollableArea::willStartLiveResize() |
{ |
if (m_inLiveResize) |
@@ -380,10 +407,45 @@ bool ScrollableArea::hasLayerForScrollCorner() const |
return layerForScrollCorner(); |
} |
-void ScrollableArea::serviceScrollAnimations() |
+void ScrollableArea::serviceScrollAnimations(double monotonicTime) |
{ |
if (ScrollAnimator* scrollAnimator = existingScrollAnimator()) |
scrollAnimator->serviceScrollAnimations(); |
+ if (ProgrammaticScrollAnimator* programmaticScrollAnimator = existingProgrammaticScrollAnimator()) |
+ programmaticScrollAnimator->tickAnimation(monotonicTime); |
+} |
+ |
+void ScrollableArea::notifyAnimationStarted(double monotonicTime) |
+{ |
+ programmaticScrollAnimator()->notifyAnimationStarted(monotonicTime); |
+} |
+ |
+void ScrollableArea::notifyAnimationFinished(double monotonicTime) |
+{ |
+ programmaticScrollAnimator()->notifyAnimationFinished(monotonicTime); |
+} |
+ |
+void ScrollableArea::layerForScrollingDidChange() |
+{ |
+ if (ProgrammaticScrollAnimator* programmaticScrollAnimator = existingProgrammaticScrollAnimator()) |
+ programmaticScrollAnimator->canUseCompositedScrollAnimationsDidChange(); |
+} |
+ |
+void ScrollableArea::requiresMainThreadScrollingDidChange() |
+{ |
+ if (ProgrammaticScrollAnimator* programmaticScrollAnimator = existingProgrammaticScrollAnimator()) |
+ programmaticScrollAnimator->canUseCompositedScrollAnimationsDidChange(); |
+} |
+ |
+bool ScrollableArea::canUseCompositedScrollAnimations() const |
+{ |
+ return compositedScrollAnimationsEnabled() && layerForScrolling() && !layerForScrolling()->platformLayer()->shouldScrollOnMainThread(); |
+} |
+ |
+void ScrollableArea::cancelProgrammaticScrollAnimation() |
+{ |
+ if (ProgrammaticScrollAnimator* programmaticScrollAnimator = existingProgrammaticScrollAnimator()) |
+ programmaticScrollAnimator->cancelAnimation(); |
} |
IntRect ScrollableArea::visibleContentRect(IncludeScrollbarsInRect scrollbarInclusion) const |