Home | History | Annotate | Download | only in gesture_detection
      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_
    215