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.
5 #ifndef UI_EVENTS_GESTURE_DETECTION_GESTURE_DETECTOR_H_
6 #define UI_EVENTS_GESTURE_DETECTION_GESTURE_DETECTOR_H_
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"
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 {
23 struct GESTURE_DETECTION_EXPORT Config {
27 base::TimeDelta longpress_timeout;
28 base::TimeDelta showpress_timeout;
29 base::TimeDelta double_tap_timeout;
31 // Distance a touch can wander before a scroll will occur (in dips).
34 // Distance the first touch can wander before it is no longer considered a
35 // double tap (in dips).
36 float double_tap_slop;
38 // Minimum velocity to initiate a fling (in dips/second).
39 float minimum_fling_velocity;
41 // Maximum velocity of an initiated fling (in dips/second).
42 float maximum_fling_velocity;
44 // Whether |OnSwipe| should be called after a secondary touch is released
45 // while a logical swipe gesture is active. Defaults to false.
48 // Minimum velocity to initiate a swipe (in dips/second).
49 float minimum_swipe_velocity;
51 // Maximum angle of the swipe from its dominant component axis, between
52 // (0, 45] degrees. The closer this is to 0, the closer the dominant
53 // direction of the swipe must be to up, down left or right.
54 float maximum_swipe_deviation_angle;
57 class GestureListener {
59 virtual ~GestureListener() {}
60 virtual bool OnDown(const MotionEvent& e) = 0;
61 virtual void OnShowPress(const MotionEvent& e) = 0;
62 virtual bool OnSingleTapUp(const MotionEvent& e) = 0;
63 virtual bool OnLongPress(const MotionEvent& e) = 0;
64 virtual bool OnScroll(const MotionEvent& e1,
65 const MotionEvent& e2,
67 float distance_y) = 0;
68 virtual bool OnFling(const MotionEvent& e1,
69 const MotionEvent& e2,
71 float velocity_y) = 0;
72 // Added for Chromium (Aura).
73 virtual bool OnSwipe(const MotionEvent& e1,
74 const MotionEvent& e2,
76 float velocity_y) = 0;
79 class DoubleTapListener {
81 virtual ~DoubleTapListener() {}
82 virtual bool OnSingleTapConfirmed(const MotionEvent& e) = 0;
83 virtual bool OnDoubleTap(const MotionEvent& e) = 0;
84 virtual bool OnDoubleTapEvent(const MotionEvent& e) = 0;
87 // A convenience class to extend when you only want to listen for a subset
88 // of all the gestures. This implements all methods in the
89 // |GestureListener| and |DoubleTapListener| but does
90 // nothing and returns false for all applicable methods.
91 class SimpleGestureListener : public GestureListener,
92 public DoubleTapListener {
94 // GestureListener implementation.
95 virtual bool OnDown(const MotionEvent& e) OVERRIDE;
96 virtual void OnShowPress(const MotionEvent& e) OVERRIDE;
97 virtual bool OnSingleTapUp(const MotionEvent& e) OVERRIDE;
98 virtual bool OnLongPress(const MotionEvent& e) OVERRIDE;
99 virtual bool OnScroll(const MotionEvent& e1,
100 const MotionEvent& e2,
102 float distance_y) OVERRIDE;
103 virtual bool OnFling(const MotionEvent& e1,
104 const MotionEvent& e2,
106 float velocity_y) OVERRIDE;
107 virtual bool OnSwipe(const MotionEvent& e1,
108 const MotionEvent& e2,
110 float velocity_y) OVERRIDE;
112 // DoubleTapListener implementation.
113 virtual bool OnSingleTapConfirmed(const MotionEvent& e) OVERRIDE;
114 virtual bool OnDoubleTap(const MotionEvent& e) OVERRIDE;
115 virtual bool OnDoubleTapEvent(const MotionEvent& e) OVERRIDE;
118 GestureDetector(const Config& config,
119 GestureListener* listener,
120 DoubleTapListener* optional_double_tap_listener);
123 bool OnTouchEvent(const MotionEvent& ev);
125 // Setting a valid |double_tap_listener| will enable double-tap detection,
126 // wherein calls to |OnSimpleTapConfirmed| are delayed by the tap timeout.
127 // Note: The listener must never be changed while |is_double_tapping| is true.
128 void SetDoubleTapListener(DoubleTapListener* double_tap_listener);
130 bool has_doubletap_listener() const { return double_tap_listener_ != NULL; }
132 bool is_double_tapping() const { return is_double_tapping_; }
134 void set_longpress_enabled(bool enabled) { longpress_enabled_ = enabled; }
137 void Init(const Config& config);
138 void OnShowPressTimeout();
139 void OnLongPressTimeout();
143 bool IsConsideredDoubleTap(const MotionEvent& first_down,
144 const MotionEvent& first_up,
145 const MotionEvent& second_down) const;
147 class TimeoutGestureHandler;
148 scoped_ptr<TimeoutGestureHandler> timeout_handler_;
149 GestureListener* const listener_;
150 DoubleTapListener* double_tap_listener_;
152 float touch_slop_square_;
153 float double_tap_touch_slop_square_;
154 float double_tap_slop_square_;
155 float min_fling_velocity_;
156 float max_fling_velocity_;
157 float min_swipe_velocity_;
158 float min_swipe_direction_component_ratio_;
159 base::TimeDelta double_tap_timeout_;
162 bool defer_confirm_single_tap_;
164 bool always_in_tap_region_;
165 bool always_in_bigger_tap_region_;
167 scoped_ptr<MotionEvent> current_down_event_;
168 scoped_ptr<MotionEvent> previous_up_event_;
170 // True when the user is still touching for the second tap (down, move, and
171 // up events). Can only be true if there is a double tap listener attached.
172 bool is_double_tapping_;
179 bool longpress_enabled_;
182 // Determines speed during touch scrolling.
183 VelocityTrackerState velocity_tracker_;
185 DISALLOW_COPY_AND_ASSIGN(GestureDetector);
190 #endif // UI_EVENTS_GESTURE_DETECTION_GESTURE_DETECTOR_H_