Chromium Code Reviews| Index: ui/aura/gestures/gesture_sequence.cc |
| diff --git a/ui/aura/gestures/gesture_sequence.cc b/ui/aura/gestures/gesture_sequence.cc |
| index 554cf106a84c532e8557bffe8c673d2b6b1683bc..bcf01bdf50ed15cc693846b820c71044e9a45624 100644 |
| --- a/ui/aura/gestures/gesture_sequence.cc |
| +++ b/ui/aura/gestures/gesture_sequence.cc |
| @@ -12,11 +12,6 @@ |
| #include "ui/aura/gestures/gesture_configuration.h" |
| #include "ui/base/events.h" |
| -// TODO(sad): Pinch gestures currently always assume that the first two |
| -// touch-points (i.e. at indices 0 and 1) are involved. This may not |
| -// always be the case. This needs to be fixed eventually. |
| -// http://crbug.com/113144 |
| - |
| namespace { |
| // TODO(girard): Make these configurable in sync with this CL |
| @@ -99,18 +94,6 @@ enum EdgeStateSignatureType { |
| GST_SCROLL_FIRST_CANCELLED = |
| G(GS_SCROLL, 0, TS_CANCELLED, false), |
| - GST_SCROLL_FIRST_PRESSED = |
| - G(GS_SCROLL, 0, TS_PRESSED, false), |
| - |
| - GST_SCROLL_SECOND_RELEASED = |
| - G(GS_SCROLL, 1, TS_RELEASED, false), |
| - |
| - GST_SCROLL_SECOND_MOVED = |
| - G(GS_SCROLL, 1, TS_MOVED, false), |
| - |
| - GST_SCROLL_SECOND_CANCELLED = |
| - G(GS_SCROLL, 1, TS_CANCELLED, false), |
| - |
| GST_SCROLL_SECOND_PRESSED = |
| G(GS_SCROLL, 1, TS_PRESSED, false), |
| @@ -164,9 +147,6 @@ GestureSequence::GestureSequence(RootWindow* root_window) |
| long_press_timer_(CreateTimer()), |
| point_count_(0), |
| root_window_(root_window) { |
| - for (int i = 0; i < kMaxGesturePoints; ++i) { |
| - points_[i].set_touch_id(i); |
| - } |
| } |
| GestureSequence::~GestureSequence() { |
| @@ -185,7 +165,11 @@ 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 either |
| + // a RELEASE or CANCEL |
| + DCHECK(!points_[event.touch_id()].in_use()); |
|
tdresser
2012/03/02 14:04:02
Is this correct?
If a touch release is preventDef
sadrul
2012/03/02 14:20:31
In such a situation, the GR should receive a touch
tdresser
2012/03/02 15:11:27
Done.
|
| + new_point->set_point_id(point_count_++); |
| } |
| GestureState last_state = state_; |
| @@ -195,7 +179,10 @@ 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(); |
| + if (point_id < 0) |
| + return NULL; |
| + 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); |
| @@ -217,7 +204,6 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( |
| NoGesture(event, point, gestures.get()); |
| break; |
| case GST_SCROLL_FIRST_MOVED: |
| - case GST_SCROLL_SECOND_MOVED: |
| if (scroll_type_ == ST_VERTICAL || |
| scroll_type_ == ST_HORIZONTAL) |
| BreakRailScroll(event, point, gestures.get()); |
| @@ -226,12 +212,9 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( |
| break; |
| case GST_SCROLL_FIRST_RELEASED: |
| case GST_SCROLL_FIRST_CANCELLED: |
| - case GST_SCROLL_SECOND_RELEASED: |
| - case GST_SCROLL_SECOND_CANCELLED: |
| ScrollEnd(event, point, gestures.get()); |
| set_state(GS_NO_GESTURE); |
| break; |
| - case GST_SCROLL_FIRST_PRESSED: |
| case GST_SCROLL_SECOND_PRESSED: |
| case GST_PENDING_SYNTHETIC_CLICK_SECOND_PRESSED: |
| PinchStart(event, point, gestures.get()); |
| @@ -240,8 +223,8 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( |
| case GST_PINCH_FIRST_MOVED: |
| case GST_PINCH_SECOND_MOVED: |
| if (PinchUpdate(event, point, gestures.get())) { |
| - points_[0].UpdateForScroll(); |
| - points_[1].UpdateForScroll(); |
| + GetPointByPointId(0)->UpdateForScroll(); |
| + GetPointByPointId(1)->UpdateForScroll(); |
| } |
| break; |
| case GST_PINCH_FIRST_RELEASED: |
| @@ -265,15 +248,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(); |
| } |
| @@ -292,6 +287,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; |
| + } |
| + NOTREACHED(); |
| + return NULL; |
| +} |
| + |
| void GestureSequence::AppendTapDownGestureEvent(const GesturePoint& point, |
| Gestures* gestures) { |
| gestures->push_back(linked_ptr<GestureEvent>(new GestureEvent( |
| @@ -482,16 +488,14 @@ 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); |
| 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); |
| root_window_->DispatchGestureEvent(gesture); |
| } |
| @@ -514,13 +518,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); |
| } |
| @@ -530,23 +537,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; |
| } |
| @@ -556,8 +567,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; |