base: Change DCHECK_IS_ON to a macro DCHECK_IS_ON().
[chromium-blink-merge.git] / ui / events / gestures / motion_event_aura.cc
blob1f4d2855b2fc0cfc5d3cd32495f5586d6f6cea13
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/gestures/motion_event_aura.h"
10 #include <cmath>
12 #include "base/logging.h"
13 #include "ui/events/gesture_detection/gesture_configuration.h"
15 namespace ui {
16 namespace {
18 PointerProperties GetPointerPropertiesFromTouchEvent(const TouchEvent& touch) {
19 PointerProperties pointer_properties;
20 pointer_properties.x = touch.x();
21 pointer_properties.y = touch.y();
22 pointer_properties.raw_x = touch.root_location_f().x();
23 pointer_properties.raw_y = touch.root_location_f().y();
24 pointer_properties.id = touch.touch_id();
25 pointer_properties.pressure = touch.force();
26 pointer_properties.source_device_id = touch.source_device_id();
28 float radius_x = touch.radius_x();
29 float radius_y = touch.radius_y();
30 float rotation_angle_rad = touch.rotation_angle() * M_PI / 180.f;
31 DCHECK_GE(radius_x, 0) << "Unexpected x-radius < 0";
32 DCHECK_GE(radius_y, 0) << "Unexpected y-radius < 0";
33 DCHECK(0 <= rotation_angle_rad && rotation_angle_rad <= M_PI_2)
34 << "Unexpected touch rotation angle";
36 if (radius_x > radius_y) {
37 // The case radius_x == radius_y is omitted from here on purpose: for
38 // circles, we want to pass the angle (which could be any value in such
39 // cases but always seem to be set to zero) unchanged.
40 pointer_properties.touch_major = 2.f * radius_x;
41 pointer_properties.touch_minor = 2.f * radius_y;
42 pointer_properties.orientation = rotation_angle_rad - M_PI_2;
43 } else {
44 pointer_properties.touch_major = 2.f * radius_y;
45 pointer_properties.touch_minor = 2.f * radius_x;
46 pointer_properties.orientation = rotation_angle_rad;
49 if (!pointer_properties.touch_major) {
50 pointer_properties.touch_major =
51 2.f * GestureConfiguration::GetInstance()->default_radius();
52 pointer_properties.touch_minor =
53 2.f * GestureConfiguration::GetInstance()->default_radius();
54 pointer_properties.orientation = 0;
57 // TODO(jdduke): Plumb tool type from the platform, crbug.com/404128.
58 pointer_properties.tool_type = MotionEvent::TOOL_TYPE_UNKNOWN;
60 return pointer_properties;
63 } // namespace
65 MotionEventAura::MotionEventAura() {
66 set_action_index(-1);
69 MotionEventAura::~MotionEventAura() {
72 bool MotionEventAura::OnTouch(const TouchEvent& touch) {
73 int index = FindPointerIndexOfId(touch.touch_id());
74 bool pointer_id_is_active = index != -1;
76 if (touch.type() == ET_TOUCH_PRESSED && pointer_id_is_active) {
77 // Ignore touch press events if we already believe the pointer is down.
79 // TODO(tdresser): this should return false (or NOTREACHED());
80 // however, there is at least one case where we need to allow a
81 // touch press from a currently used touch id. See
82 // crbug.com/446852 for details.
83 } else if (touch.type() != ET_TOUCH_PRESSED && !pointer_id_is_active) {
84 // We could have an active touch stream transfered to us, resulting in touch
85 // move or touch up events without associated touch down events. Ignore
86 // them.
87 return false;
90 if (touch.type() == ET_TOUCH_MOVED && touch.x() == GetX(index) &&
91 touch.y() == GetY(index)) {
92 return false;
95 switch (touch.type()) {
96 case ET_TOUCH_PRESSED:
97 AddTouch(touch);
98 break;
99 case ET_TOUCH_RELEASED:
100 case ET_TOUCH_CANCELLED:
101 // Removing these touch points needs to be postponed until after the
102 // MotionEvent has been dispatched. This cleanup occurs in
103 // CleanupRemovedTouchPoints.
104 UpdateTouch(touch);
105 break;
106 case ET_TOUCH_MOVED:
107 UpdateTouch(touch);
108 break;
109 default:
110 NOTREACHED();
111 return false;
114 UpdateCachedAction(touch);
115 set_flags(touch.flags());
116 set_event_time(touch.time_stamp() + base::TimeTicks());
117 return true;
120 int MotionEventAura::GetId() const {
121 return GetPointerId(0);
124 void MotionEventAura::CleanupRemovedTouchPoints(const TouchEvent& event) {
125 if (event.type() != ET_TOUCH_RELEASED &&
126 event.type() != ET_TOUCH_CANCELLED) {
127 return;
130 DCHECK(GetPointerCount());
131 int index_to_delete = GetIndexFromId(event.touch_id());
132 set_action_index(0);
133 pointer(index_to_delete) = pointer(GetPointerCount() - 1);
134 PopPointer();
137 int MotionEventAura::GetSourceDeviceId(size_t pointer_index) const {
138 DCHECK_LT(pointer_index, GetPointerCount());
139 return pointer(pointer_index).source_device_id;
142 void MotionEventAura::AddTouch(const TouchEvent& touch) {
143 if (GetPointerCount() == MotionEvent::MAX_TOUCH_POINT_COUNT)
144 return;
146 PushPointer(GetPointerPropertiesFromTouchEvent(touch));
149 void MotionEventAura::UpdateTouch(const TouchEvent& touch) {
150 pointer(GetIndexFromId(touch.touch_id())) =
151 GetPointerPropertiesFromTouchEvent(touch);
154 void MotionEventAura::UpdateCachedAction(const TouchEvent& touch) {
155 DCHECK(GetPointerCount());
156 switch (touch.type()) {
157 case ET_TOUCH_PRESSED:
158 if (GetPointerCount() == 1) {
159 set_action(ACTION_DOWN);
160 } else {
161 set_action(ACTION_POINTER_DOWN);
162 set_action_index(GetIndexFromId(touch.touch_id()));
164 break;
165 case ET_TOUCH_RELEASED:
166 if (GetPointerCount() == 1) {
167 set_action(ACTION_UP);
168 } else {
169 set_action(ACTION_POINTER_UP);
170 set_action_index(GetIndexFromId(touch.touch_id()));
172 break;
173 case ET_TOUCH_CANCELLED:
174 set_action(ACTION_CANCEL);
175 break;
176 case ET_TOUCH_MOVED:
177 set_action(ACTION_MOVE);
178 break;
179 default:
180 NOTREACHED();
181 break;
185 int MotionEventAura::GetIndexFromId(int id) const {
186 int index = FindPointerIndexOfId(id);
187 DCHECK_GE(index, 0);
188 DCHECK_LT(index, static_cast<int>(GetPointerCount()));
189 return index;
192 } // namespace ui