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_detector.h" | 5 #include "ui/events/gesture_detection/gesture_detector.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "base/timer/timer.h" | 9 #include "base/timer/timer.h" |
10 #include "ui/events/gesture_detection/motion_event.h" | 10 #include "ui/events/gesture_detection/motion_event.h" |
11 | 11 |
12 namespace ui { | 12 namespace ui { |
13 namespace { | 13 namespace { |
14 | 14 |
| 15 // Using a small epsilon when comparing slop distances allows pixel perfect |
| 16 // slop determination when using fractional DIP coordinates (assuming the slop |
| 17 // region and DPI scale are reasonably proportioned). |
| 18 const float kSlopEpsilon = .05f; |
| 19 |
| 20 // Minimum distance a scroll must have traveled from the last scroll/focal point |
| 21 // to trigger an |OnScroll| callback. |
| 22 const float kScrollEpsilon = .1f; |
| 23 |
15 // Constants used by TimeoutGestureHandler. | 24 // Constants used by TimeoutGestureHandler. |
16 enum TimeoutEvent { | 25 enum TimeoutEvent { |
17 SHOW_PRESS = 0, | 26 SHOW_PRESS = 0, |
18 LONG_PRESS, | 27 LONG_PRESS, |
19 TAP, | 28 TAP, |
20 TIMEOUT_EVENT_COUNT | 29 TIMEOUT_EVENT_COUNT |
21 }; | 30 }; |
22 | 31 |
23 } // namespace | 32 } // namespace |
24 | 33 |
25 // Note: These constants were taken directly from the default (unscaled) | 34 // Note: These constants were taken directly from the default (unscaled) |
26 // versions found in Android's ViewConfiguration. | 35 // versions found in Android's ViewConfiguration. |
27 GestureDetector::Config::Config() | 36 GestureDetector::Config::Config() |
28 : longpress_timeout(base::TimeDelta::FromMilliseconds(500)), | 37 : longpress_timeout(base::TimeDelta::FromMilliseconds(500)), |
29 showpress_timeout(base::TimeDelta::FromMilliseconds(180)), | 38 showpress_timeout(base::TimeDelta::FromMilliseconds(180)), |
30 double_tap_timeout(base::TimeDelta::FromMilliseconds(300)), | 39 double_tap_timeout(base::TimeDelta::FromMilliseconds(300)), |
31 scaled_touch_slop(8), | 40 touch_slop(8), |
32 scaled_double_tap_slop(100), | 41 double_tap_slop(100), |
33 scaled_minimum_fling_velocity(50), | 42 minimum_fling_velocity(50), |
34 scaled_maximum_fling_velocity(8000) {} | 43 maximum_fling_velocity(8000) {} |
35 | 44 |
36 GestureDetector::Config::~Config() {} | 45 GestureDetector::Config::~Config() {} |
37 | 46 |
38 bool GestureDetector::SimpleGestureListener::OnDown(const MotionEvent& e) { | 47 bool GestureDetector::SimpleGestureListener::OnDown(const MotionEvent& e) { |
39 return false; | 48 return false; |
40 } | 49 } |
41 | 50 |
42 void GestureDetector::SimpleGestureListener::OnShowPress(const MotionEvent& e) { | 51 void GestureDetector::SimpleGestureListener::OnShowPress(const MotionEvent& e) { |
43 } | 52 } |
44 | 53 |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 break; | 269 break; |
261 | 270 |
262 { | 271 { |
263 const float scroll_x = last_focus_x_ - focus_x; | 272 const float scroll_x = last_focus_x_ - focus_x; |
264 const float scroll_y = last_focus_y_ - focus_y; | 273 const float scroll_y = last_focus_y_ - focus_y; |
265 if (is_double_tapping_) { | 274 if (is_double_tapping_) { |
266 // Give the move events of the double-tap. | 275 // Give the move events of the double-tap. |
267 DCHECK(double_tap_listener_); | 276 DCHECK(double_tap_listener_); |
268 handled |= double_tap_listener_->OnDoubleTapEvent(ev); | 277 handled |= double_tap_listener_->OnDoubleTapEvent(ev); |
269 } else if (always_in_tap_region_) { | 278 } else if (always_in_tap_region_) { |
270 const int delta_x = static_cast<int>(focus_x - down_focus_x_); | 279 const float delta_x = focus_x - down_focus_x_; |
271 const int delta_y = static_cast<int>(focus_y - down_focus_y_); | 280 const float delta_y = focus_y - down_focus_y_; |
272 int distance = (delta_x * delta_x) + (delta_y * delta_y); | 281 const float distance_square = delta_x * delta_x + delta_y * delta_y; |
273 if (distance > touch_slop_square_) { | 282 if (distance_square > touch_slop_square_) { |
274 handled = listener_->OnScroll( | 283 handled = listener_->OnScroll( |
275 *current_down_event_, ev, scroll_x, scroll_y); | 284 *current_down_event_, ev, scroll_x, scroll_y); |
276 last_focus_x_ = focus_x; | 285 last_focus_x_ = focus_x; |
277 last_focus_y_ = focus_y; | 286 last_focus_y_ = focus_y; |
278 always_in_tap_region_ = false; | 287 always_in_tap_region_ = false; |
279 timeout_handler_->Stop(); | 288 timeout_handler_->Stop(); |
280 } | 289 } |
281 if (distance > double_tap_touch_slop_square_) | 290 if (distance_square > double_tap_touch_slop_square_) |
282 always_in_bigger_tap_region_ = false; | 291 always_in_bigger_tap_region_ = false; |
283 } else if ((std::abs(scroll_x) >= 1) || (std::abs(scroll_y) >= 1)) { | 292 } else if (std::abs(scroll_x) > kScrollEpsilon || |
| 293 std::abs(scroll_y) > kScrollEpsilon) { |
284 handled = | 294 handled = |
285 listener_->OnScroll(*current_down_event_, ev, scroll_x, scroll_y); | 295 listener_->OnScroll(*current_down_event_, ev, scroll_x, scroll_y); |
286 last_focus_x_ = focus_x; | 296 last_focus_x_ = focus_x; |
287 last_focus_y_ = focus_y; | 297 last_focus_y_ = focus_y; |
288 } | 298 } |
289 } | 299 } |
290 break; | 300 break; |
291 | 301 |
292 case MotionEvent::ACTION_UP: | 302 case MotionEvent::ACTION_UP: |
293 still_down_ = false; | 303 still_down_ = false; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 Cancel(); | 343 Cancel(); |
334 break; | 344 break; |
335 } | 345 } |
336 | 346 |
337 return handled; | 347 return handled; |
338 } | 348 } |
339 | 349 |
340 void GestureDetector::Init(const Config& config) { | 350 void GestureDetector::Init(const Config& config) { |
341 DCHECK(listener_); | 351 DCHECK(listener_); |
342 | 352 |
343 const int touch_slop = config.scaled_touch_slop; | 353 const float touch_slop = config.touch_slop + kSlopEpsilon; |
344 const int double_tap_touch_slop = touch_slop; | 354 const float double_tap_touch_slop = touch_slop; |
345 const int double_tap_slop = config.scaled_double_tap_slop; | 355 const float double_tap_slop = config.double_tap_slop + kSlopEpsilon; |
346 min_fling_velocity_ = config.scaled_minimum_fling_velocity; | |
347 max_fling_velocity_ = config.scaled_maximum_fling_velocity; | |
348 touch_slop_square_ = touch_slop * touch_slop; | 356 touch_slop_square_ = touch_slop * touch_slop; |
349 double_tap_touch_slop_square_ = double_tap_touch_slop * double_tap_touch_slop; | 357 double_tap_touch_slop_square_ = double_tap_touch_slop * double_tap_touch_slop; |
350 double_tap_slop_square_ = double_tap_slop * double_tap_slop; | 358 double_tap_slop_square_ = double_tap_slop * double_tap_slop; |
351 double_tap_timeout_ = config.double_tap_timeout; | 359 double_tap_timeout_ = config.double_tap_timeout; |
| 360 min_fling_velocity_ = config.minimum_fling_velocity; |
| 361 max_fling_velocity_ = config.maximum_fling_velocity; |
352 } | 362 } |
353 | 363 |
354 void GestureDetector::OnShowPressTimeout() { | 364 void GestureDetector::OnShowPressTimeout() { |
355 listener_->OnShowPress(*current_down_event_); | 365 listener_->OnShowPress(*current_down_event_); |
356 } | 366 } |
357 | 367 |
358 void GestureDetector::OnLongPressTimeout() { | 368 void GestureDetector::OnLongPressTimeout() { |
359 timeout_handler_->StopTimeout(TAP); | 369 timeout_handler_->StopTimeout(TAP); |
360 defer_confirm_single_tap_ = false; | 370 defer_confirm_single_tap_ = false; |
361 in_longpress_ = listener_->OnLongPress(*current_down_event_); | 371 in_longpress_ = listener_->OnLongPress(*current_down_event_); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
394 const MotionEvent& first_down, | 404 const MotionEvent& first_down, |
395 const MotionEvent& first_up, | 405 const MotionEvent& first_up, |
396 const MotionEvent& second_down) const { | 406 const MotionEvent& second_down) const { |
397 if (!always_in_bigger_tap_region_) | 407 if (!always_in_bigger_tap_region_) |
398 return false; | 408 return false; |
399 | 409 |
400 if (second_down.GetEventTime() - first_up.GetEventTime() > | 410 if (second_down.GetEventTime() - first_up.GetEventTime() > |
401 double_tap_timeout_) | 411 double_tap_timeout_) |
402 return false; | 412 return false; |
403 | 413 |
404 int delta_x = static_cast<int>(first_down.GetX() - second_down.GetX()); | 414 const float delta_x = first_down.GetX() - second_down.GetX(); |
405 int delta_y = static_cast<int>(first_down.GetY() - second_down.GetY()); | 415 const float delta_y = first_down.GetY() - second_down.GetY(); |
406 return (delta_x * delta_x + delta_y * delta_y < double_tap_slop_square_); | 416 return (delta_x * delta_x + delta_y * delta_y < double_tap_slop_square_); |
407 } | 417 } |
408 | 418 |
409 } // namespace ui | 419 } // namespace ui |
OLD | NEW |