| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // MSVC++ requires this to be set before any other includes to get M_PI. | 5 // MSVC++ requires this to be set before any other includes to get M_PI. |
| 6 #define _USE_MATH_DEFINES | 6 #define _USE_MATH_DEFINES |
| 7 | 7 |
| 8 #include "ui/events/gesture_detection/gesture_detector.h" | 8 #include "ui/events/gesture_detection/gesture_detector.h" |
| 9 | 9 |
| 10 #include <cmath> | 10 #include <cmath> |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 two_finger_tap_max_separation(300), | 54 two_finger_tap_max_separation(300), |
| 55 two_finger_tap_timeout(base::TimeDelta::FromMilliseconds(700)) { | 55 two_finger_tap_timeout(base::TimeDelta::FromMilliseconds(700)) { |
| 56 } | 56 } |
| 57 | 57 |
| 58 GestureDetector::Config::~Config() {} | 58 GestureDetector::Config::~Config() {} |
| 59 | 59 |
| 60 bool GestureDetector::SimpleGestureListener::OnDown(const MotionEvent& e) { | 60 bool GestureDetector::SimpleGestureListener::OnDown(const MotionEvent& e) { |
| 61 return false; | 61 return false; |
| 62 } | 62 } |
| 63 | 63 |
| 64 void GestureDetector::SimpleGestureListener::OnShowPress(const MotionEvent& e) { | 64 void GestureDetector::SimpleGestureListener::OnShowPress(const MotionEvent& e, |
| 65 float max_radius) { |
| 65 } | 66 } |
| 66 | 67 |
| 67 bool GestureDetector::SimpleGestureListener::OnSingleTapUp( | 68 bool GestureDetector::SimpleGestureListener::OnSingleTapUp(const MotionEvent& e, |
| 68 const MotionEvent& e) { | 69 float x, |
| 70 float y, |
| 71 float max_radius) { |
| 69 return false; | 72 return false; |
| 70 } | 73 } |
| 71 | 74 |
| 72 void GestureDetector::SimpleGestureListener::OnLongPress(const MotionEvent& e) { | 75 void GestureDetector::SimpleGestureListener::OnLongPress(const MotionEvent& e) { |
| 73 } | 76 } |
| 74 | 77 |
| 75 bool GestureDetector::SimpleGestureListener::OnScroll(const MotionEvent& e1, | 78 bool GestureDetector::SimpleGestureListener::OnScroll(const MotionEvent& e1, |
| 76 const MotionEvent& e2, | 79 const MotionEvent& e2, |
| 77 float distance_x, | 80 float distance_x, |
| 78 float distance_y) { | 81 float distance_y) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 93 return false; | 96 return false; |
| 94 } | 97 } |
| 95 | 98 |
| 96 bool GestureDetector::SimpleGestureListener::OnTwoFingerTap( | 99 bool GestureDetector::SimpleGestureListener::OnTwoFingerTap( |
| 97 const MotionEvent& e1, | 100 const MotionEvent& e1, |
| 98 const MotionEvent& e2) { | 101 const MotionEvent& e2) { |
| 99 return false; | 102 return false; |
| 100 } | 103 } |
| 101 | 104 |
| 102 bool GestureDetector::SimpleGestureListener::OnSingleTapConfirmed( | 105 bool GestureDetector::SimpleGestureListener::OnSingleTapConfirmed( |
| 103 const MotionEvent& e) { | 106 const MotionEvent& e, |
| 107 float x, |
| 108 float y, |
| 109 float max_touch_diameter_) { |
| 104 return false; | 110 return false; |
| 105 } | 111 } |
| 106 | 112 |
| 107 bool GestureDetector::SimpleGestureListener::OnDoubleTap(const MotionEvent& e) { | 113 bool GestureDetector::SimpleGestureListener::OnDoubleTap(const MotionEvent& e) { |
| 108 return false; | 114 return false; |
| 109 } | 115 } |
| 110 | 116 |
| 111 bool GestureDetector::SimpleGestureListener::OnDoubleTapEvent( | 117 bool GestureDetector::SimpleGestureListener::OnDoubleTapEvent( |
| 112 const MotionEvent& e) { | 118 const MotionEvent& e) { |
| 113 return false; | 119 return false; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 swipe_enabled_(false), | 196 swipe_enabled_(false), |
| 191 two_finger_tap_enabled_(false) { | 197 two_finger_tap_enabled_(false) { |
| 192 DCHECK(listener_); | 198 DCHECK(listener_); |
| 193 Init(config); | 199 Init(config); |
| 194 } | 200 } |
| 195 | 201 |
| 196 GestureDetector::~GestureDetector() {} | 202 GestureDetector::~GestureDetector() {} |
| 197 | 203 |
| 198 bool GestureDetector::OnTouchEvent(const MotionEvent& ev) { | 204 bool GestureDetector::OnTouchEvent(const MotionEvent& ev) { |
| 199 const MotionEvent::Action action = ev.GetAction(); | 205 const MotionEvent::Action action = ev.GetAction(); |
| 200 | |
| 201 velocity_tracker_.AddMovement(ev); | 206 velocity_tracker_.AddMovement(ev); |
| 202 | 207 |
| 203 const bool pointer_up = action == MotionEvent::ACTION_POINTER_UP; | 208 const bool pointer_up = action == MotionEvent::ACTION_POINTER_UP; |
| 204 const int skip_index = pointer_up ? ev.GetActionIndex() : -1; | 209 const int skip_index = pointer_up ? ev.GetActionIndex() : -1; |
| 205 | 210 |
| 206 // Determine focal point. | 211 // Determine focal point. |
| 207 float sum_x = 0, sum_y = 0; | 212 float sum_x = 0, sum_y = 0; |
| 208 const int count = static_cast<int>(ev.GetPointerCount()); | 213 const int count = static_cast<int>(ev.GetPointerCount()); |
| 209 for (int i = 0; i < count; i++) { | 214 for (int i = 0; i < count; i++) { |
| 210 if (skip_index == i) | 215 if (skip_index == i) |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 down_focus_y_ = last_focus_y_ = focus_y; | 311 down_focus_y_ = last_focus_y_ = focus_y; |
| 307 current_down_event_ = ev.Clone(); | 312 current_down_event_ = ev.Clone(); |
| 308 | 313 |
| 309 secondary_pointer_down_event_.reset(); | 314 secondary_pointer_down_event_.reset(); |
| 310 always_in_tap_region_ = true; | 315 always_in_tap_region_ = true; |
| 311 always_in_bigger_tap_region_ = true; | 316 always_in_bigger_tap_region_ = true; |
| 312 still_down_ = true; | 317 still_down_ = true; |
| 313 defer_confirm_single_tap_ = false; | 318 defer_confirm_single_tap_ = false; |
| 314 two_finger_tap_allowed_for_gesture_ = two_finger_tap_enabled_; | 319 two_finger_tap_allowed_for_gesture_ = two_finger_tap_enabled_; |
| 315 | 320 |
| 321 max_touch_diameter_ = ev.GetTouchMajor(); |
| 316 // Always start the SHOW_PRESS timer before the LONG_PRESS timer to ensure | 322 // Always start the SHOW_PRESS timer before the LONG_PRESS timer to ensure |
| 317 // proper timeout ordering. | 323 // proper timeout ordering. |
| 318 timeout_handler_->StartTimeout(SHOW_PRESS); | 324 timeout_handler_->StartTimeout(SHOW_PRESS); |
| 319 if (longpress_enabled_) | 325 if (longpress_enabled_) |
| 320 timeout_handler_->StartTimeout(LONG_PRESS); | 326 timeout_handler_->StartTimeout(LONG_PRESS); |
| 321 handled |= listener_->OnDown(ev); | 327 handled |= listener_->OnDown(ev); |
| 322 break; | 328 break; |
| 323 | 329 |
| 324 case MotionEvent::ACTION_MOVE: | 330 case MotionEvent::ACTION_MOVE: |
| 325 { | 331 { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 344 if (distance_square > double_tap_touch_slop_square_) | 350 if (distance_square > double_tap_touch_slop_square_) |
| 345 always_in_bigger_tap_region_ = false; | 351 always_in_bigger_tap_region_ = false; |
| 346 } else if (std::abs(scroll_x) > kScrollEpsilon || | 352 } else if (std::abs(scroll_x) > kScrollEpsilon || |
| 347 std::abs(scroll_y) > kScrollEpsilon) { | 353 std::abs(scroll_y) > kScrollEpsilon) { |
| 348 handled = | 354 handled = |
| 349 listener_->OnScroll(*current_down_event_, ev, scroll_x, scroll_y); | 355 listener_->OnScroll(*current_down_event_, ev, scroll_x, scroll_y); |
| 350 last_focus_x_ = focus_x; | 356 last_focus_x_ = focus_x; |
| 351 last_focus_y_ = focus_y; | 357 last_focus_y_ = focus_y; |
| 352 } | 358 } |
| 353 | 359 |
| 360 if (timeout_handler_->HasTimeout(SHOW_PRESS)) { |
| 361 max_touch_diameter_ = |
| 362 std::max(max_touch_diameter_, ev.GetTouchMajor()); |
| 363 } |
| 364 |
| 354 if (!two_finger_tap_allowed_for_gesture_) | 365 if (!two_finger_tap_allowed_for_gesture_) |
| 355 break; | 366 break; |
| 356 | 367 |
| 357 // Two-finger tap should be prevented if either pointer exceeds its | 368 // Two-finger tap should be prevented if either pointer exceeds its |
| 358 // (independent) slop region. | 369 // (independent) slop region. |
| 359 const int id0 = current_down_event_->GetPointerId(0); | 370 const int id0 = current_down_event_->GetPointerId(0); |
| 360 const int ev_idx0 = ev.GetPointerId(0) == id0 ? 0 : 1; | 371 const int ev_idx0 = ev.GetPointerId(0) == id0 ? 0 : 1; |
| 361 | 372 |
| 362 // Check if the primary pointer exceeded the slop region. | 373 // Check if the primary pointer exceeded the slop region. |
| 363 float dx = current_down_event_->GetX() - ev.GetX(ev_idx0); | 374 float dx = current_down_event_->GetX() - ev.GetX(ev_idx0); |
| 364 float dy = current_down_event_->GetY() - ev.GetY(ev_idx0); | 375 float dy = current_down_event_->GetY() - ev.GetY(ev_idx0); |
| 365 if (dx * dx + dy * dy > touch_slop_square_) { | 376 if (dx * dx + dy * dy > touch_slop_square_) { |
| 366 two_finger_tap_allowed_for_gesture_ = false; | 377 two_finger_tap_allowed_for_gesture_ = false; |
| 367 break; | 378 break; |
| 368 } | 379 } |
| 369 if (ev.GetPointerCount() == 2) { | 380 if (ev.GetPointerCount() == 2) { |
| 370 // Check if the secondary pointer exceeded the slop region. | 381 // Check if the secondary pointer exceeded the slop region. |
| 371 const int ev_idx1 = ev_idx0 == 0 ? 1 : 0; | 382 const int ev_idx1 = ev_idx0 == 0 ? 1 : 0; |
| 372 const int idx1 = secondary_pointer_down_event_->GetActionIndex(); | 383 const int idx1 = secondary_pointer_down_event_->GetActionIndex(); |
| 373 dx = secondary_pointer_down_event_->GetX(idx1) - ev.GetX(ev_idx1); | 384 dx = secondary_pointer_down_event_->GetX(idx1) - ev.GetX(ev_idx1); |
| 374 dy = secondary_pointer_down_event_->GetY(idx1) - ev.GetY(ev_idx1); | 385 dy = secondary_pointer_down_event_->GetY(idx1) - ev.GetY(ev_idx1); |
| 375 if (dx * dx + dy * dy > touch_slop_square_) | 386 if (dx * dx + dy * dy > touch_slop_square_) |
| 376 two_finger_tap_allowed_for_gesture_ = false; | 387 two_finger_tap_allowed_for_gesture_ = false; |
| 377 } | 388 } |
| 389 |
| 378 } | 390 } |
| 379 break; | 391 break; |
| 380 | 392 |
| 381 case MotionEvent::ACTION_UP: | 393 case MotionEvent::ACTION_UP: |
| 382 still_down_ = false; | 394 still_down_ = false; |
| 383 { | 395 { |
| 384 if (is_double_tapping_) { | 396 if (is_double_tapping_) { |
| 385 // Finally, give the up event of the double-tap. | 397 // Finally, give the up event of the double-tap. |
| 386 DCHECK(double_tap_listener_); | 398 DCHECK(double_tap_listener_); |
| 387 handled |= double_tap_listener_->OnDoubleTapEvent(ev); | 399 handled |= double_tap_listener_->OnDoubleTapEvent(ev); |
| 388 } else if (always_in_tap_region_) { | 400 } else if (always_in_tap_region_) { |
| 389 handled = listener_->OnSingleTapUp(ev); | 401 handled = listener_->OnSingleTapUp(ev, |
| 402 current_down_event_->GetX(), |
| 403 current_down_event_->GetY(), |
| 404 max_touch_diameter_); |
| 390 if (defer_confirm_single_tap_ && double_tap_listener_ != NULL) { | 405 if (defer_confirm_single_tap_ && double_tap_listener_ != NULL) { |
| 391 double_tap_listener_->OnSingleTapConfirmed(ev); | 406 double_tap_listener_->OnSingleTapConfirmed( |
| 407 ev, |
| 408 current_down_event_->GetX(), |
| 409 current_down_event_->GetY(), |
| 410 max_touch_diameter_); |
| 392 } | 411 } |
| 393 } else { | 412 } else { |
| 394 | 413 |
| 395 // A fling must travel the minimum tap distance. | 414 // A fling must travel the minimum tap distance. |
| 396 const int pointer_id = ev.GetPointerId(0); | 415 const int pointer_id = ev.GetPointerId(0); |
| 397 velocity_tracker_.ComputeCurrentVelocity(1000, max_fling_velocity_); | 416 velocity_tracker_.ComputeCurrentVelocity(1000, max_fling_velocity_); |
| 398 const float velocity_y = velocity_tracker_.GetYVelocity(pointer_id); | 417 const float velocity_y = velocity_tracker_.GetYVelocity(pointer_id); |
| 399 const float velocity_x = velocity_tracker_.GetXVelocity(pointer_id); | 418 const float velocity_x = velocity_tracker_.GetXVelocity(pointer_id); |
| 400 | 419 |
| 401 if ((std::abs(velocity_y) > min_fling_velocity_) || | 420 if ((std::abs(velocity_y) > min_fling_velocity_) || |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 min_swipe_direction_component_ratio_ = | 486 min_swipe_direction_component_ratio_ = |
| 468 1.f / tan(maximum_swipe_deviation_angle * kDegreesToRadians); | 487 1.f / tan(maximum_swipe_deviation_angle * kDegreesToRadians); |
| 469 | 488 |
| 470 two_finger_tap_enabled_ = config.two_finger_tap_enabled; | 489 two_finger_tap_enabled_ = config.two_finger_tap_enabled; |
| 471 two_finger_tap_distance_square_ = config.two_finger_tap_max_separation * | 490 two_finger_tap_distance_square_ = config.two_finger_tap_max_separation * |
| 472 config.two_finger_tap_max_separation; | 491 config.two_finger_tap_max_separation; |
| 473 two_finger_tap_timeout_ = config.two_finger_tap_timeout; | 492 two_finger_tap_timeout_ = config.two_finger_tap_timeout; |
| 474 } | 493 } |
| 475 | 494 |
| 476 void GestureDetector::OnShowPressTimeout() { | 495 void GestureDetector::OnShowPressTimeout() { |
| 477 listener_->OnShowPress(*current_down_event_); | 496 listener_->OnShowPress(*current_down_event_, max_touch_diameter_); |
| 478 } | 497 } |
| 479 | 498 |
| 480 void GestureDetector::OnLongPressTimeout() { | 499 void GestureDetector::OnLongPressTimeout() { |
| 481 timeout_handler_->StopTimeout(TAP); | 500 timeout_handler_->StopTimeout(TAP); |
| 482 defer_confirm_single_tap_ = false; | 501 defer_confirm_single_tap_ = false; |
| 483 listener_->OnLongPress(*current_down_event_); | 502 listener_->OnLongPress(*current_down_event_); |
| 484 } | 503 } |
| 485 | 504 |
| 486 void GestureDetector::OnTapTimeout() { | 505 void GestureDetector::OnTapTimeout() { |
| 487 if (!double_tap_listener_) | 506 if (!double_tap_listener_) |
| 488 return; | 507 return; |
| 489 if (!still_down_) | 508 if (!still_down_) |
| 490 double_tap_listener_->OnSingleTapConfirmed(*current_down_event_); | 509 double_tap_listener_->OnSingleTapConfirmed(*current_down_event_, |
| 510 current_down_event_->GetX(), |
| 511 current_down_event_->GetY(), |
| 512 max_touch_diameter_); |
| 491 else | 513 else |
| 492 defer_confirm_single_tap_ = true; | 514 defer_confirm_single_tap_ = true; |
| 493 } | 515 } |
| 494 | 516 |
| 495 void GestureDetector::Cancel() { | 517 void GestureDetector::Cancel() { |
| 496 CancelTaps(); | 518 CancelTaps(); |
| 497 velocity_tracker_.Clear(); | 519 velocity_tracker_.Clear(); |
| 498 still_down_ = false; | 520 still_down_ = false; |
| 499 } | 521 } |
| 500 | 522 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 return false; | 566 return false; |
| 545 | 567 |
| 546 if (vx_abs > vy_abs) | 568 if (vx_abs > vy_abs) |
| 547 vy = 0; | 569 vy = 0; |
| 548 else | 570 else |
| 549 vx = 0; | 571 vx = 0; |
| 550 return listener_->OnSwipe(*current_down_event_, up, vx, vy); | 572 return listener_->OnSwipe(*current_down_event_, up, vx, vy); |
| 551 } | 573 } |
| 552 | 574 |
| 553 } // namespace ui | 575 } // namespace ui |
| OLD | NEW |