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