OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 // MSVC++ requires this to be set before any other includes to get M_PI. | 5 // MSVC++ requires this to be set before any other includes to get M_PI. |
6 #define _USE_MATH_DEFINES | 6 #define _USE_MATH_DEFINES |
7 | 7 |
8 #include "ui/events/blink/blink_event_util.h" | 8 #include "ui/events/blink/blink_event_util.h" |
9 | 9 |
10 #include <stddef.h> | 10 #include <stddef.h> |
11 | 11 |
12 #include <algorithm> | 12 #include <algorithm> |
13 #include <bitset> | 13 #include <bitset> |
14 #include <cmath> | 14 #include <cmath> |
15 #include <limits> | 15 #include <limits> |
16 | 16 |
17 #include "base/time/time.h" | 17 #include "base/time/time.h" |
18 #include "build/build_config.h" | 18 #include "build/build_config.h" |
19 #include "third_party/WebKit/public/platform/WebGestureEvent.h" | 19 #include "third_party/WebKit/public/platform/WebGestureEvent.h" |
20 #include "third_party/WebKit/public/platform/WebInputEvent.h" | 20 #include "third_party/WebKit/public/platform/WebInputEvent.h" |
21 #include "ui/events/base_event_utils.h" | 21 #include "ui/events/base_event_utils.h" |
22 #include "ui/events/event_constants.h" | 22 #include "ui/events/event_constants.h" |
23 #include "ui/events/gesture_detection/gesture_event_data.h" | 23 #include "ui/events/gesture_detection/gesture_event_data.h" |
24 #include "ui/events/gesture_detection/motion_event.h" | 24 #include "ui/events/gesture_detection/motion_event.h" |
25 #include "ui/events/gesture_event_details.h" | 25 #include "ui/events/gesture_event_details.h" |
26 #include "ui/events/keycodes/dom/keycode_converter.h" | 26 #include "ui/events/keycodes/dom/keycode_converter.h" |
27 #include "ui/gfx/geometry/safe_integer_conversions.h" | 27 #include "ui/gfx/geometry/safe_integer_conversions.h" |
28 #include "ui/gfx/geometry/vector2d.h" | 28 #include "ui/gfx/geometry/vector2d.h" |
| 29 #include "ui/gfx/transform.h" |
29 | 30 |
30 using blink::WebGestureEvent; | 31 using blink::WebGestureEvent; |
31 using blink::WebInputEvent; | 32 using blink::WebInputEvent; |
32 using blink::WebMouseEvent; | 33 using blink::WebMouseEvent; |
33 using blink::WebMouseWheelEvent; | 34 using blink::WebMouseWheelEvent; |
34 using blink::WebPointerProperties; | 35 using blink::WebPointerProperties; |
35 using blink::WebTouchEvent; | 36 using blink::WebTouchEvent; |
36 using blink::WebTouchPoint; | 37 using blink::WebTouchPoint; |
37 using std::numeric_limits; | 38 using std::numeric_limits; |
38 | 39 |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 event->data.pinchUpdate.scale *= event_to_coalesce.data.pinchUpdate.scale; | 375 event->data.pinchUpdate.scale *= event_to_coalesce.data.pinchUpdate.scale; |
375 // Ensure the scale remains bounded above 0 and below Infinity so that | 376 // Ensure the scale remains bounded above 0 and below Infinity so that |
376 // we can reliably perform operations like log on the values. | 377 // we can reliably perform operations like log on the values. |
377 if (event->data.pinchUpdate.scale < numeric_limits<float>::min()) | 378 if (event->data.pinchUpdate.scale < numeric_limits<float>::min()) |
378 event->data.pinchUpdate.scale = numeric_limits<float>::min(); | 379 event->data.pinchUpdate.scale = numeric_limits<float>::min(); |
379 else if (event->data.pinchUpdate.scale > numeric_limits<float>::max()) | 380 else if (event->data.pinchUpdate.scale > numeric_limits<float>::max()) |
380 event->data.pinchUpdate.scale = numeric_limits<float>::max(); | 381 event->data.pinchUpdate.scale = numeric_limits<float>::max(); |
381 } | 382 } |
382 } | 383 } |
383 | 384 |
| 385 // Returns the transform matrix corresponding to the gesture event. |
| 386 gfx::Transform GetTransformForEvent(const WebGestureEvent& gesture_event) { |
| 387 gfx::Transform gesture_transform; |
| 388 if (gesture_event.type == WebInputEvent::GestureScrollUpdate) { |
| 389 gesture_transform.Translate(gesture_event.data.scrollUpdate.deltaX, |
| 390 gesture_event.data.scrollUpdate.deltaY); |
| 391 } else if (gesture_event.type == WebInputEvent::GesturePinchUpdate) { |
| 392 float scale = gesture_event.data.pinchUpdate.scale; |
| 393 gesture_transform.Translate(-gesture_event.x, -gesture_event.y); |
| 394 gesture_transform.Scale(scale, scale); |
| 395 gesture_transform.Translate(gesture_event.x, gesture_event.y); |
| 396 } else { |
| 397 NOTREACHED() << "Invalid event type for transform retrieval: " |
| 398 << WebInputEvent::GetName(gesture_event.type); |
| 399 } |
| 400 return gesture_transform; |
| 401 } |
| 402 |
384 } // namespace | 403 } // namespace |
385 | 404 |
386 bool CanCoalesce(const blink::WebInputEvent& event_to_coalesce, | 405 bool CanCoalesce(const blink::WebInputEvent& event_to_coalesce, |
387 const blink::WebInputEvent& event) { | 406 const blink::WebInputEvent& event) { |
388 if (blink::WebInputEvent::isGestureEventType(event_to_coalesce.type) && | 407 if (blink::WebInputEvent::isGestureEventType(event_to_coalesce.type) && |
389 blink::WebInputEvent::isGestureEventType(event.type)) { | 408 blink::WebInputEvent::isGestureEventType(event.type)) { |
390 return CanCoalesce( | 409 return CanCoalesce( |
391 static_cast<const blink::WebGestureEvent&>(event_to_coalesce), | 410 static_cast<const blink::WebGestureEvent&>(event_to_coalesce), |
392 static_cast<const blink::WebGestureEvent&>(event)); | 411 static_cast<const blink::WebGestureEvent&>(event)); |
393 } | 412 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 static_cast<blink::WebTouchEvent*>(event)); | 451 static_cast<blink::WebTouchEvent*>(event)); |
433 return; | 452 return; |
434 } | 453 } |
435 if (event_to_coalesce.type == blink::WebInputEvent::MouseWheel && | 454 if (event_to_coalesce.type == blink::WebInputEvent::MouseWheel && |
436 event->type == blink::WebInputEvent::MouseWheel) { | 455 event->type == blink::WebInputEvent::MouseWheel) { |
437 Coalesce(static_cast<const blink::WebMouseWheelEvent&>(event_to_coalesce), | 456 Coalesce(static_cast<const blink::WebMouseWheelEvent&>(event_to_coalesce), |
438 static_cast<blink::WebMouseWheelEvent*>(event)); | 457 static_cast<blink::WebMouseWheelEvent*>(event)); |
439 } | 458 } |
440 } | 459 } |
441 | 460 |
| 461 // Whether |event_in_queue| is GesturePinchUpdate or GestureScrollUpdate and |
| 462 // has the same modifiers/source as the new scroll/pinch event. Compatible |
| 463 // scroll and pinch event pairs can be logically coalesced. |
| 464 bool IsCompatibleScrollorPinch(const WebGestureEvent& new_event, |
| 465 const WebGestureEvent& event_in_queue) { |
| 466 DCHECK(new_event.type == WebInputEvent::GestureScrollUpdate || |
| 467 new_event.type == WebInputEvent::GesturePinchUpdate) |
| 468 << "Invalid event type for pinch/scroll coalescing: " |
| 469 << WebInputEvent::GetName(new_event.type); |
| 470 DLOG_IF(WARNING, new_event.timeStampSeconds < event_in_queue.timeStampSeconds) |
| 471 << "Event time not monotonic?\n"; |
| 472 return (event_in_queue.type == WebInputEvent::GestureScrollUpdate || |
| 473 event_in_queue.type == WebInputEvent::GesturePinchUpdate) && |
| 474 event_in_queue.modifiers == new_event.modifiers && |
| 475 event_in_queue.sourceDevice == new_event.sourceDevice; |
| 476 } |
| 477 |
| 478 std::pair<WebGestureEvent, WebGestureEvent> CoalesceScrollAndPinch( |
| 479 const WebGestureEvent* second_last_event, |
| 480 const WebGestureEvent& last_event, |
| 481 const WebGestureEvent& new_event) { |
| 482 DCHECK(!CanCoalesce(new_event, last_event)) |
| 483 << "New event can be coalesced with the last event in queue directly."; |
| 484 DCHECK(IsContinuousGestureEvent(new_event.type)); |
| 485 DCHECK(IsCompatibleScrollorPinch(new_event, last_event)); |
| 486 DCHECK(!second_last_event || |
| 487 IsCompatibleScrollorPinch(new_event, *second_last_event)); |
| 488 |
| 489 WebGestureEvent scroll_event; |
| 490 WebGestureEvent pinch_event; |
| 491 scroll_event.modifiers |= new_event.modifiers; |
| 492 scroll_event.sourceDevice = new_event.sourceDevice; |
| 493 scroll_event.timeStampSeconds = new_event.timeStampSeconds; |
| 494 pinch_event = scroll_event; |
| 495 scroll_event.type = WebInputEvent::GestureScrollUpdate; |
| 496 pinch_event.type = WebInputEvent::GesturePinchUpdate; |
| 497 pinch_event.x = new_event.type == WebInputEvent::GesturePinchUpdate |
| 498 ? new_event.x |
| 499 : last_event.x; |
| 500 pinch_event.y = new_event.type == WebInputEvent::GesturePinchUpdate |
| 501 ? new_event.y |
| 502 : last_event.y; |
| 503 |
| 504 gfx::Transform combined_scroll_pinch = GetTransformForEvent(last_event); |
| 505 if (second_last_event) { |
| 506 combined_scroll_pinch.PreconcatTransform( |
| 507 GetTransformForEvent(*second_last_event)); |
| 508 } |
| 509 combined_scroll_pinch.ConcatTransform(GetTransformForEvent(new_event)); |
| 510 |
| 511 float combined_scale = |
| 512 SkMScalarToFloat(combined_scroll_pinch.matrix().get(0, 0)); |
| 513 float combined_scroll_pinch_x = |
| 514 SkMScalarToFloat(combined_scroll_pinch.matrix().get(0, 3)); |
| 515 float combined_scroll_pinch_y = |
| 516 SkMScalarToFloat(combined_scroll_pinch.matrix().get(1, 3)); |
| 517 scroll_event.data.scrollUpdate.deltaX = |
| 518 (combined_scroll_pinch_x + pinch_event.x) / combined_scale - |
| 519 pinch_event.x; |
| 520 scroll_event.data.scrollUpdate.deltaY = |
| 521 (combined_scroll_pinch_y + pinch_event.y) / combined_scale - |
| 522 pinch_event.y; |
| 523 pinch_event.data.pinchUpdate.scale = combined_scale; |
| 524 |
| 525 return std::make_pair(scroll_event, pinch_event); |
| 526 } |
| 527 |
442 blink::WebTouchEvent CreateWebTouchEventFromMotionEvent( | 528 blink::WebTouchEvent CreateWebTouchEventFromMotionEvent( |
443 const MotionEvent& event, | 529 const MotionEvent& event, |
444 bool moved_beyond_slop_region) { | 530 bool moved_beyond_slop_region) { |
445 static_assert(static_cast<int>(MotionEvent::MAX_TOUCH_POINT_COUNT) == | 531 static_assert(static_cast<int>(MotionEvent::MAX_TOUCH_POINT_COUNT) == |
446 static_cast<int>(blink::WebTouchEvent::kTouchesLengthCap), | 532 static_cast<int>(blink::WebTouchEvent::kTouchesLengthCap), |
447 "inconsistent maximum number of active touch points"); | 533 "inconsistent maximum number of active touch points"); |
448 | 534 |
449 blink::WebTouchEvent result; | 535 blink::WebTouchEvent result; |
450 | 536 |
451 result.type = ToWebTouchEventType(event.GetAction()); | 537 result.type = ToWebTouchEventType(event.GetAction()); |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
875 bool IsContinuousGestureEvent(WebInputEvent::Type type) { | 961 bool IsContinuousGestureEvent(WebInputEvent::Type type) { |
876 switch (type) { | 962 switch (type) { |
877 case blink::WebGestureEvent::GestureScrollUpdate: | 963 case blink::WebGestureEvent::GestureScrollUpdate: |
878 case blink::WebGestureEvent::GesturePinchUpdate: | 964 case blink::WebGestureEvent::GesturePinchUpdate: |
879 return true; | 965 return true; |
880 default: | 966 default: |
881 return false; | 967 return false; |
882 } | 968 } |
883 } | 969 } |
884 | 970 |
| 971 const blink::WebGestureEvent* ToWebGestureEvent( |
| 972 const blink::WebInputEvent* event) { |
| 973 if (!event) |
| 974 return nullptr; |
| 975 DCHECK(IsGestureScollOrPinch(event->type)); |
| 976 return static_cast<const blink::WebGestureEvent*>(event); |
| 977 } |
| 978 |
| 979 const blink::WebGestureEvent& ToWebGestureEvent( |
| 980 const blink::WebInputEvent& event) { |
| 981 DCHECK(IsGestureScollOrPinch(event.type)); |
| 982 return static_cast<const blink::WebGestureEvent&>(event); |
| 983 } |
| 984 |
885 } // namespace ui | 985 } // namespace ui |
OLD | NEW |