gesture_detector.h revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
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    base::TimeDelta longpress_timeout;
27    base::TimeDelta showpress_timeout;
28    base::TimeDelta double_tap_timeout;
29    int scaled_touch_slop;
30    int scaled_double_tap_slop;
31    int scaled_minimum_fling_velocity;
32    int scaled_maximum_fling_velocity;
33  };
34
35  class GestureListener {
36   public:
37    virtual ~GestureListener() {}
38    virtual bool OnDown(const MotionEvent& e) = 0;
39    virtual void OnShowPress(const MotionEvent& e) = 0;
40    virtual bool OnSingleTapUp(const MotionEvent& e) = 0;
41    virtual bool OnLongPress(const MotionEvent& e) = 0;
42    virtual bool OnScroll(const MotionEvent& e1, const MotionEvent& e2,
43                          float distance_x, float distance_y) = 0;
44    virtual bool OnFling(const MotionEvent& e1, const MotionEvent& e2,
45                         float velocity_x, float velocity_y) = 0;
46  };
47
48  class DoubleTapListener {
49   public:
50    virtual ~DoubleTapListener() {}
51    virtual bool OnSingleTapConfirmed(const MotionEvent& e) = 0;
52    virtual bool OnDoubleTap(const MotionEvent& e) = 0;
53    virtual bool OnDoubleTapEvent(const MotionEvent& e) = 0;
54  };
55
56  // A convenience class to extend when you only want to listen for a subset
57  // of all the gestures. This implements all methods in the
58  // |GestureListener| and |DoubleTapListener| but does
59  // nothing and returns false for all applicable methods.
60  class SimpleGestureListener : public GestureListener,
61                                public DoubleTapListener {
62   public:
63    // GestureListener implementation.
64    virtual bool OnDown(const MotionEvent& e) OVERRIDE;
65    virtual void OnShowPress(const MotionEvent& e) OVERRIDE;
66    virtual bool OnSingleTapUp(const MotionEvent& e) OVERRIDE;
67    virtual bool OnLongPress(const MotionEvent& e) OVERRIDE;
68    virtual bool OnScroll(const MotionEvent& e1, const MotionEvent& e2,
69                          float distance_x, float distance_y) OVERRIDE;
70    virtual bool OnFling(const MotionEvent& e1, const MotionEvent& e2,
71                         float velocity_x, float velocity_y) OVERRIDE;
72
73    // DoubleTapListener implementation.
74    virtual bool OnSingleTapConfirmed(const MotionEvent& e) OVERRIDE;
75    virtual bool OnDoubleTap(const MotionEvent& e) OVERRIDE;
76    virtual bool OnDoubleTapEvent(const MotionEvent& e) OVERRIDE;
77  };
78
79  GestureDetector(const Config& config,
80                  GestureListener* listener,
81                  DoubleTapListener* optional_double_tap_listener);
82  ~GestureDetector();
83
84  bool OnTouchEvent(const MotionEvent& ev);
85
86  void set_doubletap_listener(DoubleTapListener* double_tap_listener) {
87    DCHECK(!is_double_tapping_ || double_tap_listener_);
88    double_tap_listener_ = double_tap_listener;
89  }
90
91  void set_is_longpress_enabled(bool is_longpress_enabled) {
92    is_longpress_enabled_ = is_longpress_enabled;
93  }
94
95  bool is_longpress_enabled() const { return is_longpress_enabled_; }
96
97 private:
98  void Init(const Config& config);
99  void OnShowPressTimeout();
100  void OnLongPressTimeout();
101  void OnTapTimeout();
102  void Cancel();
103  void CancelTaps();
104  bool IsConsideredDoubleTap(const MotionEvent& first_down,
105                             const MotionEvent& first_up,
106                             const MotionEvent& second_down) const;
107
108  class TimeoutGestureHandler;
109  scoped_ptr<TimeoutGestureHandler> timeout_handler_;
110  GestureListener* const listener_;
111  DoubleTapListener* double_tap_listener_;
112
113  int touch_slop_square_;
114  int double_tap_touch_slop_square_;
115  int double_tap_slop_square_;
116  int min_fling_velocity_;
117  int max_fling_velocity_;
118  base::TimeDelta double_tap_timeout_;
119
120  bool still_down_;
121  bool defer_confirm_single_tap_;
122  bool in_longpress_;
123  bool always_in_tap_region_;
124  bool always_in_bigger_tap_region_;
125
126  scoped_ptr<MotionEvent> current_down_event_;
127  scoped_ptr<MotionEvent> previous_up_event_;
128
129  // True when the user is still touching for the second tap (down, move, and
130  // up events). Can only be true if there is a double tap listener attached.
131  bool is_double_tapping_;
132
133  float last_focus_x_;
134  float last_focus_y_;
135  float down_focus_x_;
136  float down_focus_y_;
137
138  bool is_longpress_enabled_;
139
140  // Determines speed during touch scrolling.
141  VelocityTrackerState velocity_tracker_;
142
143  DISALLOW_COPY_AND_ASSIGN(GestureDetector);
144};
145
146}  // namespace ui
147
148#endif  // UI_EVENTS_GESTURE_DETECTION_GESTURE_DETECTOR_H_
149