#ifndef UI_EVENTS_GESTURES_GESTURE_SEQUENCE_H_
#define UI_EVENTS_GESTURES_GESTURE_SEQUENCE_H_
#include "base/timer/timer.h"
#include "ui/events/event_constants.h"
#include "ui/events/gesture_event_details.h"
#include "ui/events/gestures/gesture_point.h"
#include "ui/events/gestures/gesture_recognizer.h"
#include "ui/gfx/rect.h"
namespace ui {
class TouchEvent;
class GestureEvent;
enum GestureState {
GS_NO_GESTURE,
GS_PENDING_SYNTHETIC_CLICK,
GS_PENDING_SYNTHETIC_CLICK_NO_SCROLL,
GS_SYNTHETIC_CLICK_ABORTED,
GS_SCROLL,
GS_PINCH,
GS_PENDING_TWO_FINGER_TAP,
GS_PENDING_TWO_FINGER_TAP_NO_PINCH,
GS_PENDING_PINCH,
GS_PENDING_PINCH_NO_PINCH,
};
enum ScrollType {
ST_FREE,
ST_HORIZONTAL,
ST_VERTICAL,
};
enum IsFirstScroll {
FS_FIRST_SCROLL,
FS_NOT_FIRST_SCROLL,
};
class EVENTS_EXPORT GestureSequenceDelegate {
public:
virtual void DispatchPostponedGestureEvent(GestureEvent* event) = 0;
protected:
virtual ~GestureSequenceDelegate() {}
};
class EVENTS_EXPORT GestureSequence {
public:
static const int kMaxGesturePoints = 12;
explicit GestureSequence(GestureSequenceDelegate* delegate);
virtual ~GestureSequence();
typedef GestureRecognizer::Gestures Gestures;
virtual Gestures* ProcessTouchEventForGesture(const TouchEvent& event,
EventResult status);
const GesturePoint* points() const { return points_; }
int point_count() const { return point_count_; }
const gfx::PointF& last_touch_location() const {
return last_touch_location_;
}
protected:
virtual base::OneShotTimer<GestureSequence>* CreateTimer();
base::OneShotTimer<GestureSequence>* GetLongPressTimer();
base::OneShotTimer<GestureSequence>* GetShowPressTimer();
private:
void RecreateBoundingBox();
void ResetVelocities();
GesturePoint& GesturePointForEvent(const TouchEvent& event);
GesturePoint* GetPointByPointId(int point_id);
bool IsSecondTouchDownCloseEnoughForTwoFingerTap();
GestureEvent* CreateGestureEvent(const GestureEventDetails& details,
const gfx::PointF& location,
int flags,
base::Time timestamp,
unsigned int touch_id_bitmask);
void AppendTapDownGestureEvent(const GesturePoint& point, Gestures* gestures);
void PrependTapCancelGestureEvent(const GesturePoint& point,
Gestures* gestures);
void AppendBeginGestureEvent(const GesturePoint& point, Gestures* gestures);
void AppendEndGestureEvent(const GesturePoint& point, Gestures* gestures);
void AppendClickGestureEvent(const GesturePoint& point,
int tap_count,
Gestures* gestures);
void AppendDoubleClickGestureEvent(const GesturePoint& point,
Gestures* gestures);
void AppendLongPressGestureEvent();
void AppendShowPressGestureEvent();
void AppendLongTapGestureEvent(const GesturePoint& point,
Gestures* gestures);
void AppendScrollGestureBegin(const GesturePoint& point,
const gfx::PointF& location,
Gestures* gestures);
void AppendScrollGestureEnd(const GesturePoint& point,
const gfx::PointF& location,
Gestures* gestures,
float x_velocity,
float y_velocity);
void AppendScrollGestureUpdate(GesturePoint& point,
Gestures* gestures,
IsFirstScroll is_first_scroll);
void AppendPinchGestureBegin(const GesturePoint& p1,
const GesturePoint& p2,
Gestures* gestures);
void AppendPinchGestureEnd(const GesturePoint& p1,
const GesturePoint& p2,
float scale,
Gestures* gestures);
void AppendPinchGestureUpdate(const GesturePoint& point,
float scale,
Gestures* gestures);
void AppendSwipeGesture(const GesturePoint& point,
int swipe_x,
int swipe_y,
Gestures* gestures);
void AppendTwoFingerTapGestureEvent(Gestures* gestures);
void set_state(const GestureState state) { state_ = state; }
bool Click(const TouchEvent& event,
const GesturePoint& point,
Gestures* gestures);
bool ScrollStart(const TouchEvent& event,
GesturePoint& point,
Gestures* gestures);
void BreakRailScroll(const TouchEvent& event,
GesturePoint& point,
Gestures* gestures);
bool ScrollUpdate(const TouchEvent& event,
GesturePoint& point,
Gestures* gestures,
IsFirstScroll is_first_scroll);
bool TouchDown(const TouchEvent& event,
const GesturePoint& point,
Gestures* gestures);
bool TwoFingerTouchDown(const TouchEvent& event,
const GesturePoint& point,
Gestures* gestures);
bool TwoFingerTouchMove(const TouchEvent& event,
const GesturePoint& point,
Gestures* gestures);
bool TwoFingerTouchReleased(const TouchEvent& event,
const GesturePoint& point,
Gestures* gestures);
bool ScrollEnd(const TouchEvent& event,
GesturePoint& point,
Gestures* gestures);
bool PinchStart(const TouchEvent& event,
const GesturePoint& point,
Gestures* gestures);
bool PinchUpdate(const TouchEvent& event,
GesturePoint& point,
Gestures* gestures);
bool PinchEnd(const TouchEvent& event,
const GesturePoint& point,
Gestures* gestures);
bool MaybeSwipe(const TouchEvent& event,
const GesturePoint& point,
Gestures* gestures);
void TwoFingerTapOrPinch(const TouchEvent& event,
const GesturePoint& point,
Gestures* gestures);
void StopTimersIfRequired(const TouchEvent& event);
void StartRailFreeScroll(const GesturePoint& point, Gestures* gestures);
GestureState state_;
int flags_;
gfx::RectF bounding_box_;
gfx::PointF latest_multi_scroll_update_location_;
gfx::Vector2dF last_scroll_prediction_offset_;
float pinch_distance_start_;
float pinch_distance_current_;
base::TimeDelta second_touch_time_;
ScrollType scroll_type_;
scoped_ptr<base::OneShotTimer<GestureSequence> > long_press_timer_;
scoped_ptr<base::OneShotTimer<GestureSequence> > show_press_timer_;
GesturePoint points_[kMaxGesturePoints];
int point_count_;
gfx::PointF last_touch_location_;
GestureSequenceDelegate* delegate_;
DISALLOW_COPY_AND_ASSIGN(GestureSequence);
};
}
#endif