1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef UI_EVENTS_GESTURES_GESTURE_SEQUENCE_H_ 6 #define UI_EVENTS_GESTURES_GESTURE_SEQUENCE_H_ 7 8 #include "base/timer/timer.h" 9 #include "ui/events/event_constants.h" 10 #include "ui/events/gesture_event_details.h" 11 #include "ui/events/gestures/gesture_point.h" 12 #include "ui/events/gestures/gesture_recognizer.h" 13 #include "ui/gfx/rect.h" 14 15 namespace ui { 16 class TouchEvent; 17 class GestureEvent; 18 19 // Gesture state. 20 enum GestureState { 21 GS_NO_GESTURE, 22 GS_PENDING_SYNTHETIC_CLICK, 23 // One finger is down: tap could occur, but scroll cannot until the number of 24 // active touch points changes. 25 GS_PENDING_SYNTHETIC_CLICK_NO_SCROLL, 26 // One finger is down: no gestures can occur until the number of active touch 27 // points changes. 28 GS_SYNTHETIC_CLICK_ABORTED, 29 GS_SCROLL, 30 GS_PINCH, 31 GS_PENDING_TWO_FINGER_TAP, 32 GS_PENDING_TWO_FINGER_TAP_NO_PINCH, 33 GS_PENDING_PINCH, 34 GS_PENDING_PINCH_NO_PINCH, 35 }; 36 37 enum ScrollType { 38 ST_FREE, 39 ST_HORIZONTAL, 40 ST_VERTICAL, 41 }; 42 43 enum IsFirstScroll { 44 FS_FIRST_SCROLL, 45 FS_NOT_FIRST_SCROLL, 46 }; 47 48 // Delegates dispatch of gesture events for which the GestureSequence does not 49 // have enough context to dispatch itself. 50 class EVENTS_EXPORT GestureSequenceDelegate { 51 public: 52 virtual void DispatchPostponedGestureEvent(GestureEvent* event) = 0; 53 54 protected: 55 virtual ~GestureSequenceDelegate() {} 56 }; 57 58 // A GestureSequence recognizes gestures from touch sequences. 59 class EVENTS_EXPORT GestureSequence { 60 public: 61 // Maximum number of points in a single gesture. 62 static const int kMaxGesturePoints = 12; 63 64 explicit GestureSequence(GestureSequenceDelegate* delegate); 65 virtual ~GestureSequence(); 66 67 typedef GestureRecognizer::Gestures Gestures; 68 69 // Invoked for each touch event that could contribute to the current gesture. 70 // Returns list of zero or more GestureEvents identified after processing 71 // TouchEvent. 72 // Caller would be responsible for freeing up Gestures. 73 virtual Gestures* ProcessTouchEventForGesture(const TouchEvent& event, 74 EventResult status); 75 const GesturePoint* points() const { return points_; } 76 int point_count() const { return point_count_; } 77 78 const gfx::PointF& last_touch_location() const { 79 return last_touch_location_; 80 } 81 82 protected: 83 virtual base::OneShotTimer<GestureSequence>* CreateTimer(); 84 base::OneShotTimer<GestureSequence>* GetLongPressTimer(); 85 base::OneShotTimer<GestureSequence>* GetShowPressTimer(); 86 87 private: 88 // Recreates the axis-aligned bounding box that contains all the touch-points 89 // at their most recent position. 90 void RecreateBoundingBox(); 91 92 void ResetVelocities(); 93 94 GesturePoint& GesturePointForEvent(const TouchEvent& event); 95 96 // Do a linear scan through points_ to find the GesturePoint 97 // with id |point_id|. 98 GesturePoint* GetPointByPointId(int point_id); 99 100 bool IsSecondTouchDownCloseEnoughForTwoFingerTap(); 101 102 // Creates a gesture event with the specified parameters. The function 103 // includes some common information (e.g. number of touch-points in the 104 // gesture etc.) in the gesture event as well. 105 GestureEvent* CreateGestureEvent(const GestureEventDetails& details, 106 const gfx::PointF& location, 107 int flags, 108 base::Time timestamp, 109 unsigned int touch_id_bitmask); 110 111 // Functions to be called to add GestureEvents, after successful recognition. 112 113 // Tap gestures. 114 void AppendTapDownGestureEvent(const GesturePoint& point, Gestures* gestures); 115 void PrependTapCancelGestureEvent(const GesturePoint& point, 116 Gestures* gestures); 117 void AppendBeginGestureEvent(const GesturePoint& point, Gestures* gestures); 118 void AppendEndGestureEvent(const GesturePoint& point, Gestures* gestures); 119 void AppendClickGestureEvent(const GesturePoint& point, 120 int tap_count, 121 Gestures* gestures); 122 void AppendDoubleClickGestureEvent(const GesturePoint& point, 123 Gestures* gestures); 124 void AppendLongPressGestureEvent(); 125 void AppendShowPressGestureEvent(); 126 void AppendLongTapGestureEvent(const GesturePoint& point, 127 Gestures* gestures); 128 129 // Scroll gestures. 130 void AppendScrollGestureBegin(const GesturePoint& point, 131 const gfx::PointF& location, 132 Gestures* gestures); 133 void AppendScrollGestureEnd(const GesturePoint& point, 134 const gfx::PointF& location, 135 Gestures* gestures, 136 float x_velocity, 137 float y_velocity); 138 void AppendScrollGestureUpdate(GesturePoint& point, 139 Gestures* gestures, 140 IsFirstScroll is_first_scroll); 141 142 // Pinch gestures. 143 void AppendPinchGestureBegin(const GesturePoint& p1, 144 const GesturePoint& p2, 145 Gestures* gestures); 146 void AppendPinchGestureEnd(const GesturePoint& p1, 147 const GesturePoint& p2, 148 float scale, 149 Gestures* gestures); 150 void AppendPinchGestureUpdate(const GesturePoint& point, 151 float scale, 152 Gestures* gestures); 153 void AppendSwipeGesture(const GesturePoint& point, 154 int swipe_x, 155 int swipe_y, 156 Gestures* gestures); 157 void AppendTwoFingerTapGestureEvent(Gestures* gestures); 158 159 void set_state(const GestureState state) { state_ = state; } 160 161 // Various GestureTransitionFunctions for a signature. 162 // There is, 1:many mapping from GestureTransitionFunction to Signature 163 // But a Signature have only one GestureTransitionFunction. 164 bool Click(const TouchEvent& event, 165 const GesturePoint& point, 166 Gestures* gestures); 167 bool ScrollStart(const TouchEvent& event, 168 GesturePoint& point, 169 Gestures* gestures); 170 void BreakRailScroll(const TouchEvent& event, 171 GesturePoint& point, 172 Gestures* gestures); 173 bool ScrollUpdate(const TouchEvent& event, 174 GesturePoint& point, 175 Gestures* gestures, 176 IsFirstScroll is_first_scroll); 177 bool TouchDown(const TouchEvent& event, 178 const GesturePoint& point, 179 Gestures* gestures); 180 bool TwoFingerTouchDown(const TouchEvent& event, 181 const GesturePoint& point, 182 Gestures* gestures); 183 bool TwoFingerTouchMove(const TouchEvent& event, 184 const GesturePoint& point, 185 Gestures* gestures); 186 bool TwoFingerTouchReleased(const TouchEvent& event, 187 const GesturePoint& point, 188 Gestures* gestures); 189 bool ScrollEnd(const TouchEvent& event, 190 GesturePoint& point, 191 Gestures* gestures); 192 bool PinchStart(const TouchEvent& event, 193 const GesturePoint& point, 194 Gestures* gestures); 195 bool PinchUpdate(const TouchEvent& event, 196 GesturePoint& point, 197 Gestures* gestures); 198 bool PinchEnd(const TouchEvent& event, 199 const GesturePoint& point, 200 Gestures* gestures); 201 bool MaybeSwipe(const TouchEvent& event, 202 const GesturePoint& point, 203 Gestures* gestures); 204 205 void TwoFingerTapOrPinch(const TouchEvent& event, 206 const GesturePoint& point, 207 Gestures* gestures); 208 209 void StopTimersIfRequired(const TouchEvent& event); 210 211 void StartRailFreeScroll(const GesturePoint& point, Gestures* gestures); 212 213 // Current state of gesture recognizer. 214 GestureState state_; 215 216 // ui::EventFlags. 217 int flags_; 218 219 // We maintain the smallest axis-aligned rectangle that contains all the 220 // current touch-points. This box is updated after every touch-event. 221 gfx::RectF bounding_box_; 222 223 // The center of the bounding box used in the latest multi-finger scroll 224 // update gesture. 225 gfx::PointF latest_multi_scroll_update_location_; 226 227 // The last scroll update prediction offset. This is removed from the scroll 228 // distance on the next update since the page has already been scrolled this 229 // distance. 230 gfx::Vector2dF last_scroll_prediction_offset_; 231 232 // For pinch, the 'distance' represents the diagonal distance of 233 // |bounding_box_|. 234 235 // The distance between the two points at PINCH_START. 236 float pinch_distance_start_; 237 238 // This distance is updated after each PINCH_UPDATE. 239 float pinch_distance_current_; 240 241 // This is the time when second touch down was received. Used for determining 242 // if a two finger double tap has happened. 243 base::TimeDelta second_touch_time_; 244 245 ScrollType scroll_type_; 246 scoped_ptr<base::OneShotTimer<GestureSequence> > long_press_timer_; 247 scoped_ptr<base::OneShotTimer<GestureSequence> > show_press_timer_; 248 249 GesturePoint points_[kMaxGesturePoints]; 250 int point_count_; 251 252 // Location of the last touch event. 253 gfx::PointF last_touch_location_; 254 255 GestureSequenceDelegate* delegate_; 256 257 DISALLOW_COPY_AND_ASSIGN(GestureSequence); 258 }; 259 260 } // namespace ui 261 262 #endif // UI_EVENTS_GESTURES_GESTURE_SEQUENCE_H_ 263