Index: ui/events/gestures/motion_event_impl.cc |
diff --git a/ui/events/gestures/motion_event_impl.cc b/ui/events/gestures/motion_event_impl.cc |
index fd6fa6a2b758f8dc45ab6001ac9023bb3e62b1e5..505ac6cfc472f2a70669f543600937e4645a2282 100644 |
--- a/ui/events/gestures/motion_event_impl.cc |
+++ b/ui/events/gestures/motion_event_impl.cc |
@@ -2,83 +2,77 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-// MSVC++ requires this to be set before any other includes to get M_PI. |
-#define _USE_MATH_DEFINES |
- |
#include "ui/events/gestures/motion_event_impl.h" |
-#include <cmath> |
- |
#include "base/logging.h" |
-#include "ui/events/gestures/gesture_configuration.h" |
+#include "ui/events/gesture_detection/gesture_configuration.h" |
namespace ui { |
+namespace { |
+ |
+PointerProperties GetPointerPropertiesFromTouchEvent(const TouchEvent& touch) { |
+ PointerProperties pointer_properties; |
+ pointer_properties.x = touch.x(); |
+ pointer_properties.y = touch.y(); |
+ pointer_properties.raw_x = touch.root_location_f().x(); |
+ pointer_properties.raw_y = touch.root_location_f().y(); |
+ pointer_properties.id = touch.touch_id(); |
+ pointer_properties.pressure = touch.force(); |
+ pointer_properties.source_device_id = touch.source_device_id(); |
+ |
+ pointer_properties.SetAxesAndOrientation(touch.radius_x(), touch.radius_y(), |
+ touch.rotation_angle()); |
+ if (!pointer_properties.touch_major) { |
+ pointer_properties.touch_major = |
+ 2.f * GestureConfiguration::GetInstance()->default_radius(); |
+ pointer_properties.touch_minor = |
+ 2.f * GestureConfiguration::GetInstance()->default_radius(); |
+ pointer_properties.orientation = 0; |
+ } |
-MotionEventImpl::MotionEventImpl() |
- : pointer_count_(0), cached_action_index_(-1) { |
+ // TODO(jdduke): Plumb tool type from the platform, crbug.com/404128. |
+ pointer_properties.tool_type = MotionEvent::TOOL_TYPE_UNKNOWN; |
+ |
+ return pointer_properties; |
} |
-MotionEventImpl::MotionEventImpl( |
- 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]) |
- : pointer_count_(pointer_count), |
- last_touch_time_(last_touch_time), |
- cached_action_(cached_action), |
- cached_action_index_(cached_action_index), |
- flags_(flags) { |
- DCHECK(pointer_count_); |
- for (size_t i = 0; i < pointer_count; ++i) |
- active_touches_[i] = active_touches[i]; |
+} // namespace |
+ |
+MotionEventImpl::MotionEventImpl() { |
+ set_action_index(-1); |
} |
-MotionEventImpl::~MotionEventImpl() {} |
+MotionEventImpl::~MotionEventImpl() { |
+} |
-MotionEventImpl::PointData MotionEventImpl::GetPointDataFromTouchEvent( |
- const TouchEvent& touch) { |
- PointData point_data; |
- point_data.x = touch.x(); |
- point_data.y = touch.y(); |
- point_data.raw_x = touch.root_location_f().x(); |
- point_data.raw_y = touch.root_location_f().y(); |
- point_data.touch_id = touch.touch_id(); |
- point_data.pressure = touch.force(); |
- point_data.source_device_id = touch.source_device_id(); |
+bool MotionEventImpl::OnTouch(const TouchEvent& touch) { |
+ int index = FindPointerIndexOfId(touch.touch_id()); |
+ bool pointer_id_is_active = index != -1; |
- float radius_x = touch.radius_x(); |
- float radius_y = touch.radius_y(); |
- float rotation_angle_rad = touch.rotation_angle() * M_PI / 180.f; |
- DCHECK_GE(radius_x, 0) << "Unexpected x-radius < 0"; |
- DCHECK_GE(radius_y, 0) << "Unexpected y-radius < 0"; |
- DCHECK(0 <= rotation_angle_rad && rotation_angle_rad <= M_PI_2) |
- << "Unexpected touch rotation angle"; |
+ if (touch.type() == ET_TOUCH_PRESSED && pointer_id_is_active) { |
+ // TODO(tdresser): This should return false (or NOTREACHED()), and |
+ // ignore the touch; however, there is at least one case where we |
+ // need to allow a touch press from a currently used touch id. See |
+ // crbug.com/446852 for details. |
- if (radius_x > radius_y) { |
- // The case radius_x == radius_y is omitted from here on purpose: for |
- // circles, we want to pass the angle (which could be any value in such |
- // cases but always seem to be set to zero) unchanged. |
- point_data.touch_major = 2.f * radius_x; |
- point_data.touch_minor = 2.f * radius_y; |
- point_data.orientation = rotation_angle_rad - M_PI_2; |
- } else { |
- point_data.touch_major = 2.f * radius_y; |
- point_data.touch_minor = 2.f * radius_x; |
- point_data.orientation = rotation_angle_rad; |
+ // Cancel the existing touch, before handling the touch press. |
+ TouchEvent cancel(ET_TOUCH_CANCELLED, touch.location(), touch.touch_id(), |
+ touch.time_stamp()); |
+ OnTouch(cancel); |
+ CleanupRemovedTouchPoints(cancel); |
+ DCHECK_EQ(-1, FindPointerIndexOfId(touch.touch_id())); |
+ } else if (touch.type() != ET_TOUCH_PRESSED && !pointer_id_is_active) { |
+ // We could have an active touch stream transfered to us, resulting in touch |
+ // move or touch up events without associated touch down events. Ignore |
+ // them. |
+ return false; |
} |
- if (!point_data.touch_major) { |
- point_data.touch_major = 2.f * GestureConfiguration::default_radius(); |
- point_data.touch_minor = 2.f * GestureConfiguration::default_radius(); |
- point_data.orientation = 0; |
+ if (touch.type() == ET_TOUCH_MOVED && touch.x() == GetX(index) && |
+ touch.y() == GetY(index)) { |
+ return false; |
} |
- return point_data; |
-} |
- |
-void MotionEventImpl::OnTouch(const TouchEvent& touch) { |
switch (touch.type()) { |
case ET_TOUCH_PRESSED: |
AddTouch(touch); |
@@ -95,107 +89,14 @@ void MotionEventImpl::OnTouch(const TouchEvent& touch) { |
break; |
default: |
NOTREACHED(); |
- break; |
+ return false; |
} |
UpdateCachedAction(touch); |
- flags_ = touch.flags(); |
- last_touch_time_ = touch.time_stamp() + base::TimeTicks(); |
-} |
- |
-int MotionEventImpl::GetId() const { |
- return GetPointerId(0); |
-} |
- |
-MotionEvent::Action MotionEventImpl::GetAction() const { |
- return cached_action_; |
-} |
- |
-int MotionEventImpl::GetActionIndex() const { |
- DCHECK(cached_action_ == ACTION_POINTER_DOWN || |
- cached_action_ == ACTION_POINTER_UP); |
- DCHECK_GE(cached_action_index_, 0); |
- DCHECK_LT(cached_action_index_, static_cast<int>(pointer_count_)); |
- return cached_action_index_; |
-} |
- |
-size_t MotionEventImpl::GetPointerCount() const { return pointer_count_; } |
- |
-int MotionEventImpl::GetPointerId(size_t pointer_index) const { |
- DCHECK_LT(pointer_index, pointer_count_); |
- return active_touches_[pointer_index].touch_id; |
-} |
- |
-float MotionEventImpl::GetX(size_t pointer_index) const { |
- DCHECK_LT(pointer_index, pointer_count_); |
- return active_touches_[pointer_index].x; |
-} |
- |
-float MotionEventImpl::GetY(size_t pointer_index) const { |
- DCHECK_LT(pointer_index, pointer_count_); |
- return active_touches_[pointer_index].y; |
-} |
- |
-float MotionEventImpl::GetRawX(size_t pointer_index) const { |
- DCHECK_LT(pointer_index, pointer_count_); |
- return active_touches_[pointer_index].raw_x; |
-} |
- |
-float MotionEventImpl::GetRawY(size_t pointer_index) const { |
- DCHECK_LT(pointer_index, pointer_count_); |
- return active_touches_[pointer_index].raw_y; |
-} |
- |
-float MotionEventImpl::GetTouchMajor(size_t pointer_index) const { |
- DCHECK_LT(pointer_index, pointer_count_); |
- return active_touches_[pointer_index].touch_major; |
-} |
- |
-float MotionEventImpl::GetTouchMinor(size_t pointer_index) const { |
- DCHECK_LE(pointer_index, pointer_count_); |
- return active_touches_[pointer_index].touch_minor; |
-} |
- |
-float MotionEventImpl::GetOrientation(size_t pointer_index) const { |
- DCHECK_LE(pointer_index, pointer_count_); |
- return active_touches_[pointer_index].orientation; |
-} |
- |
-float MotionEventImpl::GetPressure(size_t pointer_index) const { |
- DCHECK_LT(pointer_index, pointer_count_); |
- return active_touches_[pointer_index].pressure; |
-} |
- |
-MotionEvent::ToolType MotionEventImpl::GetToolType(size_t pointer_index) const { |
- // TODO(jdduke): Plumb tool type from the platform, crbug.com/404128. |
- DCHECK_LT(pointer_index, pointer_count_); |
- return MotionEvent::TOOL_TYPE_UNKNOWN; |
-} |
- |
-int MotionEventImpl::GetButtonState() const { |
- NOTIMPLEMENTED(); |
- return 0; |
-} |
- |
-int MotionEventImpl::GetFlags() const { |
- return flags_; |
-} |
- |
-base::TimeTicks MotionEventImpl::GetEventTime() const { |
- return last_touch_time_; |
-} |
- |
-scoped_ptr<MotionEvent> MotionEventImpl::Clone() const { |
- return scoped_ptr<MotionEvent>(new MotionEventImpl(pointer_count_, |
- last_touch_time_, |
- cached_action_, |
- cached_action_index_, |
- flags_, |
- active_touches_)); |
-} |
-scoped_ptr<MotionEvent> MotionEventImpl::Cancel() const { |
- return scoped_ptr<MotionEvent>(new MotionEventImpl( |
- pointer_count_, last_touch_time_, ACTION_CANCEL, -1, 0, active_touches_)); |
+ set_unique_event_id(touch.unique_event_id()); |
+ set_flags(touch.flags()); |
+ set_event_time(touch.time_stamp() + base::TimeTicks()); |
+ return true; |
} |
void MotionEventImpl::CleanupRemovedTouchPoints(const TouchEvent& event) { |
@@ -204,70 +105,54 @@ void MotionEventImpl::CleanupRemovedTouchPoints(const TouchEvent& event) { |
return; |
} |
- int index_to_delete = static_cast<int>(GetIndexFromId(event.touch_id())); |
- pointer_count_--; |
- active_touches_[index_to_delete] = active_touches_[pointer_count_]; |
-} |
- |
-MotionEventImpl::PointData::PointData() |
- : x(0), |
- y(0), |
- raw_x(0), |
- raw_y(0), |
- touch_id(0), |
- pressure(0), |
- source_device_id(0), |
- touch_major(0), |
- touch_minor(0), |
- orientation(0) { |
+ DCHECK(GetPointerCount()); |
+ int index_to_delete = GetIndexFromId(event.touch_id()); |
+ set_action_index(0); |
+ pointer(index_to_delete) = pointer(GetPointerCount() - 1); |
+ PopPointer(); |
} |
int MotionEventImpl::GetSourceDeviceId(size_t pointer_index) const { |
- DCHECK_LT(pointer_index, pointer_count_); |
- return active_touches_[pointer_index].source_device_id; |
+ DCHECK_LT(pointer_index, GetPointerCount()); |
+ return pointer(pointer_index).source_device_id; |
} |
void MotionEventImpl::AddTouch(const TouchEvent& touch) { |
- if (pointer_count_ == MotionEvent::MAX_TOUCH_POINT_COUNT) |
+ if (GetPointerCount() == MotionEvent::MAX_TOUCH_POINT_COUNT) |
return; |
- active_touches_[pointer_count_] = GetPointDataFromTouchEvent(touch); |
- pointer_count_++; |
+ PushPointer(GetPointerPropertiesFromTouchEvent(touch)); |
} |
- |
void MotionEventImpl::UpdateTouch(const TouchEvent& touch) { |
- active_touches_[GetIndexFromId(touch.touch_id())] = |
- GetPointDataFromTouchEvent(touch); |
+ pointer(GetIndexFromId(touch.touch_id())) = |
+ GetPointerPropertiesFromTouchEvent(touch); |
} |
void MotionEventImpl::UpdateCachedAction(const TouchEvent& touch) { |
- DCHECK(pointer_count_); |
+ DCHECK(GetPointerCount()); |
switch (touch.type()) { |
case ET_TOUCH_PRESSED: |
- if (pointer_count_ == 1) { |
- cached_action_ = ACTION_DOWN; |
+ if (GetPointerCount() == 1) { |
+ set_action(ACTION_DOWN); |
} else { |
- cached_action_ = ACTION_POINTER_DOWN; |
- cached_action_index_ = |
- static_cast<int>(GetIndexFromId(touch.touch_id())); |
+ set_action(ACTION_POINTER_DOWN); |
+ set_action_index(GetIndexFromId(touch.touch_id())); |
} |
break; |
case ET_TOUCH_RELEASED: |
- if (pointer_count_ == 1) { |
- cached_action_ = ACTION_UP; |
+ if (GetPointerCount() == 1) { |
+ set_action(ACTION_UP); |
} else { |
- cached_action_ = ACTION_POINTER_UP; |
- cached_action_index_ = |
- static_cast<int>(GetIndexFromId(touch.touch_id())); |
- DCHECK_LT(cached_action_index_, static_cast<int>(pointer_count_)); |
+ set_action(ACTION_POINTER_UP); |
+ set_action_index(GetIndexFromId(touch.touch_id())); |
} |
break; |
case ET_TOUCH_CANCELLED: |
- cached_action_ = ACTION_CANCEL; |
+ set_action(ACTION_CANCEL); |
break; |
case ET_TOUCH_MOVED: |
- cached_action_ = ACTION_MOVE; |
+ set_action(ACTION_MOVE); |
break; |
default: |
NOTREACHED(); |
@@ -275,13 +160,11 @@ void MotionEventImpl::UpdateCachedAction(const TouchEvent& touch) { |
} |
} |
-size_t MotionEventImpl::GetIndexFromId(int id) const { |
- for (size_t i = 0; i < pointer_count_; ++i) { |
- if (active_touches_[i].touch_id == id) |
- return i; |
- } |
- NOTREACHED(); |
- return 0; |
+int MotionEventImpl::GetIndexFromId(int id) const { |
+ int index = FindPointerIndexOfId(id); |
+ DCHECK_GE(index, 0); |
+ DCHECK_LT(index, static_cast<int>(GetPointerCount())); |
+ return index; |
} |
} // namespace ui |