motion_event_generic.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  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. #include "ui/events/gesture_detection/motion_event_generic.h"
  5. #include <ostream>
  6. #include <utility>
  7. #include "base/check_op.h"
  8. #include "base/memory/ptr_util.h"
  9. #include "base/numerics/math_constants.h"
  10. #include "ui/events/base_event_utils.h"
  11. #include "ui/gfx/geometry/angle_conversions.h"
  12. namespace ui {
  13. PointerProperties::PointerProperties()
  14. : PointerProperties(0, 0, 0) {
  15. }
  16. PointerProperties::PointerProperties(float x, float y, float touch_major)
  17. : id(0),
  18. tool_type(MotionEvent::ToolType::UNKNOWN),
  19. x(x),
  20. y(y),
  21. raw_x(x),
  22. raw_y(y),
  23. pressure(0),
  24. touch_major(touch_major),
  25. touch_minor(0),
  26. orientation(0),
  27. tilt_x(0),
  28. tilt_y(0),
  29. twist(0),
  30. tangential_pressure(0),
  31. source_device_id(0) {}
  32. PointerProperties::PointerProperties(const MotionEvent& event,
  33. size_t pointer_index)
  34. : id(event.GetPointerId(pointer_index)),
  35. tool_type(event.GetToolType(pointer_index)),
  36. x(event.GetX(pointer_index)),
  37. y(event.GetY(pointer_index)),
  38. raw_x(event.GetRawX(pointer_index)),
  39. raw_y(event.GetRawY(pointer_index)),
  40. pressure(event.GetPressure(pointer_index)),
  41. touch_major(event.GetTouchMajor(pointer_index)),
  42. touch_minor(event.GetTouchMinor(pointer_index)),
  43. orientation(event.GetOrientation(pointer_index)),
  44. tilt_x(event.GetTiltX(pointer_index)),
  45. tilt_y(event.GetTiltY(pointer_index)),
  46. twist(event.GetTwist(pointer_index)),
  47. tangential_pressure(event.GetTangentialPressure(pointer_index)),
  48. source_device_id(0) {}
  49. PointerProperties::PointerProperties(const PointerProperties& other) = default;
  50. PointerProperties& PointerProperties::operator=(
  51. const PointerProperties& other) = default;
  52. void PointerProperties::SetAxesAndOrientation(float radius_x,
  53. float radius_y,
  54. float rotation_angle_degree) {
  55. DCHECK(!touch_major && !touch_minor && !orientation);
  56. float rotation_angle_rad = gfx::DegToRad(rotation_angle_degree);
  57. DCHECK_GE(radius_x, 0) << "Unexpected x-radius < 0 (" << radius_x << ")";
  58. DCHECK_GE(radius_y, 0) << "Unexpected y-radius < 0 (" << radius_y << ")";
  59. DCHECK(0 <= rotation_angle_rad && rotation_angle_rad < base::kPiFloat)
  60. << "Unexpected touch rotation angle " << rotation_angle_rad << " rad";
  61. // Make the angle acute to ease subsequent logic. The angle range effectively
  62. // changes from [0, pi) to [0, pi/2).
  63. if (rotation_angle_rad >= base::kPiFloat / 2) {
  64. rotation_angle_rad -= base::kPiFloat / 2;
  65. std::swap(radius_x, radius_y);
  66. }
  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 - base::kPiFloat / 2;
  74. } else {
  75. touch_major = 2.f * radius_y;
  76. touch_minor = 2.f * radius_x;
  77. orientation = rotation_angle_rad;
  78. }
  79. }
  80. MotionEventGeneric::MotionEventGeneric(Action action,
  81. base::TimeTicks event_time,
  82. const PointerProperties& pointer)
  83. : action_(action),
  84. event_time_(event_time),
  85. unique_event_id_(ui::GetNextTouchEventId()),
  86. action_index_(0),
  87. button_state_(0),
  88. flags_(0) {
  89. PushPointer(pointer);
  90. }
  91. MotionEventGeneric::MotionEventGeneric(const MotionEventGeneric& other)
  92. : action_(other.action_),
  93. event_time_(other.event_time_),
  94. unique_event_id_(other.unique_event_id_),
  95. action_index_(other.action_index_),
  96. button_state_(other.button_state_),
  97. flags_(other.flags_),
  98. pointers_(other.pointers_) {
  99. const size_t history_size = other.GetHistorySize();
  100. for (size_t h = 0; h < history_size; ++h)
  101. PushHistoricalEvent(other.historical_events_[h]->Clone());
  102. }
  103. MotionEventGeneric::~MotionEventGeneric() {
  104. }
  105. uint32_t MotionEventGeneric::GetUniqueEventId() const {
  106. return unique_event_id_;
  107. }
  108. MotionEvent::Action MotionEventGeneric::GetAction() const {
  109. return action_;
  110. }
  111. int MotionEventGeneric::GetActionIndex() const {
  112. DCHECK(action_ == Action::POINTER_DOWN || action_ == Action::POINTER_UP);
  113. DCHECK_GE(action_index_, 0);
  114. DCHECK_LT(action_index_, static_cast<int>(pointers_->size()));
  115. return action_index_;
  116. }
  117. size_t MotionEventGeneric::GetPointerCount() const {
  118. return pointers_->size();
  119. }
  120. int MotionEventGeneric::GetPointerId(size_t pointer_index) const {
  121. DCHECK_LT(pointer_index, pointers_->size());
  122. return pointers_[pointer_index].id;
  123. }
  124. float MotionEventGeneric::GetX(size_t pointer_index) const {
  125. DCHECK_LT(pointer_index, pointers_->size());
  126. return pointers_[pointer_index].x;
  127. }
  128. float MotionEventGeneric::GetY(size_t pointer_index) const {
  129. DCHECK_LT(pointer_index, pointers_->size());
  130. return pointers_[pointer_index].y;
  131. }
  132. float MotionEventGeneric::GetRawX(size_t pointer_index) const {
  133. DCHECK_LT(pointer_index, pointers_->size());
  134. return pointers_[pointer_index].raw_x;
  135. }
  136. float MotionEventGeneric::GetRawY(size_t pointer_index) const {
  137. DCHECK_LT(pointer_index, pointers_->size());
  138. return pointers_[pointer_index].raw_y;
  139. }
  140. float MotionEventGeneric::GetTouchMajor(size_t pointer_index) const {
  141. DCHECK_LT(pointer_index, pointers_->size());
  142. return pointers_[pointer_index].touch_major;
  143. }
  144. float MotionEventGeneric::GetTouchMinor(size_t pointer_index) const {
  145. DCHECK_LT(pointer_index, pointers_->size());
  146. return pointers_[pointer_index].touch_minor;
  147. }
  148. float MotionEventGeneric::GetOrientation(size_t pointer_index) const {
  149. DCHECK_LT(pointer_index, pointers_->size());
  150. return pointers_[pointer_index].orientation;
  151. }
  152. float MotionEventGeneric::GetPressure(size_t pointer_index) const {
  153. DCHECK_LT(pointer_index, pointers_->size());
  154. return pointers_[pointer_index].pressure;
  155. }
  156. float MotionEventGeneric::GetTiltX(size_t pointer_index) const {
  157. DCHECK_LT(pointer_index, pointers_->size());
  158. return pointers_[pointer_index].tilt_x;
  159. }
  160. float MotionEventGeneric::GetTiltY(size_t pointer_index) const {
  161. DCHECK_LT(pointer_index, pointers_->size());
  162. return pointers_[pointer_index].tilt_y;
  163. }
  164. float MotionEventGeneric::GetTwist(size_t pointer_index) const {
  165. DCHECK_LT(pointer_index, pointers_->size());
  166. return pointers_[pointer_index].twist;
  167. }
  168. float MotionEventGeneric::GetTangentialPressure(size_t pointer_index) const {
  169. DCHECK_LT(pointer_index, pointers_->size());
  170. return pointers_[pointer_index].tangential_pressure;
  171. }
  172. MotionEvent::ToolType MotionEventGeneric::GetToolType(
  173. size_t pointer_index) const {
  174. DCHECK_LT(pointer_index, pointers_->size());
  175. return pointers_[pointer_index].tool_type;
  176. }
  177. int MotionEventGeneric::GetButtonState() const {
  178. return button_state_;
  179. }
  180. int MotionEventGeneric::GetFlags() const {
  181. return flags_;
  182. }
  183. base::TimeTicks MotionEventGeneric::GetEventTime() const {
  184. return event_time_;
  185. }
  186. size_t MotionEventGeneric::GetHistorySize() const {
  187. return historical_events_.size();
  188. }
  189. base::TimeTicks MotionEventGeneric::GetHistoricalEventTime(
  190. size_t historical_index) const {
  191. DCHECK_LT(historical_index, historical_events_.size());
  192. return historical_events_[historical_index]->GetEventTime();
  193. }
  194. float MotionEventGeneric::GetHistoricalTouchMajor(
  195. size_t pointer_index,
  196. size_t historical_index) const {
  197. DCHECK_LT(historical_index, historical_events_.size());
  198. return historical_events_[historical_index]->GetTouchMajor(pointer_index);
  199. }
  200. float MotionEventGeneric::GetHistoricalX(size_t pointer_index,
  201. size_t historical_index) const {
  202. DCHECK_LT(historical_index, historical_events_.size());
  203. return historical_events_[historical_index]->GetX(pointer_index);
  204. }
  205. float MotionEventGeneric::GetHistoricalY(size_t pointer_index,
  206. size_t historical_index) const {
  207. DCHECK_LT(historical_index, historical_events_.size());
  208. return historical_events_[historical_index]->GetY(pointer_index);
  209. }
  210. // static
  211. std::unique_ptr<MotionEventGeneric> MotionEventGeneric::CloneEvent(
  212. const MotionEvent& event) {
  213. bool with_history = true;
  214. return base::WrapUnique(new MotionEventGeneric(event, with_history));
  215. }
  216. // static
  217. std::unique_ptr<MotionEventGeneric> MotionEventGeneric::CancelEvent(
  218. const MotionEvent& event) {
  219. bool with_history = false;
  220. std::unique_ptr<MotionEventGeneric> cancel_event(
  221. new MotionEventGeneric(event, with_history));
  222. cancel_event->set_action(Action::CANCEL);
  223. cancel_event->set_unique_event_id(ui::GetNextTouchEventId());
  224. return cancel_event;
  225. }
  226. size_t MotionEventGeneric::PushPointer(const PointerProperties& pointer) {
  227. DCHECK_EQ(0U, GetHistorySize());
  228. pointers_->push_back(pointer);
  229. return pointers_->size() - 1;
  230. }
  231. void MotionEventGeneric::RemovePointerAt(size_t index) {
  232. DCHECK_LT(index, pointers_->size());
  233. pointers_->erase(pointers_->begin() + index);
  234. }
  235. void MotionEventGeneric::PushHistoricalEvent(
  236. std::unique_ptr<MotionEvent> event) {
  237. DCHECK(event);
  238. DCHECK_EQ(event->GetAction(), Action::MOVE);
  239. DCHECK_EQ(event->GetPointerCount(), GetPointerCount());
  240. DCHECK_EQ(event->GetAction(), GetAction());
  241. DCHECK_LE(event->GetEventTime(), GetEventTime());
  242. historical_events_.push_back(std::move(event));
  243. }
  244. MotionEventGeneric::MotionEventGeneric()
  245. : action_(Action::NONE),
  246. unique_event_id_(ui::GetNextTouchEventId()),
  247. action_index_(-1),
  248. button_state_(0) {}
  249. MotionEventGeneric::MotionEventGeneric(const MotionEvent& event,
  250. bool with_history)
  251. : action_(event.GetAction()),
  252. event_time_(event.GetEventTime()),
  253. unique_event_id_(event.GetUniqueEventId()),
  254. action_index_(
  255. (action_ == Action::POINTER_UP || action_ == Action::POINTER_DOWN)
  256. ? event.GetActionIndex()
  257. : 0),
  258. button_state_(event.GetButtonState()),
  259. flags_(event.GetFlags()) {
  260. const size_t pointer_count = event.GetPointerCount();
  261. for (size_t i = 0; i < pointer_count; ++i)
  262. PushPointer(PointerProperties(event, i));
  263. if (!with_history)
  264. return;
  265. const size_t history_size = event.GetHistorySize();
  266. for (size_t h = 0; h < history_size; ++h) {
  267. std::unique_ptr<MotionEventGeneric> historical_event(
  268. new MotionEventGeneric());
  269. historical_event->set_action(Action::MOVE);
  270. historical_event->set_event_time(event.GetHistoricalEventTime(h));
  271. for (size_t i = 0; i < pointer_count; ++i) {
  272. historical_event->PushPointer(
  273. PointerProperties(event.GetHistoricalX(i, h),
  274. event.GetHistoricalY(i, h),
  275. event.GetHistoricalTouchMajor(i, h)));
  276. }
  277. PushHistoricalEvent(std::move(historical_event));
  278. }
  279. }
  280. MotionEventGeneric& MotionEventGeneric::operator=(
  281. const MotionEventGeneric& other) {
  282. action_ = other.action_;
  283. event_time_ = other.event_time_;
  284. unique_event_id_ = other.unique_event_id_;
  285. action_index_ = other.action_index_;
  286. button_state_ = other.button_state_;
  287. flags_ = other.flags_;
  288. pointers_ = other.pointers_;
  289. const size_t history_size = other.GetHistorySize();
  290. for (size_t h = 0; h < history_size; ++h)
  291. PushHistoricalEvent(other.historical_events_[h]->Clone());
  292. return *this;
  293. }
  294. void MotionEventGeneric::PopPointer() {
  295. DCHECK_GT(pointers_->size(), 0U);
  296. pointers_->pop_back();
  297. }
  298. } // namespace ui