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

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

Issue 1358263002: [Android] Support double-tap selection (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix contextual search Created 5 years, 2 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 #include "ui/events/gesture_detection/gesture_provider.h" 5 #include "ui/events/gesture_detection/gesture_provider.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/trace_event/trace_event.h" 10 #include "base/trace_event/trace_event.h"
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 e2.GetFlags())); 397 e2.GetFlags()));
398 return true; 398 return true;
399 } 399 }
400 400
401 void OnShowPress(const MotionEvent& e) override { 401 void OnShowPress(const MotionEvent& e) override {
402 GestureEventDetails show_press_details(ET_GESTURE_SHOW_PRESS); 402 GestureEventDetails show_press_details(ET_GESTURE_SHOW_PRESS);
403 show_press_event_sent_ = true; 403 show_press_event_sent_ = true;
404 Send(CreateGesture(show_press_details, e)); 404 Send(CreateGesture(show_press_details, e));
405 } 405 }
406 406
407 bool OnSingleTapUp(const MotionEvent& e) override { 407 bool OnSingleTapUp(const MotionEvent& e, int tap_count) override {
408 // This is a hack to address the issue where user hovers 408 // This is a hack to address the issue where user hovers
409 // over a link for longer than double_tap_timeout_, then 409 // over a link for longer than double_tap_timeout_, then
410 // OnSingleTapConfirmed() is not triggered. But we still 410 // OnSingleTapConfirmed() is not triggered. But we still
411 // want to trigger the tap event at UP. So we override 411 // want to trigger the tap event at UP. So we override
412 // OnSingleTapUp() in this case. This assumes singleTapUp 412 // OnSingleTapUp() in this case. This assumes singleTapUp
413 // gets always called before singleTapConfirmed. 413 // gets always called before singleTapConfirmed.
414 if (!ignore_single_tap_) { 414 if (!ignore_single_tap_) {
415 if (e.GetEventTime() - current_down_time_ > 415 if (e.GetEventTime() - current_down_time_ >
416 config_.gesture_detector_config.double_tap_timeout) { 416 config_.gesture_detector_config.double_tap_timeout) {
417 return OnSingleTapConfirmed(e); 417 return OnSingleTapImpl(e, tap_count);
418 } else if (!IsDoubleTapEnabled()) { 418 } else if (!IsDoubleTapEnabled()) {
419 // If double-tap has been disabled, there is no need to wait 419 // If double-tap has been disabled, there is no need to wait
420 // for the double-tap timeout. 420 // for the double-tap timeout.
421 return OnSingleTapConfirmed(e); 421 return OnSingleTapImpl(e, tap_count);
422 } else { 422 } else {
423 // Notify Blink about this tapUp event anyway, when none of the above 423 // Notify Blink about this tapUp event anyway, when none of the above
424 // conditions applied. 424 // conditions applied.
425 Send(CreateTapGesture(ET_GESTURE_TAP_UNCONFIRMED, e)); 425 Send(CreateTapGesture(ET_GESTURE_TAP_UNCONFIRMED, e, 1));
426 } 426 }
427 } 427 }
428 428
429 if (e.GetAction() == MotionEvent::ACTION_UP && 429 if (e.GetAction() == MotionEvent::ACTION_UP &&
430 !current_longpress_time_.is_null() && 430 !current_longpress_time_.is_null() &&
431 !IsScaleGestureDetectionInProgress()) { 431 !IsScaleGestureDetectionInProgress()) {
432 GestureEventDetails long_tap_details(ET_GESTURE_LONG_TAP); 432 GestureEventDetails long_tap_details(ET_GESTURE_LONG_TAP);
433 Send(CreateGesture(long_tap_details, e)); 433 Send(CreateGesture(long_tap_details, e));
434 return true; 434 return true;
435 } 435 }
436 436
437 return false; 437 return false;
438 } 438 }
439 439
440 // DoubleTapListener implementation. 440 // DoubleTapListener implementation.
441 bool OnSingleTapConfirmed(const MotionEvent& e) override { 441 bool OnSingleTapConfirmed(const MotionEvent& e) override {
442 // Long taps in the edges of the screen have their events delayed by 442 return OnSingleTapImpl(e, 1);
443 // ContentViewHolder for tab swipe operations. As a consequence of the delay
444 // this method might be called after receiving the up event.
445 // These corner cases should be ignored.
446 if (ignore_single_tap_)
447 return true;
448
449 ignore_single_tap_ = true;
450
451 Send(CreateTapGesture(ET_GESTURE_TAP, e));
452 return true;
453 } 443 }
454 444
455 bool OnDoubleTap(const MotionEvent& e) override { 445 bool OnDoubleTap(const MotionEvent& e) override {
456 return scale_gesture_detector_.OnDoubleTap(e); 446 return scale_gesture_detector_.OnDoubleTap(e);
457 } 447 }
458 448
459 bool OnDoubleTapEvent(const MotionEvent& e) override { 449 bool OnDoubleTapEvent(const MotionEvent& e) override {
460 switch (e.GetAction()) { 450 switch (e.GetAction()) {
461 case MotionEvent::ACTION_DOWN: 451 case MotionEvent::ACTION_DOWN:
462 gesture_detector_.set_longpress_enabled(false); 452 gesture_detector_.set_longpress_enabled(false);
463 break; 453 break;
464 454
465 case MotionEvent::ACTION_UP: 455 case MotionEvent::ACTION_UP:
466 if (!IsPinchInProgress() && !IsScrollInProgress()) { 456 if (!IsPinchInProgress() && !IsScrollInProgress()) {
467 Send(CreateTapGesture(ET_GESTURE_DOUBLE_TAP, e)); 457 Send(CreateTapGesture(ET_GESTURE_DOUBLE_TAP, e, 1));
468 return true; 458 return true;
469 } 459 }
470 break; 460 break;
471 461
472 default: 462 default:
473 break; 463 break;
474 } 464 }
475 return false; 465 return false;
476 } 466 }
477 467
478 void OnLongPress(const MotionEvent& e) override { 468 void OnLongPress(const MotionEvent& e) override {
479 DCHECK(!IsDoubleTapInProgress()); 469 DCHECK(!IsDoubleTapInProgress());
480 SetIgnoreSingleTap(true); 470 SetIgnoreSingleTap(true);
481 GestureEventDetails long_press_details(ET_GESTURE_LONG_PRESS); 471 GestureEventDetails long_press_details(ET_GESTURE_LONG_PRESS);
482 Send(CreateGesture(long_press_details, e)); 472 Send(CreateGesture(long_press_details, e));
483 } 473 }
484 474
485 GestureEventData CreateGesture(const GestureEventDetails& details, 475 GestureEventData CreateGesture(const GestureEventDetails& details,
486 int motion_event_id, 476 int motion_event_id,
487 MotionEvent::ToolType primary_tool_type, 477 MotionEvent::ToolType primary_tool_type,
488 base::TimeTicks time, 478 base::TimeTicks time,
489 float x, 479 float x,
490 float y, 480 float y,
491 float raw_x, 481 float raw_x,
492 float raw_y, 482 float raw_y,
493 size_t touch_point_count, 483 size_t touch_point_count,
494 const gfx::RectF& bounding_box, 484 const gfx::RectF& bounding_box,
495 int flags) { 485 int flags) const {
496 return GestureEventData(details, 486 return GestureEventData(details,
497 motion_event_id, 487 motion_event_id,
498 primary_tool_type, 488 primary_tool_type,
499 time, 489 time,
500 x, 490 x,
501 y, 491 y,
502 raw_x, 492 raw_x,
503 raw_y, 493 raw_y,
504 touch_point_count, 494 touch_point_count,
505 bounding_box, 495 bounding_box,
506 flags); 496 flags);
507 } 497 }
508 498
509 GestureEventData CreateGesture(EventType type, 499 GestureEventData CreateGesture(EventType type,
510 int motion_event_id, 500 int motion_event_id,
511 MotionEvent::ToolType primary_tool_type, 501 MotionEvent::ToolType primary_tool_type,
512 base::TimeTicks time, 502 base::TimeTicks time,
513 float x, 503 float x,
514 float y, 504 float y,
515 float raw_x, 505 float raw_x,
516 float raw_y, 506 float raw_y,
517 size_t touch_point_count, 507 size_t touch_point_count,
518 const gfx::RectF& bounding_box, 508 const gfx::RectF& bounding_box,
519 int flags) { 509 int flags) const {
520 return GestureEventData(GestureEventDetails(type), 510 return GestureEventData(GestureEventDetails(type),
521 motion_event_id, 511 motion_event_id,
522 primary_tool_type, 512 primary_tool_type,
523 time, 513 time,
524 x, 514 x,
525 y, 515 y,
526 raw_x, 516 raw_x,
527 raw_y, 517 raw_y,
528 touch_point_count, 518 touch_point_count,
529 bounding_box, 519 bounding_box,
530 flags); 520 flags);
531 } 521 }
532 522
533 GestureEventData CreateGesture(const GestureEventDetails& details, 523 GestureEventData CreateGesture(const GestureEventDetails& details,
534 const MotionEvent& event) { 524 const MotionEvent& event) const {
535 return GestureEventData(details, 525 return GestureEventData(details,
536 event.GetPointerId(), 526 event.GetPointerId(),
537 event.GetToolType(), 527 event.GetToolType(),
538 event.GetEventTime(), 528 event.GetEventTime(),
539 event.GetX(), 529 event.GetX(),
540 event.GetY(), 530 event.GetY(),
541 event.GetRawX(), 531 event.GetRawX(),
542 event.GetRawY(), 532 event.GetRawY(),
543 event.GetPointerCount(), 533 event.GetPointerCount(),
544 GetBoundingBox(event, details.type()), 534 GetBoundingBox(event, details.type()),
545 event.GetFlags()); 535 event.GetFlags());
546 } 536 }
547 537
548 GestureEventData CreateGesture(EventType type, const MotionEvent& event) { 538 GestureEventData CreateGesture(EventType type,
539 const MotionEvent& event) const {
549 return CreateGesture(GestureEventDetails(type), event); 540 return CreateGesture(GestureEventDetails(type), event);
550 } 541 }
551 542
552 GestureEventData CreateTapGesture(EventType type, const MotionEvent& event) { 543 GestureEventData CreateTapGesture(EventType type,
553 // Set the tap count to 1 even for ET_GESTURE_DOUBLE_TAP, in order to be 544 const MotionEvent& event,
554 // consistent with double tap behavior on a mobile viewport. See 545 int tap_count) const {
555 // crbug.com/234986 for context. 546 DCHECK_GE(tap_count, 0);
556 GestureEventDetails details(type); 547 GestureEventDetails details(type);
557 details.set_tap_count(1); 548 details.set_tap_count(tap_count);
558 return CreateGesture(details, event); 549 return CreateGesture(details, event);
559 } 550 }
560 551
561 gfx::RectF GetBoundingBox(const MotionEvent& event, EventType type) { 552 gfx::RectF GetBoundingBox(const MotionEvent& event, EventType type) const {
562 // Can't use gfx::RectF::Union, as it ignores touches with a radius of 0. 553 // Can't use gfx::RectF::Union, as it ignores touches with a radius of 0.
563 float left = std::numeric_limits<float>::max(); 554 float left = std::numeric_limits<float>::max();
564 float top = std::numeric_limits<float>::max(); 555 float top = std::numeric_limits<float>::max();
565 float right = -std::numeric_limits<float>::max(); 556 float right = -std::numeric_limits<float>::max();
566 float bottom = -std::numeric_limits<float>::max(); 557 float bottom = -std::numeric_limits<float>::max();
567 for (size_t i = 0; i < event.GetPointerCount(); ++i) { 558 for (size_t i = 0; i < event.GetPointerCount(); ++i) {
568 float x, y, diameter; 559 float x, y, diameter;
569 // Only for the show press and tap events, the bounding box is calculated 560 // Only for the show press and tap events, the bounding box is calculated
570 // based on the touch start point and the maximum diameter before the 561 // based on the touch start point and the maximum diameter before the
571 // show press event is sent. 562 // show press event is sent.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 bool IsDoubleTapInProgress() const { 597 bool IsDoubleTapInProgress() const {
607 return gesture_detector_.is_double_tapping() || 598 return gesture_detector_.is_double_tapping() ||
608 (IsScaleGestureDetectionInProgress() && InDoubleTapMode()); 599 (IsScaleGestureDetectionInProgress() && InDoubleTapMode());
609 } 600 }
610 601
611 bool IsScrollInProgress() const { return scroll_event_sent_; } 602 bool IsScrollInProgress() const { return scroll_event_sent_; }
612 603
613 bool IsPinchInProgress() const { return pinch_event_sent_; } 604 bool IsPinchInProgress() const { return pinch_event_sent_; }
614 605
615 private: 606 private:
607 bool OnSingleTapImpl(const MotionEvent& e, int tap_count) {
608 // Long taps in the edges of the screen have their events delayed by
609 // ContentViewHolder for tab swipe operations. As a consequence of the delay
610 // this method might be called after receiving the up event.
611 // These corner cases should be ignored.
612 if (ignore_single_tap_)
613 return true;
614
615 ignore_single_tap_ = true;
616
617 Send(CreateTapGesture(ET_GESTURE_TAP, e, tap_count));
618 return true;
619 }
620
616 bool IsScaleGestureDetectionInProgress() const { 621 bool IsScaleGestureDetectionInProgress() const {
617 return scale_gesture_detector_.IsInProgress(); 622 return scale_gesture_detector_.IsInProgress();
618 } 623 }
619 624
620 bool InDoubleTapMode() const { 625 bool InDoubleTapMode() const {
621 return scale_gesture_detector_.InDoubleTapMode(); 626 return scale_gesture_detector_.InDoubleTapMode();
622 } 627 }
623 628
624 bool IsDoubleTapEnabled() const { 629 bool IsDoubleTapEnabled() const {
625 return gesture_detector_.has_doubletap_listener(); 630 return gesture_detector_.has_doubletap_listener();
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 // null'ing of the listener until the sequence has ended. 826 // null'ing of the listener until the sequence has ended.
822 if (current_down_event_) 827 if (current_down_event_)
823 return; 828 return;
824 829
825 const bool double_tap_enabled = 830 const bool double_tap_enabled =
826 double_tap_support_for_page_ && double_tap_support_for_platform_; 831 double_tap_support_for_page_ && double_tap_support_for_platform_;
827 gesture_listener_->SetDoubleTapEnabled(double_tap_enabled); 832 gesture_listener_->SetDoubleTapEnabled(double_tap_enabled);
828 } 833 }
829 834
830 } // namespace ui 835 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/gesture_detection/gesture_listeners.cc ('k') | ui/events/gesture_detection/gesture_provider_config_helper.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698