Upstream version 9.37.195.0
[platform/framework/web/crosswalk.git] / src / ui / events / gesture_detection / gesture_detector.h
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_