summaryrefslogtreecommitdiffstats
path: root/ui/base
diff options
context:
space:
mode:
authortdresser@chromium.org <tdresser@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-17 13:52:45 +0000
committertdresser@chromium.org <tdresser@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-17 13:52:45 +0000
commit93425b44c4ea18ca58e3f5585d92795628bc5355 (patch)
tree0d3c398b08ab343ced67a07c48c229b535a8a1ae /ui/base
parent1895cda784ed3c8a899379f32b334761d386e6ed (diff)
downloadchromium_src-93425b44c4ea18ca58e3f5585d92795628bc5355.zip
chromium_src-93425b44c4ea18ca58e3f5585d92795628bc5355.tar.gz
chromium_src-93425b44c4ea18ca58e3f5585d92795628bc5355.tar.bz2
Three Finger Swipe
Implements a three finger swipe gesture event for the aura Gesture Recognizer. BUG=122807 TEST=SystemGestureEventFilterTest.TapOutsideRootWindow, GestureRecognizerTest.GestureEventThreeFingerSwipe Review URL: http://codereview.chromium.org/10037012 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@132570 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/base')
-rw-r--r--ui/base/events.h1
-rw-r--r--ui/base/gestures/gesture_configuration.cc2
-rw-r--r--ui/base/gestures/gesture_configuration.h14
-rw-r--r--ui/base/gestures/gesture_sequence.cc133
-rw-r--r--ui/base/gestures/gesture_sequence.h14
-rw-r--r--ui/base/gestures/gestures.dot4
6 files changed, 167 insertions, 1 deletions
diff --git a/ui/base/events.h b/ui/base/events.h
index 814ffe3..33fb77f 100644
--- a/ui/base/events.h
+++ b/ui/base/events.h
@@ -54,6 +54,7 @@ enum EventType {
ET_GESTURE_PINCH_END,
ET_GESTURE_PINCH_UPDATE,
ET_GESTURE_LONG_PRESS,
+ ET_GESTURE_THREE_FINGER_SWIPE,
// Scroll support.
// TODO[davemoore] we need to unify these events w/ touch and gestures.
diff --git a/ui/base/gestures/gesture_configuration.cc b/ui/base/gestures/gesture_configuration.cc
index 9128aa5..17a9d6f 100644
--- a/ui/base/gestures/gesture_configuration.cc
+++ b/ui/base/gestures/gesture_configuration.cc
@@ -12,6 +12,7 @@ double GestureConfiguration::long_press_time_in_seconds_ = 0.5;
double GestureConfiguration::max_seconds_between_double_click_ = 0.7;
double
GestureConfiguration::max_separation_for_gesture_touches_in_pixels_ = 150;
+double GestureConfiguration::max_swipe_deviation_ratio_ = 3;
double
GestureConfiguration::max_touch_down_duration_in_seconds_for_click_ = 0.8;
double GestureConfiguration::max_touch_move_in_pixels_for_click_ = 20;
@@ -20,6 +21,7 @@ double GestureConfiguration::min_flick_speed_squared_ = 550.f * 550.f;
double GestureConfiguration::min_pinch_update_distance_in_pixels_ = 5;
double GestureConfiguration::min_rail_break_velocity_ = 200;
double GestureConfiguration::min_scroll_delta_squared_ = 5 * 5;
+double GestureConfiguration::min_swipe_speed_ = 20;
double
GestureConfiguration::min_touch_down_duration_in_seconds_for_click_ = 0.01;
diff --git a/ui/base/gestures/gesture_configuration.h b/ui/base/gestures/gesture_configuration.h
index 83f953b..c1aa5dc 100644
--- a/ui/base/gestures/gesture_configuration.h
+++ b/ui/base/gestures/gesture_configuration.h
@@ -37,6 +37,12 @@ class UI_EXPORT GestureConfiguration {
static void set_max_separation_for_gesture_touches_in_pixels(int val) {
max_separation_for_gesture_touches_in_pixels_ = val;
}
+ static double max_swipe_deviation_ratio() {
+ return max_swipe_deviation_ratio_;
+ }
+ static void set_max_swipe_deviation_ratio(double val) {
+ max_swipe_deviation_ratio_ = val;
+ }
static double max_touch_down_duration_in_seconds_for_click() {
return max_touch_down_duration_in_seconds_for_click_;
}
@@ -79,6 +85,12 @@ class UI_EXPORT GestureConfiguration {
static void set_min_scroll_delta_squared(double val) {
min_scroll_delta_squared_ = val;
}
+ static double min_swipe_speed() {
+ return min_swipe_speed_;
+ }
+ static void set_min_swipe_speed(double val) {
+ min_swipe_speed_ = val;
+ }
static double min_touch_down_duration_in_seconds_for_click() {
return min_touch_down_duration_in_seconds_for_click_;
}
@@ -111,6 +123,7 @@ class UI_EXPORT GestureConfiguration {
static double long_press_time_in_seconds_;
static double max_seconds_between_double_click_;
static double max_separation_for_gesture_touches_in_pixels_;
+ static double max_swipe_deviation_ratio_;
static double max_touch_down_duration_in_seconds_for_click_;
static double max_touch_move_in_pixels_for_click_;
static double min_distance_for_pinch_scroll_in_pixels_;
@@ -118,6 +131,7 @@ class UI_EXPORT GestureConfiguration {
static double min_pinch_update_distance_in_pixels_;
static double min_rail_break_velocity_;
static double min_scroll_delta_squared_;
+ static double min_swipe_speed_;
static double min_touch_down_duration_in_seconds_for_click_;
static int points_buffered_for_velocity_;
static double rail_break_proportion_;
diff --git a/ui/base/gestures/gesture_sequence.cc b/ui/base/gestures/gesture_sequence.cc
index 69af3f7..ac619f8 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
diff --git a/ui/base/gestures/gesture_sequence.h b/ui/base/gestures/gesture_sequence.h
index de829d5..e8d7aab 100644
--- a/ui/base/gestures/gesture_sequence.h
+++ b/ui/base/gestures/gesture_sequence.h
@@ -20,7 +20,8 @@ enum GestureState {
GS_NO_GESTURE,
GS_PENDING_SYNTHETIC_CLICK,
GS_SCROLL,
- GS_PINCH
+ GS_PINCH,
+ GS_THREE_FINGER_SWIPE
};
enum ScrollType {
@@ -99,6 +100,13 @@ class UI_EXPORT GestureSequence {
float scale,
Gestures* gestures);
+ void AppendThreeFingerSwipeGestureEvent(const GesturePoint& p1,
+ const GesturePoint& p2,
+ const GesturePoint& p3,
+ float x_velocity,
+ float y_velocity,
+ Gestures* gestures);
+
void set_state(const GestureState state ) { state_ = state; }
// Various GestureTransitionFunctions for a signature.
@@ -134,6 +142,9 @@ class UI_EXPORT GestureSequence {
bool PinchEnd(const TouchEvent& event,
const GesturePoint& point,
Gestures* gestures);
+ bool ThreeFingerSwipeUpdate(const TouchEvent& event,
+ const GesturePoint& point,
+ Gestures* gestures);
// Current state of gesture recognizer.
GestureState state_;
@@ -148,6 +159,7 @@ class UI_EXPORT GestureSequence {
float pinch_distance_current_;
ScrollType scroll_type_;
+ bool three_finger_swipe_has_fired_;
scoped_ptr<base::OneShotTimer<GestureSequence> > long_press_timer_;
GesturePoint points_[kMaxGesturePoints];
diff --git a/ui/base/gestures/gestures.dot b/ui/base/gestures/gestures.dot
index a095575..6e3aa5c 100644
--- a/ui/base/gestures/gestures.dot
+++ b/ui/base/gestures/gestures.dot
@@ -29,4 +29,8 @@ GS_PENDING_SYNTHETIC_CLICK -> GS_PINCH [label= "D1"];
GS_SCROLL -> GS_PINCH [label= "D1"];
GS_PINCH -> GS_PINCH [label= "M0\n M1"];
GS_PINCH -> GS_SCROLL [label= "C0\n R0\n C1\n R1"];
+
+GS_PINCH -> GS_PENDING_THREE_FINGER_SWIPE [label= "D2"];
+GS_PENDING_THREE_FINGER_SWIPE -> GS_PINCH [label= "C0\n R0\n C1\n R1\n C2\n R2"];
+GS_PENDING_THREE_FINGER_SWIPE -> GS_PENDING_THREE_FINGER_SWIPE [label= "M0\n M1\n M2"];
}