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) { |
39 return GestureEventData(type, motion_event_id, time, x, y, details); | 40 return GestureEventData(type, |
41 motion_event_id, | |
42 time, | |
43 x, | |
44 y, | |
45 static_cast<int>(touch_point_count), | |
46 details); | |
40 } | 47 } |
41 | 48 |
42 GestureEventData CreateGesture(EventType type, | 49 GestureEventData CreateGesture(EventType type, |
43 int motion_event_id, | 50 int motion_event_id, |
44 base::TimeTicks time, | 51 base::TimeTicks time, |
45 float x, | 52 float x, |
46 float y) { | 53 float y, |
47 return GestureEventData(type, motion_event_id, time, x, y); | 54 size_t touch_point_count) { |
55 return GestureEventData( | |
56 type, motion_event_id, time, x, y, static_cast<int>(touch_point_count)); | |
48 } | 57 } |
49 | 58 |
50 GestureEventData CreateGesture(EventType type, | 59 GestureEventData CreateGesture(EventType type, |
51 const MotionEvent& event, | 60 const MotionEvent& event, |
52 const GestureEventDetails& details) { | 61 const GestureEventDetails& details) { |
53 return CreateGesture(type, | 62 return CreateGesture(type, |
54 event.GetId(), | 63 event.GetId(), |
55 event.GetEventTime(), | 64 event.GetEventTime(), |
56 event.GetX(), | 65 event.GetX(), |
57 event.GetY(), | 66 event.GetY(), |
67 event.GetPointerCount(), | |
58 details); | 68 details); |
59 } | 69 } |
60 | 70 |
61 GestureEventData CreateGesture(EventType type, | 71 GestureEventData CreateGesture(EventType type, |
62 const MotionEvent& event) { | 72 const MotionEvent& event) { |
63 return CreateGesture( | 73 return CreateGesture(type, |
64 type, event.GetId(), event.GetEventTime(), event.GetX(), event.GetY()); | 74 event.GetId(), |
75 event.GetEventTime(), | |
76 event.GetX(), | |
77 event.GetY(), | |
78 event.GetPointerCount()); | |
65 } | 79 } |
66 | 80 |
67 GestureEventDetails CreateTapGestureDetails(EventType type, | 81 GestureEventDetails CreateTapGestureDetails(EventType type, |
68 const MotionEvent& event) { | 82 const MotionEvent& event) { |
69 // Set the tap count to 1 even for ET_GESTURE_DOUBLE_TAP, in order to be | 83 // 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 | 84 // consistent with double tap behavior on a mobile viewport. See |
71 // crbug.com/234986 for context. | 85 // crbug.com/234986 for context. |
72 GestureEventDetails tap_details(type, 1, 0); | 86 GestureEventDetails tap_details(type, 1, 0); |
73 tap_details.set_bounding_box( | 87 tap_details.set_bounding_box( |
74 gfx::RectF(event.GetTouchMajor(), event.GetTouchMajor())); | 88 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()) | 130 if (ignore_multitouch_events_ && !detector.InDoubleTapMode()) |
117 return false; | 131 return false; |
118 pinch_event_sent_ = false; | 132 pinch_event_sent_ = false; |
119 return true; | 133 return true; |
120 } | 134 } |
121 | 135 |
122 virtual void OnScaleEnd(const ScaleGestureDetector& detector, | 136 virtual void OnScaleEnd(const ScaleGestureDetector& detector, |
123 const MotionEvent& e) OVERRIDE { | 137 const MotionEvent& e) OVERRIDE { |
124 if (!pinch_event_sent_) | 138 if (!pinch_event_sent_) |
125 return; | 139 return; |
126 provider_->Send(CreateGesture( | 140 provider_->Send(CreateGesture(ET_GESTURE_PINCH_END, |
127 ET_GESTURE_PINCH_END, e.GetId(), detector.GetEventTime(), 0, 0)); | 141 e.GetId(), |
142 detector.GetEventTime(), | |
143 0, | |
144 0, | |
145 e.GetPointerCount())); | |
128 pinch_event_sent_ = false; | 146 pinch_event_sent_ = false; |
129 } | 147 } |
130 | 148 |
131 virtual bool OnScale(const ScaleGestureDetector& detector, | 149 virtual bool OnScale(const ScaleGestureDetector& detector, |
132 const MotionEvent& e) OVERRIDE { | 150 const MotionEvent& e) OVERRIDE { |
133 if (ignore_multitouch_events_ && !detector.InDoubleTapMode()) | 151 if (ignore_multitouch_events_ && !detector.InDoubleTapMode()) |
134 return false; | 152 return false; |
135 if (!pinch_event_sent_) { | 153 if (!pinch_event_sent_) { |
136 pinch_event_sent_ = true; | 154 pinch_event_sent_ = true; |
137 provider_->Send(CreateGesture(ET_GESTURE_PINCH_BEGIN, | 155 provider_->Send(CreateGesture(ET_GESTURE_PINCH_BEGIN, |
138 e.GetId(), | 156 e.GetId(), |
139 detector.GetEventTime(), | 157 detector.GetEventTime(), |
140 detector.GetFocusX(), | 158 detector.GetFocusX(), |
141 detector.GetFocusY())); | 159 detector.GetFocusY(), |
160 e.GetPointerCount())); | |
142 } | 161 } |
143 | 162 |
144 float scale = detector.GetScaleFactor(); | 163 float scale = detector.GetScaleFactor(); |
145 if (scale == 1) | 164 if (scale == 1) |
146 return true; | 165 return true; |
147 | 166 |
148 if (detector.InDoubleTapMode()) { | 167 if (detector.InDoubleTapMode()) { |
149 // Relative changes in the double-tap scale factor computed by |detector| | 168 // Relative changes in the double-tap scale factor computed by |detector| |
150 // diminish as the touch moves away from the original double-tap focus. | 169 // diminish as the touch moves away from the original double-tap focus. |
151 // For historical reasons, Chrome has instead adopted a scale factor | 170 // For historical reasons, Chrome has instead adopted a scale factor |
152 // computation that is invariant to the focal distance, where | 171 // computation that is invariant to the focal distance, where |
153 // the scale delta remains constant if the touch velocity is constant. | 172 // the scale delta remains constant if the touch velocity is constant. |
154 float dy = | 173 float dy = |
155 (detector.GetCurrentSpanY() - detector.GetPreviousSpanY()) * 0.5f; | 174 (detector.GetCurrentSpanY() - detector.GetPreviousSpanY()) * 0.5f; |
156 scale = std::pow(scale > 1 ? 1.0f + kDoubleTapDragZoomSpeed | 175 scale = std::pow(scale > 1 ? 1.0f + kDoubleTapDragZoomSpeed |
157 : 1.0f - kDoubleTapDragZoomSpeed, | 176 : 1.0f - kDoubleTapDragZoomSpeed, |
158 std::abs(dy * px_to_dp_)); | 177 std::abs(dy * px_to_dp_)); |
159 } | 178 } |
160 GestureEventDetails pinch_details(ET_GESTURE_PINCH_UPDATE, scale, 0); | 179 GestureEventDetails pinch_details(ET_GESTURE_PINCH_UPDATE, scale, 0); |
161 provider_->Send(CreateGesture(ET_GESTURE_PINCH_UPDATE, | 180 provider_->Send(CreateGesture(ET_GESTURE_PINCH_UPDATE, |
162 e.GetId(), | 181 e.GetId(), |
163 detector.GetEventTime(), | 182 detector.GetEventTime(), |
164 detector.GetFocusX(), | 183 detector.GetFocusX(), |
165 detector.GetFocusY(), | 184 detector.GetFocusY(), |
185 e.GetPointerCount(), | |
166 pinch_details)); | 186 pinch_details)); |
167 return true; | 187 return true; |
168 } | 188 } |
169 | 189 |
170 void SetDoubleTapEnabled(bool enabled) { | 190 void SetDoubleTapEnabled(bool enabled) { |
171 DCHECK(!IsDoubleTapInProgress()); | 191 DCHECK(!IsDoubleTapInProgress()); |
172 scale_gesture_detector_.SetQuickScaleEnabled(enabled); | 192 scale_gesture_detector_.SetQuickScaleEnabled(enabled); |
173 } | 193 } |
174 | 194 |
175 void SetMultiTouchEnabled(bool value) { | 195 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)); | 287 provider_->Send(CreateGesture(ET_GESTURE_TAP_DOWN, e, tap_details)); |
268 | 288 |
269 // Return true to indicate that we want to handle touch. | 289 // Return true to indicate that we want to handle touch. |
270 return true; | 290 return true; |
271 } | 291 } |
272 | 292 |
273 virtual bool OnScroll(const MotionEvent& e1, | 293 virtual bool OnScroll(const MotionEvent& e1, |
274 const MotionEvent& e2, | 294 const MotionEvent& e2, |
275 float raw_distance_x, | 295 float raw_distance_x, |
276 float raw_distance_y) OVERRIDE { | 296 float raw_distance_y) OVERRIDE { |
297 DCHECK_NE(0u, e1.GetPointerCount()); | |
jdduke (slow)
2014/04/09 16:53:05
I think we have sufficient DCHECK coverage that we
tdresser
2014/04/09 18:21:31
Done.
| |
298 DCHECK_NE(0u, e2.GetPointerCount()); | |
299 | |
277 float distance_x = raw_distance_x; | 300 float distance_x = raw_distance_x; |
278 float distance_y = raw_distance_y; | 301 float distance_y = raw_distance_y; |
279 if (!seen_first_scroll_event_) { | 302 if (!seen_first_scroll_event_) { |
280 // Remove the touch slop region from the first scroll event to avoid a | 303 // Remove the touch slop region from the first scroll event to avoid a |
281 // jump. | 304 // jump. |
282 seen_first_scroll_event_ = true; | 305 seen_first_scroll_event_ = true; |
283 double distance = | 306 double distance = |
284 std::sqrt(distance_x * distance_x + distance_y * distance_y); | 307 std::sqrt(distance_x * distance_x + distance_y * distance_y); |
285 double epsilon = 1e-3; | 308 double epsilon = 1e-3; |
286 if (distance > epsilon) { | 309 if (distance > epsilon) { |
(...skipping 11 matching lines...) Expand all Loading... | |
298 } | 321 } |
299 } | 322 } |
300 | 323 |
301 last_raw_x_ = e2.GetRawX(); | 324 last_raw_x_ = e2.GetRawX(); |
302 last_raw_y_ = e2.GetRawY(); | 325 last_raw_y_ = e2.GetRawY(); |
303 if (!provider_->IsScrollInProgress()) { | 326 if (!provider_->IsScrollInProgress()) { |
304 // Note that scroll start hints are in distance traveled, where | 327 // Note that scroll start hints are in distance traveled, where |
305 // scroll deltas are in the opposite direction. | 328 // scroll deltas are in the opposite direction. |
306 GestureEventDetails scroll_details( | 329 GestureEventDetails scroll_details( |
307 ET_GESTURE_SCROLL_BEGIN, -raw_distance_x, -raw_distance_y); | 330 ET_GESTURE_SCROLL_BEGIN, -raw_distance_x, -raw_distance_y); |
331 | |
332 // Use the co-ordinates from the touch down, as these co-ordinates are | |
333 // used to determine which layer the scroll should affect. | |
308 provider_->Send(CreateGesture(ET_GESTURE_SCROLL_BEGIN, | 334 provider_->Send(CreateGesture(ET_GESTURE_SCROLL_BEGIN, |
309 e2.GetId(), | 335 e2.GetId(), |
310 e2.GetEventTime(), | 336 e2.GetEventTime(), |
311 e1.GetX(), | 337 e1.GetX(), |
312 e1.GetY(), | 338 e1.GetY(), |
339 e2.GetPointerCount(), | |
313 scroll_details)); | 340 scroll_details)); |
314 } | 341 } |
315 | 342 |
316 // distance_x and distance_y is the scrolling offset since last OnScroll. | 343 // distance_x and distance_y is the scrolling offset since last OnScroll. |
317 // Because we are passing integers to Blink, this could introduce | 344 // Because we are passing integers to Blink, this could introduce |
318 // rounding errors. The rounding errors will accumulate overtime. | 345 // rounding errors. The rounding errors will accumulate overtime. |
319 // To solve this, we should be adding back the rounding errors each time | 346 // To solve this, we should be adding back the rounding errors each time |
320 // when we calculate the new offset. | 347 // when we calculate the new offset. |
321 // TODO(jdduke): Determine if we can simpy use floating point deltas, as | 348 // TODO(jdduke): Determine if we can simpy use floating point deltas, as |
322 // WebGestureEvent also takes floating point deltas for GestureScrollUpdate. | 349 // WebGestureEvent also takes floating point deltas for GestureScrollUpdate. |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
534 gesture_begin_end_types_enabled_(config.gesture_begin_end_types_enabled) { | 561 gesture_begin_end_types_enabled_(config.gesture_begin_end_types_enabled) { |
535 DCHECK(client); | 562 DCHECK(client); |
536 InitGestureDetectors(config); | 563 InitGestureDetectors(config); |
537 } | 564 } |
538 | 565 |
539 GestureProvider::~GestureProvider() {} | 566 GestureProvider::~GestureProvider() {} |
540 | 567 |
541 bool GestureProvider::OnTouchEvent(const MotionEvent& event) { | 568 bool GestureProvider::OnTouchEvent(const MotionEvent& event) { |
542 TRACE_EVENT1("input", "GestureProvider::OnTouchEvent", | 569 TRACE_EVENT1("input", "GestureProvider::OnTouchEvent", |
543 "action", GetMotionEventActionName(event.GetAction())); | 570 "action", GetMotionEventActionName(event.GetAction())); |
571 | |
572 DCHECK_NE(0u, event.GetPointerCount()); | |
573 | |
544 if (!CanHandle(event)) | 574 if (!CanHandle(event)) |
545 return false; | 575 return false; |
546 | 576 |
547 const bool in_scale_gesture = | 577 const bool in_scale_gesture = |
548 scale_gesture_listener_->IsScaleGestureDetectionInProgress(); | 578 scale_gesture_listener_->IsScaleGestureDetectionInProgress(); |
549 | 579 |
550 OnTouchEventHandlingBegin(event); | 580 OnTouchEventHandlingBegin(event); |
551 gesture_listener_->OnTouchEvent(event, in_scale_gesture); | 581 gesture_listener_->OnTouchEvent(event, in_scale_gesture); |
552 scale_gesture_listener_->OnTouchEvent(event); | 582 scale_gesture_listener_->OnTouchEvent(event); |
553 OnTouchEventHandlingEnd(event); | 583 OnTouchEventHandlingEnd(event); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
662 DCHECK(!touch_scroll_in_progress_); | 692 DCHECK(!touch_scroll_in_progress_); |
663 touch_scroll_in_progress_ = true; | 693 touch_scroll_in_progress_ = true; |
664 break; | 694 break; |
665 case ET_GESTURE_SCROLL_END: | 695 case ET_GESTURE_SCROLL_END: |
666 DCHECK(touch_scroll_in_progress_); | 696 DCHECK(touch_scroll_in_progress_); |
667 if (pinch_in_progress_) | 697 if (pinch_in_progress_) |
668 Send(CreateGesture(ET_GESTURE_PINCH_END, | 698 Send(CreateGesture(ET_GESTURE_PINCH_END, |
669 gesture.motion_event_id, | 699 gesture.motion_event_id, |
670 gesture.time, | 700 gesture.time, |
671 gesture.x, | 701 gesture.x, |
672 gesture.y)); | 702 gesture.y, |
703 gesture.details.touch_points())); | |
673 touch_scroll_in_progress_ = false; | 704 touch_scroll_in_progress_ = false; |
674 break; | 705 break; |
675 case ET_GESTURE_PINCH_BEGIN: | 706 case ET_GESTURE_PINCH_BEGIN: |
676 DCHECK(!pinch_in_progress_); | 707 DCHECK(!pinch_in_progress_); |
677 if (!touch_scroll_in_progress_) | 708 if (!touch_scroll_in_progress_) |
678 Send(CreateGesture(ET_GESTURE_SCROLL_BEGIN, | 709 Send(CreateGesture(ET_GESTURE_SCROLL_BEGIN, |
679 gesture.motion_event_id, | 710 gesture.motion_event_id, |
680 gesture.time, | 711 gesture.time, |
681 gesture.x, | 712 gesture.x, |
682 gesture.y)); | 713 gesture.y, |
714 gesture.details.touch_points())); | |
683 pinch_in_progress_ = true; | 715 pinch_in_progress_ = true; |
684 break; | 716 break; |
685 case ET_GESTURE_PINCH_END: | 717 case ET_GESTURE_PINCH_END: |
686 DCHECK(pinch_in_progress_); | 718 DCHECK(pinch_in_progress_); |
687 pinch_in_progress_ = false; | 719 pinch_in_progress_ = false; |
688 break; | 720 break; |
689 case ET_GESTURE_SHOW_PRESS: | 721 case ET_GESTURE_SHOW_PRESS: |
690 // It's possible that a double-tap drag zoom (from ScaleGestureDetector) | 722 // It's possible that a double-tap drag zoom (from ScaleGestureDetector) |
691 // will start before the press gesture fires (from GestureDetector), in | 723 // will start before the press gesture fires (from GestureDetector), in |
692 // which case the press should simply be dropped. | 724 // which case the press should simply be dropped. |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
772 Send(CreateGesture(ET_GESTURE_END, event)); | 804 Send(CreateGesture(ET_GESTURE_END, event)); |
773 break; | 805 break; |
774 case MotionEvent::ACTION_DOWN: | 806 case MotionEvent::ACTION_DOWN: |
775 case MotionEvent::ACTION_POINTER_DOWN: | 807 case MotionEvent::ACTION_POINTER_DOWN: |
776 case MotionEvent::ACTION_MOVE: | 808 case MotionEvent::ACTION_MOVE: |
777 break; | 809 break; |
778 } | 810 } |
779 } | 811 } |
780 | 812 |
781 } // namespace ui | 813 } // namespace ui |
OLD | NEW |