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 : #ifndef mozilla_layers_Overscroll_h
8 : #define mozilla_layers_Overscroll_h
9 :
10 : #include "AsyncPanZoomAnimation.h"
11 : #include "AsyncPanZoomController.h"
12 : #include "FrameMetrics.h"
13 : #include "mozilla/TimeStamp.h"
14 : #include "nsThreadUtils.h"
15 :
16 : namespace mozilla {
17 : namespace layers {
18 :
19 : // Animation used by GenericOverscrollEffect.
20 : class OverscrollAnimation: public AsyncPanZoomAnimation {
21 : public:
22 0 : explicit OverscrollAnimation(AsyncPanZoomController& aApzc, const ParentLayerPoint& aVelocity)
23 0 : : mApzc(aApzc)
24 : {
25 0 : mApzc.mX.StartOverscrollAnimation(aVelocity.x);
26 0 : mApzc.mY.StartOverscrollAnimation(aVelocity.y);
27 0 : }
28 0 : ~OverscrollAnimation()
29 0 : {
30 0 : mApzc.mX.EndOverscrollAnimation();
31 0 : mApzc.mY.EndOverscrollAnimation();
32 0 : }
33 :
34 0 : virtual bool DoSample(FrameMetrics& aFrameMetrics,
35 : const TimeDuration& aDelta) override
36 : {
37 : // Can't inline these variables due to short-circuit evaluation.
38 0 : bool continueX = mApzc.mX.SampleOverscrollAnimation(aDelta);
39 0 : bool continueY = mApzc.mY.SampleOverscrollAnimation(aDelta);
40 0 : if (!continueX && !continueY) {
41 : // If we got into overscroll from a fling, that fling did not request a
42 : // fling snap to avoid a resulting scrollTo from cancelling the overscroll
43 : // animation too early. We do still want to request a fling snap, though,
44 : // in case the end of the axis at which we're overscrolled is not a valid
45 : // snap point, so we request one now. If there are no snap points, this will
46 : // do nothing. If there are snap points, we'll get a scrollTo that snaps us
47 : // back to the nearest valid snap point.
48 : // The scroll snapping is done in a deferred task, otherwise the state
49 : // change to NOTHING caused by the overscroll animation ending would
50 : // clobber a possible state change to SMOOTH_SCROLL in ScrollSnap().
51 0 : mDeferredTasks.AppendElement(
52 0 : NewRunnableMethod("layers::AsyncPanZoomController::ScrollSnap",
53 0 : &mApzc,
54 0 : &AsyncPanZoomController::ScrollSnap));
55 0 : return false;
56 : }
57 0 : return true;
58 : }
59 :
60 0 : virtual bool WantsRepaints() override
61 : {
62 0 : return false;
63 : }
64 :
65 : private:
66 : AsyncPanZoomController& mApzc;
67 : };
68 :
69 : // Base class for different overscroll effects;
70 2 : class OverscrollEffectBase {
71 : public:
72 0 : virtual ~OverscrollEffectBase() {}
73 : virtual void ConsumeOverscroll(ParentLayerPoint& aOverscroll,
74 : bool aShouldOverscrollX,
75 : bool aShouldOverscrollY) = 0;
76 : virtual void HandleFlingOverscroll(const ParentLayerPoint& aVelocity) = 0;
77 : };
78 :
79 : // A generic overscroll effect, implemented by AsyncPanZoomController itself.
80 0 : class GenericOverscrollEffect : public OverscrollEffectBase {
81 : public:
82 2 : explicit GenericOverscrollEffect(AsyncPanZoomController& aApzc) : mApzc(aApzc) {}
83 :
84 0 : void ConsumeOverscroll(ParentLayerPoint& aOverscroll,
85 : bool aShouldOverscrollX,
86 : bool aShouldOverscrollY) override {
87 0 : if (aShouldOverscrollX) {
88 0 : mApzc.mX.OverscrollBy(aOverscroll.x);
89 0 : aOverscroll.x = 0;
90 : }
91 :
92 0 : if (aShouldOverscrollY) {
93 0 : mApzc.mY.OverscrollBy(aOverscroll.y);
94 0 : aOverscroll.y = 0;
95 : }
96 :
97 0 : if (aShouldOverscrollX || aShouldOverscrollY) {
98 0 : mApzc.ScheduleComposite();
99 : }
100 0 : }
101 :
102 0 : void HandleFlingOverscroll(const ParentLayerPoint& aVelocity) override {
103 0 : mApzc.StartOverscrollAnimation(aVelocity);
104 0 : }
105 :
106 : private:
107 : AsyncPanZoomController& mApzc;
108 : };
109 :
110 : // A widget-specific overscroll effect, implemented by the widget via
111 : // GeckoContentController.
112 : class WidgetOverscrollEffect : public OverscrollEffectBase {
113 : public:
114 : explicit WidgetOverscrollEffect(AsyncPanZoomController& aApzc) : mApzc(aApzc) {}
115 :
116 : void ConsumeOverscroll(ParentLayerPoint& aOverscroll,
117 : bool aShouldOverscrollX,
118 : bool aShouldOverscrollY) override {
119 : RefPtr<GeckoContentController> controller = mApzc.GetGeckoContentController();
120 : if (controller && (aShouldOverscrollX || aShouldOverscrollY)) {
121 : controller->UpdateOverscrollOffset(aOverscroll.x, aOverscroll.y, mApzc.IsRootContent());
122 : aOverscroll = ParentLayerPoint();
123 : }
124 : }
125 :
126 : void HandleFlingOverscroll(const ParentLayerPoint& aVelocity) override {
127 : RefPtr<GeckoContentController> controller = mApzc.GetGeckoContentController();
128 : if (controller) {
129 : controller->UpdateOverscrollVelocity(aVelocity.x, aVelocity.y, mApzc.IsRootContent());
130 : }
131 : }
132 :
133 : private:
134 : AsyncPanZoomController& mApzc;
135 : };
136 :
137 : } // namespace layers
138 : } // namespace mozilla
139 :
140 : #endif // mozilla_layers_Overscroll_h
|