gesture_detector.h revision 0529e5d033099cbfc42635f6f6183833b09dff6e
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
13namespace ui {
14
15class 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.
21class 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    // Distance a touch can wander before a scroll will occur (in dips).
32    float touch_slop;
33
34    // Distance the first touch can wander before it is no longer considered a
35    // double tap (in dips).
36    float double_tap_slop;
37
38    // Minimum velocity to initiate a fling (in dips/second).
39    float minimum_fling_velocity;
40
41    // Maximum velocity of an initiated fling (in dips/second).
42    float maximum_fling_velocity;
43  };
44
45  class GestureListener {
46   public:
47    virtual ~GestureListener() {}
48    virtual bool OnDown(const MotionEvent& e) = 0;
49    virtual void OnShowPress(const MotionEvent& e) = 0;
50    virtual bool OnSingleTapUp(const MotionEvent& e) = 0;
51    virtual bool OnLongPress(const MotionEvent& e) = 0;
52    virtual bool OnScroll(const MotionEvent& e1, const MotionEvent& e2,
53                          float distance_x, float distance_y) = 0;
54    virtual bool OnFling(const MotionEvent& e1, const MotionEvent& e2,
55                         float velocity_x, float velocity_y) = 0;
56  };
57
58  class DoubleTapListener {
59   public:
60    virtual ~DoubleTapListener() {}
61    virtual bool OnSingleTapConfirmed(const MotionEvent& e) = 0;
62    virtual bool OnDoubleTap(const MotionEvent& e) = 0;
63    virtual bool OnDoubleTapEvent(const MotionEvent& e) = 0;
64  };
65
66  // A convenience class to extend when you only want to listen for a subset
67  // of all the gestures. This implements all methods in the
68  // |GestureListener| and |DoubleTapListener| but does
69  // nothing and returns false for all applicable methods.
70  class SimpleGestureListener : public GestureListener,
71                                public DoubleTapListener {
72   public:
73    // GestureListener implementation.
74    virtual bool OnDown(const MotionEvent& e) OVERRIDE;
75    virtual void OnShowPress(const MotionEvent& e) OVERRIDE;
76    virtual bool OnSingleTapUp(const MotionEvent& e) OVERRIDE;
77    virtual bool OnLongPress(const MotionEvent& e) OVERRIDE;
78    virtual bool OnScroll(const MotionEvent& e1, const MotionEvent& e2,
79                          float distance_x, float distance_y) OVERRIDE;
80    virtual bool OnFling(const MotionEvent& e1, const MotionEvent& e2,
81                         float velocity_x, float velocity_y) OVERRIDE;
82
83    // DoubleTapListener implementation.
84    virtual bool OnSingleTapConfirmed(const MotionEvent& e) OVERRIDE;
85    virtual bool OnDoubleTap(const MotionEvent& e) OVERRIDE;
86    virtual bool OnDoubleTapEvent(const MotionEvent& e) OVERRIDE;
87  };
88
89  GestureDetector(const Config& config,
90                  GestureListener* listener,
91                  DoubleTapListener* optional_double_tap_listener);
92  ~GestureDetector();
93
94  bool OnTouchEvent(const MotionEvent& ev);
95
96  // Setting a valid |double_tap_listener| will enable double-tap detection,
97  // wherein calls to |OnSimpleTapConfirmed| are delayed by the tap timeout.
98  // Note: The listener must never be changed while |is_double_tapping| is true.
99  void SetDoubleTapListener(DoubleTapListener* double_tap_listener);
100
101  bool has_doubletap_listener() const { return double_tap_listener_ != NULL; }
102
103  bool is_double_tapping() const { return is_double_tapping_; }
104
105  void set_is_longpress_enabled(bool is_longpress_enabled) {
106    is_longpress_enabled_ = is_longpress_enabled;
107  }
108
109  bool is_longpress_enabled() const { return is_longpress_enabled_; }
110
111 private:
112  void Init(const Config& config);
113  void OnShowPressTimeout();
114  void OnLongPressTimeout();
115  void OnTapTimeout();
116  void Cancel();
117  void CancelTaps();
118  bool IsConsideredDoubleTap(const MotionEvent& first_down,
119                             const MotionEvent& first_up,
120                             const MotionEvent& second_down) const;
121
122  class TimeoutGestureHandler;
123  scoped_ptr<TimeoutGestureHandler> timeout_handler_;
124  GestureListener* const listener_;
125  DoubleTapListener* double_tap_listener_;
126
127  float touch_slop_square_;
128  float double_tap_touch_slop_square_;
129  float double_tap_slop_square_;
130  float min_fling_velocity_;
131  float max_fling_velocity_;
132  base::TimeDelta double_tap_timeout_;
133
134  bool still_down_;
135  bool defer_confirm_single_tap_;
136  bool in_longpress_;
137  bool always_in_tap_region_;
138  bool always_in_bigger_tap_region_;
139
140  scoped_ptr<MotionEvent> current_down_event_;
141  scoped_ptr<MotionEvent> previous_up_event_;
142
143  // True when the user is still touching for the second tap (down, move, and
144  // up events). Can only be true if there is a double tap listener attached.
145  bool is_double_tapping_;
146
147  float last_focus_x_;
148  float last_focus_y_;
149  float down_focus_x_;
150  float down_focus_y_;
151
152  bool is_longpress_enabled_;
153
154  // Determines speed during touch scrolling.
155  VelocityTrackerState velocity_tracker_;
156
157  DISALLOW_COPY_AND_ASSIGN(GestureDetector);
158};
159
160}  // namespace ui
161
162#endif  // UI_EVENTS_GESTURE_DETECTION_GESTURE_DETECTOR_H_
163