Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: ui/events/gesture_detection/gesture_detector.cc

Issue 1358263002: [Android] Support double-tap selection (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix aura Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 touch_slop(8), 48 touch_slop(8),
49 double_tap_slop(100), 49 double_tap_slop(100),
50 minimum_fling_velocity(50), 50 minimum_fling_velocity(50),
51 maximum_fling_velocity(8000), 51 maximum_fling_velocity(8000),
52 swipe_enabled(false), 52 swipe_enabled(false),
53 minimum_swipe_velocity(20), 53 minimum_swipe_velocity(20),
54 maximum_swipe_deviation_angle(20.f), 54 maximum_swipe_deviation_angle(20.f),
55 two_finger_tap_enabled(false), 55 two_finger_tap_enabled(false),
56 two_finger_tap_max_separation(300), 56 two_finger_tap_max_separation(300),
57 two_finger_tap_timeout(base::TimeDelta::FromMilliseconds(700)), 57 two_finger_tap_timeout(base::TimeDelta::FromMilliseconds(700)),
58 velocity_tracker_strategy(VelocityTracker::Strategy::STRATEGY_DEFAULT) { 58 single_tap_repeat_length(1),
59 } 59 velocity_tracker_strategy(VelocityTracker::Strategy::STRATEGY_DEFAULT) {}
60 60
61 GestureDetector::Config::~Config() {} 61 GestureDetector::Config::~Config() {}
62 62
63 class GestureDetector::TimeoutGestureHandler { 63 class GestureDetector::TimeoutGestureHandler {
64 public: 64 public:
65 TimeoutGestureHandler(const Config& config, GestureDetector* gesture_detector) 65 TimeoutGestureHandler(const Config& config, GestureDetector* gesture_detector)
66 : gesture_detector_(gesture_detector) { 66 : gesture_detector_(gesture_detector) {
67 DCHECK(config.showpress_timeout <= config.longpress_timeout); 67 DCHECK(config.showpress_timeout <= config.longpress_timeout);
68 68
69 timeout_callbacks_[SHOW_PRESS] = &GestureDetector::OnShowPressTimeout; 69 timeout_callbacks_[SHOW_PRESS] = &GestureDetector::OnShowPressTimeout;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 min_fling_velocity_(1), 122 min_fling_velocity_(1),
123 max_fling_velocity_(1), 123 max_fling_velocity_(1),
124 min_swipe_velocity_(0), 124 min_swipe_velocity_(0),
125 min_swipe_direction_component_ratio_(0), 125 min_swipe_direction_component_ratio_(0),
126 still_down_(false), 126 still_down_(false),
127 defer_confirm_single_tap_(false), 127 defer_confirm_single_tap_(false),
128 always_in_tap_region_(false), 128 always_in_tap_region_(false),
129 always_in_bigger_tap_region_(false), 129 always_in_bigger_tap_region_(false),
130 two_finger_tap_allowed_for_gesture_(false), 130 two_finger_tap_allowed_for_gesture_(false),
131 is_double_tapping_(false), 131 is_double_tapping_(false),
132 single_tap_count_(1),
133 single_tap_repeat_length_(1),
132 last_focus_x_(0), 134 last_focus_x_(0),
133 last_focus_y_(0), 135 last_focus_y_(0),
134 down_focus_x_(0), 136 down_focus_x_(0),
135 down_focus_y_(0), 137 down_focus_y_(0),
136 longpress_enabled_(true), 138 longpress_enabled_(true),
137 showpress_enabled_(true), 139 showpress_enabled_(true),
138 swipe_enabled_(false), 140 swipe_enabled_(false),
139 two_finger_tap_enabled_(false), 141 two_finger_tap_enabled_(false),
140 velocity_tracker_(config.velocity_tracker_strategy) { 142 velocity_tracker_(config.velocity_tracker_strategy) {
141 DCHECK(listener_); 143 DCHECK(listener_);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 handled = HandleSwipeIfNeeded(ev, vx_total / count, vy_total / count); 229 handled = HandleSwipeIfNeeded(ev, vx_total / count, vy_total / count);
228 230
229 if (two_finger_tap_allowed_for_gesture_ && ev.GetPointerCount() == 2 && 231 if (two_finger_tap_allowed_for_gesture_ && ev.GetPointerCount() == 2 &&
230 (ev.GetEventTime() - secondary_pointer_down_event_->GetEventTime() <= 232 (ev.GetEventTime() - secondary_pointer_down_event_->GetEventTime() <=
231 two_finger_tap_timeout_)) { 233 two_finger_tap_timeout_)) {
232 handled = listener_->OnTwoFingerTap(*current_down_event_, ev); 234 handled = listener_->OnTwoFingerTap(*current_down_event_, ev);
233 } 235 }
234 two_finger_tap_allowed_for_gesture_ = false; 236 two_finger_tap_allowed_for_gesture_ = false;
235 } break; 237 } break;
236 238
237 case MotionEvent::ACTION_DOWN: 239 case MotionEvent::ACTION_DOWN: {
240 bool maybe_double_tapping =
241 current_down_event_ && previous_up_event_ &&
242 IsConsideredDoubleTap(*current_down_event_, *previous_up_event_, ev);
238 if (double_tap_listener_) { 243 if (double_tap_listener_) {
244 single_tap_count_ = 1;
239 bool had_tap_message = timeout_handler_->HasTimeout(TAP); 245 bool had_tap_message = timeout_handler_->HasTimeout(TAP);
240 if (had_tap_message) 246 if (had_tap_message)
241 timeout_handler_->StopTimeout(TAP); 247 timeout_handler_->StopTimeout(TAP);
242 if (current_down_event_ && previous_up_event_ && had_tap_message && 248 if (maybe_double_tapping && had_tap_message) {
243 IsConsideredDoubleTap(
244 *current_down_event_, *previous_up_event_, ev)) {
245 // This is a second tap. 249 // This is a second tap.
246 is_double_tapping_ = true; 250 is_double_tapping_ = true;
247 // Give a callback with the first tap of the double-tap. 251 // Give a callback with the first tap of the double-tap.
248 handled |= double_tap_listener_->OnDoubleTap(*current_down_event_); 252 handled |= double_tap_listener_->OnDoubleTap(*current_down_event_);
249 // Give a callback with down event of the double-tap. 253 // Give a callback with down event of the double-tap.
250 handled |= double_tap_listener_->OnDoubleTapEvent(ev); 254 handled |= double_tap_listener_->OnDoubleTapEvent(ev);
251 } else { 255 } else {
252 // This is a first tap. 256 // This is a first tap.
253 DCHECK(double_tap_timeout_ > base::TimeDelta()); 257 DCHECK(double_tap_timeout_ > base::TimeDelta());
254 timeout_handler_->StartTimeout(TAP); 258 timeout_handler_->StartTimeout(TAP);
255 } 259 }
260 } else if (maybe_double_tapping) {
261 single_tap_count_ = 1 + (single_tap_count_ % single_tap_repeat_length_);
256 } 262 }
257 263
258 down_focus_x_ = last_focus_x_ = focus_x; 264 down_focus_x_ = last_focus_x_ = focus_x;
259 down_focus_y_ = last_focus_y_ = focus_y; 265 down_focus_y_ = last_focus_y_ = focus_y;
260 current_down_event_ = ev.Clone(); 266 current_down_event_ = ev.Clone();
261 267
262 secondary_pointer_down_event_.reset(); 268 secondary_pointer_down_event_.reset();
263 always_in_tap_region_ = true; 269 always_in_tap_region_ = true;
264 always_in_bigger_tap_region_ = true; 270 always_in_bigger_tap_region_ = true;
265 still_down_ = true; 271 still_down_ = true;
266 defer_confirm_single_tap_ = false; 272 defer_confirm_single_tap_ = false;
267 two_finger_tap_allowed_for_gesture_ = two_finger_tap_enabled_; 273 two_finger_tap_allowed_for_gesture_ = two_finger_tap_enabled_;
268 274
269 // Always start the SHOW_PRESS timer before the LONG_PRESS timer to ensure 275 // Always start the SHOW_PRESS timer before the LONG_PRESS timer to ensure
270 // proper timeout ordering. 276 // proper timeout ordering.
271 if (showpress_enabled_) 277 if (showpress_enabled_)
272 timeout_handler_->StartTimeout(SHOW_PRESS); 278 timeout_handler_->StartTimeout(SHOW_PRESS);
273 if (longpress_enabled_) 279 if (longpress_enabled_)
274 timeout_handler_->StartTimeout(LONG_PRESS); 280 timeout_handler_->StartTimeout(LONG_PRESS);
275 handled |= listener_->OnDown(ev); 281 handled |= listener_->OnDown(ev);
276 break; 282 } break;
277 283
278 case MotionEvent::ACTION_MOVE: 284 case MotionEvent::ACTION_MOVE:
279 { 285 {
280 const float scroll_x = last_focus_x_ - focus_x; 286 const float scroll_x = last_focus_x_ - focus_x;
281 const float scroll_y = last_focus_y_ - focus_y; 287 const float scroll_y = last_focus_y_ - focus_y;
282 if (is_double_tapping_) { 288 if (is_double_tapping_) {
283 // Give the move events of the double-tap. 289 // Give the move events of the double-tap.
284 DCHECK(double_tap_listener_); 290 DCHECK(double_tap_listener_);
285 handled |= double_tap_listener_->OnDoubleTapEvent(ev); 291 handled |= double_tap_listener_->OnDoubleTapEvent(ev);
286 } else if (always_in_tap_region_) { 292 } else if (always_in_tap_region_) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 break; 342 break;
337 343
338 case MotionEvent::ACTION_UP: 344 case MotionEvent::ACTION_UP:
339 still_down_ = false; 345 still_down_ = false;
340 { 346 {
341 if (is_double_tapping_) { 347 if (is_double_tapping_) {
342 // Finally, give the up event of the double-tap. 348 // Finally, give the up event of the double-tap.
343 DCHECK(double_tap_listener_); 349 DCHECK(double_tap_listener_);
344 handled |= double_tap_listener_->OnDoubleTapEvent(ev); 350 handled |= double_tap_listener_->OnDoubleTapEvent(ev);
345 } else if (always_in_tap_region_) { 351 } else if (always_in_tap_region_) {
346 handled = listener_->OnSingleTapUp(ev); 352 handled = listener_->OnSingleTapUp(ev, single_tap_count_);
347 if (defer_confirm_single_tap_ && double_tap_listener_ != NULL) { 353 if (defer_confirm_single_tap_ && double_tap_listener_ != NULL) {
348 double_tap_listener_->OnSingleTapConfirmed(ev); 354 double_tap_listener_->OnSingleTapConfirmed(ev);
349 } 355 }
350 } else { 356 } else {
351 357 single_tap_count_ = 1;
352 // A fling must travel the minimum tap distance. 358 // A fling must travel the minimum tap distance.
353 const int pointer_id = ev.GetPointerId(0); 359 const int pointer_id = ev.GetPointerId(0);
354 velocity_tracker_.ComputeCurrentVelocity(1000, max_fling_velocity_); 360 velocity_tracker_.ComputeCurrentVelocity(1000, max_fling_velocity_);
355 const float velocity_y = velocity_tracker_.GetYVelocity(pointer_id); 361 const float velocity_y = velocity_tracker_.GetYVelocity(pointer_id);
356 const float velocity_x = velocity_tracker_.GetXVelocity(pointer_id); 362 const float velocity_x = velocity_tracker_.GetXVelocity(pointer_id);
357 363
358 if ((std::abs(velocity_y) > min_fling_velocity_) || 364 if ((std::abs(velocity_y) > min_fling_velocity_) ||
359 (std::abs(velocity_x) > min_fling_velocity_)) { 365 (std::abs(velocity_x) > min_fling_velocity_)) {
360 handled = listener_->OnFling( 366 handled = listener_->OnFling(
361 *current_down_event_, ev, velocity_x, velocity_y); 367 *current_down_event_, ev, velocity_x, velocity_y);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 DCHECK_LE(config.maximum_swipe_deviation_angle, 45); 427 DCHECK_LE(config.maximum_swipe_deviation_angle, 45);
422 const float maximum_swipe_deviation_angle = 428 const float maximum_swipe_deviation_angle =
423 std::min(45.f, std::max(0.001f, config.maximum_swipe_deviation_angle)); 429 std::min(45.f, std::max(0.001f, config.maximum_swipe_deviation_angle));
424 min_swipe_direction_component_ratio_ = 430 min_swipe_direction_component_ratio_ =
425 1.f / tan(maximum_swipe_deviation_angle * kDegreesToRadians); 431 1.f / tan(maximum_swipe_deviation_angle * kDegreesToRadians);
426 432
427 two_finger_tap_enabled_ = config.two_finger_tap_enabled; 433 two_finger_tap_enabled_ = config.two_finger_tap_enabled;
428 two_finger_tap_distance_square_ = config.two_finger_tap_max_separation * 434 two_finger_tap_distance_square_ = config.two_finger_tap_max_separation *
429 config.two_finger_tap_max_separation; 435 config.two_finger_tap_max_separation;
430 two_finger_tap_timeout_ = config.two_finger_tap_timeout; 436 two_finger_tap_timeout_ = config.two_finger_tap_timeout;
437
438 DCHECK_GE(config.single_tap_repeat_length, 1);
439 single_tap_repeat_length_ = config.single_tap_repeat_length;
431 } 440 }
432 441
433 void GestureDetector::OnShowPressTimeout() { 442 void GestureDetector::OnShowPressTimeout() {
434 listener_->OnShowPress(*current_down_event_); 443 listener_->OnShowPress(*current_down_event_);
435 } 444 }
436 445
437 void GestureDetector::OnLongPressTimeout() { 446 void GestureDetector::OnLongPressTimeout() {
438 timeout_handler_->StopTimeout(TAP); 447 timeout_handler_->StopTimeout(TAP);
439 defer_confirm_single_tap_ = false; 448 defer_confirm_single_tap_ = false;
440 listener_->OnLongPress(*current_down_event_); 449 listener_->OnLongPress(*current_down_event_);
(...skipping 15 matching lines...) Expand all
456 velocity_tracker_.Clear(); 465 velocity_tracker_.Clear();
457 still_down_ = false; 466 still_down_ = false;
458 } 467 }
459 468
460 void GestureDetector::CancelTaps() { 469 void GestureDetector::CancelTaps() {
461 timeout_handler_->Stop(); 470 timeout_handler_->Stop();
462 is_double_tapping_ = false; 471 is_double_tapping_ = false;
463 always_in_tap_region_ = false; 472 always_in_tap_region_ = false;
464 always_in_bigger_tap_region_ = false; 473 always_in_bigger_tap_region_ = false;
465 defer_confirm_single_tap_ = false; 474 defer_confirm_single_tap_ = false;
475 single_tap_count_ = 1;
466 } 476 }
467 477
468 bool GestureDetector::IsConsideredDoubleTap( 478 bool GestureDetector::IsConsideredDoubleTap(
469 const MotionEvent& first_down, 479 const MotionEvent& first_down,
470 const MotionEvent& first_up, 480 const MotionEvent& first_up,
471 const MotionEvent& second_down) const { 481 const MotionEvent& second_down) const {
472 if (!always_in_bigger_tap_region_) 482 if (!always_in_bigger_tap_region_)
473 return false; 483 return false;
474 484
475 const base::TimeDelta delta_time = 485 const base::TimeDelta delta_time =
(...skipping 27 matching lines...) Expand all
503 return false; 513 return false;
504 514
505 if (vx_abs > vy_abs) 515 if (vx_abs > vy_abs)
506 vy = 0; 516 vy = 0;
507 else 517 else
508 vx = 0; 518 vx = 0;
509 return listener_->OnSwipe(*current_down_event_, up, vx, vy); 519 return listener_->OnSwipe(*current_down_event_, up, vx, vy);
510 } 520 }
511 521
512 } // namespace ui 522 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698