OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |