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