Chromium Code Reviews| 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 57 GestureDetector::Config::~Config() {} | 57 GestureDetector::Config::~Config() {} |
| 58 | 58 |
| 59 bool GestureDetector::SimpleGestureListener::OnDown(const MotionEvent& e) { | 59 bool GestureDetector::SimpleGestureListener::OnDown(const MotionEvent& e) { |
| 60 return false; | 60 return false; |
| 61 } | 61 } |
| 62 | 62 |
| 63 void GestureDetector::SimpleGestureListener::OnShowPress(const MotionEvent& e) { | 63 void GestureDetector::SimpleGestureListener::OnShowPress(const MotionEvent& e) { |
| 64 } | 64 } |
| 65 | 65 |
| 66 bool GestureDetector::SimpleGestureListener::OnSingleTapUp( | 66 bool GestureDetector::SimpleGestureListener::OnSingleTapUp( |
| 67 const MotionEvent& e) { | 67 const MotionEvent& e, int tap_count) { |
|
jdduke (slow)
2014/05/21 15:07:14
Maybe tap_repeat_count? Hmm, but that's slightly a
tdresser
2014/05/21 16:39:15
We use tap_count throughout (GestureEventDetails,
| |
| 68 return false; | 68 return false; |
| 69 } | 69 } |
| 70 | 70 |
| 71 bool GestureDetector::SimpleGestureListener::OnLongPress(const MotionEvent& e) { | 71 bool GestureDetector::SimpleGestureListener::OnLongPress(const MotionEvent& e) { |
| 72 return false; | 72 return false; |
| 73 } | 73 } |
| 74 | 74 |
| 75 bool GestureDetector::SimpleGestureListener::OnScroll(const MotionEvent& e1, | 75 bool GestureDetector::SimpleGestureListener::OnScroll(const MotionEvent& e1, |
| 76 const MotionEvent& e2, | 76 const MotionEvent& e2, |
| 77 float distance_x, | 77 float distance_x, |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 93 return false; | 93 return false; |
| 94 } | 94 } |
| 95 | 95 |
| 96 bool GestureDetector::SimpleGestureListener::OnTwoFingerTap( | 96 bool GestureDetector::SimpleGestureListener::OnTwoFingerTap( |
| 97 const MotionEvent& e1, | 97 const MotionEvent& e1, |
| 98 const MotionEvent& e2) { | 98 const MotionEvent& e2) { |
| 99 return false; | 99 return false; |
| 100 } | 100 } |
| 101 | 101 |
| 102 bool GestureDetector::SimpleGestureListener::OnSingleTapConfirmed( | 102 bool GestureDetector::SimpleGestureListener::OnSingleTapConfirmed( |
| 103 const MotionEvent& e) { | 103 const MotionEvent& e, int tap_count) { |
| 104 return false; | 104 return false; |
| 105 } | 105 } |
| 106 | 106 |
| 107 bool GestureDetector::SimpleGestureListener::OnDoubleTap(const MotionEvent& e) { | 107 bool GestureDetector::SimpleGestureListener::OnDoubleTap(const MotionEvent& e) { |
| 108 return false; | 108 return false; |
| 109 } | 109 } |
| 110 | 110 |
| 111 bool GestureDetector::SimpleGestureListener::OnDoubleTapEvent( | 111 bool GestureDetector::SimpleGestureListener::OnDoubleTapEvent( |
| 112 const MotionEvent& e) { | 112 const MotionEvent& e) { |
| 113 return false; | 113 return false; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 180 defer_confirm_single_tap_(false), | 180 defer_confirm_single_tap_(false), |
| 181 in_longpress_(false), | 181 in_longpress_(false), |
| 182 always_in_tap_region_(false), | 182 always_in_tap_region_(false), |
| 183 always_in_bigger_tap_region_(false), | 183 always_in_bigger_tap_region_(false), |
| 184 two_finger_tap_allowed_for_gesture_(false), | 184 two_finger_tap_allowed_for_gesture_(false), |
| 185 is_double_tapping_(false), | 185 is_double_tapping_(false), |
| 186 last_focus_x_(0), | 186 last_focus_x_(0), |
| 187 last_focus_y_(0), | 187 last_focus_y_(0), |
| 188 down_focus_x_(0), | 188 down_focus_x_(0), |
| 189 down_focus_y_(0), | 189 down_focus_y_(0), |
| 190 longpress_enabled_(true), | 190 longpress_enabled_(true), |
| 191 swipe_enabled_(false), | 191 swipe_enabled_(false), |
| 192 two_finger_tap_enabled_(false) { | 192 two_finger_tap_enabled_(false), |
| 193 tap_count_(0) { | |
| 193 DCHECK(listener_); | 194 DCHECK(listener_); |
| 194 Init(config); | 195 Init(config); |
| 195 } | 196 } |
| 196 | 197 |
| 197 GestureDetector::~GestureDetector() {} | 198 GestureDetector::~GestureDetector() {} |
| 198 | 199 |
| 199 bool GestureDetector::OnTouchEvent(const MotionEvent& ev) { | 200 bool GestureDetector::OnTouchEvent(const MotionEvent& ev) { |
| 200 const MotionEvent::Action action = ev.GetAction(); | 201 const MotionEvent::Action action = ev.GetAction(); |
| 201 | 202 |
| 202 velocity_tracker_.AddMovement(ev); | 203 velocity_tracker_.AddMovement(ev); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 320 handled |= double_tap_listener_->OnDoubleTapEvent(ev); | 321 handled |= double_tap_listener_->OnDoubleTapEvent(ev); |
| 321 } else { | 322 } else { |
| 322 // This is a first tap. | 323 // This is a first tap. |
| 323 DCHECK(double_tap_timeout_ > base::TimeDelta()); | 324 DCHECK(double_tap_timeout_ > base::TimeDelta()); |
| 324 timeout_handler_->StartTimeout(TAP); | 325 timeout_handler_->StartTimeout(TAP); |
| 325 } | 326 } |
| 326 } | 327 } |
| 327 | 328 |
| 328 down_focus_x_ = last_focus_x_ = focus_x; | 329 down_focus_x_ = last_focus_x_ = focus_x; |
| 329 down_focus_y_ = last_focus_y_ = focus_y; | 330 down_focus_y_ = last_focus_y_ = focus_y; |
| 331 previous_down_event_ = current_down_event_.Pass(); | |
| 330 current_down_event_ = ev.Clone(); | 332 current_down_event_ = ev.Clone(); |
| 331 | 333 |
| 332 secondary_pointer_down_event_.reset(); | 334 secondary_pointer_down_event_.reset(); |
| 333 always_in_tap_region_ = true; | 335 always_in_tap_region_ = true; |
| 334 always_in_bigger_tap_region_ = true; | 336 always_in_bigger_tap_region_ = true; |
| 335 still_down_ = true; | 337 still_down_ = true; |
| 336 in_longpress_ = false; | 338 in_longpress_ = false; |
| 337 defer_confirm_single_tap_ = false; | 339 defer_confirm_single_tap_ = false; |
| 338 two_finger_tap_allowed_for_gesture_ = two_finger_tap_enabled_; | 340 two_finger_tap_allowed_for_gesture_ = two_finger_tap_enabled_; |
| 339 | 341 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 409 still_down_ = false; | 411 still_down_ = false; |
| 410 { | 412 { |
| 411 if (is_double_tapping_) { | 413 if (is_double_tapping_) { |
| 412 // Finally, give the up event of the double-tap. | 414 // Finally, give the up event of the double-tap. |
| 413 DCHECK(double_tap_listener_); | 415 DCHECK(double_tap_listener_); |
| 414 handled |= double_tap_listener_->OnDoubleTapEvent(ev); | 416 handled |= double_tap_listener_->OnDoubleTapEvent(ev); |
| 415 } else if (in_longpress_) { | 417 } else if (in_longpress_) { |
| 416 timeout_handler_->StopTimeout(TAP); | 418 timeout_handler_->StopTimeout(TAP); |
| 417 in_longpress_ = false; | 419 in_longpress_ = false; |
| 418 } else if (always_in_tap_region_) { | 420 } else if (always_in_tap_region_) { |
| 419 handled = listener_->OnSingleTapUp(ev); | 421 if (double_tap_listener_) { |
| 422 tap_count_ = 1; | |
| 423 } else { | |
| 424 if (previous_down_event_ && previous_up_event_ && | |
| 425 current_down_event_ && | |
| 426 IsConsideredDoubleTap(*previous_down_event_, | |
| 427 *previous_up_event_, | |
| 428 *current_down_event_)) { | |
| 429 ++tap_count_; | |
| 430 // We only support up to triple tap. Further taps are also treated | |
| 431 // as triple taps. | |
| 432 tap_count_ = std::min(tap_count_, 3); | |
|
jdduke (slow)
2014/05/21 15:07:14
I'd prefer the GestureDetector not have any awaren
tdresser
2014/05/21 16:39:15
Done.
| |
| 433 } else { | |
| 434 // As we're outside of the double tap range, reset the | |
| 435 // |tap_count_|. | |
| 436 tap_count_ = 1; | |
| 437 } | |
| 438 } | |
| 439 handled = listener_->OnSingleTapUp(ev, tap_count_); | |
| 420 if (defer_confirm_single_tap_ && double_tap_listener_ != NULL) { | 440 if (defer_confirm_single_tap_ && double_tap_listener_ != NULL) { |
| 421 double_tap_listener_->OnSingleTapConfirmed(ev); | 441 double_tap_listener_->OnSingleTapConfirmed(ev, 1); |
|
jdduke (slow)
2014/05/21 15:07:14
Might as well just use |tap_count_| here instead o
tdresser
2014/05/21 16:39:15
Done.
| |
| 422 } | 442 } |
| 423 } else { | 443 } else { |
| 424 | 444 |
| 425 // A fling must travel the minimum tap distance. | 445 // A fling must travel the minimum tap distance. |
| 426 const int pointer_id = ev.GetPointerId(0); | 446 const int pointer_id = ev.GetPointerId(0); |
| 427 velocity_tracker_.ComputeCurrentVelocity(1000, max_fling_velocity_); | 447 velocity_tracker_.ComputeCurrentVelocity(1000, max_fling_velocity_); |
| 428 const float velocity_y = velocity_tracker_.GetYVelocity(pointer_id); | 448 const float velocity_y = velocity_tracker_.GetYVelocity(pointer_id); |
| 429 const float velocity_x = velocity_tracker_.GetXVelocity(pointer_id); | 449 const float velocity_x = velocity_tracker_.GetXVelocity(pointer_id); |
| 430 | 450 |
| 431 if ((std::abs(velocity_y) > min_fling_velocity_) || | 451 if ((std::abs(velocity_y) > min_fling_velocity_) || |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 506 void GestureDetector::OnLongPressTimeout() { | 526 void GestureDetector::OnLongPressTimeout() { |
| 507 timeout_handler_->StopTimeout(TAP); | 527 timeout_handler_->StopTimeout(TAP); |
| 508 defer_confirm_single_tap_ = false; | 528 defer_confirm_single_tap_ = false; |
| 509 in_longpress_ = listener_->OnLongPress(*current_down_event_); | 529 in_longpress_ = listener_->OnLongPress(*current_down_event_); |
| 510 } | 530 } |
| 511 | 531 |
| 512 void GestureDetector::OnTapTimeout() { | 532 void GestureDetector::OnTapTimeout() { |
| 513 if (!double_tap_listener_) | 533 if (!double_tap_listener_) |
| 514 return; | 534 return; |
| 515 if (!still_down_) | 535 if (!still_down_) |
| 516 double_tap_listener_->OnSingleTapConfirmed(*current_down_event_); | 536 double_tap_listener_->OnSingleTapConfirmed(*current_down_event_, 1); |
| 517 else | 537 else |
| 518 defer_confirm_single_tap_ = true; | 538 defer_confirm_single_tap_ = true; |
| 519 } | 539 } |
| 520 | 540 |
| 521 void GestureDetector::Cancel() { | 541 void GestureDetector::Cancel() { |
| 522 timeout_handler_->Stop(); | 542 timeout_handler_->Stop(); |
| 523 velocity_tracker_.Clear(); | 543 velocity_tracker_.Clear(); |
| 524 is_double_tapping_ = false; | 544 is_double_tapping_ = false; |
| 525 still_down_ = false; | 545 still_down_ = false; |
|
jdduke (slow)
2014/05/21 15:07:14
We should probably reset tap_count_ both here and
tdresser
2014/05/21 16:39:15
Done.
| |
| 526 always_in_tap_region_ = false; | 546 always_in_tap_region_ = false; |
| 527 always_in_bigger_tap_region_ = false; | 547 always_in_bigger_tap_region_ = false; |
| 528 defer_confirm_single_tap_ = false; | 548 defer_confirm_single_tap_ = false; |
| 529 in_longpress_ = false; | 549 in_longpress_ = false; |
| 530 } | 550 } |
| 531 | 551 |
| 532 void GestureDetector::CancelTaps() { | 552 void GestureDetector::CancelTaps() { |
| 533 timeout_handler_->Stop(); | 553 timeout_handler_->Stop(); |
| 534 is_double_tapping_ = false; | 554 is_double_tapping_ = false; |
| 535 always_in_tap_region_ = false; | 555 always_in_tap_region_ = false; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 548 if (second_down.GetEventTime() - first_up.GetEventTime() > | 568 if (second_down.GetEventTime() - first_up.GetEventTime() > |
| 549 double_tap_timeout_) | 569 double_tap_timeout_) |
| 550 return false; | 570 return false; |
| 551 | 571 |
| 552 const float delta_x = first_down.GetX() - second_down.GetX(); | 572 const float delta_x = first_down.GetX() - second_down.GetX(); |
| 553 const float delta_y = first_down.GetY() - second_down.GetY(); | 573 const float delta_y = first_down.GetY() - second_down.GetY(); |
| 554 return (delta_x * delta_x + delta_y * delta_y < double_tap_slop_square_); | 574 return (delta_x * delta_x + delta_y * delta_y < double_tap_slop_square_); |
| 555 } | 575 } |
| 556 | 576 |
| 557 } // namespace ui | 577 } // namespace ui |
| OLD | NEW |