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