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

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

Issue 223673006: Support GestureBegin and GestureEnd in ui::GestureProvider (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address jdduke's comments. Created 6 years, 8 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 | Annotate | Revision Log
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/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 GestureEventDetails tap_details(type, 1, 0); 69 GestureEventDetails tap_details(type, 1, 0);
70 tap_details.set_bounding_box( 70 tap_details.set_bounding_box(
71 gfx::RectF(event.GetTouchMajor(), event.GetTouchMajor())); 71 gfx::RectF(event.GetTouchMajor(), event.GetTouchMajor()));
72 return tap_details; 72 return tap_details;
73 } 73 }
74 74
75 } // namespace 75 } // namespace
76 76
77 // GestureProvider:::Config 77 // GestureProvider:::Config
78 78
79 GestureProvider::Config::Config() : disable_click_delay(false) {} 79 GestureProvider::Config::Config()
80 : disable_click_delay(false), gesture_begin_end_types_enabled(false) {}
80 81
81 GestureProvider::Config::~Config() {} 82 GestureProvider::Config::~Config() {}
82 83
83 // GestureProvider::ScaleGestureListener 84 // GestureProvider::ScaleGestureListener
84 85
85 class GestureProvider::ScaleGestureListenerImpl 86 class GestureProvider::ScaleGestureListenerImpl
86 : public ScaleGestureDetector::ScaleGestureListener { 87 : public ScaleGestureDetector::ScaleGestureListener {
87 public: 88 public:
88 ScaleGestureListenerImpl(const ScaleGestureDetector::Config& config, 89 ScaleGestureListenerImpl(const ScaleGestureDetector::Config& config,
89 GestureProvider* provider) 90 GestureProvider* provider)
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 }; 598 };
598 599
599 // GestureProvider 600 // GestureProvider
600 601
601 GestureProvider::GestureProvider(const Config& config, 602 GestureProvider::GestureProvider(const Config& config,
602 GestureProviderClient* client) 603 GestureProviderClient* client)
603 : client_(client), 604 : client_(client),
604 needs_show_press_event_(false), 605 needs_show_press_event_(false),
605 needs_tap_ending_event_(false), 606 needs_tap_ending_event_(false),
606 touch_scroll_in_progress_(false), 607 touch_scroll_in_progress_(false),
607 pinch_in_progress_(false) { 608 pinch_in_progress_(false),
609 gesture_begin_end_types_enabled_(false) {
jdduke (slow) 2014/04/03 22:03:28 gesture_begin_end_types_enabled_(config.gesture_be
tdresser 2014/04/04 16:39:31 Done.
608 DCHECK(client); 610 DCHECK(client);
609 InitGestureDetectors(config); 611 InitGestureDetectors(config);
610 } 612 }
611 613
612 GestureProvider::~GestureProvider() {} 614 GestureProvider::~GestureProvider() {}
613 615
614 bool GestureProvider::OnTouchEvent(const MotionEvent& event) { 616 bool GestureProvider::OnTouchEvent(const MotionEvent& event) {
615 TRACE_EVENT1("input", "GestureProvider::OnTouchEvent", 617 TRACE_EVENT1("input", "GestureProvider::OnTouchEvent",
616 "action", GetMotionEventActionName(event.GetAction())); 618 "action", GetMotionEventActionName(event.GetAction()));
617 if (!CanHandle(event)) 619 if (!CanHandle(event))
618 return false; 620 return false;
619 621
620 const bool was_touch_scrolling_ = touch_scroll_in_progress_; 622 OnTouchEventHandlingBegin(event);
623
624 const bool was_touch_scrolling = touch_scroll_in_progress_;
621 const bool in_scale_gesture = 625 const bool in_scale_gesture =
622 scale_gesture_listener_->IsScaleGestureDetectionInProgress(); 626 scale_gesture_listener_->IsScaleGestureDetectionInProgress();
623 627
624 if (event.GetAction() == MotionEvent::ACTION_DOWN) {
625 current_down_event_ = event.Clone();
626 touch_scroll_in_progress_ = false;
627 needs_show_press_event_ = true;
628 current_longpress_time_ = base::TimeTicks();
629 SendTapCancelIfNecessary(event);
630 }
631 628
632 bool handled = gesture_listener_->OnTouchEvent(event, in_scale_gesture); 629 bool handled = gesture_listener_->OnTouchEvent(event, in_scale_gesture);
jdduke (slow) 2014/04/03 22:03:28 I guess we'll no longer need the |handled| variabl
tdresser 2014/04/04 16:39:31 Done.
633 handled |= scale_gesture_listener_->OnTouchEvent(event); 630 handled |= scale_gesture_listener_->OnTouchEvent(event);
634 631
635 if (event.GetAction() == MotionEvent::ACTION_UP || 632 OnTouchEventHandlingEnd(event, handled, was_touch_scrolling);
636 event.GetAction() == MotionEvent::ACTION_CANCEL) {
637 // "Last finger raised" could be an end to movement, but it should
638 // only terminate scrolling if the event did not cause a fling.
639 if (was_touch_scrolling_ && !handled)
640 EndTouchScrollIfNecessary(event.GetEventTime(), true);
641
642 // We shouldn't necessarily cancel a tap on ACTION_UP, as the double-tap
643 // timeout may yet trigger a SINGLE_TAP.
644 if (event.GetAction() == MotionEvent::ACTION_CANCEL)
645 SendTapCancelIfNecessary(event);
646
647 current_down_event_.reset();
648 }
649 633
650 return true; 634 return true;
651 } 635 }
652 636
653 void GestureProvider::ResetGestureDetectors() { 637 void GestureProvider::ResetGestureDetectors() {
654 if (!current_down_event_) 638 if (!current_down_event_)
655 return; 639 return;
656 scoped_ptr<MotionEvent> cancel_event = current_down_event_->Cancel(); 640 scoped_ptr<MotionEvent> cancel_event = current_down_event_->Cancel();
657 gesture_listener_->OnTouchEvent(*cancel_event, false); 641 gesture_listener_->OnTouchEvent(*cancel_event, false);
658 scale_gesture_listener_->OnTouchEvent(*cancel_event); 642 scale_gesture_listener_->OnTouchEvent(*cancel_event);
659 } 643 }
660 644
661 void GestureProvider::SetMultiTouchSupportEnabled(bool enabled) { 645 void GestureProvider::SetMultiTouchSupportEnabled(bool enabled) {
662 scale_gesture_listener_->set_ignore_detector_events(!enabled); 646 scale_gesture_listener_->set_ignore_detector_events(!enabled);
663 } 647 }
664 648
665 void GestureProvider::SetDoubleTapSupportForPlatformEnabled(bool enabled) { 649 void GestureProvider::SetDoubleTapSupportForPlatformEnabled(bool enabled) {
666 gesture_listener_->SetDoubleTapSupportForPlatformEnabled(enabled); 650 gesture_listener_->SetDoubleTapSupportForPlatformEnabled(enabled);
667 } 651 }
668 652
669 void GestureProvider::SetDoubleTapSupportForPageEnabled(bool enabled) { 653 void GestureProvider::SetDoubleTapSupportForPageEnabled(bool enabled) {
670 gesture_listener_->SetDoubleTapSupportForPageEnabled(enabled); 654 gesture_listener_->SetDoubleTapSupportForPageEnabled(enabled);
671 } 655 }
672 656
657 void GestureProvider::SetBeginEndTypesEnabled(bool enabled) {
658 gesture_begin_end_types_enabled_ = enabled;
659 }
660
673 bool GestureProvider::IsScrollInProgress() const { 661 bool GestureProvider::IsScrollInProgress() const {
674 // TODO(wangxianzhu): Also return true when fling is active once the UI knows 662 // TODO(wangxianzhu): Also return true when fling is active once the UI knows
675 // exactly when the fling ends. 663 // exactly when the fling ends.
676 return touch_scroll_in_progress_; 664 return touch_scroll_in_progress_;
677 } 665 }
678 666
679 bool GestureProvider::IsPinchInProgress() const { return pinch_in_progress_; } 667 bool GestureProvider::IsPinchInProgress() const { return pinch_in_progress_; }
680 668
681 bool GestureProvider::IsDoubleTapInProgress() const { 669 bool GestureProvider::IsDoubleTapInProgress() const {
682 return gesture_listener_->IsDoubleTapInProgress(); 670 return gesture_listener_->IsDoubleTapInProgress();
683 } 671 }
684 672
685 bool GestureProvider::IsClickDelayDisabled() const { 673 bool GestureProvider::IsClickDelayDisabled() const {
686 return gesture_listener_->IsClickDelayDisabled(); 674 return gesture_listener_->IsClickDelayDisabled();
687 } 675 }
688 676
689 void GestureProvider::InitGestureDetectors(const Config& config) { 677 void GestureProvider::InitGestureDetectors(const Config& config) {
690 TRACE_EVENT0("input", "GestureProvider::InitGestureDetectors"); 678 TRACE_EVENT0("input", "GestureProvider::InitGestureDetectors");
691 gesture_listener_.reset( 679 gesture_listener_.reset(
692 new GestureListenerImpl(config.gesture_detector_config, 680 new GestureListenerImpl(config.gesture_detector_config,
693 config.snap_scroll_controller_config, 681 config.snap_scroll_controller_config,
694 config.disable_click_delay, 682 config.disable_click_delay,
695 this)); 683 this));
696 684
697 scale_gesture_listener_.reset( 685 scale_gesture_listener_.reset(
698 new ScaleGestureListenerImpl(config.scale_gesture_detector_config, this)); 686 new ScaleGestureListenerImpl(config.scale_gesture_detector_config, this));
687 gesture_begin_end_types_enabled_ = config.gesture_begin_end_types_enabled;
699 } 688 }
700 689
701 bool GestureProvider::CanHandle(const MotionEvent& event) const { 690 bool GestureProvider::CanHandle(const MotionEvent& event) const {
702 return event.GetAction() == MotionEvent::ACTION_DOWN || current_down_event_; 691 return event.GetAction() == MotionEvent::ACTION_DOWN || current_down_event_;
703 } 692 }
704 693
705 void GestureProvider::Fling(base::TimeTicks time, 694 void GestureProvider::Fling(base::TimeTicks time,
706 float x, 695 float x,
707 float y, 696 float y,
708 float velocity_x, 697 float velocity_x,
(...skipping 18 matching lines...) Expand all
727 ET_SCROLL_FLING_START, velocity_x, velocity_y); 716 ET_SCROLL_FLING_START, velocity_x, velocity_y);
728 Send(CreateGesture(ET_SCROLL_FLING_START, time, x, y, fling_details)); 717 Send(CreateGesture(ET_SCROLL_FLING_START, time, x, y, fling_details));
729 } 718 }
730 719
731 void GestureProvider::Send(const GestureEventData& gesture) { 720 void GestureProvider::Send(const GestureEventData& gesture) {
732 DCHECK(!gesture.time.is_null()); 721 DCHECK(!gesture.time.is_null());
733 // The only valid events that should be sent without an active touch sequence 722 // The only valid events that should be sent without an active touch sequence
734 // are SHOW_PRESS and TAP, potentially triggered by the double-tap 723 // are SHOW_PRESS and TAP, potentially triggered by the double-tap
735 // delay timing out. 724 // delay timing out.
736 DCHECK(current_down_event_ || gesture.type == ET_GESTURE_TAP || 725 DCHECK(current_down_event_ || gesture.type == ET_GESTURE_TAP ||
737 gesture.type == ET_GESTURE_SHOW_PRESS); 726 gesture.type == ET_GESTURE_SHOW_PRESS ||
727 gesture.type == ET_GESTURE_BEGIN || gesture.type == ET_GESTURE_END);
jdduke (slow) 2014/04/03 22:03:28 If we send GESTURE_END before resetting the down e
tdresser 2014/04/04 16:39:31 Done.
738 728
739 switch (gesture.type) { 729 switch (gesture.type) {
740 case ET_GESTURE_TAP_DOWN: 730 case ET_GESTURE_TAP_DOWN:
741 needs_tap_ending_event_ = true; 731 needs_tap_ending_event_ = true;
742 break; 732 break;
743 case ET_GESTURE_TAP_UNCONFIRMED: 733 case ET_GESTURE_TAP_UNCONFIRMED:
744 needs_show_press_event_ = false; 734 needs_show_press_event_ = false;
745 break; 735 break;
746 case ET_GESTURE_TAP: 736 case ET_GESTURE_TAP:
747 if (needs_show_press_event_) 737 if (needs_show_press_event_)
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 801
812 void GestureProvider::EndTouchScrollIfNecessary(base::TimeTicks time, 802 void GestureProvider::EndTouchScrollIfNecessary(base::TimeTicks time,
813 bool send_scroll_end_event) { 803 bool send_scroll_end_event) {
814 if (!touch_scroll_in_progress_) 804 if (!touch_scroll_in_progress_)
815 return; 805 return;
816 touch_scroll_in_progress_ = false; 806 touch_scroll_in_progress_ = false;
817 if (send_scroll_end_event) 807 if (send_scroll_end_event)
818 Send(CreateGesture(ET_GESTURE_SCROLL_END, time, 0, 0)); 808 Send(CreateGesture(ET_GESTURE_SCROLL_END, time, 0, 0));
819 } 809 }
820 810
811 void GestureProvider::OnTouchEventHandlingBegin(const MotionEvent& event) {
812 switch (event.GetAction()) {
813 case MotionEvent::ACTION_DOWN:
814 current_down_event_ = event.Clone();
815 touch_scroll_in_progress_ = false;
816 needs_show_press_event_ = true;
jdduke (slow) 2014/04/03 22:03:28 Hmm, this show press assignment looks funky (prett
tdresser 2014/04/04 16:39:31 Done.
817 current_longpress_time_ = base::TimeTicks();
818 SendTapCancelIfNecessary(event);
819 if (gesture_begin_end_types_enabled_)
820 Send(CreateGesture(ET_GESTURE_BEGIN, event));
821 break;
822 case MotionEvent::ACTION_POINTER_DOWN:
823 if (gesture_begin_end_types_enabled_)
824 Send(CreateGesture(ET_GESTURE_BEGIN, event));
825 break;
826 case MotionEvent::ACTION_POINTER_UP:
827 case MotionEvent::ACTION_UP:
828 case MotionEvent::ACTION_CANCEL:
829 case MotionEvent::ACTION_MOVE:
830 break;
831 }
832 }
833
834 void GestureProvider::OnTouchEventHandlingEnd(
835 const MotionEvent& event, bool handled, bool was_touch_scrolling) {
836 switch (event.GetAction()) {
837 case MotionEvent::ACTION_UP:
838 case MotionEvent::ACTION_CANCEL:
839 // "Last finger raised" could be an end to movement, but it should
840 // only terminate scrolling if the event did not cause a fling.
841 if (was_touch_scrolling && !handled)
842 EndTouchScrollIfNecessary(event.GetEventTime(), true);
jdduke (slow) 2014/04/03 22:03:28 This will probably fail during rebase after https:
tdresser 2014/04/04 16:39:31 Done.
843
844 // We shouldn't necessarily cancel a tap on ACTION_UP, as the double-tap
845 // timeout may yet trigger a SINGLE_TAP.
846 if (event.GetAction() == MotionEvent::ACTION_CANCEL)
847 SendTapCancelIfNecessary(event);
848
849 current_down_event_.reset();
850 if (gesture_begin_end_types_enabled_)
jdduke (slow) 2014/04/03 22:03:28 This should come before resetting the down event (
tdresser 2014/04/04 16:39:31 Done.
851 Send(CreateGesture(ET_GESTURE_END, event));
852 break;
853 case MotionEvent::ACTION_POINTER_UP:
854 if (gesture_begin_end_types_enabled_)
855 Send(CreateGesture(ET_GESTURE_END, event));
856 break;
857 case MotionEvent::ACTION_DOWN:
858 case MotionEvent::ACTION_POINTER_DOWN:
859 case MotionEvent::ACTION_MOVE:
860 break;
861 }
862 }
863
821 } // namespace ui 864 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698