gesture_detector.h revision 5c02ac1a9c1b504631c0a3d2b6e737b5d738bae1
1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#ifndef UI_EVENTS_GESTURE_DETECTION_GESTURE_DETECTOR_H_ 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define UI_EVENTS_GESTURE_DETECTION_GESTURE_DETECTOR_H_ 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/logging.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/events/gesture_detection/gesture_detection_export.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/events/gesture_detection/velocity_tracker_state.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace ui { 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class MotionEvent; 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Port of GestureDetector.java from Android 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// * platform/frameworks/base/core/java/android/view/GestureDetector.java 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// * Change-Id: Ib470735ec929b0b358fca4597e92dc81084e675f 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// * Please update the Change-Id as upstream Android changes are pulled. 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class GestureDetector { 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) struct GESTURE_DETECTION_EXPORT Config { 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Config(); 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ~Config(); 26a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeDelta longpress_timeout; 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeDelta showpress_timeout; 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeDelta double_tap_timeout; 30a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 31a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Distance a touch can wander before a scroll will occur (in dips). 32a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch float touch_slop; 33a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 34a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Distance the first touch can wander before it is no longer considered a 35a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // double tap (in dips). 36a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch float double_tap_slop; 37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 38a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Minimum velocity to initiate a fling (in dips/second). 39a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch float minimum_fling_velocity; 40a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 41a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Maximum velocity of an initiated fling (in dips/second). 42a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch float maximum_fling_velocity; 435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Whether |OnSwipe| should be called after a secondary touch is released 455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // while a logical swipe gesture is active. Defaults to false. 465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool swipe_enabled; 475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Minimum velocity to initiate a swipe (in dips/second). 495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu float minimum_swipe_velocity; 505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Maximum angle of the swipe from its dominant component axis, between 525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // (0, 45] degrees. The closer this is to 0, the closer the dominant 535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // direction of the swipe must be to up, down left or right. 545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu float maximum_swipe_deviation_angle; 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) }; 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) class GestureListener { 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual ~GestureListener() {} 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool OnDown(const MotionEvent& e) = 0; 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnShowPress(const MotionEvent& e) = 0; 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool OnSingleTapUp(const MotionEvent& e) = 0; 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool OnLongPress(const MotionEvent& e) = 0; 645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual bool OnScroll(const MotionEvent& e1, 655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const MotionEvent& e2, 665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu float distance_x, 675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu float distance_y) = 0; 685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual bool OnFling(const MotionEvent& e1, 695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const MotionEvent& e2, 705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu float velocity_x, 715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu float velocity_y) = 0; 725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Added for Chromium (Aura). 735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual bool OnSwipe(const MotionEvent& e1, 745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const MotionEvent& e2, 755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu float velocity_x, 765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu float velocity_y) = 0; 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) }; 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) class DoubleTapListener { 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual ~DoubleTapListener() {} 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool OnSingleTapConfirmed(const MotionEvent& e) = 0; 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool OnDoubleTap(const MotionEvent& e) = 0; 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool OnDoubleTapEvent(const MotionEvent& e) = 0; 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) }; 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // A convenience class to extend when you only want to listen for a subset 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // of all the gestures. This implements all methods in the 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // |GestureListener| and |DoubleTapListener| but does 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // nothing and returns false for all applicable methods. 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) class SimpleGestureListener : public GestureListener, 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public DoubleTapListener { 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // GestureListener implementation. 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool OnDown(const MotionEvent& e) OVERRIDE; 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnShowPress(const MotionEvent& e) OVERRIDE; 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool OnSingleTapUp(const MotionEvent& e) OVERRIDE; 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool OnLongPress(const MotionEvent& e) OVERRIDE; 995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual bool OnScroll(const MotionEvent& e1, 1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const MotionEvent& e2, 1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu float distance_x, 1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu float distance_y) OVERRIDE; 1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual bool OnFling(const MotionEvent& e1, 1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const MotionEvent& e2, 1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu float velocity_x, 1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu float velocity_y) OVERRIDE; 1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual bool OnSwipe(const MotionEvent& e1, 1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const MotionEvent& e2, 1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu float velocity_x, 1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu float velocity_y) OVERRIDE; 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // DoubleTapListener implementation. 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool OnSingleTapConfirmed(const MotionEvent& e) OVERRIDE; 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool OnDoubleTap(const MotionEvent& e) OVERRIDE; 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool OnDoubleTapEvent(const MotionEvent& e) OVERRIDE; 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) }; 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GestureDetector(const Config& config, 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GestureListener* listener, 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DoubleTapListener* optional_double_tap_listener); 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ~GestureDetector(); 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool OnTouchEvent(const MotionEvent& ev); 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Setting a valid |double_tap_listener| will enable double-tap detection, 1260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // wherein calls to |OnSimpleTapConfirmed| are delayed by the tap timeout. 1270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Note: The listener must never be changed while |is_double_tapping| is true. 1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void SetDoubleTapListener(DoubleTapListener* double_tap_listener); 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool has_doubletap_listener() const { return double_tap_listener_ != NULL; } 131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool is_double_tapping() const { return is_double_tapping_; } 133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void set_longpress_enabled(bool enabled) { longpress_enabled_ = enabled; } 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void Init(const Config& config); 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void OnShowPressTimeout(); 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void OnLongPressTimeout(); 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void OnTapTimeout(); 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void Cancel(); 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void CancelTaps(); 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool IsConsideredDoubleTap(const MotionEvent& first_down, 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const MotionEvent& first_up, 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const MotionEvent& second_down) const; 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) class TimeoutGestureHandler; 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<TimeoutGestureHandler> timeout_handler_; 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GestureListener* const listener_; 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DoubleTapListener* double_tap_listener_; 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 152a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch float touch_slop_square_; 153a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch float double_tap_touch_slop_square_; 154a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch float double_tap_slop_square_; 155a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch float min_fling_velocity_; 156a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch float max_fling_velocity_; 1575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu float min_swipe_velocity_; 1585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu float min_swipe_direction_component_ratio_; 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeDelta double_tap_timeout_; 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool still_down_; 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool defer_confirm_single_tap_; 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool in_longpress_; 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool always_in_tap_region_; 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool always_in_bigger_tap_region_; 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<MotionEvent> current_down_event_; 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<MotionEvent> previous_up_event_; 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // True when the user is still touching for the second tap (down, move, and 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // up events). Can only be true if there is a double tap listener attached. 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool is_double_tapping_; 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) float last_focus_x_; 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) float last_focus_y_; 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) float down_focus_x_; 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) float down_focus_y_; 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool longpress_enabled_; 1805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool swipe_enabled_; 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Determines speed during touch scrolling. 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VelocityTrackerState velocity_tracker_; 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(GestureDetector); 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace ui 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif // UI_EVENTS_GESTURE_DETECTION_GESTURE_DETECTOR_H_ 191