1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/InputData.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,267 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef InputData_h__ 1.10 +#define InputData_h__ 1.11 + 1.12 +#include "nsDebug.h" 1.13 +#include "nsPoint.h" 1.14 +#include "nsTArray.h" 1.15 +#include "Units.h" 1.16 +#include "mozilla/EventForwards.h" 1.17 + 1.18 +namespace mozilla { 1.19 + 1.20 + 1.21 +enum InputType 1.22 +{ 1.23 + MULTITOUCH_INPUT, 1.24 + PINCHGESTURE_INPUT, 1.25 + TAPGESTURE_INPUT 1.26 +}; 1.27 + 1.28 +class MultiTouchInput; 1.29 +class PinchGestureInput; 1.30 +class TapGestureInput; 1.31 + 1.32 +// This looks unnecessary now, but as we add more and more classes that derive 1.33 +// from InputType (eventually probably almost as many as *Events.h has), it 1.34 +// will be more and more clear what's going on with a macro that shortens the 1.35 +// definition of the RTTI functions. 1.36 +#define INPUTDATA_AS_CHILD_TYPE(type, enumID) \ 1.37 + const type& As##type() const \ 1.38 + { \ 1.39 + NS_ABORT_IF_FALSE(mInputType == enumID, "Invalid cast of InputData."); \ 1.40 + return (const type&) *this; \ 1.41 + } 1.42 + 1.43 +/** Base input data class. Should never be instantiated. */ 1.44 +class InputData 1.45 +{ 1.46 +public: 1.47 + InputType mInputType; 1.48 + // Time in milliseconds that this data is relevant to. This only really 1.49 + // matters when this data is used as an event. We use uint32_t instead of 1.50 + // TimeStamp because it is easier to convert from WidgetInputEvent. The time 1.51 + // is platform-specific but it in the case of B2G and Fennec it is since 1.52 + // startup. 1.53 + uint32_t mTime; 1.54 + 1.55 + Modifiers modifiers; 1.56 + 1.57 + INPUTDATA_AS_CHILD_TYPE(MultiTouchInput, MULTITOUCH_INPUT) 1.58 + INPUTDATA_AS_CHILD_TYPE(PinchGestureInput, PINCHGESTURE_INPUT) 1.59 + INPUTDATA_AS_CHILD_TYPE(TapGestureInput, TAPGESTURE_INPUT) 1.60 + 1.61 + InputData() 1.62 + { 1.63 + } 1.64 + 1.65 +protected: 1.66 + InputData(InputType aInputType, uint32_t aTime, Modifiers aModifiers) 1.67 + : mInputType(aInputType), 1.68 + mTime(aTime), 1.69 + modifiers(aModifiers) 1.70 + { 1.71 + 1.72 + 1.73 + } 1.74 +}; 1.75 + 1.76 +/** 1.77 + * Data container for a single touch input. Similar to dom::Touch, but used in 1.78 + * off-main-thread situations. This is more for just storing touch data, whereas 1.79 + * dom::Touch is more useful for dispatching through the DOM (which can only 1.80 + * happen on the main thread). dom::Touch also bears the problem of storing 1.81 + * pointers to nsIWidget instances which can only be used on the main thread, 1.82 + * so if instead we used dom::Touch and ever set these pointers 1.83 + * off-main-thread, Bad Things Can Happen(tm). 1.84 + * 1.85 + * Note that this doesn't inherit from InputData because this itself is not an 1.86 + * event. It is only a container/struct that should have any number of instances 1.87 + * within a MultiTouchInput. 1.88 + * 1.89 + * fixme/bug 775746: Make dom::Touch inherit from this class. 1.90 + */ 1.91 +class SingleTouchData 1.92 +{ 1.93 +public: 1.94 + SingleTouchData(int32_t aIdentifier, 1.95 + ScreenIntPoint aScreenPoint, 1.96 + ScreenSize aRadius, 1.97 + float aRotationAngle, 1.98 + float aForce) 1.99 + : mIdentifier(aIdentifier), 1.100 + mScreenPoint(aScreenPoint), 1.101 + mRadius(aRadius), 1.102 + mRotationAngle(aRotationAngle), 1.103 + mForce(aForce) 1.104 + { 1.105 + 1.106 + 1.107 + } 1.108 + 1.109 + SingleTouchData() 1.110 + { 1.111 + } 1.112 + 1.113 + // A unique number assigned to each SingleTouchData within a MultiTouchInput so 1.114 + // that they can be easily distinguished when handling a touch start/move/end. 1.115 + int32_t mIdentifier; 1.116 + 1.117 + // Point on the screen that the touch hit, in device pixels. They are 1.118 + // coordinates on the screen. 1.119 + ScreenIntPoint mScreenPoint; 1.120 + 1.121 + // Radius that the touch covers, i.e. if you're using your thumb it will 1.122 + // probably be larger than using your pinky, even with the same force. 1.123 + // Radius can be different along x and y. For example, if you press down with 1.124 + // your entire finger vertically, the y radius will be much larger than the x 1.125 + // radius. 1.126 + ScreenSize mRadius; 1.127 + 1.128 + float mRotationAngle; 1.129 + 1.130 + // How hard the screen is being pressed. 1.131 + float mForce; 1.132 +}; 1.133 + 1.134 +/** 1.135 + * Similar to WidgetTouchEvent, but for use off-main-thread. Also only stores a 1.136 + * screen touch point instead of the many different coordinate spaces 1.137 + * WidgetTouchEvent stores its touch point in. This includes a way to initialize 1.138 + * itself from a WidgetTouchEvent by copying all relevant data over. Note that 1.139 + * this copying from WidgetTouchEvent functionality can only be used on the main 1.140 + * thread. 1.141 + * 1.142 + * Stores an array of SingleTouchData. 1.143 + */ 1.144 +class MultiTouchInput : public InputData 1.145 +{ 1.146 +public: 1.147 + enum MultiTouchType 1.148 + { 1.149 + MULTITOUCH_START, 1.150 + MULTITOUCH_MOVE, 1.151 + MULTITOUCH_END, 1.152 + MULTITOUCH_ENTER, 1.153 + MULTITOUCH_LEAVE, 1.154 + MULTITOUCH_CANCEL 1.155 + }; 1.156 + 1.157 + MultiTouchInput(MultiTouchType aType, uint32_t aTime, Modifiers aModifiers) 1.158 + : InputData(MULTITOUCH_INPUT, aTime, aModifiers), 1.159 + mType(aType) 1.160 + { 1.161 + 1.162 + 1.163 + } 1.164 + 1.165 + MultiTouchInput() 1.166 + { 1.167 + } 1.168 + 1.169 + MultiTouchInput(const WidgetTouchEvent& aTouchEvent); 1.170 + 1.171 + // This conversion from WidgetMouseEvent to MultiTouchInput is needed because 1.172 + // on the B2G emulator we can only receive mouse events, but we need to be 1.173 + // able to pan correctly. To do this, we convert the events into a format that 1.174 + // the panning code can handle. This code is very limited and only supports 1.175 + // SingleTouchData. It also sends garbage for the identifier, radius, force 1.176 + // and rotation angle. 1.177 + MultiTouchInput(const WidgetMouseEvent& aMouseEvent); 1.178 + 1.179 + MultiTouchType mType; 1.180 + nsTArray<SingleTouchData> mTouches; 1.181 +}; 1.182 + 1.183 +/** 1.184 + * Encapsulation class for pinch events. In general, these will be generated by 1.185 + * a gesture listener by looking at SingleTouchData/MultiTouchInput instances and 1.186 + * determining whether or not the user was trying to do a gesture. 1.187 + */ 1.188 +class PinchGestureInput : public InputData 1.189 +{ 1.190 +public: 1.191 + enum PinchGestureType 1.192 + { 1.193 + PINCHGESTURE_START, 1.194 + PINCHGESTURE_SCALE, 1.195 + PINCHGESTURE_END 1.196 + }; 1.197 + 1.198 + PinchGestureInput(PinchGestureType aType, 1.199 + uint32_t aTime, 1.200 + const ScreenPoint& aFocusPoint, 1.201 + float aCurrentSpan, 1.202 + float aPreviousSpan, 1.203 + Modifiers aModifiers) 1.204 + : InputData(PINCHGESTURE_INPUT, aTime, aModifiers), 1.205 + mType(aType), 1.206 + mFocusPoint(aFocusPoint), 1.207 + mCurrentSpan(aCurrentSpan), 1.208 + mPreviousSpan(aPreviousSpan) 1.209 + { 1.210 + 1.211 + 1.212 + } 1.213 + 1.214 + PinchGestureType mType; 1.215 + 1.216 + // Center point of the pinch gesture. That is, if there are two fingers on the 1.217 + // screen, it is their midpoint. In the case of more than two fingers, the 1.218 + // point is implementation-specific, but can for example be the midpoint 1.219 + // between the very first and very last touch. This is in device pixels and 1.220 + // are the coordinates on the screen of this midpoint. 1.221 + ScreenPoint mFocusPoint; 1.222 + 1.223 + // The distance in device pixels (though as a float for increased precision 1.224 + // and because it is the distance along both the x and y axis) between the 1.225 + // touches responsible for the pinch gesture. 1.226 + float mCurrentSpan; 1.227 + 1.228 + // The previous |mCurrentSpan| in the PinchGestureInput preceding this one. 1.229 + // This is only really relevant during a PINCHGESTURE_SCALE because when it is 1.230 + // of this type then there must have been a history of spans. 1.231 + float mPreviousSpan; 1.232 +}; 1.233 + 1.234 +/** 1.235 + * Encapsulation class for tap events. In general, these will be generated by 1.236 + * a gesture listener by looking at SingleTouchData/MultiTouchInput instances and 1.237 + * determining whether or not the user was trying to do a gesture. 1.238 + */ 1.239 +class TapGestureInput : public InputData 1.240 +{ 1.241 +public: 1.242 + enum TapGestureType 1.243 + { 1.244 + TAPGESTURE_LONG, 1.245 + TAPGESTURE_LONG_UP, 1.246 + TAPGESTURE_UP, 1.247 + TAPGESTURE_CONFIRMED, 1.248 + TAPGESTURE_DOUBLE, 1.249 + TAPGESTURE_CANCEL 1.250 + }; 1.251 + 1.252 + TapGestureInput(TapGestureType aType, 1.253 + uint32_t aTime, 1.254 + const ScreenIntPoint& aPoint, 1.255 + Modifiers aModifiers) 1.256 + : InputData(TAPGESTURE_INPUT, aTime, aModifiers), 1.257 + mType(aType), 1.258 + mPoint(aPoint) 1.259 + { 1.260 + 1.261 + 1.262 + } 1.263 + 1.264 + TapGestureType mType; 1.265 + ScreenIntPoint mPoint; 1.266 +}; 1.267 + 1.268 +} 1.269 + 1.270 +#endif // InputData_h__