|
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_Axis_h |
|
8 #define mozilla_layers_Axis_h |
|
9 |
|
10 #include <sys/types.h> // for int32_t |
|
11 #include "Units.h" // for CSSRect, CSSPoint |
|
12 #include "mozilla/TimeStamp.h" // for TimeDuration |
|
13 #include "nsTArray.h" // for nsTArray |
|
14 |
|
15 namespace mozilla { |
|
16 namespace layers { |
|
17 |
|
18 const float EPSILON = 0.0001f; |
|
19 |
|
20 class AsyncPanZoomController; |
|
21 |
|
22 /** |
|
23 * Helper class to maintain each axis of movement (X,Y) for panning and zooming. |
|
24 * Note that everything here is specific to one axis; that is, the X axis knows |
|
25 * nothing about the Y axis and vice versa. |
|
26 */ |
|
27 class Axis { |
|
28 public: |
|
29 Axis(AsyncPanZoomController* aAsyncPanZoomController); |
|
30 |
|
31 enum Overscroll { |
|
32 // Overscroll is not happening at all. |
|
33 OVERSCROLL_NONE = 0, |
|
34 // Overscroll is happening in the negative direction. This means either to |
|
35 // the left or to the top depending on the axis. |
|
36 OVERSCROLL_MINUS, |
|
37 // Overscroll is happening in the positive direction. This means either to |
|
38 // the right or to the bottom depending on the axis. |
|
39 OVERSCROLL_PLUS, |
|
40 // Overscroll is happening both ways. This only means something when the |
|
41 // page is scaled out to a smaller size than the viewport. |
|
42 OVERSCROLL_BOTH |
|
43 }; |
|
44 |
|
45 /** |
|
46 * Notify this Axis that a new touch has been received, including a time delta |
|
47 * indicating how long it has been since the previous one. This triggers a |
|
48 * recalculation of velocity. |
|
49 */ |
|
50 void UpdateWithTouchAtDevicePoint(int32_t aPos, const TimeDuration& aTimeDelta); |
|
51 |
|
52 /** |
|
53 * Notify this Axis that a touch has begun, i.e. the user has put their finger |
|
54 * on the screen but has not yet tried to pan. |
|
55 */ |
|
56 void StartTouch(int32_t aPos); |
|
57 |
|
58 /** |
|
59 * Notify this Axis that a touch has ended gracefully. This may perform |
|
60 * recalculations of the axis velocity. |
|
61 */ |
|
62 void EndTouch(); |
|
63 |
|
64 /** |
|
65 * Notify this Axis that a touch has ended forcefully. Useful for stopping |
|
66 * flings when a user puts their finger down in the middle of one (i.e. to |
|
67 * stop a previous touch including its fling so that a new one can take its |
|
68 * place). |
|
69 */ |
|
70 void CancelTouch(); |
|
71 |
|
72 /** |
|
73 * Takes a requested displacement to the position of this axis, and adjusts it |
|
74 * to account for overscroll (which might decrease the displacement; this is |
|
75 * to prevent the viewport from overscrolling the page rect), and axis locking |
|
76 * (which might prevent any displacement from happening). If overscroll |
|
77 * ocurred, its amount is written to |aOverscrollAmountOut|. |
|
78 * The adjusted displacement is returned. |
|
79 */ |
|
80 float AdjustDisplacement(float aDisplacement, float& aOverscrollAmountOut); |
|
81 |
|
82 /** |
|
83 * Gets the distance between the starting position of the touch supplied in |
|
84 * startTouch() and the current touch from the last |
|
85 * updateWithTouchAtDevicePoint(). |
|
86 */ |
|
87 float PanDistance(); |
|
88 |
|
89 /** |
|
90 * Gets the distance between the starting position of the touch supplied in |
|
91 * startTouch() and the supplied position. |
|
92 */ |
|
93 float PanDistance(float aPos); |
|
94 |
|
95 /** |
|
96 * Applies friction during a fling, or cancels the fling if the velocity is |
|
97 * too low. Returns true if the fling should continue to another frame, or |
|
98 * false if it should end. |aDelta| is the amount of time that has passed |
|
99 * since the last time friction was applied. |
|
100 */ |
|
101 bool FlingApplyFrictionOrCancel(const TimeDuration& aDelta); |
|
102 |
|
103 /* |
|
104 * Returns true if the page is zoomed in to some degree along this axis such that scrolling is |
|
105 * possible and this axis has not been scroll locked while panning. Otherwise, returns false. |
|
106 */ |
|
107 bool Scrollable(); |
|
108 |
|
109 void SetAxisLocked(bool aAxisLocked) { mAxisLocked = aAxisLocked; } |
|
110 |
|
111 /** |
|
112 * Gets the overscroll state of the axis in its current position. |
|
113 */ |
|
114 Overscroll GetOverscroll(); |
|
115 |
|
116 /** |
|
117 * If there is overscroll, returns the amount. Sign depends on in what |
|
118 * direction it is overscrolling. Positive excess means that it is |
|
119 * overscrolling in the positive direction, whereas negative excess means |
|
120 * that it is overscrolling in the negative direction. If there is overscroll |
|
121 * in both directions, this returns 0; it assumes that you check |
|
122 * GetOverscroll() first. |
|
123 */ |
|
124 float GetExcess(); |
|
125 |
|
126 /** |
|
127 * Gets the raw velocity of this axis at this moment. |
|
128 */ |
|
129 float GetVelocity(); |
|
130 |
|
131 /** |
|
132 * Sets the raw velocity of this axis at this moment. |
|
133 * Intended to be called only when the axis "takes over" a velocity from |
|
134 * another APZC, in which case there are no touch points available to call |
|
135 * UpdateWithTouchAtDevicePoint. In other circumstances, |
|
136 * UpdateWithTouchAtDevicePoint should be used and the velocity calculated |
|
137 * there. |
|
138 */ |
|
139 void SetVelocity(float aVelocity); |
|
140 |
|
141 /** |
|
142 * Gets the overscroll state of the axis given an additional displacement. |
|
143 * That is to say, if the given displacement is applied, this will tell you |
|
144 * whether or not it will overscroll, and in what direction. |
|
145 */ |
|
146 Overscroll DisplacementWillOverscroll(float aDisplacement); |
|
147 |
|
148 /** |
|
149 * If a displacement will overscroll the axis, this returns the amount and in |
|
150 * what direction. Similar to GetExcess() but takes a displacement to apply. |
|
151 */ |
|
152 float DisplacementWillOverscrollAmount(float aDisplacement); |
|
153 |
|
154 /** |
|
155 * If a scale will overscroll the axis, this returns the amount and in what |
|
156 * direction. Similar to GetExcess() but takes a displacement to apply. |
|
157 * |
|
158 * |aFocus| is the point at which the scale is focused at. We will offset the |
|
159 * scroll offset in such a way that it remains in the same place on the page |
|
160 * relative. |
|
161 */ |
|
162 float ScaleWillOverscrollAmount(float aScale, float aFocus); |
|
163 |
|
164 /** |
|
165 * Checks if an axis will overscroll in both directions by computing the |
|
166 * content rect and checking that its height/width (depending on the axis) |
|
167 * does not overextend past the viewport. |
|
168 * |
|
169 * This gets called by ScaleWillOverscroll(). |
|
170 */ |
|
171 bool ScaleWillOverscrollBothSides(float aScale); |
|
172 |
|
173 /** |
|
174 * Returns whether there is room to pan on this axis in either direction. |
|
175 */ |
|
176 bool HasRoomToPan() const; |
|
177 |
|
178 float GetOrigin() const; |
|
179 float GetCompositionLength() const; |
|
180 float GetPageStart() const; |
|
181 float GetPageLength() const; |
|
182 float GetCompositionEnd() const; |
|
183 float GetPageEnd() const; |
|
184 |
|
185 int32_t GetPos() const { return mPos; } |
|
186 |
|
187 virtual float GetPointOffset(const CSSPoint& aPoint) const = 0; |
|
188 virtual float GetRectLength(const CSSRect& aRect) const = 0; |
|
189 virtual float GetRectOffset(const CSSRect& aRect) const = 0; |
|
190 |
|
191 protected: |
|
192 int32_t mPos; |
|
193 int32_t mStartPos; |
|
194 float mVelocity; |
|
195 bool mAxisLocked; // Whether movement on this axis is locked. |
|
196 AsyncPanZoomController* mAsyncPanZoomController; |
|
197 nsTArray<float> mVelocityQueue; |
|
198 }; |
|
199 |
|
200 class AxisX : public Axis { |
|
201 public: |
|
202 AxisX(AsyncPanZoomController* mAsyncPanZoomController); |
|
203 virtual float GetPointOffset(const CSSPoint& aPoint) const; |
|
204 virtual float GetRectLength(const CSSRect& aRect) const; |
|
205 virtual float GetRectOffset(const CSSRect& aRect) const; |
|
206 }; |
|
207 |
|
208 class AxisY : public Axis { |
|
209 public: |
|
210 AxisY(AsyncPanZoomController* mAsyncPanZoomController); |
|
211 virtual float GetPointOffset(const CSSPoint& aPoint) const; |
|
212 virtual float GetRectLength(const CSSRect& aRect) const; |
|
213 virtual float GetRectOffset(const CSSRect& aRect) const; |
|
214 }; |
|
215 |
|
216 } |
|
217 } |
|
218 |
|
219 #endif |