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.
5 #ifndef UI_EVENTS_GESTURES_GESTURE_SEQUENCE_H_
6 #define UI_EVENTS_GESTURES_GESTURE_SEQUENCE_H_
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"
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
28 GS_SYNTHETIC_CLICK_ABORTED,
31 GS_PENDING_TWO_FINGER_TAP,
32 GS_PENDING_TWO_FINGER_TAP_NO_PINCH,
34 GS_PENDING_PINCH_NO_PINCH,
48 // Delegates dispatch of gesture events for which the GestureSequence does not
49 // have enough context to dispatch itself.
50 class EVENTS_EXPORT GestureSequenceDelegate {
52 virtual void DispatchPostponedGestureEvent(GestureEvent* event) = 0;
55 virtual ~GestureSequenceDelegate() {}
58 // A GestureSequence recognizes gestures from touch sequences.
59 class EVENTS_EXPORT GestureSequence {
61 // Maximum number of points in a single gesture.
62 static const int kMaxGesturePoints = 12;
64 explicit GestureSequence(GestureSequenceDelegate* delegate);
65 virtual ~GestureSequence();
67 typedef GestureRecognizer::Gestures Gestures;
69 // Invoked for each touch event that could contribute to the current gesture.
70 // Returns list of zero or more GestureEvents identified after processing
72 // Caller would be responsible for freeing up Gestures.
73 virtual Gestures* ProcessTouchEventForGesture(const TouchEvent& event,
75 const GesturePoint* points() const { return points_; }
76 int point_count() const { return point_count_; }
78 const gfx::PointF& last_touch_location() const {
79 return last_touch_location_;
83 virtual base::OneShotTimer<GestureSequence>* CreateTimer();
84 base::OneShotTimer<GestureSequence>* GetLongPressTimer();
85 base::OneShotTimer<GestureSequence>* GetShowPressTimer();
88 // Recreates the axis-aligned bounding box that contains all the touch-points
89 // at their most recent position.
90 void RecreateBoundingBox();
92 void ResetVelocities();
94 GesturePoint& GesturePointForEvent(const TouchEvent& event);
96 // Do a linear scan through points_ to find the GesturePoint
97 // with id |point_id|.
98 GesturePoint* GetPointByPointId(int point_id);
100 bool IsSecondTouchDownCloseEnoughForTwoFingerTap();
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,
108 base::Time timestamp,
109 int oldest_touch_id);
111 // Functions to be called to add GestureEvents, after successful recognition.
114 void AppendTapDownGestureEvent(const GesturePoint& point, Gestures* gestures);
115 void PrependTapCancelGestureEvent(const GesturePoint& point,
117 void AppendBeginGestureEvent(const GesturePoint& point, Gestures* gestures);
118 void AppendEndGestureEvent(const GesturePoint& point, Gestures* gestures);
119 void AppendClickGestureEvent(const GesturePoint& point,
122 void AppendDoubleClickGestureEvent(const GesturePoint& point,
124 void AppendLongPressGestureEvent();
125 void AppendShowPressGestureEvent();
126 void AppendLongTapGestureEvent(const GesturePoint& point,
130 void AppendScrollGestureBegin(const GesturePoint& point,
131 const gfx::PointF& location,
133 void AppendScrollGestureEnd(const GesturePoint& point,
134 const gfx::PointF& location,
138 void AppendScrollGestureUpdate(GesturePoint& point,
140 IsFirstScroll is_first_scroll);
143 void AppendPinchGestureBegin(const GesturePoint& p1,
144 const GesturePoint& p2,
146 void AppendPinchGestureEnd(const GesturePoint& p1,
147 const GesturePoint& p2,
150 void AppendPinchGestureUpdate(const GesturePoint& point,
153 void AppendSwipeGesture(const GesturePoint& point,
157 void AppendTwoFingerTapGestureEvent(Gestures* gestures);
159 void set_state(const GestureState state) { state_ = state; }
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,
167 bool ScrollStart(const TouchEvent& event,
170 void BreakRailScroll(const TouchEvent& event,
173 bool ScrollUpdate(const TouchEvent& event,
176 IsFirstScroll is_first_scroll);
177 bool TouchDown(const TouchEvent& event,
178 const GesturePoint& point,
180 bool TwoFingerTouchDown(const TouchEvent& event,
181 const GesturePoint& point,
183 bool TwoFingerTouchMove(const TouchEvent& event,
184 const GesturePoint& point,
186 bool TwoFingerTouchReleased(const TouchEvent& event,
187 const GesturePoint& point,
189 bool ScrollEnd(const TouchEvent& event,
192 bool PinchStart(const TouchEvent& event,
193 const GesturePoint& point,
195 bool PinchUpdate(const TouchEvent& event,
198 bool PinchEnd(const TouchEvent& event,
199 const GesturePoint& point,
201 bool MaybeSwipe(const TouchEvent& event,
202 const GesturePoint& point,
205 void TwoFingerTapOrPinch(const TouchEvent& event,
206 const GesturePoint& point,
209 void StopTimersIfRequired(const TouchEvent& event);
211 void StartRailFreeScroll(const GesturePoint& point, Gestures* gestures);
213 // Current state of gesture recognizer.
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_;
223 // The center of the bounding box used in the latest multi-finger scroll
225 gfx::PointF latest_multi_scroll_update_location_;
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
230 gfx::Vector2dF last_scroll_prediction_offset_;
232 // For pinch, the 'distance' represents the diagonal distance of
235 // The distance between the two points at PINCH_START.
236 float pinch_distance_start_;
238 // This distance is updated after each PINCH_UPDATE.
239 float pinch_distance_current_;
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_;
245 ScrollType scroll_type_;
246 scoped_ptr<base::OneShotTimer<GestureSequence> > long_press_timer_;
247 scoped_ptr<base::OneShotTimer<GestureSequence> > show_press_timer_;
249 GesturePoint points_[kMaxGesturePoints];
252 // Location of the last touch event.
253 gfx::PointF last_touch_location_;
255 GestureSequenceDelegate* delegate_;
257 DISALLOW_COPY_AND_ASSIGN(GestureSequence);
262 #endif // UI_EVENTS_GESTURES_GESTURE_SEQUENCE_H_