#ifndef UI_EVENTS_GESTURE_DETECTION_GESTURE_DETECTOR_H_
#define UI_EVENTS_GESTURE_DETECTION_GESTURE_DETECTOR_H_
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "ui/events/gesture_detection/gesture_detection_export.h"
#include "ui/events/gesture_detection/velocity_tracker_state.h"
namespace ui {
class MotionEvent;
class GestureDetector {
public:
struct GESTURE_DETECTION_EXPORT Config {
Config();
~Config();
base::TimeDelta longpress_timeout;
base::TimeDelta showpress_timeout;
base::TimeDelta double_tap_timeout;
int scaled_touch_slop;
int scaled_double_tap_slop;
int scaled_minimum_fling_velocity;
int scaled_maximum_fling_velocity;
};
class GestureListener {
public:
virtual ~GestureListener() {}
virtual bool OnDown(const MotionEvent& e) = 0;
virtual void OnShowPress(const MotionEvent& e) = 0;
virtual bool OnSingleTapUp(const MotionEvent& e) = 0;
virtual bool OnLongPress(const MotionEvent& e) = 0;
virtual bool OnScroll(const MotionEvent& e1, const MotionEvent& e2,
float distance_x, float distance_y) = 0;
virtual bool OnFling(const MotionEvent& e1, const MotionEvent& e2,
float velocity_x, float velocity_y) = 0;
};
class DoubleTapListener {
public:
virtual ~DoubleTapListener() {}
virtual bool OnSingleTapConfirmed(const MotionEvent& e) = 0;
virtual bool OnDoubleTap(const MotionEvent& e) = 0;
virtual bool OnDoubleTapEvent(const MotionEvent& e) = 0;
};
class SimpleGestureListener : public GestureListener,
public DoubleTapListener {
public:
virtual bool OnDown(const MotionEvent& e) OVERRIDE;
virtual void OnShowPress(const MotionEvent& e) OVERRIDE;
virtual bool OnSingleTapUp(const MotionEvent& e) OVERRIDE;
virtual bool OnLongPress(const MotionEvent& e) OVERRIDE;
virtual bool OnScroll(const MotionEvent& e1, const MotionEvent& e2,
float distance_x, float distance_y) OVERRIDE;
virtual bool OnFling(const MotionEvent& e1, const MotionEvent& e2,
float velocity_x, float velocity_y) OVERRIDE;
virtual bool OnSingleTapConfirmed(const MotionEvent& e) OVERRIDE;
virtual bool OnDoubleTap(const MotionEvent& e) OVERRIDE;
virtual bool OnDoubleTapEvent(const MotionEvent& e) OVERRIDE;
};
GestureDetector(const Config& config,
GestureListener* listener,
DoubleTapListener* optional_double_tap_listener);
~GestureDetector();
bool OnTouchEvent(const MotionEvent& ev);
void set_doubletap_listener(DoubleTapListener* double_tap_listener) {
DCHECK(!is_double_tapping_ || double_tap_listener_);
double_tap_listener_ = double_tap_listener;
}
bool has_doubletap_listener() const { return double_tap_listener_ != NULL; }
bool is_double_tapping() const { return is_double_tapping_; }
void set_is_longpress_enabled(bool is_longpress_enabled) {
is_longpress_enabled_ = is_longpress_enabled;
}
bool is_longpress_enabled() const { return is_longpress_enabled_; }
private:
void Init(const Config& config);
void OnShowPressTimeout();
void OnLongPressTimeout();
void OnTapTimeout();
void Cancel();
void CancelTaps();
bool IsConsideredDoubleTap(const MotionEvent& first_down,
const MotionEvent& first_up,
const MotionEvent& second_down) const;
class TimeoutGestureHandler;
scoped_ptr<TimeoutGestureHandler> timeout_handler_;
GestureListener* const listener_;
DoubleTapListener* double_tap_listener_;
int touch_slop_square_;
int double_tap_touch_slop_square_;
int double_tap_slop_square_;
int min_fling_velocity_;
int max_fling_velocity_;
base::TimeDelta double_tap_timeout_;
bool still_down_;
bool defer_confirm_single_tap_;
bool in_longpress_;
bool always_in_tap_region_;
bool always_in_bigger_tap_region_;
scoped_ptr<MotionEvent> current_down_event_;
scoped_ptr<MotionEvent> previous_up_event_;
bool is_double_tapping_;
float last_focus_x_;
float last_focus_y_;
float down_focus_x_;
float down_focus_y_;
bool is_longpress_enabled_;
VelocityTrackerState velocity_tracker_;
DISALLOW_COPY_AND_ASSIGN(GestureDetector);
};
}
#endif