Index: ui/events/gesture_detection/motion_event_ui.cc |
diff --git a/ui/events/gesture_detection/motion_event_ui.cc b/ui/events/gesture_detection/motion_event_ui.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..66aea68b91e5ec850b833955c55dda0eebb51ccf |
--- /dev/null |
+++ b/ui/events/gesture_detection/motion_event_ui.cc |
@@ -0,0 +1,223 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "ui/events/gesture_detection/motion_event_ui.h" |
+ |
+#include "base/logging.h" |
+#include "ui/events/gestures/gesture_configuration.h" |
+ |
+namespace ui { |
+ |
+MotionEventUI::MotionEventUI() : pointer_count_(0), cached_action_index_(-1) {} |
+ |
+MotionEventUI::MotionEventUI( |
+ size_t pointer_count, |
+ const base::TimeDelta& last_touch_time, |
+ Action cached_action, |
+ int cached_action_index, |
+ const PointData (&active_touches)[GestureSequence::kMaxGesturePoints], |
+ const std::map<int, int>& id_to_index) |
+ : pointer_count_(pointer_count), |
+ last_touch_time_(last_touch_time), |
+ cached_action_(cached_action), |
+ cached_action_index_(cached_action_index), |
+ id_to_index_(id_to_index) { |
+ DCHECK(pointer_count_); |
+ for (size_t i = 0; i < pointer_count; ++i) |
+ active_touches_[i] = active_touches[i]; |
+} |
+ |
+MotionEventUI::~MotionEventUI() {} |
+ |
+void MotionEventUI::OnTouch(const TouchEvent& touch) { |
+ switch (touch.type()) { |
+ case ET_TOUCH_PRESSED: |
+ AddTouch(touch); |
+ break; |
+ case ET_TOUCH_RELEASED: |
+ case ET_TOUCH_CANCELLED: |
+ UpdateTouch(touch); |
+ // Removing these touch points needs to be postponed until after the |
+ // MotionEvent has been dispatched. This cleanup occurs in |
+ // CleanupRemovedTouchPoints. |
+ break; |
+ case ET_TOUCH_MOVED: |
+ UpdateTouch(touch); |
+ break; |
+ default: |
+ NOTREACHED(); |
+ break; |
+ } |
+ |
+ SetCachedAction(touch); |
jdduke (slow)
2014/05/02 17:56:43
UpdateCachedAction?
tdresser
2014/05/05 15:42:35
Done.
|
+ last_touch_time_ = touch.time_stamp(); |
jdduke (slow)
2014/05/02 17:56:43
We should probably make this member a |TimeTicks|,
tdresser
2014/05/05 15:42:35
Done.
|
+} |
+ |
+int MotionEventUI::GetId() const { |
+ return GetPointerId(0); |
+} |
+ |
+MotionEvent::Action MotionEventUI::GetAction() const { return cached_action_; } |
+ |
+int MotionEventUI::GetActionIndex() const { |
+ DCHECK(cached_action_ == ACTION_POINTER_DOWN || |
jdduke (slow)
2014/05/02 17:56:43
Hmm, we should probably make a note in the MotionE
tdresser
2014/05/05 15:42:35
Done.
|
+ cached_action_ == ACTION_POINTER_UP); |
+ DCHECK(0 <= cached_action_index_ && |
jdduke (slow)
2014/05/02 17:56:43
DCHECK_GE + DCHECK_LT
tdresser
2014/05/05 15:42:35
Done.
|
+ cached_action_index_ < static_cast<int>(pointer_count_)); |
+ return cached_action_index_; |
+} |
+ |
+size_t MotionEventUI::GetPointerCount() const { return pointer_count_; } |
+ |
+int MotionEventUI::GetPointerId(size_t pointer_index) const { |
+ DCHECK(pointer_index < pointer_count_); |
jdduke (slow)
2014/05/02 17:56:43
DCHECK_LT for all |pointer_index| checks.
tdresser
2014/05/05 15:42:35
Done.
|
+ return active_touches_[pointer_index].touch_id; |
+} |
+ |
+float MotionEventUI::GetX(size_t pointer_index) const { |
+ DCHECK(pointer_index < pointer_count_); |
+ return active_touches_[pointer_index].x; |
+} |
+ |
+float MotionEventUI::GetY(size_t pointer_index) const { |
+ DCHECK(pointer_index < pointer_count_); |
+ return active_touches_[pointer_index].y; |
+} |
+ |
+float MotionEventUI::GetTouchMajor(size_t pointer_index) const { |
+ DCHECK(pointer_index < pointer_count_); |
+ return active_touches_[pointer_index].major_radius * 2; |
+} |
+ |
+float MotionEventUI::GetPressure(size_t pointer_index) const { |
+ DCHECK(pointer_index < pointer_count_); |
+ return active_touches_[pointer_index].pressure; |
+} |
+ |
+base::TimeTicks MotionEventUI::GetEventTime() const { |
+ return base::TimeTicks() + last_touch_time_; |
+} |
+ |
+size_t MotionEventUI::GetHistorySize() const { return 0; } |
+ |
+base::TimeTicks MotionEventUI::GetHistoricalEventTime( |
+ size_t historical_index) const { |
+ return base::TimeTicks(); |
+ NOTIMPLEMENTED(); |
jdduke (slow)
2014/05/02 17:56:43
Hmm, I think you want |NOTIMPLEMENTED()| before th
tdresser
2014/05/05 15:42:35
Pffft, done.
Thanks.
|
+} |
+ |
+float MotionEventUI::GetHistoricalTouchMajor(size_t pointer_index, |
+ size_t historical_index) const { |
+ return 0; |
+ NOTIMPLEMENTED(); |
+} |
+ |
+float MotionEventUI::GetHistoricalX(size_t pointer_index, |
+ size_t historical_index) const { |
+ return 0; |
+ NOTIMPLEMENTED(); |
+} |
+ |
+float MotionEventUI::GetHistoricalY(size_t pointer_index, |
+ size_t historical_index) const { |
+ return 0; |
+ NOTIMPLEMENTED(); |
+} |
+ |
+scoped_ptr<MotionEvent> MotionEventUI::Clone() const { |
+ MotionEventUI* event = new MotionEventUI(pointer_count_, |
+ last_touch_time_, |
jdduke (slow)
2014/05/02 17:56:43
Might as well return scoped_ptr<MotionEvent>(new .
tdresser
2014/05/05 15:42:35
Done.
|
+ cached_action_, |
+ cached_action_index_, |
+ active_touches_, |
+ id_to_index_); |
+ return scoped_ptr<MotionEvent>(event); |
+} |
+scoped_ptr<MotionEvent> MotionEventUI::Cancel() const { |
+ scoped_ptr<MotionEvent> clone = Clone(); |
+ static_cast<MotionEventUI*>(clone.get())->cached_action_ = ACTION_CANCEL; |
jdduke (slow)
2014/05/02 17:56:43
I'm not sure re-using clone buys us much here. Le
tdresser
2014/05/05 15:42:35
Done.
|
+ return clone.Pass(); |
+} |
+ |
+void MotionEventUI::CleanupRemovedTouchPoints(const TouchEvent& touch) { |
+ if (touch.type() != ET_TOUCH_RELEASED && touch.type() != ET_TOUCH_CANCELLED) |
+ return; |
+ |
+ DCHECK(id_to_index_.count(touch.touch_id())); |
+ int index_to_delete = id_to_index_[touch.touch_id()]; |
+ |
+ pointer_count_--; |
+ active_touches_[index_to_delete] = active_touches_[pointer_count_]; |
+ id_to_index_[active_touches_[pointer_count_].touch_id] = index_to_delete; |
+} |
+ |
+int MotionEventUI::GetSourceDeviceId(size_t pointer_index) const { |
+ DCHECK(pointer_index < pointer_count_); |
+ return active_touches_[pointer_index].source_device_id; |
+} |
+ |
+void MotionEventUI::UpdatePointData(const TouchEvent& touch, |
+ PointData* point_data) { |
+ point_data->x = touch.x(); |
+ point_data->y = touch.y(); |
+ point_data->touch_id = touch.touch_id(); |
+ point_data->pressure = touch.force(); |
+ point_data->source_device_id = touch.source_device_id(); |
+ |
+ // TODO(tdresser): at some point we should start using both radii if they are |
+ // available, but for now we use the max. |
+ point_data->major_radius = std::max(touch.radius_x(), touch.radius_y()); |
+ if (!point_data->major_radius) |
+ point_data->major_radius = GestureConfiguration::default_radius(); |
+} |
+ |
+void MotionEventUI::AddTouch(const TouchEvent& touch) { |
jdduke (slow)
2014/05/02 17:56:43
Would it ever make sense for |AddTouch()| to be th
tdresser
2014/05/05 15:42:35
In GestureProviderAura::OnTouchEvent, where we ign
|
+ if (pointer_count_ == static_cast<size_t>(GestureSequence::kMaxGesturePoints)) |
+ return; |
+ |
+ PointData* point_data = &active_touches_[pointer_count_]; |
jdduke (slow)
2014/05/02 17:56:43
What if we had a free function |GetPointDataFromTo
tdresser
2014/05/05 15:42:35
Can't quite be free, since PointData is (and I bel
|
+ UpdatePointData(touch, point_data); |
+ id_to_index_[touch.touch_id()] = static_cast<int>(pointer_count_); |
+ pointer_count_++; |
+} |
+ |
+ |
+void MotionEventUI::UpdateTouch(const TouchEvent& touch) { |
+ PointData* point_data = &active_touches_[id_to_index_[touch.touch_id()]]; |
jdduke (slow)
2014/05/02 17:56:43
What if touch_id() is not contained in id_to_index
tdresser
2014/05/05 15:42:35
Done.
|
+ UpdatePointData(touch, point_data); |
+} |
+ |
+void MotionEventUI::SetCachedAction(const TouchEvent& touch) { |
+ switch (touch.type()) { |
jdduke (slow)
2014/05/02 17:56:43
Might be worth another DCHECK(pointer_count_) here
tdresser
2014/05/05 15:42:35
Done.
|
+ case ET_TOUCH_PRESSED: |
+ if (pointer_count_ == 1) { |
+ cached_action_ = ACTION_DOWN; |
+ } else { |
+ cached_action_ = ACTION_POINTER_DOWN; |
+ cached_action_index_ = static_cast<int>(id_to_index_[touch.touch_id()]); |
+ } |
+ break; |
+ case ET_TOUCH_RELEASED: |
+ if (pointer_count_ == 1) { |
+ cached_action_ = ACTION_UP; |
+ } else { |
+ cached_action_ = ACTION_POINTER_UP; |
+ DCHECK(id_to_index_.count(touch.touch_id())); |
+ cached_action_index_ = static_cast<int>(id_to_index_[touch.touch_id()]); |
+ DCHECK(cached_action_index_ < static_cast<int>(pointer_count_)); |
+ } |
+ break; |
+ case ET_TOUCH_CANCELLED: |
+ cached_action_ = ACTION_CANCEL; |
+ break; |
+ case ET_TOUCH_MOVED: |
+ cached_action_ = ACTION_MOVE; |
+ break; |
+ default: |
+ NOTREACHED(); |
+ break; |
+ } |
+} |
+ |
+} // namespace ui |