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
3 // found in the LICENSE file.
5 // MSVC++ requires this to be set before any other includes to get M_PI.
6 #define _USE_MATH_DEFINES
8 #include "content/browser/renderer_host/input/motion_event_web.h"
12 #include "base/logging.h"
13 #include "content/browser/renderer_host/input/web_input_event_util.h"
14 #include "content/common/input/web_touch_event_traits.h"
16 using blink::WebInputEvent
;
17 using blink::WebTouchEvent
;
18 using blink::WebTouchPoint
;
23 ui::MotionEvent::Action
GetActionFrom(const WebTouchEvent
& event
) {
24 DCHECK(event
.touchesLength
);
26 case WebInputEvent::TouchStart
:
27 if (WebTouchEventTraits::AllTouchPointsHaveState(
28 event
, WebTouchPoint::StatePressed
))
29 return ui::MotionEvent::ACTION_DOWN
;
31 return ui::MotionEvent::ACTION_POINTER_DOWN
;
32 case WebInputEvent::TouchEnd
:
33 if (WebTouchEventTraits::AllTouchPointsHaveState(
34 event
, WebTouchPoint::StateReleased
))
35 return ui::MotionEvent::ACTION_UP
;
37 return ui::MotionEvent::ACTION_POINTER_UP
;
38 case WebInputEvent::TouchCancel
:
39 DCHECK(WebTouchEventTraits::AllTouchPointsHaveState(
40 event
, WebTouchPoint::StateCancelled
));
41 return ui::MotionEvent::ACTION_CANCEL
;
42 case WebInputEvent::TouchMove
:
43 return ui::MotionEvent::ACTION_MOVE
;
48 << "Unable to derive a valid MotionEvent::Action from the WebTouchEvent.";
49 return ui::MotionEvent::ACTION_CANCEL
;
52 int GetActionIndexFrom(const WebTouchEvent
& event
) {
53 for (size_t i
= 0; i
< event
.touchesLength
; ++i
) {
54 if (event
.touches
[i
].state
!= WebTouchPoint::StateUndefined
&&
55 event
.touches
[i
].state
!= WebTouchPoint::StateStationary
)
63 MotionEventWeb::MotionEventWeb(const WebTouchEvent
& event
)
65 cached_action_(GetActionFrom(event
)),
66 cached_action_index_(GetActionIndexFrom(event
)) {
67 DCHECK_GT(GetPointerCount(), 0U);
70 MotionEventWeb::~MotionEventWeb() {}
72 int MotionEventWeb::GetId() const {
76 MotionEventWeb::Action
MotionEventWeb::GetAction() const {
77 return cached_action_
;
80 int MotionEventWeb::GetActionIndex() const {
81 DCHECK(cached_action_
== ACTION_POINTER_UP
||
82 cached_action_
== ACTION_POINTER_DOWN
)
83 << "Invalid action for GetActionIndex(): " << cached_action_
;
84 DCHECK_GE(cached_action_index_
, 0);
85 DCHECK_LT(cached_action_index_
, static_cast<int>(event_
.touchesLength
));
86 return cached_action_index_
;
89 size_t MotionEventWeb::GetPointerCount() const { return event_
.touchesLength
; }
91 int MotionEventWeb::GetPointerId(size_t pointer_index
) const {
92 DCHECK_LT(pointer_index
, GetPointerCount());
93 return event_
.touches
[pointer_index
].id
;
96 float MotionEventWeb::GetX(size_t pointer_index
) const {
97 DCHECK_LT(pointer_index
, GetPointerCount());
98 return event_
.touches
[pointer_index
].position
.x
;
101 float MotionEventWeb::GetY(size_t pointer_index
) const {
102 DCHECK_LT(pointer_index
, GetPointerCount());
103 return event_
.touches
[pointer_index
].position
.y
;
106 float MotionEventWeb::GetRawX(size_t pointer_index
) const {
107 DCHECK_LT(pointer_index
, GetPointerCount());
108 return event_
.touches
[pointer_index
].screenPosition
.x
;
111 float MotionEventWeb::GetRawY(size_t pointer_index
) const {
112 DCHECK_LT(pointer_index
, GetPointerCount());
113 return event_
.touches
[pointer_index
].screenPosition
.y
;
116 float MotionEventWeb::GetTouchMajor(size_t pointer_index
) const {
117 DCHECK_LT(pointer_index
, GetPointerCount());
118 return 2.f
* std::max(event_
.touches
[pointer_index
].radiusX
,
119 event_
.touches
[pointer_index
].radiusY
);
122 float MotionEventWeb::GetTouchMinor(size_t pointer_index
) const {
123 DCHECK_LT(pointer_index
, GetPointerCount());
124 return 2.f
* std::min(event_
.touches
[pointer_index
].radiusX
,
125 event_
.touches
[pointer_index
].radiusY
);
128 float MotionEventWeb::GetOrientation(size_t pointer_index
) const {
129 DCHECK_LT(pointer_index
, GetPointerCount());
131 float rotation_angle_rad
= event_
.touches
[pointer_index
].rotationAngle
133 DCHECK(0 <= rotation_angle_rad
&& rotation_angle_rad
<= M_PI_2
)
134 << "Unexpected touch rotation angle";
136 if (event_
.touches
[pointer_index
].radiusX
137 > event_
.touches
[pointer_index
].radiusY
) {
138 // The case radiusX == radiusY is omitted from here on purpose: for circles,
139 // we want to pass the angle (which could be any value in such cases but
140 // always seem to be set to zero) unchanged.
141 rotation_angle_rad
-= (float) M_PI_2
;
144 return rotation_angle_rad
;
147 float MotionEventWeb::GetPressure(size_t pointer_index
) const {
151 base::TimeTicks
MotionEventWeb::GetEventTime() const {
152 return base::TimeTicks() +
153 base::TimeDelta::FromMicroseconds(event_
.timeStampSeconds
*
154 base::Time::kMicrosecondsPerSecond
);
157 ui::MotionEvent::ToolType
MotionEventWeb::GetToolType(
158 size_t pointer_index
) const {
159 // TODO(jdduke): Plumb tool type from the platform event, crbug.com/404128.
160 DCHECK_LT(pointer_index
, GetPointerCount());
161 return TOOL_TYPE_UNKNOWN
;
164 int MotionEventWeb::GetButtonState() const {
168 int MotionEventWeb::GetFlags() const {
169 return WebEventModifiersToEventFlags(event_
.modifiers
);
172 } // namespace content