Index: ui/base/gestures/gesture_sequence.cc |
diff --git a/ui/base/gestures/gesture_sequence.cc b/ui/base/gestures/gesture_sequence.cc |
index 69af3f7516b180d31fe3e5415a5af8c07fb532ef..a5f00c3b80048119d7125c54470a3f2aefb01243 100644 |
--- a/ui/base/gestures/gesture_sequence.cc |
+++ b/ui/base/gestures/gesture_sequence.cc |
@@ -4,6 +4,8 @@ |
#include "ui/base/gestures/gesture_sequence.h" |
+#include <cmath> |
+ |
#include "base/logging.h" |
#include "base/memory/scoped_ptr.h" |
#include "base/time.h" |
@@ -102,6 +104,36 @@ enum EdgeStateSignatureType { |
GST_PINCH_SECOND_CANCELLED = |
G(GS_PINCH, 1, TS_CANCELLED, false), |
+ |
+ GST_PINCH_THIRD_PRESSED = |
+ G(GS_PINCH, 2, TS_PRESSED, false), |
+ |
+ GST_THREE_FINGER_SWIPE_FIRST_RELEASED = |
+ G(GS_THREE_FINGER_SWIPE, 0, TS_RELEASED, false), |
+ |
+ GST_THREE_FINGER_SWIPE_SECOND_RELEASED = |
+ G(GS_THREE_FINGER_SWIPE, 1, TS_RELEASED, false), |
+ |
+ GST_THREE_FINGER_SWIPE_THIRD_RELEASED = |
+ G(GS_THREE_FINGER_SWIPE, 2, TS_RELEASED, false), |
+ |
+ GST_THREE_FINGER_SWIPE_FIRST_MOVED = |
+ G(GS_THREE_FINGER_SWIPE, 0, TS_MOVED, false), |
+ |
+ GST_THREE_FINGER_SWIPE_SECOND_MOVED = |
+ G(GS_THREE_FINGER_SWIPE, 1, TS_MOVED, false), |
+ |
+ GST_THREE_FINGER_SWIPE_THIRD_MOVED = |
+ G(GS_THREE_FINGER_SWIPE, 2, TS_MOVED, false), |
+ |
+ GST_THREE_FINGER_SWIPE_FIRST_CANCELLED = |
+ G(GS_THREE_FINGER_SWIPE, 0, TS_CANCELLED, false), |
+ |
+ GST_THREE_FINGER_SWIPE_SECOND_CANCELLED = |
+ G(GS_THREE_FINGER_SWIPE, 1, TS_CANCELLED, false), |
+ |
+ GST_THREE_FINGER_SWIPE_THIRD_CANCELLED = |
+ G(GS_THREE_FINGER_SWIPE, 2, TS_CANCELLED, false), |
}; |
// Builds a signature. Signatures are assembled by joining together |
@@ -227,6 +259,30 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( |
scroll_type_ = ST_FREE; |
set_state(GS_SCROLL); |
break; |
+ case GST_PINCH_THIRD_PRESSED: |
+ PinchEnd(event, point, gestures.get()); |
sadrul
2012/04/10 20:32:51
Should there also be a ScrollEnd here?
tdresser
2012/04/11 18:17:04
And the related ScrollStart, when a finger from a
|
+ three_finger_swipe_has_fired_ = false; |
+ set_state(GS_THREE_FINGER_SWIPE); |
+ break; |
+ case GST_THREE_FINGER_SWIPE_FIRST_RELEASED: |
+ case GST_THREE_FINGER_SWIPE_SECOND_RELEASED: |
+ case GST_THREE_FINGER_SWIPE_THIRD_RELEASED: |
+ case GST_THREE_FINGER_SWIPE_FIRST_CANCELLED: |
+ case GST_THREE_FINGER_SWIPE_SECOND_CANCELLED: |
+ case GST_THREE_FINGER_SWIPE_THIRD_CANCELLED: |
+ PinchStart(event, point, gestures.get()); |
+ set_state(GS_PINCH); |
+ break; |
+ case GST_THREE_FINGER_SWIPE_FIRST_MOVED: |
+ case GST_THREE_FINGER_SWIPE_SECOND_MOVED: |
+ case GST_THREE_FINGER_SWIPE_THIRD_MOVED: |
+ if (!three_finger_swipe_has_fired_) { |
+ ThreeFingerSwipeUpdate(event, point, gestures.get()); |
+ GetPointByPointId(0)->UpdateForScroll(); |
+ GetPointByPointId(1)->UpdateForScroll(); |
+ GetPointByPointId(2)->UpdateForScroll(); |
+ } |
+ break; |
} |
if (state_ != last_state) |
@@ -409,6 +465,30 @@ void GestureSequence::AppendPinchGestureUpdate(const GesturePoint& p1, |
scale, 0.f, 1 << p1.touch_id() | 1 << p2.touch_id()))); |
} |
+void GestureSequence::AppendThreeFingerSwipeGestureEvent(const GesturePoint& p1, |
+ const GesturePoint& p2, |
+ const GesturePoint& p3, |
+ float xVelocity, |
+ float yVelocity, |
+ Gestures* gestures) { |
+ int x = ( |
+ p1.last_touch_position().x() + |
+ p2.last_touch_position().x() + |
+ p3.last_touch_position().x()) / 3; |
+ int y = ( |
+ p1.last_touch_position().y() + |
+ p2.last_touch_position().y() + |
+ p3.last_touch_position().y()) / 3; |
+ gfx::Point center(x, y); |
+ gestures->push_back(helper_->CreateGestureEvent( |
+ ui::ET_GESTURE_THREE_FINGER_SWIPE, |
+ center, |
+ flags_, |
+ base::Time::FromDoubleT(p1.last_touch_time()), |
+ xVelocity, yVelocity, |
+ 1 << p1.touch_id() | 1 << p2.touch_id() | 1 << p3.touch_id())); |
+} |
+ |
bool GestureSequence::Click(const TouchEvent& event, |
const GesturePoint& point, Gestures* gestures) { |
DCHECK(state_ == GS_PENDING_SYNTHETIC_CLICK); |
@@ -504,7 +584,8 @@ bool GestureSequence::ScrollEnd(const TouchEvent& event, |
bool GestureSequence::PinchStart(const TouchEvent& event, |
const GesturePoint& point, Gestures* gestures) { |
DCHECK(state_ == GS_SCROLL || |
- state_ == GS_PENDING_SYNTHETIC_CLICK); |
+ state_ == GS_PENDING_SYNTHETIC_CLICK || |
+ state_ == GS_THREE_FINGER_SWIPE); |
AppendTapDownGestureEvent(point, gestures); |
const GesturePoint* point1 = GetPointByPointId(0); |
@@ -569,4 +650,61 @@ bool GestureSequence::PinchEnd(const TouchEvent& event, |
return true; |
} |
+bool GestureSequence::ThreeFingerSwipeUpdate(const TouchEvent& event, |
+ const GesturePoint& point, Gestures* gestures) { |
+ DCHECK(state_ == GS_THREE_FINGER_SWIPE); |
+ |
+ GesturePoint* point1 = GetPointByPointId(0); |
+ GesturePoint* point2 = GetPointByPointId(1); |
+ GesturePoint* point3 = GetPointByPointId(2); |
+ |
+ int minVelocity = 20; |
sadrul
2012/04/10 20:32:51
min_velocity
tdresser
2012/04/11 18:17:04
Done.
|
+ |
+ float vx1 = point1->XVelocity(); |
+ float vx2 = point2->XVelocity(); |
+ float vx3 = point3->XVelocity(); |
+ float vy1 = point1->YVelocity(); |
+ float vy2 = point2->YVelocity(); |
+ float vy3 = point3->YVelocity(); |
+ |
sadrul
2012/04/10 20:32:51
I think we should check whether all points are mov
tdresser
2012/04/11 18:17:04
I feel like ensuring that the points are within a
|
+ float vx = (vx1 + vx2 + vx3) / 3; |
+ float vy = (vy1 + vy2 + vy3) / 3; |
+ |
+ // Not moving fast enough |
+ if (fabs(vx) < minVelocity && fabs(vy) < minVelocity) |
+ return true; |
sadrul
2012/04/10 20:32:51
return false;
tdresser
2012/04/11 18:17:04
Done.
|
+ |
+ // Diagonal swipe, no event fired |
+ if (fabs(vx) >= minVelocity && fabs(vy) >= minVelocity) { |
+ float ratio = fabs(vx) > fabs(vy) ? fabs(vx / vy) : fabs(vy / vx); |
+ if (ratio < 3) |
+ return true; |
sadrul
2012/04/10 20:32:51
return false;
Also, why this restriction?
tdresser
2012/04/11 18:17:04
Done.
Added TODO to consider diagonal swipes.
|
+ } |
+ |
+ if (fabs(vx) > fabs(vy)) { |
+ int sign = vx > 0 ? 1 : -1; |
+ // ensure all touches are moving in the same direction, and are |
+ // all moving faster than minVelocity. |
+ if (vx1 * sign < minVelocity || |
+ vx2 * sign < minVelocity || |
+ vx3 * sign < minVelocity) |
+ return true; |
+ AppendThreeFingerSwipeGestureEvent(*point1, *point2, *point3, |
+ sign, 0, gestures); |
+ three_finger_swipe_has_fired_ = true; |
+ } else { |
+ int sign = vy > 0 ? 1 : -1; |
+ // ensure all touches are moving in the same direction, and are |
+ // all moving faster than minVelocity. |
+ if (vy1 * sign < minVelocity || |
+ vy2 * sign < minVelocity || |
+ vy3 * sign < minVelocity) |
+ return true; |
+ AppendThreeFingerSwipeGestureEvent(*point1, *point2, *point3, |
+ 0, sign, gestures); |
sadrul
2012/04/10 20:32:51
It looks like one of the velocities is always zero
tdresser
2012/04/11 18:17:04
This implementation currently assumes that we aren
|
+ three_finger_swipe_has_fired_ = true; |
+ } |
+ return true; |
+} |
+ |
} // namespace ui |