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