diff options
author | tdresser@chromium.org <tdresser@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-17 13:52:45 +0000 |
---|---|---|
committer | tdresser@chromium.org <tdresser@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-17 13:52:45 +0000 |
commit | 93425b44c4ea18ca58e3f5585d92795628bc5355 (patch) | |
tree | 0d3c398b08ab343ced67a07c48c229b535a8a1ae /ui/base | |
parent | 1895cda784ed3c8a899379f32b334761d386e6ed (diff) | |
download | chromium_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.h | 1 | ||||
-rw-r--r-- | ui/base/gestures/gesture_configuration.cc | 2 | ||||
-rw-r--r-- | ui/base/gestures/gesture_configuration.h | 14 | ||||
-rw-r--r-- | ui/base/gestures/gesture_sequence.cc | 133 | ||||
-rw-r--r-- | ui/base/gestures/gesture_sequence.h | 14 | ||||
-rw-r--r-- | ui/base/gestures/gestures.dot | 4 |
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"]; } |