Source code

Revision control

Other Tools

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