• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
MotionEventAura()17 MotionEventAura::MotionEventAura()
18     : pointer_count_(0), cached_action_index_(-1) {
19 }
20 
MotionEventAura(size_t pointer_count,const base::TimeTicks & last_touch_time,Action cached_action,int cached_action_index,int flags,const PointData (& active_touches)[MotionEvent::MAX_TOUCH_POINT_COUNT])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 
~MotionEventAura()38 MotionEventAura::~MotionEventAura() {}
39 
GetPointDataFromTouchEvent(const TouchEvent & touch)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 
OnTouch(const TouchEvent & touch)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 
GetId() const106 int MotionEventAura::GetId() const {
107   return GetPointerId(0);
108 }
109 
GetAction() const110 MotionEvent::Action MotionEventAura::GetAction() const {
111   return cached_action_;
112 }
113 
GetActionIndex() const114 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 
GetPointerCount() const122 size_t MotionEventAura::GetPointerCount() const { return pointer_count_; }
123 
GetPointerId(size_t pointer_index) const124 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 
GetX(size_t pointer_index) const129 float MotionEventAura::GetX(size_t pointer_index) const {
130   DCHECK_LT(pointer_index, pointer_count_);
131   return active_touches_[pointer_index].x;
132 }
133 
GetY(size_t pointer_index) const134 float MotionEventAura::GetY(size_t pointer_index) const {
135   DCHECK_LT(pointer_index, pointer_count_);
136   return active_touches_[pointer_index].y;
137 }
138 
GetRawX(size_t pointer_index) const139 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 
GetRawY(size_t pointer_index) const144 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 
GetTouchMajor(size_t pointer_index) const149 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 
GetTouchMinor(size_t pointer_index) const154 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 
GetOrientation(size_t pointer_index) const159 float MotionEventAura::GetOrientation(size_t pointer_index) const {
160   DCHECK_LE(pointer_index, pointer_count_);
161   return active_touches_[pointer_index].orientation;
162 }
163 
GetPressure(size_t pointer_index) const164 float MotionEventAura::GetPressure(size_t pointer_index) const {
165   DCHECK_LT(pointer_index, pointer_count_);
166   return active_touches_[pointer_index].pressure;
167 }
168 
GetToolType(size_t pointer_index) const169 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 
GetButtonState() const175 int MotionEventAura::GetButtonState() const {
176   NOTIMPLEMENTED();
177   return 0;
178 }
179 
GetFlags() const180 int MotionEventAura::GetFlags() const {
181   return flags_;
182 }
183 
GetEventTime() const184 base::TimeTicks MotionEventAura::GetEventTime() const {
185   return last_touch_time_;
186 }
187 
Clone() const188 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 }
Cancel() const196 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 
CleanupRemovedTouchPoints(const TouchEvent & event)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 
PointData()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 
GetSourceDeviceId(size_t pointer_index) const225 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 
AddTouch(const TouchEvent & touch)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 
UpdateTouch(const TouchEvent & touch)239 void MotionEventAura::UpdateTouch(const TouchEvent& touch) {
240   active_touches_[GetIndexFromId(touch.touch_id())] =
241       GetPointDataFromTouchEvent(touch);
242 }
243 
UpdateCachedAction(const TouchEvent & 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;
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 
GetIndexFromId(int id) const278 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
288