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

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

Issue 2058723003: Slop region check for multi-finger scroll (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 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 <stddef.h> 7 #include <stddef.h>
8 8
9 #include <cmath> 9 #include <cmath>
10 10
11 #include "base/auto_reset.h" 11 #include "base/auto_reset.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/trace_event/trace_event.h" 13 #include "base/trace_event/trace_event.h"
14 #include "ui/events/event_constants.h" 14 #include "ui/events/event_constants.h"
15 #include "ui/events/gesture_detection/gesture_event_data.h" 15 #include "ui/events/gesture_detection/gesture_event_data.h"
16 #include "ui/events/gesture_detection/gesture_listeners.h" 16 #include "ui/events/gesture_detection/gesture_listeners.h"
17 #include "ui/events/gesture_detection/motion_event.h" 17 #include "ui/events/gesture_detection/motion_event.h"
18 #include "ui/events/gesture_detection/motion_event_generic.h" 18 #include "ui/events/gesture_detection/motion_event_generic.h"
19 #include "ui/events/gesture_detection/scale_gesture_listeners.h" 19 #include "ui/events/gesture_detection/scale_gesture_listeners.h"
20 #include "ui/gfx/geometry/point_f.h" 20 #include "ui/gfx/geometry/point_f.h"
21 #include "ui/gfx/geometry/vector2d_f.h"
21 22
22 namespace ui { 23 namespace ui {
23 namespace { 24 namespace {
24 25
25 // Double-tap drag zoom sensitivity (speed). 26 // Double-tap drag zoom sensitivity (speed).
26 const float kDoubleTapDragZoomSpeed = 0.005f; 27 const float kDoubleTapDragZoomSpeed = 0.005f;
27 28
28 const char* GetMotionEventActionName(MotionEvent::Action action) { 29 const char* GetMotionEventActionName(MotionEvent::Action action) {
29 switch (action) { 30 switch (action) {
30 case MotionEvent::ACTION_NONE: 31 case MotionEvent::ACTION_NONE:
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 current_down_time_ = event.GetEventTime(); 112 current_down_time_ = event.GetEventTime();
112 current_longpress_time_ = base::TimeTicks(); 113 current_longpress_time_ = base::TimeTicks();
113 ignore_single_tap_ = false; 114 ignore_single_tap_ = false;
114 scroll_event_sent_ = false; 115 scroll_event_sent_ = false;
115 pinch_event_sent_ = false; 116 pinch_event_sent_ = false;
116 show_press_event_sent_ = false; 117 show_press_event_sent_ = false;
117 gesture_detector_.set_longpress_enabled(true); 118 gesture_detector_.set_longpress_enabled(true);
118 tap_down_point_ = gfx::PointF(event.GetX(), event.GetY()); 119 tap_down_point_ = gfx::PointF(event.GetX(), event.GetY());
119 max_diameter_before_show_press_ = event.GetTouchMajor(); 120 max_diameter_before_show_press_ = event.GetTouchMajor();
120 } 121 }
121
122 gesture_detector_.OnTouchEvent(event); 122 gesture_detector_.OnTouchEvent(event);
123 scale_gesture_detector_.OnTouchEvent(event); 123 scale_gesture_detector_.OnTouchEvent(event);
124 124
125 if (action == MotionEvent::ACTION_UP || 125 if (action == MotionEvent::ACTION_UP ||
126 action == MotionEvent::ACTION_CANCEL) { 126 action == MotionEvent::ACTION_CANCEL) {
127 // Note: This call will have no effect if a fling was just generated, as 127 // Note: This call will have no effect if a fling was just generated, as
128 // |Fling()| will have already signalled an end to touch-scrolling. 128 // |Fling()| will have already signalled an end to touch-scrolling.
129 if (scroll_event_sent_) 129 if (scroll_event_sent_)
130 Send(CreateGesture(ET_GESTURE_SCROLL_END, event)); 130 Send(CreateGesture(ET_GESTURE_SCROLL_END, event));
131 current_down_time_ = base::TimeTicks(); 131 current_down_time_ = base::TimeTicks();
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 GestureEventDetails tap_details(ET_GESTURE_TAP_DOWN); 277 GestureEventDetails tap_details(ET_GESTURE_TAP_DOWN);
278 tap_details.set_device_type(GestureDeviceType::DEVICE_TOUCHSCREEN); 278 tap_details.set_device_type(GestureDeviceType::DEVICE_TOUCHSCREEN);
279 Send(CreateGesture(tap_details, e)); 279 Send(CreateGesture(tap_details, e));
280 280
281 // Return true to indicate that we want to handle touch. 281 // Return true to indicate that we want to handle touch.
282 return true; 282 return true;
283 } 283 }
284 284
285 bool OnScroll(const MotionEvent& e1, 285 bool OnScroll(const MotionEvent& e1,
286 const MotionEvent& e2, 286 const MotionEvent& e2,
287 const MotionEvent& secondary_pointer_down,
287 float raw_distance_x, 288 float raw_distance_x,
288 float raw_distance_y) override { 289 float raw_distance_y) override {
289 float distance_x = raw_distance_x; 290 float distance_x = raw_distance_x;
290 float distance_y = raw_distance_y; 291 float distance_y = raw_distance_y;
291 if (!scroll_event_sent_ && e2.GetPointerCount() == 1) { 292 if (!scroll_event_sent_ && e2.GetPointerCount() < 3) {
292 // Remove the touch slop region from the first scroll event to 293 // Remove the touch slop region from the first scroll event to avoid a
293 // avoid a jump. Touch slop isn't used for multi-finger 294 // jump. Touch slop isn't used for scroll gestures with greater than 2
294 // gestures, so in those cases we don't subtract the slop. 295 // pointers down, in those cases we don't subtract the slop.
295 float distance = 296 gfx::Vector2dF delta =
296 std::sqrt(distance_x * distance_x + distance_y * distance_y); 297 ComputeFirstScrollDelta(e1, e2, secondary_pointer_down);
297 float epsilon = 1e-3f; 298 distance_x = delta.x();
298 if (distance > epsilon) { 299 distance_y = delta.y();
299 float ratio =
300 std::max(0.f,
301 distance - config_.gesture_detector_config.touch_slop) /
302 distance;
303 distance_x *= ratio;
304 distance_y *= ratio;
305 }
306 } 300 }
307 301
308 snap_scroll_controller_.UpdateSnapScrollMode(distance_x, distance_y); 302 snap_scroll_controller_.UpdateSnapScrollMode(distance_x, distance_y);
309 if (snap_scroll_controller_.IsSnappingScrolls()) { 303 if (snap_scroll_controller_.IsSnappingScrolls()) {
310 if (snap_scroll_controller_.IsSnapHorizontal()) 304 if (snap_scroll_controller_.IsSnapHorizontal())
311 distance_y = 0; 305 distance_y = 0;
312 else 306 else
313 distance_x = 0; 307 distance_x = 0;
314 } 308 }
315 309
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 bool InAnchoredScaleMode() const { 643 bool InAnchoredScaleMode() const {
650 return scale_gesture_detector_.InAnchoredScaleMode(); 644 return scale_gesture_detector_.InAnchoredScaleMode();
651 } 645 }
652 646
653 bool IsDoubleTapEnabled() const { 647 bool IsDoubleTapEnabled() const {
654 return gesture_detector_.has_doubletap_listener(); 648 return gesture_detector_.has_doubletap_listener();
655 } 649 }
656 650
657 void SetIgnoreSingleTap(bool value) { ignore_single_tap_ = value; } 651 void SetIgnoreSingleTap(bool value) { ignore_single_tap_ = value; }
658 652
653 // When any of the currently down pointers exceeds its slop region
654 // for the first time, scroll delta is adjusted.
655 // The new deltas are calculated for each pointer individually,
656 // and the final scroll delta is the average over all delta values.
657 gfx::Vector2dF ComputeFirstScrollDelta(
658 const MotionEvent& ev1,
659 const MotionEvent& ev2,
660 const MotionEvent& secondary_pointer_down) {
661 // If there are more than two down pointers, tapping is not possible,
662 // so Slop region is not deducted.
663 DCHECK(ev2.GetPointerCount() < 3);
664
665 const int id0 = ev1.GetPointerId(0);
666 const int ev_idx0 = ev2.GetPointerId(0) == id0 ? 0 : 1;
667
668 // Subtract the slop region from the first pointer move.
669 float dx0 = ev1.GetX() - ev2.GetX(ev_idx0);
670 float dy0 = ev1.GetY() - ev2.GetY(ev_idx0);
671 float distance0 = std::sqrt(dx0 * dx0 + dy0 * dy0);
672 float epsilon = 1e-3f;
673 if (distance0 > epsilon) {
674 float ratio =
675 std::max(0.f,
676 distance0 - config_.gesture_detector_config.touch_slop) /
677 distance0;
678 dx0 *= ratio;
679 dy0 *= ratio;
680 }
681 float dx1 = 0;
682 float dy1 = 0;
683 // Subtract the slop region from the second pointer move.
684 if (ev2.GetPointerCount() == 2) {
tdresser 2016/07/01 14:29:15 Could we factor out the slop subtraction here? Li
sahel 2016/07/05 20:36:35 Done.
685 const int ev_idx1 = ev_idx0 == 0 ? 1 : 0;
686 const int idx1 = secondary_pointer_down.GetActionIndex();
687 dx1 = secondary_pointer_down.GetX(idx1) - ev2.GetX(ev_idx1);
688 dy1 = secondary_pointer_down.GetY(idx1) - ev2.GetY(ev_idx1);
689 float distance1 = std::sqrt(dx1 * dx1 + dy1 * dy1);
690 if (distance1 > epsilon) {
691 float ratio =
692 std::max(0.f,
693 distance1 - config_.gesture_detector_config.touch_slop) /
694 distance1;
695 dx1 *= ratio;
696 dy1 *= ratio;
697 }
698 }
699 float delta_x = (dx0 + dx1) / ev2.GetPointerCount();
700 float delta_y = (dy0 + dy1) / ev2.GetPointerCount();
701 gfx::Vector2dF delta(delta_x, delta_y);
702 return delta;
703 }
704
659 const GestureProvider::Config config_; 705 const GestureProvider::Config config_;
660 GestureProviderClient* const client_; 706 GestureProviderClient* const client_;
661 707
662 GestureDetector gesture_detector_; 708 GestureDetector gesture_detector_;
663 ScaleGestureDetector scale_gesture_detector_; 709 ScaleGestureDetector scale_gesture_detector_;
664 SnapScrollController snap_scroll_controller_; 710 SnapScrollController snap_scroll_controller_;
665 711
666 base::TimeTicks current_down_time_; 712 base::TimeTicks current_down_time_;
667 713
668 // Keeps track of the current GESTURE_LONG_PRESS event. If a context menu is 714 // Keeps track of the current GESTURE_LONG_PRESS event. If a context menu is
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 // null'ing of the listener until the sequence has ended. 895 // null'ing of the listener until the sequence has ended.
850 if (current_down_event_) 896 if (current_down_event_)
851 return; 897 return;
852 898
853 const bool double_tap_enabled = 899 const bool double_tap_enabled =
854 double_tap_support_for_page_ && double_tap_support_for_platform_; 900 double_tap_support_for_page_ && double_tap_support_for_platform_;
855 gesture_listener_->SetDoubleTapEnabled(double_tap_enabled); 901 gesture_listener_->SetDoubleTapEnabled(double_tap_enabled);
856 } 902 }
857 903
858 } // namespace ui 904 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698