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 |