1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
13 #include "mozilla/EventForwards.h"
14 #include "mozilla/TimeStamp.h"
16 template<class E
> struct already_AddRefed
;
33 class MultiTouchInput
;
34 class PanGestureInput
;
35 class PinchGestureInput
;
36 class TapGestureInput
;
38 // This looks unnecessary now, but as we add more and more classes that derive
39 // from InputType (eventually probably almost as many as *Events.h has), it
40 // will be more and more clear what's going on with a macro that shortens the
41 // definition of the RTTI functions.
42 #define INPUTDATA_AS_CHILD_TYPE(type, enumID) \
43 const type& As##type() const \
45 NS_ABORT_IF_FALSE(mInputType == enumID, "Invalid cast of InputData."); \
46 return (const type&) *this; \
50 NS_ABORT_IF_FALSE(mInputType == enumID, "Invalid cast of InputData."); \
51 return (type&) *this; \
54 /** Base input data class. Should never be instantiated. */
59 // Time in milliseconds that this data is relevant to. This only really
60 // matters when this data is used as an event. We use uint32_t instead of
61 // TimeStamp because it is easier to convert from WidgetInputEvent. The time
62 // is platform-specific but it in the case of B2G and Fennec it is since
65 // Set in parallel to mTime until we determine it is safe to drop
66 // platform-specific event times (see bug 77992).
71 INPUTDATA_AS_CHILD_TYPE(MultiTouchInput
, MULTITOUCH_INPUT
)
72 INPUTDATA_AS_CHILD_TYPE(PanGestureInput
, PANGESTURE_INPUT
)
73 INPUTDATA_AS_CHILD_TYPE(PinchGestureInput
, PINCHGESTURE_INPUT
)
74 INPUTDATA_AS_CHILD_TYPE(TapGestureInput
, TAPGESTURE_INPUT
)
81 InputData(InputType aInputType
, uint32_t aTime
, TimeStamp aTimeStamp
,
83 : mInputType(aInputType
),
85 mTimeStamp(aTimeStamp
),
94 * Data container for a single touch input. Similar to dom::Touch, but used in
95 * off-main-thread situations. This is more for just storing touch data, whereas
96 * dom::Touch is more useful for dispatching through the DOM (which can only
97 * happen on the main thread). dom::Touch also bears the problem of storing
98 * pointers to nsIWidget instances which can only be used on the main thread,
99 * so if instead we used dom::Touch and ever set these pointers
100 * off-main-thread, Bad Things Can Happen(tm).
102 * Note that this doesn't inherit from InputData because this itself is not an
103 * event. It is only a container/struct that should have any number of instances
104 * within a MultiTouchInput.
106 * fixme/bug 775746: Make dom::Touch inherit from this class.
108 class SingleTouchData
111 SingleTouchData(int32_t aIdentifier
,
112 ScreenIntPoint aScreenPoint
,
114 float aRotationAngle
,
116 : mIdentifier(aIdentifier
),
117 mScreenPoint(aScreenPoint
),
119 mRotationAngle(aRotationAngle
),
128 already_AddRefed
<dom::Touch
> ToNewDOMTouch() const;
130 // A unique number assigned to each SingleTouchData within a MultiTouchInput so
131 // that they can be easily distinguished when handling a touch start/move/end.
134 // Point on the screen that the touch hit, in device pixels. They are
135 // coordinates on the screen.
136 ScreenIntPoint mScreenPoint
;
138 // Radius that the touch covers, i.e. if you're using your thumb it will
139 // probably be larger than using your pinky, even with the same force.
140 // Radius can be different along x and y. For example, if you press down with
141 // your entire finger vertically, the y radius will be much larger than the x
145 float mRotationAngle
;
147 // How hard the screen is being pressed.
152 * Similar to WidgetTouchEvent, but for use off-main-thread. Also only stores a
153 * screen touch point instead of the many different coordinate spaces
154 * WidgetTouchEvent stores its touch point in. This includes a way to initialize
155 * itself from a WidgetTouchEvent by copying all relevant data over. Note that
156 * this copying from WidgetTouchEvent functionality can only be used on the main
159 * Stores an array of SingleTouchData.
161 class MultiTouchInput
: public InputData
172 MultiTouchInput(MultiTouchType aType
, uint32_t aTime
, TimeStamp aTimeStamp
,
173 Modifiers aModifiers
)
174 : InputData(MULTITOUCH_INPUT
, aTime
, aTimeStamp
, aModifiers
),
183 MultiTouchInput(const MultiTouchInput
& aOther
)
184 : InputData(MULTITOUCH_INPUT
, aOther
.mTime
,
185 aOther
.mTimeStamp
, aOther
.modifiers
)
186 , mType(aOther
.mType
)
188 mTouches
.AppendElements(aOther
.mTouches
);
191 explicit MultiTouchInput(const WidgetTouchEvent
& aTouchEvent
);
192 WidgetTouchEvent
ToWidgetTouchEvent(nsIWidget
* aWidget
) const;
194 // This conversion from WidgetMouseEvent to MultiTouchInput is needed because
195 // on the B2G emulator we can only receive mouse events, but we need to be
196 // able to pan correctly. To do this, we convert the events into a format that
197 // the panning code can handle. This code is very limited and only supports
198 // SingleTouchData. It also sends garbage for the identifier, radius, force
199 // and rotation angle.
200 explicit MultiTouchInput(const WidgetMouseEvent
& aMouseEvent
);
202 MultiTouchType mType
;
203 nsTArray
<SingleTouchData
> mTouches
;
207 * Encapsulation class for pan events, can be used off-main-thread.
208 * These events are currently only used for scrolling on desktop.
210 class PanGestureInput
: public InputData
215 // MayStart: Dispatched before any actual panning has occurred but when a
216 // pan gesture is probably about to start, for example when the user
217 // starts touching the touchpad. Should interrupt any ongoing APZ
218 // animation and can be used to trigger scrollability indicators (e.g.
219 // flashing overlay scrollbars).
222 // Cancelled: Dispatched after MayStart when no pan gesture is going to
223 // happen after all, for example when the user lifts their fingers from a
224 // touchpad without having done any scrolling.
225 PANGESTURE_CANCELLED
,
227 // Start: A pan gesture is starting.
228 // For devices that do not support the MayStart event type, this event can
229 // be used to interrupt ongoing APZ animations.
232 // Pan: The actual pan motion by mPanDisplacement.
235 // End: The pan gesture has ended, for example because the user has lifted
236 // their fingers from a touchpad after scrolling.
237 // Any potential momentum events fire after this event.
240 // The following momentum event types are used in order to control the pan
241 // momentum animation. Using these instead of our own animation ensures
242 // that the animation curve is OS native and that the animation stops
243 // reliably if it is cancelled by the user.
245 // MomentumStart: Dispatched between the End event of the actual
246 // user-controlled pan, and the first MomentumPan event of the momentum
248 PANGESTURE_MOMENTUMSTART
,
250 // MomentumPan: The actual momentum motion by mPanDisplacement.
251 PANGESTURE_MOMENTUMPAN
,
253 // MomentumEnd: The momentum animation has ended, for example because the
254 // momentum velocity has gone below the stopping threshold, or because the
255 // user has stopped the animation by putting their fingers on a touchpad.
256 PANGESTURE_MOMENTUMEND
259 PanGestureInput(PanGestureType aType
,
261 TimeStamp aTimeStamp
,
262 const ScreenPoint
& aPanStartPoint
,
263 const ScreenPoint
& aPanDisplacement
,
264 Modifiers aModifiers
)
265 : InputData(PANGESTURE_INPUT
, aTime
, aTimeStamp
, aModifiers
),
267 mPanStartPoint(aPanStartPoint
),
268 mPanDisplacement(aPanDisplacement
)
272 PanGestureType mType
;
273 ScreenPoint mPanStartPoint
;
275 // Only non-zero if mType is PANGESTURE_PAN or PANGESTURE_MOMENTUMPAN.
276 ScreenPoint mPanDisplacement
;
280 * Encapsulation class for pinch events. In general, these will be generated by
281 * a gesture listener by looking at SingleTouchData/MultiTouchInput instances and
282 * determining whether or not the user was trying to do a gesture.
284 class PinchGestureInput
: public InputData
287 enum PinchGestureType
294 PinchGestureInput(PinchGestureType aType
,
296 TimeStamp aTimeStamp
,
297 const ScreenPoint
& aFocusPoint
,
300 Modifiers aModifiers
)
301 : InputData(PINCHGESTURE_INPUT
, aTime
, aTimeStamp
, aModifiers
),
303 mFocusPoint(aFocusPoint
),
304 mCurrentSpan(aCurrentSpan
),
305 mPreviousSpan(aPreviousSpan
)
311 PinchGestureType mType
;
313 // Center point of the pinch gesture. That is, if there are two fingers on the
314 // screen, it is their midpoint. In the case of more than two fingers, the
315 // point is implementation-specific, but can for example be the midpoint
316 // between the very first and very last touch. This is in device pixels and
317 // are the coordinates on the screen of this midpoint.
318 ScreenPoint mFocusPoint
;
320 // The distance in device pixels (though as a float for increased precision
321 // and because it is the distance along both the x and y axis) between the
322 // touches responsible for the pinch gesture.
325 // The previous |mCurrentSpan| in the PinchGestureInput preceding this one.
326 // This is only really relevant during a PINCHGESTURE_SCALE because when it is
327 // of this type then there must have been a history of spans.
332 * Encapsulation class for tap events. In general, these will be generated by
333 * a gesture listener by looking at SingleTouchData/MultiTouchInput instances and
334 * determining whether or not the user was trying to do a gesture.
336 class TapGestureInput
: public InputData
344 TAPGESTURE_CONFIRMED
,
349 TapGestureInput(TapGestureType aType
,
351 TimeStamp aTimeStamp
,
352 const ScreenIntPoint
& aPoint
,
353 Modifiers aModifiers
)
354 : InputData(TAPGESTURE_INPUT
, aTime
, aTimeStamp
, aModifiers
),
362 TapGestureType mType
;
363 ScreenIntPoint mPoint
;
368 #endif // InputData_h__