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 #include "ui/events/gestures/motion_event_aura.h" 6 7 #include "base/logging.h" 8 #include "ui/events/gestures/gesture_configuration.h" 9 10 namespace ui { 11 12 MotionEventAura::MotionEventAura() 13 : pointer_count_(0), cached_action_index_(-1) { 14 } 15 16 MotionEventAura::MotionEventAura( 17 size_t pointer_count, 18 const base::TimeTicks& last_touch_time, 19 Action cached_action, 20 int cached_action_index, 21 const PointData (&active_touches)[GestureSequence::kMaxGesturePoints]) 22 : pointer_count_(pointer_count), 23 last_touch_time_(last_touch_time), 24 cached_action_(cached_action), 25 cached_action_index_(cached_action_index) { 26 DCHECK(pointer_count_); 27 for (size_t i = 0; i < pointer_count; ++i) 28 active_touches_[i] = active_touches[i]; 29 } 30 31 MotionEventAura::~MotionEventAura() {} 32 33 MotionEventAura::PointData MotionEventAura::GetPointDataFromTouchEvent( 34 const TouchEvent& touch) { 35 PointData point_data; 36 point_data.x = touch.x(); 37 point_data.y = touch.y(); 38 point_data.raw_x = touch.root_location_f().x(); 39 point_data.raw_y = touch.root_location_f().y(); 40 point_data.touch_id = touch.touch_id(); 41 point_data.pressure = touch.force(); 42 point_data.source_device_id = touch.source_device_id(); 43 44 // TODO(tdresser): at some point we should start using both radii if they are 45 // available, but for now we use the max. 46 point_data.major_radius = std::max(touch.radius_x(), touch.radius_y()); 47 if (!point_data.major_radius) 48 point_data.major_radius = GestureConfiguration::default_radius(); 49 return point_data; 50 } 51 52 void MotionEventAura::OnTouch(const TouchEvent& touch) { 53 switch (touch.type()) { 54 case ET_TOUCH_PRESSED: 55 AddTouch(touch); 56 break; 57 case ET_TOUCH_RELEASED: 58 case ET_TOUCH_CANCELLED: 59 // Removing these touch points needs to be postponed until after the 60 // MotionEvent has been dispatched. This cleanup occurs in 61 // CleanupRemovedTouchPoints. 62 UpdateTouch(touch); 63 break; 64 case ET_TOUCH_MOVED: 65 UpdateTouch(touch); 66 break; 67 default: 68 NOTREACHED(); 69 break; 70 } 71 72 UpdateCachedAction(touch); 73 last_touch_time_ = touch.time_stamp() + base::TimeTicks(); 74 } 75 76 int MotionEventAura::GetId() const { 77 return GetPointerId(0); 78 } 79 80 MotionEvent::Action MotionEventAura::GetAction() const { 81 return cached_action_; 82 } 83 84 int MotionEventAura::GetActionIndex() const { 85 DCHECK(cached_action_ == ACTION_POINTER_DOWN || 86 cached_action_ == ACTION_POINTER_UP); 87 DCHECK_GE(cached_action_index_, 0); 88 DCHECK_LE(cached_action_index_, static_cast<int>(pointer_count_)); 89 return cached_action_index_; 90 } 91 92 size_t MotionEventAura::GetPointerCount() const { return pointer_count_; } 93 94 int MotionEventAura::GetPointerId(size_t pointer_index) const { 95 DCHECK_LE(pointer_index, pointer_count_); 96 return active_touches_[pointer_index].touch_id; 97 } 98 99 float MotionEventAura::GetX(size_t pointer_index) const { 100 DCHECK_LE(pointer_index, pointer_count_); 101 return active_touches_[pointer_index].x; 102 } 103 104 float MotionEventAura::GetY(size_t pointer_index) const { 105 DCHECK_LE(pointer_index, pointer_count_); 106 return active_touches_[pointer_index].y; 107 } 108 109 float MotionEventAura::GetRawX(size_t pointer_index) const { 110 DCHECK_LE(pointer_index, pointer_count_); 111 return active_touches_[pointer_index].raw_x; 112 } 113 114 float MotionEventAura::GetRawY(size_t pointer_index) const { 115 DCHECK_LE(pointer_index, pointer_count_); 116 return active_touches_[pointer_index].raw_y; 117 } 118 119 float MotionEventAura::GetTouchMajor(size_t pointer_index) const { 120 DCHECK_LE(pointer_index, pointer_count_); 121 return active_touches_[pointer_index].major_radius * 2; 122 } 123 124 float MotionEventAura::GetPressure(size_t pointer_index) const { 125 DCHECK_LE(pointer_index, pointer_count_); 126 return active_touches_[pointer_index].pressure; 127 } 128 129 base::TimeTicks MotionEventAura::GetEventTime() const { 130 return last_touch_time_; 131 } 132 133 size_t MotionEventAura::GetHistorySize() const { return 0; } 134 135 base::TimeTicks MotionEventAura::GetHistoricalEventTime( 136 size_t historical_index) const { 137 NOTIMPLEMENTED(); 138 return base::TimeTicks(); 139 } 140 141 float MotionEventAura::GetHistoricalTouchMajor(size_t pointer_index, 142 size_t historical_index) const { 143 NOTIMPLEMENTED(); 144 return 0; 145 } 146 147 float MotionEventAura::GetHistoricalX(size_t pointer_index, 148 size_t historical_index) const { 149 NOTIMPLEMENTED(); 150 return 0; 151 } 152 153 float MotionEventAura::GetHistoricalY(size_t pointer_index, 154 size_t historical_index) const { 155 NOTIMPLEMENTED(); 156 return 0; 157 } 158 159 MotionEvent::ToolType MotionEventAura::GetToolType(size_t pointer_index) const { 160 NOTIMPLEMENTED(); 161 return MotionEvent::TOOL_TYPE_UNKNOWN; 162 } 163 164 int MotionEventAura::GetButtonState() const { 165 NOTIMPLEMENTED(); 166 return 0; 167 } 168 169 scoped_ptr<MotionEvent> MotionEventAura::Clone() const { 170 return scoped_ptr<MotionEvent>(new MotionEventAura(pointer_count_, 171 last_touch_time_, 172 cached_action_, 173 cached_action_index_, 174 active_touches_)); 175 } 176 scoped_ptr<MotionEvent> MotionEventAura::Cancel() const { 177 return scoped_ptr<MotionEvent>(new MotionEventAura( 178 pointer_count_, last_touch_time_, ACTION_CANCEL, -1, active_touches_)); 179 } 180 181 void MotionEventAura::CleanupRemovedTouchPoints(const TouchEvent& event) { 182 if (event.type() != ET_TOUCH_RELEASED && 183 event.type() != ET_TOUCH_CANCELLED) { 184 return; 185 } 186 187 int index_to_delete = static_cast<int>(GetIndexFromId(event.touch_id())); 188 pointer_count_--; 189 active_touches_[index_to_delete] = active_touches_[pointer_count_]; 190 } 191 192 MotionEventAura::PointData::PointData() 193 : x(0), 194 y(0), 195 raw_x(0), 196 raw_y(0), 197 touch_id(0), 198 pressure(0), 199 source_device_id(0), 200 major_radius(0) { 201 } 202 203 int MotionEventAura::GetSourceDeviceId(size_t pointer_index) const { 204 DCHECK_LE(pointer_index, pointer_count_); 205 return active_touches_[pointer_index].source_device_id; 206 } 207 208 void MotionEventAura::AddTouch(const TouchEvent& touch) { 209 if (pointer_count_ == static_cast<size_t>(GestureSequence::kMaxGesturePoints)) 210 return; 211 212 active_touches_[pointer_count_] = GetPointDataFromTouchEvent(touch); 213 pointer_count_++; 214 } 215 216 217 void MotionEventAura::UpdateTouch(const TouchEvent& touch) { 218 active_touches_[GetIndexFromId(touch.touch_id())] = 219 GetPointDataFromTouchEvent(touch); 220 } 221 222 void MotionEventAura::UpdateCachedAction(const TouchEvent& touch) { 223 DCHECK(pointer_count_); 224 switch (touch.type()) { 225 case ET_TOUCH_PRESSED: 226 if (pointer_count_ == 1) { 227 cached_action_ = ACTION_DOWN; 228 } else { 229 cached_action_ = ACTION_POINTER_DOWN; 230 cached_action_index_ = 231 static_cast<int>(GetIndexFromId(touch.touch_id())); 232 } 233 break; 234 case ET_TOUCH_RELEASED: 235 if (pointer_count_ == 1) { 236 cached_action_ = ACTION_UP; 237 } else { 238 cached_action_ = ACTION_POINTER_UP; 239 cached_action_index_ = 240 static_cast<int>(GetIndexFromId(touch.touch_id())); 241 DCHECK_LE(cached_action_index_, static_cast<int>(pointer_count_)); 242 } 243 break; 244 case ET_TOUCH_CANCELLED: 245 cached_action_ = ACTION_CANCEL; 246 break; 247 case ET_TOUCH_MOVED: 248 cached_action_ = ACTION_MOVE; 249 break; 250 default: 251 NOTREACHED(); 252 break; 253 } 254 } 255 256 size_t MotionEventAura::GetIndexFromId(int id) const { 257 for (size_t i = 0; i < pointer_count_; ++i) { 258 if (active_touches_[i].touch_id == id) 259 return i; 260 } 261 NOTREACHED(); 262 return 0; 263 } 264 265 } // namespace ui 266