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 <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 17 matching lines...) Expand all Loading... | |
28 case MotionEvent::ACTION_MOVE: return "ACTION_MOVE"; | 28 case MotionEvent::ACTION_MOVE: return "ACTION_MOVE"; |
29 } | 29 } |
30 return ""; | 30 return ""; |
31 } | 31 } |
32 | 32 |
33 GestureEventData CreateGesture(EventType type, | 33 GestureEventData CreateGesture(EventType type, |
34 int motion_event_id, | 34 int motion_event_id, |
35 base::TimeTicks time, | 35 base::TimeTicks time, |
36 float x, | 36 float x, |
37 float y, | 37 float y, |
38 size_t touch_point_count, | |
38 const GestureEventDetails& details) { | 39 const GestureEventDetails& details) { |
jdduke (slow)
2014/04/08 21:07:41
Might as well pass this by value, then you can cal
tdresser
2014/04/09 14:50:48
I'm still passing by reference, based on the chang
| |
39 return GestureEventData(type, motion_event_id, time, x, y, details); | 40 DCHECK_NE(0u, touch_point_count); |
41 GestureEventDetails d = details; | |
42 d.set_touch_points(touch_point_count); | |
43 return GestureEventData(type, motion_event_id, time, x, y, d); | |
40 } | 44 } |
41 | 45 |
42 GestureEventData CreateGesture(EventType type, | 46 GestureEventData CreateGesture(EventType type, |
43 int motion_event_id, | 47 int motion_event_id, |
44 base::TimeTicks time, | 48 base::TimeTicks time, |
45 float x, | 49 float x, |
46 float y) { | 50 float y, |
47 return GestureEventData(type, motion_event_id, time, x, y); | 51 size_t touch_point_count) { |
52 DCHECK_NE(0u, touch_point_count); | |
53 GestureEventDetails details; | |
54 details.set_touch_points(touch_point_count); | |
55 return GestureEventData(type, motion_event_id, time, x, y, details); | |
jdduke (slow)
2014/04/08 21:07:41
Hmm, now that we only use one constructor for Gest
tdresser
2014/04/09 14:50:48
Is this what you were thinking?
| |
48 } | 56 } |
49 | 57 |
50 GestureEventData CreateGesture(EventType type, | 58 GestureEventData CreateGesture(EventType type, |
51 const MotionEvent& event, | 59 const MotionEvent& event, |
52 const GestureEventDetails& details) { | 60 const GestureEventDetails& details) { |
53 return CreateGesture(type, | 61 return CreateGesture(type, |
54 event.GetId(), | 62 event.GetId(), |
55 event.GetEventTime(), | 63 event.GetEventTime(), |
56 event.GetX(), | 64 event.GetX(), |
57 event.GetY(), | 65 event.GetY(), |
66 event.GetPointerCount(), | |
58 details); | 67 details); |
59 } | 68 } |
60 | 69 |
61 GestureEventData CreateGesture(EventType type, | 70 GestureEventData CreateGesture(EventType type, |
62 const MotionEvent& event) { | 71 const MotionEvent& event) { |
63 return CreateGesture( | 72 return CreateGesture(type, |
64 type, event.GetId(), event.GetEventTime(), event.GetX(), event.GetY()); | 73 event.GetId(), |
74 event.GetEventTime(), | |
75 event.GetX(), | |
76 event.GetY(), | |
77 event.GetPointerCount()); | |
65 } | 78 } |
66 | 79 |
67 GestureEventDetails CreateTapGestureDetails(EventType type, | 80 GestureEventDetails CreateTapGestureDetails(EventType type, |
68 const MotionEvent& event) { | 81 const MotionEvent& event) { |
69 // Set the tap count to 1 even for ET_GESTURE_DOUBLE_TAP, in order to be | 82 // Set the tap count to 1 even for ET_GESTURE_DOUBLE_TAP, in order to be |
70 // consistent with double tap behavior on a mobile viewport. See | 83 // consistent with double tap behavior on a mobile viewport. See |
71 // crbug.com/234986 for context. | 84 // crbug.com/234986 for context. |
72 GestureEventDetails tap_details(type, 1, 0); | 85 GestureEventDetails tap_details(type, 1, 0); |
73 tap_details.set_bounding_box( | 86 tap_details.set_bounding_box( |
74 gfx::RectF(event.GetTouchMajor(), event.GetTouchMajor())); | 87 gfx::RectF(event.GetTouchMajor(), event.GetTouchMajor())); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
116 if (ignore_multitouch_events_ && !detector.InDoubleTapMode()) | 129 if (ignore_multitouch_events_ && !detector.InDoubleTapMode()) |
117 return false; | 130 return false; |
118 pinch_event_sent_ = false; | 131 pinch_event_sent_ = false; |
119 return true; | 132 return true; |
120 } | 133 } |
121 | 134 |
122 virtual void OnScaleEnd(const ScaleGestureDetector& detector, | 135 virtual void OnScaleEnd(const ScaleGestureDetector& detector, |
123 const MotionEvent& e) OVERRIDE { | 136 const MotionEvent& e) OVERRIDE { |
124 if (!pinch_event_sent_) | 137 if (!pinch_event_sent_) |
125 return; | 138 return; |
126 provider_->Send(CreateGesture( | 139 provider_->Send(CreateGesture(ET_GESTURE_PINCH_END, |
127 ET_GESTURE_PINCH_END, e.GetId(), detector.GetEventTime(), 0, 0)); | 140 e.GetId(), |
141 detector.GetEventTime(), | |
142 0, | |
143 0, | |
144 e.GetPointerCount())); | |
128 pinch_event_sent_ = false; | 145 pinch_event_sent_ = false; |
129 } | 146 } |
130 | 147 |
131 virtual bool OnScale(const ScaleGestureDetector& detector, | 148 virtual bool OnScale(const ScaleGestureDetector& detector, |
132 const MotionEvent& e) OVERRIDE { | 149 const MotionEvent& e) OVERRIDE { |
133 if (ignore_multitouch_events_ && !detector.InDoubleTapMode()) | 150 if (ignore_multitouch_events_ && !detector.InDoubleTapMode()) |
134 return false; | 151 return false; |
135 if (!pinch_event_sent_) { | 152 if (!pinch_event_sent_) { |
136 pinch_event_sent_ = true; | 153 pinch_event_sent_ = true; |
137 provider_->Send(CreateGesture(ET_GESTURE_PINCH_BEGIN, | 154 provider_->Send(CreateGesture(ET_GESTURE_PINCH_BEGIN, |
138 e.GetId(), | 155 e.GetId(), |
139 detector.GetEventTime(), | 156 detector.GetEventTime(), |
140 detector.GetFocusX(), | 157 detector.GetFocusX(), |
141 detector.GetFocusY())); | 158 detector.GetFocusY(), |
159 e.GetPointerCount())); | |
142 } | 160 } |
143 | 161 |
144 float scale = detector.GetScaleFactor(); | 162 float scale = detector.GetScaleFactor(); |
145 if (scale == 1) | 163 if (scale == 1) |
146 return true; | 164 return true; |
147 | 165 |
148 if (detector.InDoubleTapMode()) { | 166 if (detector.InDoubleTapMode()) { |
149 // Relative changes in the double-tap scale factor computed by |detector| | 167 // Relative changes in the double-tap scale factor computed by |detector| |
150 // diminish as the touch moves away from the original double-tap focus. | 168 // diminish as the touch moves away from the original double-tap focus. |
151 // For historical reasons, Chrome has instead adopted a scale factor | 169 // For historical reasons, Chrome has instead adopted a scale factor |
152 // computation that is invariant to the focal distance, where | 170 // computation that is invariant to the focal distance, where |
153 // the scale delta remains constant if the touch velocity is constant. | 171 // the scale delta remains constant if the touch velocity is constant. |
154 float dy = | 172 float dy = |
155 (detector.GetCurrentSpanY() - detector.GetPreviousSpanY()) * 0.5f; | 173 (detector.GetCurrentSpanY() - detector.GetPreviousSpanY()) * 0.5f; |
156 scale = std::pow(scale > 1 ? 1.0f + kDoubleTapDragZoomSpeed | 174 scale = std::pow(scale > 1 ? 1.0f + kDoubleTapDragZoomSpeed |
157 : 1.0f - kDoubleTapDragZoomSpeed, | 175 : 1.0f - kDoubleTapDragZoomSpeed, |
158 std::abs(dy * px_to_dp_)); | 176 std::abs(dy * px_to_dp_)); |
159 } | 177 } |
160 GestureEventDetails pinch_details(ET_GESTURE_PINCH_UPDATE, scale, 0); | 178 GestureEventDetails pinch_details(ET_GESTURE_PINCH_UPDATE, scale, 0); |
161 provider_->Send(CreateGesture(ET_GESTURE_PINCH_UPDATE, | 179 provider_->Send(CreateGesture(ET_GESTURE_PINCH_UPDATE, |
162 e.GetId(), | 180 e.GetId(), |
163 detector.GetEventTime(), | 181 detector.GetEventTime(), |
164 detector.GetFocusX(), | 182 detector.GetFocusX(), |
165 detector.GetFocusY(), | 183 detector.GetFocusY(), |
184 e.GetPointerCount(), | |
166 pinch_details)); | 185 pinch_details)); |
167 return true; | 186 return true; |
168 } | 187 } |
169 | 188 |
170 void SetDoubleTapEnabled(bool enabled) { | 189 void SetDoubleTapEnabled(bool enabled) { |
171 DCHECK(!IsDoubleTapInProgress()); | 190 DCHECK(!IsDoubleTapInProgress()); |
172 scale_gesture_detector_.SetQuickScaleEnabled(enabled); | 191 scale_gesture_detector_.SetQuickScaleEnabled(enabled); |
173 } | 192 } |
174 | 193 |
175 void SetMultiTouchEnabled(bool value) { | 194 void SetMultiTouchEnabled(bool value) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
267 provider_->Send(CreateGesture(ET_GESTURE_TAP_DOWN, e, tap_details)); | 286 provider_->Send(CreateGesture(ET_GESTURE_TAP_DOWN, e, tap_details)); |
268 | 287 |
269 // Return true to indicate that we want to handle touch. | 288 // Return true to indicate that we want to handle touch. |
270 return true; | 289 return true; |
271 } | 290 } |
272 | 291 |
273 virtual bool OnScroll(const MotionEvent& e1, | 292 virtual bool OnScroll(const MotionEvent& e1, |
274 const MotionEvent& e2, | 293 const MotionEvent& e2, |
275 float raw_distance_x, | 294 float raw_distance_x, |
276 float raw_distance_y) OVERRIDE { | 295 float raw_distance_y) OVERRIDE { |
296 DCHECK_NE(0u, e1.GetPointerCount()); | |
297 DCHECK_NE(0u, e2.GetPointerCount()); | |
298 | |
277 float distance_x = raw_distance_x; | 299 float distance_x = raw_distance_x; |
278 float distance_y = raw_distance_y; | 300 float distance_y = raw_distance_y; |
279 if (!seen_first_scroll_event_) { | 301 if (!seen_first_scroll_event_) { |
280 // Remove the touch slop region from the first scroll event to avoid a | 302 // Remove the touch slop region from the first scroll event to avoid a |
281 // jump. | 303 // jump. |
282 seen_first_scroll_event_ = true; | 304 seen_first_scroll_event_ = true; |
283 double distance = | 305 double distance = |
284 std::sqrt(distance_x * distance_x + distance_y * distance_y); | 306 std::sqrt(distance_x * distance_x + distance_y * distance_y); |
285 double epsilon = 1e-3; | 307 double epsilon = 1e-3; |
286 if (distance > epsilon) { | 308 if (distance > epsilon) { |
(...skipping 11 matching lines...) Expand all Loading... | |
298 } | 320 } |
299 } | 321 } |
300 | 322 |
301 last_raw_x_ = e2.GetRawX(); | 323 last_raw_x_ = e2.GetRawX(); |
302 last_raw_y_ = e2.GetRawY(); | 324 last_raw_y_ = e2.GetRawY(); |
303 if (!provider_->IsScrollInProgress()) { | 325 if (!provider_->IsScrollInProgress()) { |
304 // Note that scroll start hints are in distance traveled, where | 326 // Note that scroll start hints are in distance traveled, where |
305 // scroll deltas are in the opposite direction. | 327 // scroll deltas are in the opposite direction. |
306 GestureEventDetails scroll_details( | 328 GestureEventDetails scroll_details( |
307 ET_GESTURE_SCROLL_BEGIN, -raw_distance_x, -raw_distance_y); | 329 ET_GESTURE_SCROLL_BEGIN, -raw_distance_x, -raw_distance_y); |
308 provider_->Send(CreateGesture(ET_GESTURE_SCROLL_BEGIN, | 330 provider_->Send( |
309 e2.GetId(), | 331 CreateGesture(ET_GESTURE_SCROLL_BEGIN, e2, scroll_details)); |
310 e2.GetEventTime(), | |
jdduke (slow)
2014/04/08 21:07:41
This is a change in behavior. GestureScrollBegin
tdresser
2014/04/09 14:50:48
Done.
| |
311 e1.GetX(), | |
312 e1.GetY(), | |
313 scroll_details)); | |
314 } | 332 } |
315 | 333 |
316 // distance_x and distance_y is the scrolling offset since last OnScroll. | 334 // distance_x and distance_y is the scrolling offset since last OnScroll. |
317 // Because we are passing integers to Blink, this could introduce | 335 // Because we are passing integers to Blink, this could introduce |
318 // rounding errors. The rounding errors will accumulate overtime. | 336 // rounding errors. The rounding errors will accumulate overtime. |
319 // To solve this, we should be adding back the rounding errors each time | 337 // To solve this, we should be adding back the rounding errors each time |
320 // when we calculate the new offset. | 338 // when we calculate the new offset. |
321 // TODO(jdduke): Determine if we can simpy use floating point deltas, as | 339 // TODO(jdduke): Determine if we can simpy use floating point deltas, as |
322 // WebGestureEvent also takes floating point deltas for GestureScrollUpdate. | 340 // WebGestureEvent also takes floating point deltas for GestureScrollUpdate. |
323 int dx = (int)(distance_x + accumulated_scroll_error_x_); | 341 int dx = (int)(distance_x + accumulated_scroll_error_x_); |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
537 gesture_begin_end_types_enabled_(config.gesture_begin_end_types_enabled) { | 555 gesture_begin_end_types_enabled_(config.gesture_begin_end_types_enabled) { |
538 DCHECK(client); | 556 DCHECK(client); |
539 InitGestureDetectors(config); | 557 InitGestureDetectors(config); |
540 } | 558 } |
541 | 559 |
542 GestureProvider::~GestureProvider() {} | 560 GestureProvider::~GestureProvider() {} |
543 | 561 |
544 bool GestureProvider::OnTouchEvent(const MotionEvent& event) { | 562 bool GestureProvider::OnTouchEvent(const MotionEvent& event) { |
545 TRACE_EVENT1("input", "GestureProvider::OnTouchEvent", | 563 TRACE_EVENT1("input", "GestureProvider::OnTouchEvent", |
546 "action", GetMotionEventActionName(event.GetAction())); | 564 "action", GetMotionEventActionName(event.GetAction())); |
565 | |
566 DCHECK_NE(0u, event.GetPointerCount()); | |
567 | |
547 if (!CanHandle(event)) | 568 if (!CanHandle(event)) |
548 return false; | 569 return false; |
549 | 570 |
550 const bool in_scale_gesture = | 571 const bool in_scale_gesture = |
551 scale_gesture_listener_->IsScaleGestureDetectionInProgress(); | 572 scale_gesture_listener_->IsScaleGestureDetectionInProgress(); |
552 | 573 |
553 OnTouchEventHandlingBegin(event); | 574 OnTouchEventHandlingBegin(event); |
554 gesture_listener_->OnTouchEvent(event, in_scale_gesture); | 575 gesture_listener_->OnTouchEvent(event, in_scale_gesture); |
555 scale_gesture_listener_->OnTouchEvent(event); | 576 scale_gesture_listener_->OnTouchEvent(event); |
556 OnTouchEventHandlingEnd(event); | 577 OnTouchEventHandlingEnd(event); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
660 break; | 681 break; |
661 case ET_GESTURE_TAP_UNCONFIRMED: | 682 case ET_GESTURE_TAP_UNCONFIRMED: |
662 needs_show_press_event_ = false; | 683 needs_show_press_event_ = false; |
663 break; | 684 break; |
664 case ET_GESTURE_TAP: | 685 case ET_GESTURE_TAP: |
665 if (needs_show_press_event_) | 686 if (needs_show_press_event_) |
666 Send(CreateGesture(ET_GESTURE_SHOW_PRESS, | 687 Send(CreateGesture(ET_GESTURE_SHOW_PRESS, |
667 gesture.motion_event_id, | 688 gesture.motion_event_id, |
668 gesture.time, | 689 gesture.time, |
669 gesture.x, | 690 gesture.x, |
670 gesture.y)); | 691 gesture.y, |
692 gesture.details.touch_points())); | |
671 needs_tap_ending_event_ = false; | 693 needs_tap_ending_event_ = false; |
672 break; | 694 break; |
673 case ET_GESTURE_DOUBLE_TAP: | 695 case ET_GESTURE_DOUBLE_TAP: |
674 needs_tap_ending_event_ = false; | 696 needs_tap_ending_event_ = false; |
675 break; | 697 break; |
676 case ET_GESTURE_TAP_CANCEL: | 698 case ET_GESTURE_TAP_CANCEL: |
677 if (!needs_tap_ending_event_) | 699 if (!needs_tap_ending_event_) |
678 return; | 700 return; |
679 needs_tap_ending_event_ = false; | 701 needs_tap_ending_event_ = false; |
680 break; | 702 break; |
(...skipping 14 matching lines...) Expand all Loading... | |
695 break; | 717 break; |
696 case ET_GESTURE_SCROLL_END: | 718 case ET_GESTURE_SCROLL_END: |
697 touch_scroll_in_progress_ = false; | 719 touch_scroll_in_progress_ = false; |
698 break; | 720 break; |
699 case ET_GESTURE_PINCH_BEGIN: | 721 case ET_GESTURE_PINCH_BEGIN: |
700 if (!touch_scroll_in_progress_) | 722 if (!touch_scroll_in_progress_) |
701 Send(CreateGesture(ET_GESTURE_SCROLL_BEGIN, | 723 Send(CreateGesture(ET_GESTURE_SCROLL_BEGIN, |
702 gesture.motion_event_id, | 724 gesture.motion_event_id, |
703 gesture.time, | 725 gesture.time, |
704 gesture.x, | 726 gesture.x, |
705 gesture.y)); | 727 gesture.y, |
728 gesture.details.touch_points())); | |
706 pinch_in_progress_ = true; | 729 pinch_in_progress_ = true; |
707 break; | 730 break; |
708 case ET_GESTURE_PINCH_END: | 731 case ET_GESTURE_PINCH_END: |
709 pinch_in_progress_ = false; | 732 pinch_in_progress_ = false; |
710 break; | 733 break; |
711 default: | 734 default: |
712 break; | 735 break; |
713 }; | 736 }; |
714 | 737 |
715 client_->OnGestureEvent(gesture); | 738 client_->OnGestureEvent(gesture); |
716 } | 739 } |
717 | 740 |
718 void GestureProvider::SendTapCancelIfNecessary(const MotionEvent& event) { | 741 void GestureProvider::SendTapCancelIfNecessary(const MotionEvent& event) { |
719 if (!needs_tap_ending_event_) | 742 if (!needs_tap_ending_event_) |
720 return; | 743 return; |
721 current_longpress_time_ = base::TimeTicks(); | 744 current_longpress_time_ = base::TimeTicks(); |
722 Send(CreateGesture(ET_GESTURE_TAP_CANCEL, event)); | 745 Send(CreateGesture(ET_GESTURE_TAP_CANCEL, event)); |
723 } | 746 } |
724 | 747 |
725 void GestureProvider::SendTapCancelIfNecessary( | 748 void GestureProvider::SendTapCancelIfNecessary( |
726 const GestureEventData& gesture) { | 749 const GestureEventData& gesture) { |
727 if (!needs_tap_ending_event_) | 750 if (!needs_tap_ending_event_) |
728 return; | 751 return; |
729 current_longpress_time_ = base::TimeTicks(); | 752 current_longpress_time_ = base::TimeTicks(); |
730 Send(CreateGesture(ET_GESTURE_TAP_CANCEL, | 753 Send(CreateGesture(ET_GESTURE_TAP_CANCEL, |
731 gesture.motion_event_id, | 754 gesture.motion_event_id, |
732 gesture.time, | 755 gesture.time, |
733 gesture.x, | 756 gesture.x, |
734 gesture.y)); | 757 gesture.y, |
758 gesture.details.touch_points())); | |
735 } | 759 } |
736 | 760 |
737 bool GestureProvider::SendLongTapIfNecessary(const MotionEvent& event) { | 761 bool GestureProvider::SendLongTapIfNecessary(const MotionEvent& event) { |
738 if (event.GetAction() == MotionEvent::ACTION_UP && | 762 if (event.GetAction() == MotionEvent::ACTION_UP && |
739 !current_longpress_time_.is_null() && | 763 !current_longpress_time_.is_null() && |
740 !scale_gesture_listener_->IsScaleGestureDetectionInProgress()) { | 764 !scale_gesture_listener_->IsScaleGestureDetectionInProgress()) { |
741 SendTapCancelIfNecessary(event); | 765 SendTapCancelIfNecessary(event); |
742 GestureEventDetails long_tap_details(ET_GESTURE_LONG_TAP, 0, 0); | 766 GestureEventDetails long_tap_details(ET_GESTURE_LONG_TAP, 0, 0); |
743 long_tap_details.set_bounding_box( | 767 long_tap_details.set_bounding_box( |
744 gfx::RectF(event.GetTouchMajor(), event.GetTouchMajor())); | 768 gfx::RectF(event.GetTouchMajor(), event.GetTouchMajor())); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
814 Send(CreateGesture(ET_GESTURE_END, event)); | 838 Send(CreateGesture(ET_GESTURE_END, event)); |
815 break; | 839 break; |
816 case MotionEvent::ACTION_DOWN: | 840 case MotionEvent::ACTION_DOWN: |
817 case MotionEvent::ACTION_POINTER_DOWN: | 841 case MotionEvent::ACTION_POINTER_DOWN: |
818 case MotionEvent::ACTION_MOVE: | 842 case MotionEvent::ACTION_MOVE: |
819 break; | 843 break; |
820 } | 844 } |
821 } | 845 } |
822 | 846 |
823 } // namespace ui | 847 } // namespace ui |
OLD | NEW |