Home | History | Annotate | Download | only in gestures
      1 // Copyright (c) 2012 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_GESTURES_GESTURE_SEQUENCE_H_
      6 #define UI_EVENTS_GESTURES_GESTURE_SEQUENCE_H_
      7 
      8 #include "base/timer/timer.h"
      9 #include "ui/events/event_constants.h"
     10 #include "ui/events/gestures/gesture_point.h"
     11 #include "ui/events/gestures/gesture_recognizer.h"
     12 #include "ui/gfx/rect.h"
     13 
     14 namespace ui {
     15 class TouchEvent;
     16 class GestureEvent;
     17 
     18 // Gesture state.
     19 enum GestureState {
     20   GS_NO_GESTURE,
     21   GS_PENDING_SYNTHETIC_CLICK,
     22   GS_PENDING_SYNTHETIC_CLICK_NO_SCROLL,
     23   GS_SCROLL,
     24   GS_PINCH,
     25   GS_PENDING_TWO_FINGER_TAP,
     26   GS_PENDING_TWO_FINGER_TAP_NO_PINCH,
     27   GS_PENDING_PINCH,
     28   GS_PENDING_PINCH_NO_PINCH,
     29 };
     30 
     31 enum ScrollType {
     32   ST_FREE,
     33   ST_HORIZONTAL,
     34   ST_VERTICAL,
     35 };
     36 
     37 // Delegates dispatch of gesture events for which the GestureSequence does not
     38 // have enough context to dispatch itself.
     39 class EVENTS_EXPORT GestureSequenceDelegate {
     40  public:
     41   virtual void DispatchPostponedGestureEvent(GestureEvent* event) = 0;
     42 
     43  protected:
     44   virtual ~GestureSequenceDelegate() {}
     45 };
     46 
     47 // A GestureSequence recognizes gestures from touch sequences.
     48 class EVENTS_EXPORT GestureSequence {
     49  public:
     50   // Maximum number of points in a single gesture.
     51   static const int kMaxGesturePoints = 12;
     52 
     53   explicit GestureSequence(GestureSequenceDelegate* delegate);
     54   virtual ~GestureSequence();
     55 
     56   typedef GestureRecognizer::Gestures Gestures;
     57 
     58   // Invoked for each touch event that could contribute to the current gesture.
     59   // Returns list of  zero or more GestureEvents identified after processing
     60   // TouchEvent.
     61   // Caller would be responsible for freeing up Gestures.
     62   virtual Gestures* ProcessTouchEventForGesture(const TouchEvent& event,
     63                                                 EventResult status);
     64   const GesturePoint* points() const { return points_; }
     65   int point_count() const { return point_count_; }
     66 
     67   const gfx::Point& last_touch_location() const { return last_touch_location_; }
     68 
     69  protected:
     70   virtual base::OneShotTimer<GestureSequence>* CreateTimer();
     71   base::OneShotTimer<GestureSequence>* GetLongPressTimer();
     72   base::OneShotTimer<GestureSequence>* GetShowPressTimer();
     73 
     74  private:
     75   // Recreates the axis-aligned bounding box that contains all the touch-points
     76   // at their most recent position.
     77   void RecreateBoundingBox();
     78 
     79   void ResetVelocities();
     80 
     81   GesturePoint& GesturePointForEvent(const TouchEvent& event);
     82 
     83   // Do a linear scan through points_ to find the GesturePoint
     84   // with id |point_id|.
     85   GesturePoint* GetPointByPointId(int point_id);
     86 
     87   bool IsSecondTouchDownCloseEnoughForTwoFingerTap();
     88 
     89   // Creates a gesture event with the specified parameters. The function
     90   // includes some common information (e.g. number of touch-points in the
     91   // gesture etc.) in the gesture event as well.
     92   GestureEvent* CreateGestureEvent(const GestureEventDetails& details,
     93                                    const gfx::Point& location,
     94                                    int flags,
     95                                    base::Time timestamp,
     96                                    unsigned int touch_id_bitmask);
     97 
     98   // Functions to be called to add GestureEvents, after successful recognition.
     99 
    100   // Tap gestures.
    101   void AppendTapDownGestureEvent(const GesturePoint& point, Gestures* gestures);
    102   void PrependTapCancelGestureEvent(const GesturePoint& point,
    103                                    Gestures* gestures);
    104   void AppendBeginGestureEvent(const GesturePoint& point, Gestures* gestures);
    105   void AppendEndGestureEvent(const GesturePoint& point, Gestures* gestures);
    106   void AppendClickGestureEvent(const GesturePoint& point,
    107                                int tap_count,
    108                                Gestures* gestures);
    109   void AppendDoubleClickGestureEvent(const GesturePoint& point,
    110                                      Gestures* gestures);
    111   void AppendLongPressGestureEvent();
    112   void AppendShowPressGestureEvent();
    113   void AppendLongTapGestureEvent(const GesturePoint& point,
    114                                  Gestures* gestures);
    115 
    116   // Scroll gestures.
    117   void AppendScrollGestureBegin(const GesturePoint& point,
    118                                 const gfx::Point& location,
    119                                 Gestures* gestures);
    120   void AppendScrollGestureEnd(const GesturePoint& point,
    121                               const gfx::Point& location,
    122                               Gestures* gestures,
    123                               float x_velocity,
    124                               float y_velocity);
    125   void AppendScrollGestureUpdate(GesturePoint& point,
    126                                  Gestures* gestures);
    127 
    128   // Pinch gestures.
    129   void AppendPinchGestureBegin(const GesturePoint& p1,
    130                                const GesturePoint& p2,
    131                                Gestures* gestures);
    132   void AppendPinchGestureEnd(const GesturePoint& p1,
    133                              const GesturePoint& p2,
    134                              float scale,
    135                              Gestures* gestures);
    136   void AppendPinchGestureUpdate(const GesturePoint& point,
    137                                 float scale,
    138                                 Gestures* gestures);
    139   void AppendSwipeGesture(const GesturePoint& point,
    140                           int swipe_x,
    141                           int swipe_y,
    142                           Gestures* gestures);
    143   void AppendTwoFingerTapGestureEvent(Gestures* gestures);
    144 
    145   void set_state(const GestureState state) { state_ = state; }
    146 
    147   // Various GestureTransitionFunctions for a signature.
    148   // There is, 1:many mapping from GestureTransitionFunction to Signature
    149   // But a Signature have only one GestureTransitionFunction.
    150   bool Click(const TouchEvent& event,
    151              const GesturePoint& point,
    152              Gestures* gestures);
    153   bool ScrollStart(const TouchEvent& event,
    154                    GesturePoint& point,
    155                    Gestures* gestures);
    156   void BreakRailScroll(const TouchEvent& event,
    157                        GesturePoint& point,
    158                        Gestures* gestures);
    159   bool ScrollUpdate(const TouchEvent& event,
    160                     GesturePoint& point,
    161                     Gestures* gestures);
    162   bool TouchDown(const TouchEvent& event,
    163                  const GesturePoint& point,
    164                  Gestures* gestures);
    165   bool TwoFingerTouchDown(const TouchEvent& event,
    166                           const GesturePoint& point,
    167                           Gestures* gestures);
    168   bool TwoFingerTouchMove(const TouchEvent& event,
    169                           const GesturePoint& point,
    170                           Gestures* gestures);
    171   bool TwoFingerTouchReleased(const TouchEvent& event,
    172                               const GesturePoint& point,
    173                               Gestures* gestures);
    174   bool ScrollEnd(const TouchEvent& event,
    175                  GesturePoint& point,
    176                  Gestures* gestures);
    177   bool PinchStart(const TouchEvent& event,
    178                   const GesturePoint& point,
    179                   Gestures* gestures);
    180   bool PinchUpdate(const TouchEvent& event,
    181                    GesturePoint& point,
    182                    Gestures* gestures);
    183   bool PinchEnd(const TouchEvent& event,
    184                 const GesturePoint& point,
    185                 Gestures* gestures);
    186   bool MaybeSwipe(const TouchEvent& event,
    187                   const GesturePoint& point,
    188                   Gestures* gestures);
    189 
    190   void TwoFingerTapOrPinch(const TouchEvent& event,
    191                            const GesturePoint& point,
    192                            Gestures* gestures);
    193 
    194   void StopTimersIfRequired(const TouchEvent& event);
    195 
    196   // Current state of gesture recognizer.
    197   GestureState state_;
    198 
    199   // ui::EventFlags.
    200   int flags_;
    201 
    202   // We maintain the smallest axis-aligned rectangle that contains all the
    203   // current touch-points. This box is updated after every touch-event.
    204   gfx::Rect bounding_box_;
    205 
    206   // The center of the bounding box used in the latest multi-finger scroll
    207   // update gesture.
    208   gfx::Point latest_multi_scroll_update_location_;
    209 
    210   // The last scroll update prediction offset. This is removed from the scroll
    211   // distance on the next update since the page has already been scrolled this
    212   // distance.
    213   gfx::Vector2dF last_scroll_prediction_offset_;
    214 
    215   // For pinch, the 'distance' represents the diagonal distance of
    216   // |bounding_box_|.
    217 
    218   // The distance between the two points at PINCH_START.
    219   float pinch_distance_start_;
    220 
    221   // This distance is updated after each PINCH_UPDATE.
    222   float pinch_distance_current_;
    223 
    224   // This is the time when second touch down was received. Used for determining
    225   // if a two finger double tap has happened.
    226   base::TimeDelta second_touch_time_;
    227 
    228   ScrollType scroll_type_;
    229   scoped_ptr<base::OneShotTimer<GestureSequence> > long_press_timer_;
    230   scoped_ptr<base::OneShotTimer<GestureSequence> > show_press_timer_;
    231 
    232   GesturePoint points_[kMaxGesturePoints];
    233   int point_count_;
    234 
    235   // Location of the last touch event.
    236   gfx::Point last_touch_location_;
    237 
    238   GestureSequenceDelegate* delegate_;
    239 
    240   DISALLOW_COPY_AND_ASSIGN(GestureSequence);
    241 };
    242 
    243 }  // namespace ui
    244 
    245 #endif  // UI_EVENTS_GESTURES_GESTURE_SEQUENCE_H_
    246