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

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 gfx::Vector2dF SubtractSlopRegion(const float dx, const float dy) {
654 float distance = std::sqrt(dx * dx + dy * dy);
655 float epsilon = 1e-3f;
656 if (distance > epsilon) {
657 float ratio =
658 std::max(0.f, distance - config_.gesture_detector_config.touch_slop) /
659 distance;
660 gfx::Vector2dF delta(dx * ratio, dy * ratio);
661 return delta;
662 }
663 gfx::Vector2dF delta(dx, dy);
664 return delta;
665 }
666
667 // When any of the currently down pointers exceeds its slop region
668 // for the first time, scroll delta is adjusted.
669 // The new deltas are calculated for each pointer individually,
670 // and the final scroll delta is the average over all delta values.
671 gfx::Vector2dF ComputeFirstScrollDelta(
672 const MotionEvent& ev1,
673 const MotionEvent& ev2,
674 const MotionEvent& secondary_pointer_down) {
675 // If there are more than two down pointers, tapping is not possible,
676 // so Slop region is not deducted.
677 DCHECK(ev2.GetPointerCount() < 3);
678
679 const int id0 = ev1.GetPointerId(0);
680 const int ev_idx0 = ev2.GetPointerId(0) == id0 ? 0 : 1;
681
682 // Subtract the slop region from the first pointer move.
683 float dx0 = ev1.GetX() - ev2.GetX(ev_idx0);
684 float dy0 = ev1.GetY() - ev2.GetY(ev_idx0);
685 gfx::Vector2dF first_pointer_delta = SubtractSlopRegion(dx0, dy0);
686
687 gfx::Vector2dF second_pointer_delta(0, 0);
688 // Subtract the slop region from the second pointer move.
689 if (ev2.GetPointerCount() == 2) {
690 const int ev_idx1 = ev_idx0 == 0 ? 1 : 0;
691 const int idx1 = secondary_pointer_down.GetActionIndex();
692 float dx1 = secondary_pointer_down.GetX(idx1) - ev2.GetX(ev_idx1);
693 float dy1 = secondary_pointer_down.GetY(idx1) - ev2.GetY(ev_idx1);
694 second_pointer_delta = SubtractSlopRegion(dx1, dy1);
695 }
696
697 gfx::Vector2dF delta = first_pointer_delta + second_pointer_delta;
698 delta.Scale(1.0 / ev2.GetPointerCount());
699 return delta;
700 }
701
659 const GestureProvider::Config config_; 702 const GestureProvider::Config config_;
660 GestureProviderClient* const client_; 703 GestureProviderClient* const client_;
661 704
662 GestureDetector gesture_detector_; 705 GestureDetector gesture_detector_;
663 ScaleGestureDetector scale_gesture_detector_; 706 ScaleGestureDetector scale_gesture_detector_;
664 SnapScrollController snap_scroll_controller_; 707 SnapScrollController snap_scroll_controller_;
665 708
666 base::TimeTicks current_down_time_; 709 base::TimeTicks current_down_time_;
667 710
668 // Keeps track of the current GESTURE_LONG_PRESS event. If a context menu is 711 // 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. 892 // null'ing of the listener until the sequence has ended.
850 if (current_down_event_) 893 if (current_down_event_)
851 return; 894 return;
852 895
853 const bool double_tap_enabled = 896 const bool double_tap_enabled =
854 double_tap_support_for_page_ && double_tap_support_for_platform_; 897 double_tap_support_for_page_ && double_tap_support_for_platform_;
855 gesture_listener_->SetDoubleTapEnabled(double_tap_enabled); 898 gesture_listener_->SetDoubleTapEnabled(double_tap_enabled);
856 } 899 }
857 900
858 } // namespace ui 901 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/gesture_detection/gesture_listeners.cc ('k') | ui/events/gesture_detection/gesture_provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698