Index: ui/aura/gestures/gesture_sequence.cc |
diff --git a/ui/aura/gestures/gesture_sequence.cc b/ui/aura/gestures/gesture_sequence.cc |
index 6b5182b5d288977da844aec7f8986950e5609c86..33003089ba80e1b2843577eb6d81f5c1af0761d5 100644 |
--- a/ui/aura/gestures/gesture_sequence.cc |
+++ b/ui/aura/gestures/gesture_sequence.cc |
@@ -163,9 +163,6 @@ GestureSequence::GestureSequence() |
pinch_distance_current_(0.f), |
long_press_timer_(CreateTimer()), |
point_count_(0) { |
- for (int i = 0; i < kMaxGesturePoints; ++i) { |
- points_[i].set_touch_id(i); |
- } |
} |
GestureSequence::~GestureSequence() { |
@@ -184,7 +181,13 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( |
if (event.type() == ui::ET_TOUCH_PRESSED) { |
if (point_count_ == kMaxGesturePoints) |
return NULL; |
- ++point_count_; |
+ GesturePoint* new_point = &points_[event.touch_id()]; |
+ // We shouldn't be able to get two PRESSED events, without a RELEASE |
+ DCHECK(!points_[event.touch_id()].in_use()); |
+ new_point->set_point_id(point_count_++); |
+ } else { |
+ // Make sure the point we're modifying was PRESSED at some point in the past |
+ DCHECK(points_[event.touch_id()].in_use()); |
} |
GestureState last_state = state_; |
@@ -194,7 +197,8 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( |
GesturePoint& point = GesturePointForEvent(event); |
point.UpdateValues(event); |
flags_ = event.flags(); |
- switch (Signature(state_, event.touch_id(), event.type(), false)) { |
+ const int point_id = points_[event.touch_id()].point_id(); |
+ switch (Signature(state_, point_id, event.type(), false)) { |
case GST_NO_GESTURE_FIRST_PRESSED: |
TouchDown(event, point, gestures.get()); |
set_state(GS_PENDING_SYNTHETIC_CLICK); |
@@ -264,15 +268,27 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( |
if (last_state == GS_PENDING_SYNTHETIC_CLICK && state_ != last_state) |
long_press_timer_->Stop(); |
- if (event.type() == ui::ET_TOUCH_RELEASED) |
+ // The set of point_ids must be contiguous and include 0. |
+ // When a touch point is released, all points with ids greater than the |
+ // released point must have their ids decremented, or the set of point_ids |
+ // could end up with gaps. |
+ if (event.type() == ui::ET_TOUCH_RELEASED) { |
+ GesturePoint& old_point = points_[event.touch_id()]; |
+ for (int i = 0; i < kMaxGesturePoints; ++i) { |
+ GesturePoint& point = points_[i]; |
+ if (point.point_id() > old_point.point_id()) |
+ point.set_point_id(point.point_id() - 1); |
+ } |
+ old_point.Reset(); |
--point_count_; |
+ } |
return gestures.release(); |
} |
void GestureSequence::Reset() { |
set_state(GS_NO_GESTURE); |
- for (int i = 0; i < point_count_; ++i) |
+ for (int i = 0; i < kMaxGesturePoints; ++i) |
points_[i].Reset(); |
} |
@@ -291,6 +307,17 @@ GesturePoint& GestureSequence::GesturePointForEvent( |
return points_[event.touch_id()]; |
} |
+GesturePoint* GestureSequence::GetPointByPointId(int point_id) { |
+ DCHECK(0 <= point_id && point_id < kMaxGesturePoints); |
+ for (int i = 0; i < kMaxGesturePoints; ++i) { |
+ GesturePoint& point = points_[i]; |
+ if (point.in_use() && point.point_id() == point_id) |
+ return &point; |
+ } |
+ DCHECK(false); |
sadrul
2012/02/23 21:44:14
NOTREACHED
tdresser
2012/02/23 22:16:55
Done.
|
+ return NULL; |
+} |
+ |
void GestureSequence::AppendTapDownGestureEvent(const GesturePoint& point, |
Gestures* gestures) { |
gestures->push_back(linked_ptr<GestureEvent>(new GestureEvent( |
@@ -481,16 +508,15 @@ bool GestureSequence::TouchDown(const TouchEvent& event, |
} |
void GestureSequence::AppendLongPressGestureEvent() { |
- // TODO(tdresser) - this may not always be the first point |
- const GesturePoint& point = points_[0]; |
+ const GesturePoint* point = GetPointByPointId(0); |
+ DCHECK(point); |
GestureEvent* gesture = new GestureEvent( |
ui::ET_GESTURE_LONG_PRESS, |
- point.first_touch_position().x(), |
- point.first_touch_position().y(), |
+ point->first_touch_position().x(), |
+ point->first_touch_position().y(), |
flags_, |
- base::Time::FromDoubleT(point.last_touch_time()), |
- point.touch_id(), 0.f); |
- |
+ base::Time::FromDoubleT(point->last_touch_time()), |
+ point->point_id(), 0.f); |
RootWindow::GetInstance()->DispatchGestureEvent(gesture); |
} |
@@ -513,13 +539,16 @@ bool GestureSequence::PinchStart(const TouchEvent& event, |
state_ == GS_PENDING_SYNTHETIC_CLICK); |
AppendTapDownGestureEvent(point, gestures); |
- pinch_distance_current_ = points_[0].Distance(points_[1]); |
+ const GesturePoint* point1 = GetPointByPointId(0); |
+ const GesturePoint* point2 = GetPointByPointId(1); |
+ |
+ pinch_distance_current_ = point1->Distance(*point2); |
pinch_distance_start_ = pinch_distance_current_; |
- AppendPinchGestureBegin(points_[0], points_[1], gestures); |
+ AppendPinchGestureBegin(*point1, *point2, gestures); |
if (state_ == GS_PENDING_SYNTHETIC_CLICK) { |
- gfx::Point center = points_[0].last_touch_position().Middle( |
- points_[1].last_touch_position()); |
+ gfx::Point center = point1->last_touch_position().Middle( |
+ point2->last_touch_position()); |
AppendScrollGestureBegin(point, center, gestures); |
} |
@@ -529,23 +558,27 @@ bool GestureSequence::PinchStart(const TouchEvent& event, |
bool GestureSequence::PinchUpdate(const TouchEvent& event, |
const GesturePoint& point, Gestures* gestures) { |
DCHECK(state_ == GS_PINCH); |
- float distance = points_[0].Distance(points_[1]); |
+ |
+ const GesturePoint* point1 = GetPointByPointId(0); |
+ const GesturePoint* point2 = GetPointByPointId(1); |
+ |
+ float distance = point1->Distance(*point2); |
if (abs(distance - pinch_distance_current_) < |
GestureConfiguration::minimum_pinch_update_distance_in_pixels()) { |
// The fingers didn't move towards each other, or away from each other, |
// enough to constitute a pinch. But perhaps they moved enough in the same |
// direction to do a two-finger scroll. |
- if (!points_[0].DidScroll(event, |
+ if (!point1->DidScroll(event, |
GestureConfiguration::minimum_distance_for_pinch_scroll_in_pixels()) || |
- !points_[1].DidScroll(event, |
+ !point2->DidScroll(event, |
GestureConfiguration::minimum_distance_for_pinch_scroll_in_pixels())) |
return false; |
- gfx::Point center = points_[0].last_touch_position().Middle( |
- points_[1].last_touch_position()); |
+ gfx::Point center = point1->last_touch_position().Middle( |
+ point2->last_touch_position()); |
AppendScrollGestureUpdate(point, center, gestures); |
} else { |
- AppendPinchGestureUpdate(points_[0], points_[1], |
+ AppendPinchGestureUpdate(*point1, *point2, |
distance / pinch_distance_current_, gestures); |
pinch_distance_current_ = distance; |
} |
@@ -555,8 +588,12 @@ bool GestureSequence::PinchUpdate(const TouchEvent& event, |
bool GestureSequence::PinchEnd(const TouchEvent& event, |
const GesturePoint& point, Gestures* gestures) { |
DCHECK(state_ == GS_PINCH); |
- float distance = points_[0].Distance(points_[1]); |
- AppendPinchGestureEnd(points_[0], points_[1], |
+ |
+ const GesturePoint* point1 = GetPointByPointId(0); |
+ const GesturePoint* point2 = GetPointByPointId(1); |
+ |
+ float distance = point1->Distance(*point2); |
+ AppendPinchGestureEnd(*point1, *point2, |
distance / pinch_distance_start_, gestures); |
pinch_distance_start_ = 0; |