Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ui / events / gesture_detection / motion_event_generic.cc
blobbe367bd841fde7507475786ed6bda1b0122cc706
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"
10 #include <cmath>
12 #include "base/logging.h"
13 #include "ui/events/base_event_utils.h"
15 namespace ui {
17 PointerProperties::PointerProperties()
18 : PointerProperties(0, 0, 0) {
21 PointerProperties::PointerProperties(float x, float y, float touch_major)
22 : id(0),
23 tool_type(MotionEvent::TOOL_TYPE_UNKNOWN),
24 x(x),
25 y(y),
26 raw_x(x),
27 raw_y(y),
28 pressure(0),
29 touch_major(touch_major),
30 touch_minor(0),
31 orientation(0),
32 source_device_id(0) {
35 PointerProperties::PointerProperties(const MotionEvent& event,
36 size_t pointer_index)
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)),
47 source_device_id(0) {
50 void PointerProperties::SetAxesAndOrientation(float radius_x,
51 float radius_y,
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;
74 } else {
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)
84 : action_(action),
85 event_time_(event_time),
86 unique_event_id_(ui::GetNextTouchEventId()),
87 action_index_(0),
88 button_state_(0),
89 flags_(0) {
90 PushPointer(pointer);
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_),
99 flags_(other.flags_),
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 {
114 return action_;
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 {
184 return flags_;
187 base::TimeTicks MotionEventGeneric::GetEventTime() const {
188 return event_time_;
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);
220 // static
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));
227 // static
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) {
250 DCHECK(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()),
262 action_index_(-1),
263 button_state_(0) {
266 MotionEventGeneric::MotionEventGeneric(const MotionEvent& event,
267 bool with_history)
268 : action_(event.GetAction()),
269 event_time_(event.GetEventTime()),
270 unique_event_id_(event.GetUniqueEventId()),
271 action_index_(
272 (action_ == ACTION_POINTER_UP || action_ == ACTION_POINTER_DOWN)
273 ? event.GetActionIndex()
274 : 0),
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));
281 if (!with_history)
282 return;
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());
311 return *this;
314 void MotionEventGeneric::PopPointer() {
315 DCHECK_GT(pointers_->size(), 0U);
316 pointers_->pop_back();
319 } // namespace ui