1 // Copyright 2014 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_GESTURE_DETECTION_GESTURE_DETECTOR_H_ 6 #define UI_EVENTS_GESTURE_DETECTION_GESTURE_DETECTOR_H_ 7 8 #include "base/logging.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "ui/events/gesture_detection/gesture_detection_export.h" 11 #include "ui/events/gesture_detection/velocity_tracker_state.h" 12 13 namespace ui { 14 15 class MotionEvent; 16 17 // Port of GestureDetector.java from Android 18 // * platform/frameworks/base/core/java/android/view/GestureDetector.java 19 // * Change-Id: Ib470735ec929b0b358fca4597e92dc81084e675f 20 // * Please update the Change-Id as upstream Android changes are pulled. 21 class GestureDetector { 22 public: 23 struct GESTURE_DETECTION_EXPORT Config { 24 Config(); 25 ~Config(); 26 27 base::TimeDelta longpress_timeout; 28 base::TimeDelta showpress_timeout; 29 base::TimeDelta double_tap_timeout; 30 31 // The minimum duration between the first tap's up event and the second 32 // tap's down event for an interaction to be considered a double-tap. 33 base::TimeDelta double_tap_min_time; 34 35 // Distance a touch can wander before a scroll will occur (in dips). 36 float touch_slop; 37 38 // Distance the first touch can wander before it is no longer considered a 39 // double tap (in dips). 40 float double_tap_slop; 41 42 // Minimum velocity to initiate a fling (in dips/second). 43 float minimum_fling_velocity; 44 45 // Maximum velocity of an initiated fling (in dips/second). 46 float maximum_fling_velocity; 47 48 // Whether |OnSwipe| should be called after a secondary touch is released 49 // while a logical swipe gesture is active. Defaults to false. 50 bool swipe_enabled; 51 52 // Minimum velocity to initiate a swipe (in dips/second). 53 float minimum_swipe_velocity; 54 55 // Maximum angle of the swipe from its dominant component axis, between 56 // (0, 45] degrees. The closer this is to 0, the closer the dominant 57 // direction of the swipe must be to up, down left or right. 58 float maximum_swipe_deviation_angle; 59 60 // Whether |OnTwoFingerTap| should be called for two finger tap 61 // gestures. Defaults to false. 62 bool two_finger_tap_enabled; 63 64 // Maximum distance between pointers for a two finger tap. 65 float two_finger_tap_max_separation; 66 67 // Maximum time the second pointer can be active for a two finger tap. 68 base::TimeDelta two_finger_tap_timeout; 69 }; 70 71 class GestureListener { 72 public: 73 virtual ~GestureListener() {} 74 virtual bool OnDown(const MotionEvent& e) = 0; 75 virtual void OnShowPress(const MotionEvent& e) = 0; 76 virtual bool OnSingleTapUp(const MotionEvent& e) = 0; 77 virtual void OnLongPress(const MotionEvent& e) = 0; 78 virtual bool OnScroll(const MotionEvent& e1, 79 const MotionEvent& e2, 80 float distance_x, 81 float distance_y) = 0; 82 virtual bool OnFling(const MotionEvent& e1, 83 const MotionEvent& e2, 84 float velocity_x, 85 float velocity_y) = 0; 86 // Added for Chromium (Aura). 87 virtual bool OnSwipe(const MotionEvent& e1, 88 const MotionEvent& e2, 89 float velocity_x, 90 float velocity_y) = 0; 91 virtual bool OnTwoFingerTap(const MotionEvent& e1, 92 const MotionEvent& e2) = 0; 93 }; 94 95 class DoubleTapListener { 96 public: 97 virtual ~DoubleTapListener() {} 98 virtual bool OnSingleTapConfirmed(const MotionEvent& e) = 0; 99 virtual bool OnDoubleTap(const MotionEvent& e) = 0; 100 virtual bool OnDoubleTapEvent(const MotionEvent& e) = 0; 101 }; 102 103 // A convenience class to extend when you only want to listen for a subset 104 // of all the gestures. This implements all methods in the 105 // |GestureListener| and |DoubleTapListener| but does 106 // nothing and returns false for all applicable methods. 107 class SimpleGestureListener : public GestureListener, 108 public DoubleTapListener { 109 public: 110 // GestureListener implementation. 111 virtual bool OnDown(const MotionEvent& e) OVERRIDE; 112 virtual void OnShowPress(const MotionEvent& e) OVERRIDE; 113 virtual bool OnSingleTapUp(const MotionEvent& e) OVERRIDE; 114 virtual void OnLongPress(const MotionEvent& e) OVERRIDE; 115 virtual bool OnScroll(const MotionEvent& e1, 116 const MotionEvent& e2, 117 float distance_x, 118 float distance_y) OVERRIDE; 119 virtual bool OnFling(const MotionEvent& e1, 120 const MotionEvent& e2, 121 float velocity_x, 122 float velocity_y) OVERRIDE; 123 virtual bool OnSwipe(const MotionEvent& e1, 124 const MotionEvent& e2, 125 float velocity_x, 126 float velocity_y) OVERRIDE; 127 virtual bool OnTwoFingerTap(const MotionEvent& e1, 128 const MotionEvent& e2) OVERRIDE; 129 130 // DoubleTapListener implementation. 131 virtual bool OnSingleTapConfirmed(const MotionEvent& e) OVERRIDE; 132 virtual bool OnDoubleTap(const MotionEvent& e) OVERRIDE; 133 virtual bool OnDoubleTapEvent(const MotionEvent& e) OVERRIDE; 134 }; 135 136 GestureDetector(const Config& config, 137 GestureListener* listener, 138 DoubleTapListener* optional_double_tap_listener); 139 ~GestureDetector(); 140 141 bool OnTouchEvent(const MotionEvent& ev); 142 143 // Setting a valid |double_tap_listener| will enable double-tap detection, 144 // wherein calls to |OnSimpleTapConfirmed| are delayed by the tap timeout. 145 // Note: The listener must never be changed while |is_double_tapping| is true. 146 void SetDoubleTapListener(DoubleTapListener* double_tap_listener); 147 148 bool has_doubletap_listener() const { return double_tap_listener_ != NULL; } 149 150 bool is_double_tapping() const { return is_double_tapping_; } 151 152 void set_longpress_enabled(bool enabled) { longpress_enabled_ = enabled; } 153 154 private: 155 void Init(const Config& config); 156 void OnShowPressTimeout(); 157 void OnLongPressTimeout(); 158 void OnTapTimeout(); 159 void Cancel(); 160 void CancelTaps(); 161 bool IsConsideredDoubleTap(const MotionEvent& first_down, 162 const MotionEvent& first_up, 163 const MotionEvent& second_down) const; 164 bool HandleSwipeIfNeeded(const MotionEvent& up, float vx, float vy); 165 166 class TimeoutGestureHandler; 167 scoped_ptr<TimeoutGestureHandler> timeout_handler_; 168 GestureListener* const listener_; 169 DoubleTapListener* double_tap_listener_; 170 171 float touch_slop_square_; 172 float double_tap_touch_slop_square_; 173 float double_tap_slop_square_; 174 float two_finger_tap_distance_square_; 175 float min_fling_velocity_; 176 float max_fling_velocity_; 177 float min_swipe_velocity_; 178 float min_swipe_direction_component_ratio_; 179 base::TimeDelta double_tap_timeout_; 180 base::TimeDelta two_finger_tap_timeout_; 181 base::TimeDelta double_tap_min_time_; 182 183 bool still_down_; 184 bool defer_confirm_single_tap_; 185 bool always_in_tap_region_; 186 bool always_in_bigger_tap_region_; 187 bool two_finger_tap_allowed_for_gesture_; 188 189 scoped_ptr<MotionEvent> current_down_event_; 190 scoped_ptr<MotionEvent> previous_up_event_; 191 scoped_ptr<MotionEvent> secondary_pointer_down_event_; 192 193 // True when the user is still touching for the second tap (down, move, and 194 // up events). Can only be true if there is a double tap listener attached. 195 bool is_double_tapping_; 196 197 float last_focus_x_; 198 float last_focus_y_; 199 float down_focus_x_; 200 float down_focus_y_; 201 202 bool longpress_enabled_; 203 bool swipe_enabled_; 204 bool two_finger_tap_enabled_; 205 206 // Determines speed during touch scrolling. 207 VelocityTrackerState velocity_tracker_; 208 209 DISALLOW_COPY_AND_ASSIGN(GestureDetector); 210 }; 211 212 } // namespace ui 213 214 #endif // UI_EVENTS_GESTURE_DETECTION_GESTURE_DETECTOR_H_ 215