Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set sw=2 ts=8 et tw=80 : */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "GenericScrollAnimation.h"
8 :
9 : #include "AsyncPanZoomController.h"
10 : #include "gfxPrefs.h"
11 : #include "nsPoint.h"
12 :
13 : namespace mozilla {
14 : namespace layers {
15 :
16 0 : GenericScrollAnimation::GenericScrollAnimation(AsyncPanZoomController& aApzc,
17 0 : const nsPoint& aInitialPosition)
18 : : AsyncScrollBase(aInitialPosition)
19 : , mApzc(aApzc)
20 : , mFinalDestination(aInitialPosition)
21 0 : , mForceVerticalOverscroll(false)
22 : {
23 0 : }
24 :
25 : void
26 0 : GenericScrollAnimation::UpdateDelta(TimeStamp aTime, nsPoint aDelta, const nsSize& aCurrentVelocity)
27 : {
28 0 : mFinalDestination += aDelta;
29 :
30 0 : Update(aTime, aCurrentVelocity);
31 0 : }
32 :
33 : void
34 0 : GenericScrollAnimation::UpdateDestination(TimeStamp aTime, nsPoint aDestination, const nsSize& aCurrentVelocity)
35 : {
36 0 : mFinalDestination = aDestination;
37 :
38 0 : Update(aTime, aCurrentVelocity);
39 0 : }
40 :
41 : void
42 0 : GenericScrollAnimation::Update(TimeStamp aTime, const nsSize& aCurrentVelocity)
43 : {
44 0 : if (mIsFirstIteration) {
45 0 : InitializeHistory(aTime);
46 : }
47 :
48 : // Clamp the final destination to the scrollable area.
49 0 : CSSPoint clamped = CSSPoint::FromAppUnits(mFinalDestination);
50 0 : clamped.x = mApzc.mX.ClampOriginToScrollableRect(clamped.x);
51 0 : clamped.y = mApzc.mY.ClampOriginToScrollableRect(clamped.y);
52 0 : mFinalDestination = CSSPoint::ToAppUnits(clamped);
53 :
54 0 : AsyncScrollBase::Update(aTime, mFinalDestination, aCurrentVelocity);
55 0 : }
56 :
57 : bool
58 0 : GenericScrollAnimation::DoSample(FrameMetrics& aFrameMetrics, const TimeDuration& aDelta)
59 : {
60 0 : TimeStamp now = mApzc.GetFrameTime();
61 0 : CSSToParentLayerScale2D zoom = aFrameMetrics.GetZoom();
62 :
63 : // If the animation is finished, make sure the final position is correct by
64 : // using one last displacement. Otherwise, compute the delta via the timing
65 : // function as normal.
66 0 : bool finished = IsFinished(now);
67 : nsPoint sampledDest = finished
68 : ? mDestination
69 0 : : PositionAt(now);
70 : ParentLayerPoint displacement =
71 0 : (CSSPoint::FromAppUnits(sampledDest) - aFrameMetrics.GetScrollOffset()) * zoom;
72 :
73 0 : if (finished) {
74 0 : mApzc.mX.SetVelocity(0);
75 0 : mApzc.mY.SetVelocity(0);
76 0 : } else if (!IsZero(displacement)) {
77 : // Velocity is measured in ParentLayerCoords / Milliseconds
78 0 : float xVelocity = displacement.x / aDelta.ToMilliseconds();
79 0 : float yVelocity = displacement.y / aDelta.ToMilliseconds();
80 0 : mApzc.mX.SetVelocity(xVelocity);
81 0 : mApzc.mY.SetVelocity(yVelocity);
82 : }
83 :
84 : // Note: we ignore overscroll for generic animations.
85 0 : ParentLayerPoint adjustedOffset, overscroll;
86 0 : mApzc.mX.AdjustDisplacement(displacement.x, adjustedOffset.x, overscroll.x);
87 0 : mApzc.mY.AdjustDisplacement(displacement.y, adjustedOffset.y, overscroll.y,
88 0 : mForceVerticalOverscroll);
89 :
90 : // If we expected to scroll, but there's no more scroll range on either axis,
91 : // then end the animation early. Note that the initial displacement could be 0
92 : // if the compositor ran very quickly (<1ms) after the animation was created.
93 : // When that happens we want to make sure the animation continues.
94 0 : if (!IsZero(displacement) && IsZero(adjustedOffset)) {
95 : // Nothing more to do - end the animation.
96 0 : return false;
97 : }
98 :
99 0 : aFrameMetrics.ScrollBy(adjustedOffset / zoom);
100 0 : return !finished;
101 : }
102 :
103 : } // namespace layers
104 : } // namespace mozilla
|