gesture_detector.h revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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  bool has_doubletap_listener() const { return double_tap_listener_ != NULL; }
92
93  bool is_double_tapping() const { return is_double_tapping_; }
94
95  void set_is_longpress_enabled(bool is_longpress_enabled) {
96    is_longpress_enabled_ = is_longpress_enabled;
97  }
98
99  bool is_longpress_enabled() const { return is_longpress_enabled_; }
100
101 private:
102  void Init(const Config& config);
103  void OnShowPressTimeout();
104  void OnLongPressTimeout();
105  void OnTapTimeout();
106  void Cancel();
107  void CancelTaps();
108  bool IsConsideredDoubleTap(const MotionEvent& first_down,
109                             const MotionEvent& first_up,
110                             const MotionEvent& second_down) const;
111
112  class TimeoutGestureHandler;
113  scoped_ptr<TimeoutGestureHandler> timeout_handler_;
114  GestureListener* const listener_;
115  DoubleTapListener* double_tap_listener_;
116
117  int touch_slop_square_;
118  int double_tap_touch_slop_square_;
119  int double_tap_slop_square_;
120  int min_fling_velocity_;
121  int max_fling_velocity_;
122  base::TimeDelta double_tap_timeout_;
123
124  bool still_down_;
125  bool defer_confirm_single_tap_;
126  bool in_longpress_;
127  bool always_in_tap_region_;
128  bool always_in_bigger_tap_region_;
129
130  scoped_ptr<MotionEvent> current_down_event_;
131  scoped_ptr<MotionEvent> previous_up_event_;
132
133  // True when the user is still touching for the second tap (down, move, and
134  // up events). Can only be true if there is a double tap listener attached.
135  bool is_double_tapping_;
136
137  float last_focus_x_;
138  float last_focus_y_;
139  float down_focus_x_;
140  float down_focus_y_;
141
142  bool is_longpress_enabled_;
143
144  // Determines speed during touch scrolling.
145  VelocityTrackerState velocity_tracker_;
146
147  DISALLOW_COPY_AND_ASSIGN(GestureDetector);
148};
149
150}  // namespace ui
151
152#endif  // UI_EVENTS_GESTURE_DETECTION_GESTURE_DETECTOR_H_
153