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/gesture_detection/motion_event_generic.h"
12 #include "base/logging.h"
13 #include "ui/events/base_event_utils.h"
17 PointerProperties::PointerProperties()
18 : PointerProperties(0, 0, 0) {
21 PointerProperties::PointerProperties(float x
, float y
, float touch_major
)
23 tool_type(MotionEvent::TOOL_TYPE_UNKNOWN
),
29 touch_major(touch_major
),
35 PointerProperties::PointerProperties(const MotionEvent
& event
,
37 : id(event
.GetPointerId(pointer_index
)),
38 tool_type(event
.GetToolType(pointer_index
)),
39 x(event
.GetX(pointer_index
)),
40 y(event
.GetY(pointer_index
)),
41 raw_x(event
.GetRawX(pointer_index
)),
42 raw_y(event
.GetRawY(pointer_index
)),
43 pressure(event
.GetPressure(pointer_index
)),
44 touch_major(event
.GetTouchMajor(pointer_index
)),
45 touch_minor(event
.GetTouchMinor(pointer_index
)),
46 orientation(event
.GetOrientation(pointer_index
)),
50 void PointerProperties::SetAxesAndOrientation(float radius_x
,
52 float rotation_angle_degree
) {
53 DCHECK(!touch_major
&& !touch_minor
&& !orientation
);
54 float rotation_angle_rad
= rotation_angle_degree
* M_PI
/ 180.f
;
55 DCHECK_GE(radius_x
, 0) << "Unexpected x-radius < 0 (" << radius_x
<< ")";
56 DCHECK_GE(radius_y
, 0) << "Unexpected y-radius < 0 (" << radius_y
<< ")";
57 DCHECK(0 <= rotation_angle_rad
&& rotation_angle_rad
< M_PI
)
58 << "Unexpected touch rotation angle " << rotation_angle_rad
<< " rad";
60 // Make the angle acute to ease subsequent logic. The angle range effectively
61 // changes from [0, pi) to [0, pi/2).
62 if (rotation_angle_rad
>= M_PI_2
) {
63 rotation_angle_rad
-= static_cast<float>(M_PI_2
);
64 std::swap(radius_x
, radius_y
);
67 if (radius_x
> radius_y
) {
68 // The case radius_x == radius_y is omitted from here on purpose: for
69 // circles, we want to pass the angle (which could be any value in such
70 // cases but always seem to be set to zero) unchanged.
71 touch_major
= 2.f
* radius_x
;
72 touch_minor
= 2.f
* radius_y
;
73 orientation
= rotation_angle_rad
- M_PI_2
;
75 touch_major
= 2.f
* radius_y
;
76 touch_minor
= 2.f
* radius_x
;
77 orientation
= rotation_angle_rad
;
81 MotionEventGeneric::MotionEventGeneric(Action action
,
82 base::TimeTicks event_time
,
83 const PointerProperties
& pointer
)
85 event_time_(event_time
),
86 unique_event_id_(ui::GetNextTouchEventId()),
93 MotionEventGeneric::MotionEventGeneric(const MotionEventGeneric
& other
)
94 : action_(other
.action_
),
95 event_time_(other
.event_time_
),
96 unique_event_id_(other
.unique_event_id_
),
97 action_index_(other
.action_index_
),
98 button_state_(other
.button_state_
),
100 pointers_(other
.pointers_
) {
101 const size_t history_size
= other
.GetHistorySize();
102 for (size_t h
= 0; h
< history_size
; ++h
)
103 PushHistoricalEvent(other
.historical_events_
[h
]->Clone());
106 MotionEventGeneric::~MotionEventGeneric() {
109 uint32
MotionEventGeneric::GetUniqueEventId() const {
110 return unique_event_id_
;
113 MotionEvent::Action
MotionEventGeneric::GetAction() const {
117 int MotionEventGeneric::GetActionIndex() const {
118 DCHECK(action_
== ACTION_POINTER_DOWN
|| action_
== ACTION_POINTER_UP
);
119 DCHECK_GE(action_index_
, 0);
120 DCHECK_LT(action_index_
, static_cast<int>(pointers_
->size()));
121 return action_index_
;
124 size_t MotionEventGeneric::GetPointerCount() const {
125 return pointers_
->size();
128 int MotionEventGeneric::GetPointerId(size_t pointer_index
) const {
129 DCHECK_LT(pointer_index
, pointers_
->size());
130 return pointers_
[pointer_index
].id
;
133 float MotionEventGeneric::GetX(size_t pointer_index
) const {
134 DCHECK_LT(pointer_index
, pointers_
->size());
135 return pointers_
[pointer_index
].x
;
138 float MotionEventGeneric::GetY(size_t pointer_index
) const {
139 DCHECK_LT(pointer_index
, pointers_
->size());
140 return pointers_
[pointer_index
].y
;
143 float MotionEventGeneric::GetRawX(size_t pointer_index
) const {
144 DCHECK_LT(pointer_index
, pointers_
->size());
145 return pointers_
[pointer_index
].raw_x
;
148 float MotionEventGeneric::GetRawY(size_t pointer_index
) const {
149 DCHECK_LT(pointer_index
, pointers_
->size());
150 return pointers_
[pointer_index
].raw_y
;
153 float MotionEventGeneric::GetTouchMajor(size_t pointer_index
) const {
154 DCHECK_LT(pointer_index
, pointers_
->size());
155 return pointers_
[pointer_index
].touch_major
;
158 float MotionEventGeneric::GetTouchMinor(size_t pointer_index
) const {
159 DCHECK_LT(pointer_index
, pointers_
->size());
160 return pointers_
[pointer_index
].touch_minor
;
163 float MotionEventGeneric::GetOrientation(size_t pointer_index
) const {
164 DCHECK_LT(pointer_index
, pointers_
->size());
165 return pointers_
[pointer_index
].orientation
;
168 float MotionEventGeneric::GetPressure(size_t pointer_index
) const {
169 DCHECK_LT(pointer_index
, pointers_
->size());
170 return pointers_
[pointer_index
].pressure
;
173 MotionEvent::ToolType
MotionEventGeneric::GetToolType(
174 size_t pointer_index
) const {
175 DCHECK_LT(pointer_index
, pointers_
->size());
176 return pointers_
[pointer_index
].tool_type
;
179 int MotionEventGeneric::GetButtonState() const {
180 return button_state_
;
183 int MotionEventGeneric::GetFlags() const {
187 base::TimeTicks
MotionEventGeneric::GetEventTime() const {
191 size_t MotionEventGeneric::GetHistorySize() const {
192 return historical_events_
.size();
195 base::TimeTicks
MotionEventGeneric::GetHistoricalEventTime(
196 size_t historical_index
) const {
197 DCHECK_LT(historical_index
, historical_events_
.size());
198 return historical_events_
[historical_index
]->GetEventTime();
201 float MotionEventGeneric::GetHistoricalTouchMajor(
202 size_t pointer_index
,
203 size_t historical_index
) const {
204 DCHECK_LT(historical_index
, historical_events_
.size());
205 return historical_events_
[historical_index
]->GetTouchMajor(pointer_index
);
208 float MotionEventGeneric::GetHistoricalX(size_t pointer_index
,
209 size_t historical_index
) const {
210 DCHECK_LT(historical_index
, historical_events_
.size());
211 return historical_events_
[historical_index
]->GetX(pointer_index
);
214 float MotionEventGeneric::GetHistoricalY(size_t pointer_index
,
215 size_t historical_index
) const {
216 DCHECK_LT(historical_index
, historical_events_
.size());
217 return historical_events_
[historical_index
]->GetY(pointer_index
);
221 scoped_ptr
<MotionEventGeneric
> MotionEventGeneric::CloneEvent(
222 const MotionEvent
& event
) {
223 bool with_history
= true;
224 return make_scoped_ptr(new MotionEventGeneric(event
, with_history
));
228 scoped_ptr
<MotionEventGeneric
> MotionEventGeneric::CancelEvent(
229 const MotionEvent
& event
) {
230 bool with_history
= false;
231 scoped_ptr
<MotionEventGeneric
> cancel_event(
232 new MotionEventGeneric(event
, with_history
));
233 cancel_event
->set_action(ACTION_CANCEL
);
234 cancel_event
->set_unique_event_id(ui::GetNextTouchEventId());
235 return cancel_event
.Pass();
238 size_t MotionEventGeneric::PushPointer(const PointerProperties
& pointer
) {
239 DCHECK_EQ(0U, GetHistorySize());
240 pointers_
->push_back(pointer
);
241 return pointers_
->size() - 1;
244 void MotionEventGeneric::RemovePointerAt(size_t index
) {
245 DCHECK_LT(index
, pointers_
->size());
246 pointers_
->erase(pointers_
->begin() + index
);
249 void MotionEventGeneric::PushHistoricalEvent(scoped_ptr
<MotionEvent
> event
) {
251 DCHECK_EQ(event
->GetAction(), ACTION_MOVE
);
252 DCHECK_EQ(event
->GetPointerCount(), GetPointerCount());
253 DCHECK_EQ(event
->GetAction(), GetAction());
254 DCHECK_LE(event
->GetEventTime().ToInternalValue(),
255 GetEventTime().ToInternalValue());
256 historical_events_
.push_back(event
.Pass());
259 MotionEventGeneric::MotionEventGeneric()
260 : action_(ACTION_NONE
),
261 unique_event_id_(ui::GetNextTouchEventId()),
266 MotionEventGeneric::MotionEventGeneric(const MotionEvent
& event
,
268 : action_(event
.GetAction()),
269 event_time_(event
.GetEventTime()),
270 unique_event_id_(event
.GetUniqueEventId()),
272 (action_
== ACTION_POINTER_UP
|| action_
== ACTION_POINTER_DOWN
)
273 ? event
.GetActionIndex()
275 button_state_(event
.GetButtonState()),
276 flags_(event
.GetFlags()) {
277 const size_t pointer_count
= event
.GetPointerCount();
278 for (size_t i
= 0; i
< pointer_count
; ++i
)
279 PushPointer(PointerProperties(event
, i
));
284 const size_t history_size
= event
.GetHistorySize();
285 for (size_t h
= 0; h
< history_size
; ++h
) {
286 scoped_ptr
<MotionEventGeneric
> historical_event(new MotionEventGeneric());
287 historical_event
->set_action(ACTION_MOVE
);
288 historical_event
->set_event_time(event
.GetHistoricalEventTime(h
));
289 for (size_t i
= 0; i
< pointer_count
; ++i
) {
290 historical_event
->PushPointer(
291 PointerProperties(event
.GetHistoricalX(i
, h
),
292 event
.GetHistoricalY(i
, h
),
293 event
.GetHistoricalTouchMajor(i
, h
)));
295 PushHistoricalEvent(historical_event
.Pass());
299 MotionEventGeneric
& MotionEventGeneric::operator=(
300 const MotionEventGeneric
& other
) {
301 action_
= other
.action_
;
302 event_time_
= other
.event_time_
;
303 unique_event_id_
= other
.unique_event_id_
;
304 action_index_
= other
.action_index_
;
305 button_state_
= other
.button_state_
;
306 flags_
= other
.flags_
;
307 pointers_
= other
.pointers_
;
308 const size_t history_size
= other
.GetHistorySize();
309 for (size_t h
= 0; h
< history_size
; ++h
)
310 PushHistoricalEvent(other
.historical_events_
[h
]->Clone());
314 void MotionEventGeneric::PopPointer() {
315 DCHECK_GT(pointers_
->size(), 0U);
316 pointers_
->pop_back();