Chromium Code Reviews| Index: ui/events/gesture_detection/gesture_detector.cc |
| diff --git a/ui/events/gesture_detection/gesture_detector.cc b/ui/events/gesture_detection/gesture_detector.cc |
| index e086ef0745d6bcb6c6d30685bed1aca8bbf27402..27c7d249ad80788007c5d2c1a377c1c9dcbd14f8 100644 |
| --- a/ui/events/gesture_detection/gesture_detector.cc |
| +++ b/ui/events/gesture_detection/gesture_detector.cc |
| @@ -21,6 +21,8 @@ const float kSlopEpsilon = .05f; |
| // to trigger an |OnScroll| callback. |
| const float kScrollEpsilon = .1f; |
| +const float kDegreesToRadians = 3.14159265f / 180.0f; |
|
tdresser
2014/04/24 12:42:40
Might as well use M_PI here.
Note that you need a
jdduke (slow)
2014/04/24 15:13:55
Done.
|
| + |
| // Constants used by TimeoutGestureHandler. |
| enum TimeoutEvent { |
| SHOW_PRESS = 0, |
| @@ -40,7 +42,11 @@ GestureDetector::Config::Config() |
| touch_slop(8), |
| double_tap_slop(100), |
| minimum_fling_velocity(50), |
| - maximum_fling_velocity(8000) {} |
| + maximum_fling_velocity(8000), |
| + swipe_enabled(false), |
| + minimum_swipe_velocity(20), |
| + maximum_swipe_deviation_angle(20.f) { |
| +} |
| GestureDetector::Config::~Config() {} |
| @@ -74,6 +80,13 @@ bool GestureDetector::SimpleGestureListener::OnFling(const MotionEvent& e1, |
| return false; |
| } |
| +bool GestureDetector::SimpleGestureListener::OnSwipe(const MotionEvent& e1, |
| + const MotionEvent& e2, |
| + float velocity_x, |
| + float velocity_y) { |
| + return false; |
| +} |
| + |
| bool GestureDetector::SimpleGestureListener::OnSingleTapConfirmed( |
| const MotionEvent& e) { |
| return false; |
| @@ -158,7 +171,7 @@ GestureDetector::GestureDetector( |
| last_focus_y_(0), |
| down_focus_x_(0), |
| down_focus_y_(0), |
| - is_longpress_enabled_(true) { |
| + longpress_enabled_(true) { |
| DCHECK(listener_); |
| Init(config); |
| } |
| @@ -206,21 +219,50 @@ bool GestureDetector::OnTouchEvent(const MotionEvent& ev) { |
| { |
| const int up_index = ev.GetActionIndex(); |
| const int id1 = ev.GetPointerId(up_index); |
| - const float x1 = velocity_tracker_.GetXVelocity(id1); |
| - const float y1 = velocity_tracker_.GetYVelocity(id1); |
| + const float vx1 = velocity_tracker_.GetXVelocity(id1); |
| + const float vy1 = velocity_tracker_.GetYVelocity(id1); |
| + float vx_total = vx1; |
| + float vy_total = vy1; |
| for (int i = 0; i < count; i++) { |
| if (i == up_index) |
| continue; |
| const int id2 = ev.GetPointerId(i); |
| - const float x = x1 * velocity_tracker_.GetXVelocity(id2); |
| - const float y = y1 * velocity_tracker_.GetYVelocity(id2); |
| - |
| - const float dot = x + y; |
| + const float vx2 = velocity_tracker_.GetXVelocity(id2); |
| + const float vy2 = velocity_tracker_.GetYVelocity(id2); |
| + const float dot = vx1 * vx2 + vy1 * vy2; |
| if (dot < 0) { |
| + vx_total = 0; |
| + vy_total = 0; |
| velocity_tracker_.Clear(); |
| break; |
| } |
| + vx_total += vx2; |
| + vy_total += vy2; |
| + } |
| + |
| + if (swipe_enabled_ && (vx_total || vy_total)) { |
| + float vx = vx_total / count; |
| + float vy = vy_total / count; |
| + float vx_abs = std::abs(vx); |
| + float vy_abs = std::abs(vy); |
| + |
| + if (vx_abs < min_swipe_velocity_) |
| + vx_abs = vx = 0; |
| + if (vy_abs < min_swipe_velocity_) |
| + vy_abs = vy = 0; |
| + |
| + // Note that the ratio will be 0 if both velocites are below the min. |
| + float ratio = vx_abs > vy_abs ? vx_abs / std::max(vy_abs, 0.001f) |
| + : vy_abs / std::max(vx_abs, 0.001f); |
| + if (ratio > min_swipe_direction_component_ratio_) { |
| + if (vx_abs > vy_abs) |
| + vy = 0; |
| + else |
| + vx = 0; |
| + |
| + handled = listener_->OnSwipe(*current_down_event_, ev, vx, vy); |
| + } |
| } |
| } |
| break; |
| @@ -259,7 +301,7 @@ bool GestureDetector::OnTouchEvent(const MotionEvent& ev) { |
| // Always start the SHOW_PRESS timer before the LONG_PRESS timer to ensure |
| // proper timeout ordering. |
| timeout_handler_->StartTimeout(SHOW_PRESS); |
| - if (is_longpress_enabled_) |
| + if (longpress_enabled_) |
| timeout_handler_->StartTimeout(LONG_PRESS); |
| handled |= listener_->OnDown(ev); |
| break; |
| @@ -377,6 +419,15 @@ void GestureDetector::Init(const Config& config) { |
| double_tap_timeout_ = config.double_tap_timeout; |
| min_fling_velocity_ = config.minimum_fling_velocity; |
| max_fling_velocity_ = config.maximum_fling_velocity; |
| + |
| + swipe_enabled_ = config.swipe_enabled; |
| + min_swipe_velocity_ = config.minimum_swipe_velocity; |
| + DCHECK_GT(config.maximum_swipe_deviation_angle, 0); |
| + DCHECK_LE(config.maximum_swipe_deviation_angle, 45); |
| + const float maximum_swipe_deviation_angle = |
| + std::min(45.f, std::max(0.001f, config.maximum_swipe_deviation_angle)); |
| + min_swipe_direction_component_ratio_ = |
| + 1.f / tan(maximum_swipe_deviation_angle * kDegreesToRadians); |
| } |
| void GestureDetector::OnShowPressTimeout() { |