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