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 "ui/events/gestures/motion_event_aura.h"
12 #include "base/logging.h"
13 #include "ui/events/gestures/gesture_configuration.h"
17 MotionEventAura::MotionEventAura()
18 : pointer_count_(0), cached_action_index_(-1) {
21 MotionEventAura::MotionEventAura(
23 const base::TimeTicks
& last_touch_time
,
25 int cached_action_index
,
27 const PointData (&active_touches
)[MotionEvent::MAX_TOUCH_POINT_COUNT
])
28 : pointer_count_(pointer_count
),
29 last_touch_time_(last_touch_time
),
30 cached_action_(cached_action
),
31 cached_action_index_(cached_action_index
),
33 DCHECK(pointer_count_
);
34 for (size_t i
= 0; i
< pointer_count
; ++i
)
35 active_touches_
[i
] = active_touches
[i
];
38 MotionEventAura::~MotionEventAura() {}
40 MotionEventAura::PointData
MotionEventAura::GetPointDataFromTouchEvent(
41 const TouchEvent
& touch
) {
43 point_data
.x
= touch
.x();
44 point_data
.y
= touch
.y();
45 point_data
.raw_x
= touch
.root_location_f().x();
46 point_data
.raw_y
= touch
.root_location_f().y();
47 point_data
.touch_id
= touch
.touch_id();
48 point_data
.pressure
= touch
.force();
49 point_data
.source_device_id
= touch
.source_device_id();
51 float radius_x
= touch
.radius_x();
52 float radius_y
= touch
.radius_y();
53 float rotation_angle_rad
= touch
.rotation_angle() * M_PI
/ 180.f
;
54 DCHECK_GE(radius_x
, 0) << "Unexpected x-radius < 0";
55 DCHECK_GE(radius_y
, 0) << "Unexpected y-radius < 0";
56 DCHECK(0 <= rotation_angle_rad
&& rotation_angle_rad
<= M_PI_2
)
57 << "Unexpected touch rotation angle";
59 if (radius_x
> radius_y
) {
60 // The case radius_x == radius_y is omitted from here on purpose: for
61 // circles, we want to pass the angle (which could be any value in such
62 // cases but always seem to be set to zero) unchanged.
63 point_data
.touch_major
= 2.f
* radius_x
;
64 point_data
.touch_minor
= 2.f
* radius_y
;
65 point_data
.orientation
= rotation_angle_rad
- M_PI_2
;
67 point_data
.touch_major
= 2.f
* radius_y
;
68 point_data
.touch_minor
= 2.f
* radius_x
;
69 point_data
.orientation
= rotation_angle_rad
;
72 if (!point_data
.touch_major
) {
73 point_data
.touch_major
= 2.f
* GestureConfiguration::default_radius();
74 point_data
.touch_minor
= 2.f
* GestureConfiguration::default_radius();
75 point_data
.orientation
= 0;
81 void MotionEventAura::OnTouch(const TouchEvent
& touch
) {
82 switch (touch
.type()) {
83 case ET_TOUCH_PRESSED
:
86 case ET_TOUCH_RELEASED
:
87 case ET_TOUCH_CANCELLED
:
88 // Removing these touch points needs to be postponed until after the
89 // MotionEvent has been dispatched. This cleanup occurs in
90 // CleanupRemovedTouchPoints.
101 UpdateCachedAction(touch
);
102 flags_
= touch
.flags();
103 last_touch_time_
= touch
.time_stamp() + base::TimeTicks();
106 int MotionEventAura::GetId() const {
107 return GetPointerId(0);
110 MotionEvent::Action
MotionEventAura::GetAction() const {
111 return cached_action_
;
114 int MotionEventAura::GetActionIndex() const {
115 DCHECK(cached_action_
== ACTION_POINTER_DOWN
||
116 cached_action_
== ACTION_POINTER_UP
);
117 DCHECK_GE(cached_action_index_
, 0);
118 DCHECK_LT(cached_action_index_
, static_cast<int>(pointer_count_
));
119 return cached_action_index_
;
122 size_t MotionEventAura::GetPointerCount() const { return pointer_count_
; }
124 int MotionEventAura::GetPointerId(size_t pointer_index
) const {
125 DCHECK_LT(pointer_index
, pointer_count_
);
126 return active_touches_
[pointer_index
].touch_id
;
129 float MotionEventAura::GetX(size_t pointer_index
) const {
130 DCHECK_LT(pointer_index
, pointer_count_
);
131 return active_touches_
[pointer_index
].x
;
134 float MotionEventAura::GetY(size_t pointer_index
) const {
135 DCHECK_LT(pointer_index
, pointer_count_
);
136 return active_touches_
[pointer_index
].y
;
139 float MotionEventAura::GetRawX(size_t pointer_index
) const {
140 DCHECK_LT(pointer_index
, pointer_count_
);
141 return active_touches_
[pointer_index
].raw_x
;
144 float MotionEventAura::GetRawY(size_t pointer_index
) const {
145 DCHECK_LT(pointer_index
, pointer_count_
);
146 return active_touches_
[pointer_index
].raw_y
;
149 float MotionEventAura::GetTouchMajor(size_t pointer_index
) const {
150 DCHECK_LT(pointer_index
, pointer_count_
);
151 return active_touches_
[pointer_index
].touch_major
;
154 float MotionEventAura::GetTouchMinor(size_t pointer_index
) const {
155 DCHECK_LE(pointer_index
, pointer_count_
);
156 return active_touches_
[pointer_index
].touch_minor
;
159 float MotionEventAura::GetOrientation(size_t pointer_index
) const {
160 DCHECK_LE(pointer_index
, pointer_count_
);
161 return active_touches_
[pointer_index
].orientation
;
164 float MotionEventAura::GetPressure(size_t pointer_index
) const {
165 DCHECK_LT(pointer_index
, pointer_count_
);
166 return active_touches_
[pointer_index
].pressure
;
169 MotionEvent::ToolType
MotionEventAura::GetToolType(size_t pointer_index
) const {
170 // TODO(jdduke): Plumb tool type from the platform, crbug.com/404128.
171 DCHECK_LT(pointer_index
, pointer_count_
);
172 return MotionEvent::TOOL_TYPE_UNKNOWN
;
175 int MotionEventAura::GetButtonState() const {
180 int MotionEventAura::GetFlags() const {
184 base::TimeTicks
MotionEventAura::GetEventTime() const {
185 return last_touch_time_
;
188 scoped_ptr
<MotionEvent
> MotionEventAura::Clone() const {
189 return scoped_ptr
<MotionEvent
>(new MotionEventAura(pointer_count_
,
192 cached_action_index_
,
196 scoped_ptr
<MotionEvent
> MotionEventAura::Cancel() const {
197 return scoped_ptr
<MotionEvent
>(new MotionEventAura(
198 pointer_count_
, last_touch_time_
, ACTION_CANCEL
, -1, 0, active_touches_
));
201 void MotionEventAura::CleanupRemovedTouchPoints(const TouchEvent
& event
) {
202 if (event
.type() != ET_TOUCH_RELEASED
&&
203 event
.type() != ET_TOUCH_CANCELLED
) {
207 int index_to_delete
= static_cast<int>(GetIndexFromId(event
.touch_id()));
209 active_touches_
[index_to_delete
] = active_touches_
[pointer_count_
];
212 MotionEventAura::PointData::PointData()
225 int MotionEventAura::GetSourceDeviceId(size_t pointer_index
) const {
226 DCHECK_LT(pointer_index
, pointer_count_
);
227 return active_touches_
[pointer_index
].source_device_id
;
230 void MotionEventAura::AddTouch(const TouchEvent
& touch
) {
231 if (pointer_count_
== MotionEvent::MAX_TOUCH_POINT_COUNT
)
234 active_touches_
[pointer_count_
] = GetPointDataFromTouchEvent(touch
);
239 void MotionEventAura::UpdateTouch(const TouchEvent
& touch
) {
240 active_touches_
[GetIndexFromId(touch
.touch_id())] =
241 GetPointDataFromTouchEvent(touch
);
244 void MotionEventAura::UpdateCachedAction(const TouchEvent
& touch
) {
245 DCHECK(pointer_count_
);
246 switch (touch
.type()) {
247 case ET_TOUCH_PRESSED
:
248 if (pointer_count_
== 1) {
249 cached_action_
= ACTION_DOWN
;
251 cached_action_
= ACTION_POINTER_DOWN
;
252 cached_action_index_
=
253 static_cast<int>(GetIndexFromId(touch
.touch_id()));
256 case ET_TOUCH_RELEASED
:
257 if (pointer_count_
== 1) {
258 cached_action_
= ACTION_UP
;
260 cached_action_
= ACTION_POINTER_UP
;
261 cached_action_index_
=
262 static_cast<int>(GetIndexFromId(touch
.touch_id()));
263 DCHECK_LT(cached_action_index_
, static_cast<int>(pointer_count_
));
266 case ET_TOUCH_CANCELLED
:
267 cached_action_
= ACTION_CANCEL
;
270 cached_action_
= ACTION_MOVE
;
278 size_t MotionEventAura::GetIndexFromId(int id
) const {
279 for (size_t i
= 0; i
< pointer_count_
; ++i
) {
280 if (active_touches_
[i
].touch_id
== id
)