#ifndef UI_EVENTS_GESTURE_DETECTION_GESTURE_DETECTOR_H_
#define UI_EVENTS_GESTURE_DETECTION_GESTURE_DETECTOR_H_
#include <memory>
#include "base/memory/raw_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "ui/events/gesture_detection/gesture_detection_export.h"
#include "ui/events/velocity_tracker/velocity_tracker_state.h"
#include "arkweb/build/features/features.h"
namespace ui {
class DoubleTapListener;
class GestureListener;
class MotionEvent;
#if BUILDFLAG(IS_ARKWEB)
class GestureDetectorExt;
class TimeoutGestureHandlerUtils;
#endif
class GESTURE_DETECTION_EXPORT GestureDetector {
public:
struct GESTURE_DETECTION_EXPORT Config {
Config();
Config(const Config& other);
~Config();
base::TimeDelta shortpress_timeout = base::Milliseconds(400);
base::TimeDelta longpress_timeout = base::Milliseconds(500);
#if BUILDFLAG(ARKWEB_DRAG_DROP)
base::TimeDelta draglongpress_timeout = base::Milliseconds(1500);
#endif
#if BUILDFLAG(ARKWEB_AI)
base::TimeDelta createoverlay_timeout = base::Milliseconds(50);
#endif
base::TimeDelta showpress_timeout = base::Milliseconds(180);
base::TimeDelta double_tap_timeout = base::Milliseconds(300);
base::TimeDelta double_tap_min_time = base::Milliseconds(40);
float stylus_slop = 12;
float touch_slop = 8;
float double_tap_slop = 100;
float minimum_fling_velocity = 50;
float maximum_fling_velocity = 8000;
bool swipe_enabled = false;
float minimum_swipe_velocity = 20;
float maximum_swipe_deviation_angle = 20;
bool two_finger_tap_enabled = false;
float two_finger_tap_max_separation = 300;
base::TimeDelta two_finger_tap_timeout = base::Milliseconds(700);
int single_tap_repeat_interval = 1;
#if BUILDFLAG(IS_CHROMEOS)
bool stylus_button_accelerated_longpress_enabled = true;
#else
bool stylus_button_accelerated_longpress_enabled = false;
#endif
#if BUILDFLAG(IS_ANDROID)
bool deep_press_accelerated_longpress_enabled = true;
#else
bool deep_press_accelerated_longpress_enabled = false;
#endif
VelocityTracker::Strategy velocity_tracker_strategy =
VelocityTracker::Strategy::STRATEGY_DEFAULT;
scoped_refptr<base::SequencedTaskRunner> task_runner;
};
GestureDetector(const Config& config,
GestureListener* listener,
DoubleTapListener* optional_double_tap_listener);
GestureDetector(const GestureDetector&) = delete;
GestureDetector& operator=(const GestureDetector&) = delete;
#if BUILDFLAG(IS_ARKWEB)
friend class GestureDetectorExt;
friend class TimeoutGestureHandlerUtils;
virtual GestureDetectorExt* AsGestureDetectorExt() { return nullptr; }
virtual
#endif
~GestureDetector();
bool OnTouchEvent(const MotionEvent& ev, bool should_process_double_tap);
void SetDoubleTapListener(DoubleTapListener* double_tap_listener);
bool has_doubletap_listener() const { return !!double_tap_listener_; }
bool is_double_tapping() const { return is_double_tapping_; }
void set_press_and_hold_enabled(bool enabled) {
press_and_hold_enabled_ = enabled;
}
void set_showpress_enabled(bool enabled) { showpress_enabled_ = enabled; }
const MotionEvent* GetSourcePointerDownEvent(
const MotionEvent& current_down_event,
const MotionEvent* secondary_pointer_down_event,
const int pointer_id) const;
void OnUnconfirmedTapConvertedToTap();
bool HasPendingTapTimeoutForTesting() const;
private:
void Init(const Config& config);
void OnShowPressTimeout();
void OnShortPressTimeout();
void OnLongPressTimeout();
#if BUILDFLAG(ARKWEB_DRAG_DROP)
void OnDragLongPressTimeout();
#endif
#if BUILDFLAG(ARKWEB_AI)
void OnCreateOverlayTimeout();
#endif
void OnTapTimeout();
void ActivateShortPressGesture(const MotionEvent& ev);
void ActivateLongPressGesture(const MotionEvent& ev);
void Cancel();
void CancelTaps();
bool IsRepeatedTap(const MotionEvent& first_down,
const MotionEvent& first_up,
const MotionEvent& second_down,
bool should_process_double_tap) const;
bool HandleSwipeIfNeeded(const MotionEvent& up, float vx, float vy);
bool IsWithinSlopForTap(const MotionEvent& ev) const;
class TimeoutGestureHandler;
std::unique_ptr<TimeoutGestureHandler> timeout_handler_;
const raw_ptr<GestureListener> listener_;
raw_ptr<DoubleTapListener> double_tap_listener_;
float stylus_slop_square_ = 0;
float touch_slop_square_ = 0;
float double_tap_touch_slop_square_ = 0;
float double_tap_slop_square_ = 0;
float two_finger_tap_distance_square_ = 0;
float min_fling_velocity_ = 1;
float max_fling_velocity_ = 1;
float min_swipe_velocity_ = 0;
float min_swipe_direction_component_ratio_ = 0;
base::TimeDelta double_tap_timeout_;
base::TimeDelta two_finger_tap_timeout_;
base::TimeDelta double_tap_min_time_;
bool still_down_ = false;
bool defer_confirm_single_tap_ = false;
bool all_pointers_within_slop_regions_ = false;
bool always_in_bigger_tap_region_ = false;
bool two_finger_tap_allowed_for_gesture_ = false;
std::unique_ptr<MotionEvent> current_down_event_;
std::unique_ptr<MotionEvent> previous_up_event_;
std::unique_ptr<MotionEvent> secondary_pointer_down_event_;
bool is_double_tapping_ = false;
bool is_down_candidate_for_repeated_single_tap_ = false;
int maximum_pointer_count_ = 0;
int current_single_tap_repeat_count_ = 0;
int single_tap_repeat_interval_ = 1;
float last_focus_x_ = 0;
float last_focus_y_ = 0;
float down_focus_x_ = 0;
float down_focus_y_ = 0;
bool stylus_button_accelerated_longpress_enabled_ = false;
bool deep_press_accelerated_longpress_enabled_ = false;
bool press_and_hold_enabled_ = true;
bool showpress_enabled_ = true;
bool swipe_enabled_ = false;
bool two_finger_tap_enabled_ = false;
#if BUILDFLAG(ARKWEB_DRAG_DROP)
bool draglongpress_enabled_ = true;
#endif
VelocityTrackerState velocity_tracker_;
};
}
#if BUILDFLAG(IS_ARKWEB)
#include "arkweb/chromium_ext/ui/events/gesture_detection/gesture_detector_ext.h"
#endif
#endif