gesture_detector.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. // Copyright 2014 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. #ifndef UI_EVENTS_GESTURE_DETECTION_GESTURE_DETECTOR_H_
  5. #define UI_EVENTS_GESTURE_DETECTION_GESTURE_DETECTOR_H_
  6. #include <memory>
  7. #include "base/memory/raw_ptr.h"
  8. #include "base/task/sequenced_task_runner.h"
  9. #include "base/time/time.h"
  10. #include "ui/events/gesture_detection/gesture_detection_export.h"
  11. #include "ui/events/gesture_detection/velocity_tracker_state.h"
  12. namespace ui {
  13. class DoubleTapListener;
  14. class GestureListener;
  15. class MotionEvent;
  16. // Port of GestureDetector.java from Android
  17. // * platform/frameworks/base/core/java/android/view/GestureDetector.java
  18. // * Change-Id: Ib470735ec929b0b358fca4597e92dc81084e675f
  19. // * Please update the Change-Id as upstream Android changes are pulled.
  20. class GESTURE_DETECTION_EXPORT GestureDetector {
  21. public:
  22. struct GESTURE_DETECTION_EXPORT Config {
  23. Config();
  24. Config(const Config& other);
  25. ~Config();
  26. base::TimeDelta shortpress_timeout;
  27. base::TimeDelta longpress_timeout;
  28. base::TimeDelta showpress_timeout;
  29. base::TimeDelta double_tap_timeout;
  30. // The minimum duration between the first tap's up event and the second
  31. // tap's down event for an interaction to be considered a double-tap.
  32. base::TimeDelta double_tap_min_time;
  33. // Distance a touch can wander before a scroll will occur (in dips).
  34. float touch_slop;
  35. // Distance the first touch can wander before it is no longer considered a
  36. // double tap (in dips).
  37. float double_tap_slop;
  38. // Minimum velocity to initiate a fling (in dips/second).
  39. float minimum_fling_velocity;
  40. // Maximum velocity of an initiated fling (in dips/second).
  41. float maximum_fling_velocity;
  42. // Whether |OnSwipe| should be called after a secondary touch is released
  43. // while a logical swipe gesture is active. Defaults to false.
  44. bool swipe_enabled;
  45. // Minimum velocity to initiate a swipe (in dips/second).
  46. float minimum_swipe_velocity;
  47. // Maximum angle of the swipe from its dominant component axis, between
  48. // (0, 45] degrees. The closer this is to 0, the closer the dominant
  49. // direction of the swipe must be to up, down left or right.
  50. float maximum_swipe_deviation_angle;
  51. // Whether |OnTwoFingerTap| should be called for two finger tap
  52. // gestures. Defaults to false.
  53. bool two_finger_tap_enabled;
  54. // Maximum distance between pointers for a two finger tap.
  55. float two_finger_tap_max_separation;
  56. // Maximum time the second pointer can be active for a two finger tap.
  57. base::TimeDelta two_finger_tap_timeout;
  58. // Single tap count repetition length. Defaults to 1 (no repetition count).
  59. // Note that when double-tap detection is enabled, the single tap repeat
  60. // count will always be 1.
  61. int single_tap_repeat_interval;
  62. // Whether a longpress should be generated immediately when a stylus button
  63. // is pressed, given that the longpress timeout is still active.
  64. bool stylus_button_accelerated_longpress_enabled;
  65. // Whether a longpress should be generated immediately when a pointer is
  66. // deep-pressing, given that the longpress timeout is still active.
  67. bool deep_press_accelerated_longpress_enabled;
  68. VelocityTracker::Strategy velocity_tracker_strategy;
  69. // If set the task runner to use for tasks generated by the
  70. // GestureDetector. If null the current sequence is used. This should be a
  71. // Browser UI thread task runner.
  72. scoped_refptr<base::SequencedTaskRunner> task_runner;
  73. };
  74. GestureDetector(const Config& config,
  75. GestureListener* listener,
  76. DoubleTapListener* optional_double_tap_listener);
  77. GestureDetector(const GestureDetector&) = delete;
  78. GestureDetector& operator=(const GestureDetector&) = delete;
  79. ~GestureDetector();
  80. bool OnTouchEvent(const MotionEvent& ev, bool should_process_double_tap);
  81. // Setting a valid |double_tap_listener| will enable double-tap detection,
  82. // wherein calls to |OnSimpleTapConfirmed| are delayed by the tap timeout.
  83. // Note: The listener must never be changed while |is_double_tapping| is true.
  84. void SetDoubleTapListener(DoubleTapListener* double_tap_listener);
  85. bool has_doubletap_listener() const { return !!double_tap_listener_; }
  86. bool is_double_tapping() const { return is_double_tapping_; }
  87. // Enables or disables gestures that require holding the finger steady for a
  88. // while (i.e. both short-press and long-press).
  89. void set_press_and_hold_enabled(bool enabled) {
  90. press_and_hold_enabled_ = enabled;
  91. }
  92. void set_showpress_enabled(bool enabled) { showpress_enabled_ = enabled; }
  93. // Returns the event storing the initial position of the pointer with given
  94. // pointer ID. This returns nullptr if the source event isn't
  95. // current_down_event_ or secondary_pointer_down_event_.
  96. const MotionEvent* GetSourcePointerDownEvent(
  97. const MotionEvent& current_down_event,
  98. const MotionEvent* secondary_pointer_down_event,
  99. const int pointer_id);
  100. private:
  101. void Init(const Config& config);
  102. void OnShowPressTimeout();
  103. void OnShortPressTimeout();
  104. void OnLongPressTimeout();
  105. void OnTapTimeout();
  106. void ActivateShortPressGesture(const MotionEvent& ev);
  107. void ActivateLongPressGesture(const MotionEvent& ev);
  108. void Cancel();
  109. void CancelTaps();
  110. bool IsRepeatedTap(const MotionEvent& first_down,
  111. const MotionEvent& first_up,
  112. const MotionEvent& second_down,
  113. bool should_process_double_tap) const;
  114. bool HandleSwipeIfNeeded(const MotionEvent& up, float vx, float vy);
  115. bool IsWithinTouchSlop(const MotionEvent& ev);
  116. class TimeoutGestureHandler;
  117. std::unique_ptr<TimeoutGestureHandler> timeout_handler_;
  118. const raw_ptr<GestureListener> listener_;
  119. raw_ptr<DoubleTapListener> double_tap_listener_;
  120. float touch_slop_square_;
  121. float double_tap_touch_slop_square_;
  122. float double_tap_slop_square_;
  123. float two_finger_tap_distance_square_;
  124. float min_fling_velocity_;
  125. float max_fling_velocity_;
  126. float min_swipe_velocity_;
  127. float min_swipe_direction_component_ratio_;
  128. base::TimeDelta double_tap_timeout_;
  129. base::TimeDelta two_finger_tap_timeout_;
  130. base::TimeDelta double_tap_min_time_;
  131. bool still_down_;
  132. bool defer_confirm_single_tap_;
  133. bool all_pointers_within_slop_regions_;
  134. bool always_in_bigger_tap_region_;
  135. bool two_finger_tap_allowed_for_gesture_;
  136. std::unique_ptr<MotionEvent> current_down_event_;
  137. std::unique_ptr<MotionEvent> previous_up_event_;
  138. std::unique_ptr<MotionEvent> secondary_pointer_down_event_;
  139. // True when the user is still touching for the second tap (down, move, and
  140. // up events). Can only be true if there is a double tap listener attached.
  141. bool is_double_tapping_;
  142. // Whether the current ACTION_DOWN event meets the criteria for being a
  143. // repeated tap. Note that it will be considered a repeated tap only if the
  144. // corresponding ACTION_UP yields a valid tap and double-tap detection is
  145. // disabled.
  146. bool is_down_candidate_for_repeated_single_tap_;
  147. // Stores the maximum number of pointers that have been down simultaneously
  148. // during the current touch sequence.
  149. int maximum_pointer_count_;
  150. // The number of repeated taps in the current sequence, i.e., for the initial
  151. // tap this is 0, for the first *repeated* tap 1, etc...
  152. int current_single_tap_repeat_count_;
  153. int single_tap_repeat_interval_;
  154. float last_focus_x_;
  155. float last_focus_y_;
  156. float down_focus_x_;
  157. float down_focus_y_;
  158. bool stylus_button_accelerated_longpress_enabled_ = false;
  159. bool deep_press_accelerated_longpress_enabled_ = false;
  160. bool press_and_hold_enabled_ = true;
  161. bool showpress_enabled_ = true;
  162. bool swipe_enabled_ = false;
  163. bool two_finger_tap_enabled_ = false;
  164. // Determines speed during touch scrolling.
  165. VelocityTrackerState velocity_tracker_;
  166. };
  167. } // namespace ui
  168. #endif // UI_EVENTS_GESTURE_DETECTION_GESTURE_DETECTOR_H_