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..ac619f8a04e1052b273d450deb38671d18e027ed 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,28 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( |
scroll_type_ = ST_FREE; |
set_state(GS_SCROLL); |
break; |
+ case GST_PINCH_THIRD_PRESSED: |
+ 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: |
+ 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 +463,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 x_velocity, |
+ float y_velocity, |
+ 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()), |
+ x_velocity, y_velocity, |
+ 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); |
@@ -569,4 +647,59 @@ 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 min_velocity = GestureConfiguration::min_swipe_speed(); |
+ |
+ float vx1 = point1->XVelocity(); |
+ float vx2 = point2->XVelocity(); |
+ float vx3 = point3->XVelocity(); |
+ float vy1 = point1->YVelocity(); |
+ float vy2 = point2->YVelocity(); |
+ float vy3 = point3->YVelocity(); |
+ |
+ float vx = (vx1 + vx2 + vx3) / 3; |
+ float vy = (vy1 + vy2 + vy3) / 3; |
+ |
+ // Not moving fast enough |
+ if (fabs(vx) < min_velocity && fabs(vy) < min_velocity) |
+ return false; |
+ |
+ // Diagonal swipe, no event fired |
+ // TODO(tdresser|sadrul): consider adding diagonal swipes |
+ float ratio = fabs(vx) > fabs(vy) ? fabs(vx / vy) : fabs(vy / vx); |
+ if (ratio < GestureConfiguration::max_swipe_deviation_ratio()) |
+ return false; |
+ |
+ 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 min_velocity. |
+ if (vx1 * sign < min_velocity || |
+ vx2 * sign < min_velocity || |
+ vx3 * sign < min_velocity) |
+ return false; |
+ AppendThreeFingerSwipeGestureEvent(*point1, *point2, *point3, |
+ sign, 0, gestures); |
+ } else { |
+ int sign = vy > 0 ? 1 : -1; |
+ // ensure all touches are moving in the same direction, and are |
+ // all moving faster than min_velocity. |
+ if (vy1 * sign < min_velocity || |
+ vy2 * sign < min_velocity || |
+ vy3 * sign < min_velocity) |
+ return false; |
+ AppendThreeFingerSwipeGestureEvent(*point1, *point2, *point3, |
+ 0, sign, gestures); |
+ } |
+ three_finger_swipe_has_fired_ = true; |
+ return true; |
+} |
+ |
} // namespace ui |