OLD | NEW |
| (Empty) |
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. | |
4 | |
5 // MSVC++ requires this to be set before any other includes to get M_PI. | |
6 #define _USE_MATH_DEFINES | |
7 | |
8 #include "ui/events/gestures/motion_event_aura.h" | |
9 | |
10 #include <cmath> | |
11 | |
12 #include "base/logging.h" | |
13 #include "ui/events/gestures/gesture_configuration.h" | |
14 | |
15 namespace ui { | |
16 | |
17 MotionEventAura::MotionEventAura() | |
18 : pointer_count_(0), cached_action_index_(-1) { | |
19 } | |
20 | |
21 MotionEventAura::MotionEventAura( | |
22 size_t pointer_count, | |
23 const base::TimeTicks& last_touch_time, | |
24 Action cached_action, | |
25 int cached_action_index, | |
26 int flags, | |
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), | |
32 flags_(flags) { | |
33 DCHECK(pointer_count_); | |
34 for (size_t i = 0; i < pointer_count; ++i) | |
35 active_touches_[i] = active_touches[i]; | |
36 } | |
37 | |
38 MotionEventAura::~MotionEventAura() {} | |
39 | |
40 MotionEventAura::PointData MotionEventAura::GetPointDataFromTouchEvent( | |
41 const TouchEvent& touch) { | |
42 PointData point_data; | |
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(); | |
50 | |
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"; | |
58 | |
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; | |
66 } else { | |
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; | |
70 } | |
71 | |
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; | |
76 } | |
77 | |
78 return point_data; | |
79 } | |
80 | |
81 void MotionEventAura::OnTouch(const TouchEvent& touch) { | |
82 switch (touch.type()) { | |
83 case ET_TOUCH_PRESSED: | |
84 AddTouch(touch); | |
85 break; | |
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. | |
91 UpdateTouch(touch); | |
92 break; | |
93 case ET_TOUCH_MOVED: | |
94 UpdateTouch(touch); | |
95 break; | |
96 default: | |
97 NOTREACHED(); | |
98 break; | |
99 } | |
100 | |
101 UpdateCachedAction(touch); | |
102 flags_ = touch.flags(); | |
103 last_touch_time_ = touch.time_stamp() + base::TimeTicks(); | |
104 } | |
105 | |
106 int MotionEventAura::GetId() const { | |
107 return GetPointerId(0); | |
108 } | |
109 | |
110 MotionEvent::Action MotionEventAura::GetAction() const { | |
111 return cached_action_; | |
112 } | |
113 | |
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_; | |
120 } | |
121 | |
122 size_t MotionEventAura::GetPointerCount() const { return pointer_count_; } | |
123 | |
124 int MotionEventAura::GetPointerId(size_t pointer_index) const { | |
125 DCHECK_LT(pointer_index, pointer_count_); | |
126 return active_touches_[pointer_index].touch_id; | |
127 } | |
128 | |
129 float MotionEventAura::GetX(size_t pointer_index) const { | |
130 DCHECK_LT(pointer_index, pointer_count_); | |
131 return active_touches_[pointer_index].x; | |
132 } | |
133 | |
134 float MotionEventAura::GetY(size_t pointer_index) const { | |
135 DCHECK_LT(pointer_index, pointer_count_); | |
136 return active_touches_[pointer_index].y; | |
137 } | |
138 | |
139 float MotionEventAura::GetRawX(size_t pointer_index) const { | |
140 DCHECK_LT(pointer_index, pointer_count_); | |
141 return active_touches_[pointer_index].raw_x; | |
142 } | |
143 | |
144 float MotionEventAura::GetRawY(size_t pointer_index) const { | |
145 DCHECK_LT(pointer_index, pointer_count_); | |
146 return active_touches_[pointer_index].raw_y; | |
147 } | |
148 | |
149 float MotionEventAura::GetTouchMajor(size_t pointer_index) const { | |
150 DCHECK_LT(pointer_index, pointer_count_); | |
151 return active_touches_[pointer_index].touch_major; | |
152 } | |
153 | |
154 float MotionEventAura::GetTouchMinor(size_t pointer_index) const { | |
155 DCHECK_LE(pointer_index, pointer_count_); | |
156 return active_touches_[pointer_index].touch_minor; | |
157 } | |
158 | |
159 float MotionEventAura::GetOrientation(size_t pointer_index) const { | |
160 DCHECK_LE(pointer_index, pointer_count_); | |
161 return active_touches_[pointer_index].orientation; | |
162 } | |
163 | |
164 float MotionEventAura::GetPressure(size_t pointer_index) const { | |
165 DCHECK_LT(pointer_index, pointer_count_); | |
166 return active_touches_[pointer_index].pressure; | |
167 } | |
168 | |
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; | |
173 } | |
174 | |
175 int MotionEventAura::GetButtonState() const { | |
176 NOTIMPLEMENTED(); | |
177 return 0; | |
178 } | |
179 | |
180 int MotionEventAura::GetFlags() const { | |
181 return flags_; | |
182 } | |
183 | |
184 base::TimeTicks MotionEventAura::GetEventTime() const { | |
185 return last_touch_time_; | |
186 } | |
187 | |
188 scoped_ptr<MotionEvent> MotionEventAura::Clone() const { | |
189 return scoped_ptr<MotionEvent>(new MotionEventAura(pointer_count_, | |
190 last_touch_time_, | |
191 cached_action_, | |
192 cached_action_index_, | |
193 flags_, | |
194 active_touches_)); | |
195 } | |
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_)); | |
199 } | |
200 | |
201 void MotionEventAura::CleanupRemovedTouchPoints(const TouchEvent& event) { | |
202 if (event.type() != ET_TOUCH_RELEASED && | |
203 event.type() != ET_TOUCH_CANCELLED) { | |
204 return; | |
205 } | |
206 | |
207 int index_to_delete = static_cast<int>(GetIndexFromId(event.touch_id())); | |
208 pointer_count_--; | |
209 active_touches_[index_to_delete] = active_touches_[pointer_count_]; | |
210 } | |
211 | |
212 MotionEventAura::PointData::PointData() | |
213 : x(0), | |
214 y(0), | |
215 raw_x(0), | |
216 raw_y(0), | |
217 touch_id(0), | |
218 pressure(0), | |
219 source_device_id(0), | |
220 touch_major(0), | |
221 touch_minor(0), | |
222 orientation(0) { | |
223 } | |
224 | |
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; | |
228 } | |
229 | |
230 void MotionEventAura::AddTouch(const TouchEvent& touch) { | |
231 if (pointer_count_ == MotionEvent::MAX_TOUCH_POINT_COUNT) | |
232 return; | |
233 | |
234 active_touches_[pointer_count_] = GetPointDataFromTouchEvent(touch); | |
235 pointer_count_++; | |
236 } | |
237 | |
238 | |
239 void MotionEventAura::UpdateTouch(const TouchEvent& touch) { | |
240 active_touches_[GetIndexFromId(touch.touch_id())] = | |
241 GetPointDataFromTouchEvent(touch); | |
242 } | |
243 | |
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; | |
250 } else { | |
251 cached_action_ = ACTION_POINTER_DOWN; | |
252 cached_action_index_ = | |
253 static_cast<int>(GetIndexFromId(touch.touch_id())); | |
254 } | |
255 break; | |
256 case ET_TOUCH_RELEASED: | |
257 if (pointer_count_ == 1) { | |
258 cached_action_ = ACTION_UP; | |
259 } else { | |
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_)); | |
264 } | |
265 break; | |
266 case ET_TOUCH_CANCELLED: | |
267 cached_action_ = ACTION_CANCEL; | |
268 break; | |
269 case ET_TOUCH_MOVED: | |
270 cached_action_ = ACTION_MOVE; | |
271 break; | |
272 default: | |
273 NOTREACHED(); | |
274 break; | |
275 } | |
276 } | |
277 | |
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) | |
281 return i; | |
282 } | |
283 NOTREACHED(); | |
284 return 0; | |
285 } | |
286 | |
287 } // namespace ui | |
OLD | NEW |