summaryrefslogtreecommitdiffstats
path: root/ui/aura
diff options
context:
space:
mode:
authortdresser@chromium.org <tdresser@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-10 21:06:13 +0000
committertdresser@chromium.org <tdresser@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-10 21:06:13 +0000
commit5694aac3f93ce3889324168764e1b4c688b2bd8d (patch)
treefe3be653fb01191bf5730369321fe8a055fc6d96 /ui/aura
parentd602b58cadea6a5b047913ea9fd16cdd83448b0f (diff)
downloadchromium_src-5694aac3f93ce3889324168764e1b4c688b2bd8d.zip
chromium_src-5694aac3f93ce3889324168764e1b4c688b2bd8d.tar.gz
chromium_src-5694aac3f93ce3889324168764e1b4c688b2bd8d.tar.bz2
Scrolling "on rails"
If a scroll begins primarily horizontally or vertically, it will be locked into only horizontal or only vertical movement. If the user attempts to scroll against the rail, the rail will break, and the scroll will continue without rails. BUG=101655 TEST=GestureRecognizerTest.GestureEventHorizontalRailScroll, GestureRecognizerTest.GestureEventVerticalRailScroll Review URL: http://codereview.chromium.org/9381005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@121529 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/aura')
-rw-r--r--ui/aura/gestures/gesture_point.cc42
-rw-r--r--ui/aura/gestures/gesture_point.h5
-rw-r--r--ui/aura/gestures/gesture_recognizer_unittest.cc134
-rw-r--r--ui/aura/gestures/gesture_sequence.cc95
-rw-r--r--ui/aura/gestures/gesture_sequence.h25
5 files changed, 253 insertions, 48 deletions
diff --git a/ui/aura/gestures/gesture_point.cc b/ui/aura/gestures/gesture_point.cc
index 6619b93..78f32fb 100644
--- a/ui/aura/gestures/gesture_point.cc
+++ b/ui/aura/gestures/gesture_point.cc
@@ -12,13 +12,19 @@
namespace {
-// TODO(girard): Make these configurable in sync with this CL
-// http://crbug.com/100773
+// TODO(girard): Make these configurable in sync with
+// http://crbug.com/113227
+// It will be necessary to update gesture_recognizer_unittest when
+// these constants are made configurable.
const double kMaximumTouchDownDurationInSecondsForClick = 0.8;
const double kMinimumTouchDownDurationInSecondsForClick = 0.01;
const double kMaximumSecondsBetweenDoubleClick = 0.7;
const int kMaximumTouchMoveInPixelsForClick = 20;
const float kMinFlickSpeedSquared = 550.f * 550.f;
+const int kMinRailBreakVelocity = 200;
+const int kMinScrollDeltaSquared = 5 * 5;
+const int kRailBreakProportion = 15;
+const int kRailStartProportion = 2;
const int kBufferedPoints = 10;
} // namespace
@@ -105,6 +111,38 @@ float GesturePoint::Distance(const GesturePoint& point) const {
return sqrt(x_diff * x_diff + y_diff * y_diff);
}
+bool GesturePoint::HasEnoughDataToEstablishRail() const {
+ int dx = x_delta();
+ int dy = y_delta();
+
+ int delta_squared = dx * dx + dy * dy;
+ return delta_squared > kMinScrollDeltaSquared;
+}
+
+bool GesturePoint::IsInHorizontalRailWindow() const {
+ int dx = x_delta();
+ int dy = y_delta();
+ return abs(dx) > kRailStartProportion * abs(dy);
+}
+
+bool GesturePoint::IsInVerticalRailWindow() const {
+ int dx = x_delta();
+ int dy = y_delta();
+ return abs(dy) > kRailStartProportion * abs(dx);
+}
+
+bool GesturePoint::BreaksHorizontalRail() {
+ float vx = XVelocity();
+ float vy = YVelocity();
+ return fabs(vy) > kRailBreakProportion * fabs(vx) + kMinRailBreakVelocity;
+}
+
+bool GesturePoint::BreaksVerticalRail() {
+ float vx = XVelocity();
+ float vy = YVelocity();
+ return fabs(vx) > kRailBreakProportion * fabs(vy) + kMinRailBreakVelocity;
+}
+
bool GesturePoint::IsInClickTimeWindow() const {
double duration = last_touch_time_ - first_touch_time_;
return duration >= kMinimumTouchDownDurationInSecondsForClick &&
diff --git a/ui/aura/gestures/gesture_point.h b/ui/aura/gestures/gesture_point.h
index 115eccc..1fbd4ae 100644
--- a/ui/aura/gestures/gesture_point.h
+++ b/ui/aura/gestures/gesture_point.h
@@ -39,6 +39,11 @@ class GesturePoint {
bool IsInDoubleClickWindow(const TouchEvent& event) const;
bool IsInScrollWindow(const TouchEvent& event) const;
bool IsInFlickWindow(const TouchEvent& event);
+ bool IsInHorizontalRailWindow() const;
+ bool IsInVerticalRailWindow() const;
+ bool HasEnoughDataToEstablishRail() const;
+ bool BreaksHorizontalRail();
+ bool BreaksVerticalRail();
bool DidScroll(const TouchEvent& event, int distance) const;
const gfx::Point& first_touch_position() const {
diff --git a/ui/aura/gestures/gesture_recognizer_unittest.cc b/ui/aura/gestures/gesture_recognizer_unittest.cc
index 3a3636d..6857675 100644
--- a/ui/aura/gestures/gesture_recognizer_unittest.cc
+++ b/ui/aura/gestures/gesture_recognizer_unittest.cc
@@ -199,6 +199,38 @@ class GestureEventSynthDelegate : public TestWindowDelegate {
DISALLOW_COPY_AND_ASSIGN(GestureEventSynthDelegate);
};
+void SendScrollEvents(int x_start,
+ int y_start,
+ base::TimeDelta time_start,
+ int dx,
+ int dy,
+ int time_step,
+ int num_steps,
+ GestureEventConsumeDelegate* delegate) {
+ int x = x_start;
+ int y = y_start;
+ base::TimeDelta time = time_start;
+
+ for (int i = 0; i < num_steps; i++) {
+ delegate->Reset();
+ TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(x, y), 0);
+ Event::TestApi test_move(&move);
+ test_move.set_time_stamp(time);
+ RootWindow::GetInstance()->DispatchTouchEvent(&move);
+ x += dx;
+ y += dy;
+ time = time + base::TimeDelta::FromMilliseconds(time_step);
+ }
+}
+
+void SendScrollEvent(int x, int y, GestureEventConsumeDelegate* delegate) {
+ delegate->Reset();
+ TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(x, y), 0);
+ RootWindow::GetInstance()->DispatchTouchEvent(&move);
+}
+
+const int kBufferedPoints = 10;
+
} // namespace
typedef AuraTestBase GestureRecognizerTest;
@@ -261,9 +293,9 @@ TEST_F(GestureRecognizerTest, GestureEventScroll) {
// Move the touch-point enough so that it is considered as a scroll. This
// should generate both SCROLL_BEGIN and SCROLL_UPDATE gestures.
- delegate->Reset();
- TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(130, 201), 0);
- RootWindow::GetInstance()->DispatchTouchEvent(&move);
+ // The first movement is diagonal, to ensure that we have a free scroll,
+ // and not a rail scroll.
+ SendScrollEvent(130, 230, delegate.get());
EXPECT_FALSE(delegate->tap());
EXPECT_FALSE(delegate->tap_down());
EXPECT_FALSE(delegate->double_tap());
@@ -271,12 +303,10 @@ TEST_F(GestureRecognizerTest, GestureEventScroll) {
EXPECT_TRUE(delegate->scroll_update());
EXPECT_FALSE(delegate->scroll_end());
EXPECT_EQ(29, delegate->scroll_x());
- EXPECT_EQ(0, delegate->scroll_y());
+ EXPECT_EQ(29, delegate->scroll_y());
// Move some more to generate a few more scroll updates.
- delegate->Reset();
- TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(110, 211), 0);
- RootWindow::GetInstance()->DispatchTouchEvent(&move1);
+ SendScrollEvent(110, 211, delegate.get());
EXPECT_FALSE(delegate->tap());
EXPECT_FALSE(delegate->tap_down());
EXPECT_FALSE(delegate->double_tap());
@@ -284,11 +314,9 @@ TEST_F(GestureRecognizerTest, GestureEventScroll) {
EXPECT_TRUE(delegate->scroll_update());
EXPECT_FALSE(delegate->scroll_end());
EXPECT_EQ(-20, delegate->scroll_x());
- EXPECT_EQ(10, delegate->scroll_y());
+ EXPECT_EQ(-19, delegate->scroll_y());
- delegate->Reset();
- TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(140, 215), 0);
- RootWindow::GetInstance()->DispatchTouchEvent(&move2);
+ SendScrollEvent(140, 215, delegate.get());
EXPECT_FALSE(delegate->tap());
EXPECT_FALSE(delegate->tap_down());
EXPECT_FALSE(delegate->double_tap());
@@ -313,6 +341,82 @@ TEST_F(GestureRecognizerTest, GestureEventScroll) {
EXPECT_TRUE(delegate->scroll_end());
}
+// Check that horizontal scroll gestures cause scrolls on horizontal rails.
+// Also tests that horizontal rails can be broken.
+TEST_F(GestureRecognizerTest, GestureEventHorizontalRailScroll) {
+ scoped_ptr<GestureEventConsumeDelegate> delegate(
+ new GestureEventConsumeDelegate());
+ gfx::Rect bounds(0, 0, 1000, 1000);
+ scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
+ delegate.get(), -1234, bounds, NULL));
+
+ TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), 0);
+ RootWindow::GetInstance()->DispatchTouchEvent(&press);
+
+ // Move the touch-point horizontally enough that it is considered a
+ // horizontal scroll.
+ SendScrollEvent(20, 1, delegate.get());
+ EXPECT_EQ(0, delegate->scroll_y());
+ EXPECT_EQ(20, delegate->scroll_x());
+
+ SendScrollEvent(25, 6, delegate.get());
+ EXPECT_TRUE(delegate->scroll_update());
+ EXPECT_EQ(5, delegate->scroll_x());
+ // y shouldn't change, as we're on a horizontal rail.
+ EXPECT_EQ(0, delegate->scroll_y());
+
+ // Send enough information that a velocity can be calculated for the gesture,
+ // and we can break the rail
+ SendScrollEvents(1, 1, press.time_stamp(),
+ 1, 100, 1, kBufferedPoints, delegate.get());
+
+ SendScrollEvent(0, 0, delegate.get());
+ SendScrollEvent(5, 5, delegate.get());
+
+ // The rail should be broken
+ EXPECT_TRUE(delegate->scroll_update());
+ EXPECT_EQ(5, delegate->scroll_x());
+ EXPECT_EQ(5, delegate->scroll_y());
+}
+
+// Check that vertical scroll gestures cause scrolls on vertical rails.
+// Also tests that vertical rails can be broken.
+TEST_F(GestureRecognizerTest, GestureEventVerticalRailScroll) {
+ scoped_ptr<GestureEventConsumeDelegate> delegate(
+ new GestureEventConsumeDelegate());
+ gfx::Rect bounds(0, 0, 1000, 1000);
+ scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
+ delegate.get(), -1234, bounds, NULL));
+
+ TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), 0);
+ RootWindow::GetInstance()->DispatchTouchEvent(&press);
+
+ // Move the touch-point vertically enough that it is considered a
+ // vertical scroll.
+ SendScrollEvent(1, 20, delegate.get());
+ EXPECT_EQ(0, delegate->scroll_x());
+ EXPECT_EQ(20, delegate->scroll_y());
+
+ SendScrollEvent(6, 25, delegate.get());
+ EXPECT_TRUE(delegate->scroll_update());
+ EXPECT_EQ(5, delegate->scroll_y());
+ // x shouldn't change, as we're on a vertical rail.
+ EXPECT_EQ(0, delegate->scroll_x());
+
+ // Send enough information that a velocity can be calculated for the gesture,
+ // and we can break the rail
+ SendScrollEvents(1, 1, press.time_stamp(),
+ 100, 1, 1, kBufferedPoints, delegate.get());
+
+ SendScrollEvent(0, 0, delegate.get());
+ SendScrollEvent(5, 5, delegate.get());
+
+ // The rail should be broken
+ EXPECT_TRUE(delegate->scroll_update());
+ EXPECT_EQ(5, delegate->scroll_x());
+ EXPECT_EQ(5, delegate->scroll_y());
+}
+
TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) {
// First, tap. Then, do a scroll using the same touch-id.
scoped_ptr<GestureEventConsumeDelegate> delegate(
@@ -365,8 +469,10 @@ TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) {
// Move the touch-point enough so that it is considered as a scroll. This
// should generate both SCROLL_BEGIN and SCROLL_UPDATE gestures.
+ // The first movement is diagonal, to ensure that we have a free scroll,
+ // and not a rail scroll.
delegate->Reset();
- TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(130, 201), 0);
+ TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(130, 230), 0);
RootWindow::GetInstance()->DispatchTouchEvent(&move);
EXPECT_FALSE(delegate->tap());
EXPECT_FALSE(delegate->tap_down());
@@ -375,7 +481,7 @@ TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) {
EXPECT_TRUE(delegate->scroll_update());
EXPECT_FALSE(delegate->scroll_end());
EXPECT_EQ(29, delegate->scroll_x());
- EXPECT_EQ(0, delegate->scroll_y());
+ EXPECT_EQ(29, delegate->scroll_y());
// Move some more to generate a few more scroll updates.
delegate->Reset();
@@ -388,7 +494,7 @@ TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) {
EXPECT_TRUE(delegate->scroll_update());
EXPECT_FALSE(delegate->scroll_end());
EXPECT_EQ(-20, delegate->scroll_x());
- EXPECT_EQ(10, delegate->scroll_y());
+ EXPECT_EQ(-19, delegate->scroll_y());
delegate->Reset();
TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(140, 215), 0);
diff --git a/ui/aura/gestures/gesture_sequence.cc b/ui/aura/gestures/gesture_sequence.cc
index a4a834d..f946b25 100644
--- a/ui/aura/gestures/gesture_sequence.cc
+++ b/ui/aura/gestures/gesture_sequence.cc
@@ -62,10 +62,10 @@ TouchState TouchEventTypeToTouchState(ui::EventType type) {
//
// Note: New addition of types should be placed as per their Signature value.
#define G(gesture_state, id, touch_state, handled) 1 + ( \
- (((touch_state) & 0x7) << 1) | \
- ((handled) ? (1 << 4) : 0) | \
- (((id) & 0xfff) << 5) | \
- ((gesture_state) << 17))
+ (((touch_state) & 0x7) << 1) | \
+ ((handled) ? (1 << 4) : 0) | \
+ (((id) & 0xfff) << 5) | \
+ ((gesture_state) << 17))
enum EdgeStateSignatureType {
GST_NO_GESTURE_FIRST_PRESSED =
@@ -83,6 +83,9 @@ enum EdgeStateSignatureType {
GST_PENDING_SYNTHETIC_CLICK_FIRST_CANCELLED =
G(GS_PENDING_SYNTHETIC_CLICK, 0, TS_CANCELLED, false),
+ GST_PENDING_SYNTHETIC_CLICK_SECOND_PRESSED =
+ G(GS_PENDING_SYNTHETIC_CLICK, 1, TS_PRESSED, false),
+
GST_SCROLL_FIRST_RELEASED =
G(GS_SCROLL, 0, TS_RELEASED, false),
@@ -92,6 +95,9 @@ 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),
@@ -101,12 +107,6 @@ enum EdgeStateSignatureType {
GST_SCROLL_SECOND_CANCELLED =
G(GS_SCROLL, 1, TS_CANCELLED, false),
- GST_PENDING_SYNTHETIC_CLICK_SECOND_PRESSED =
- G(GS_PENDING_SYNTHETIC_CLICK, 1, TS_PRESSED, false),
-
- GST_SCROLL_FIRST_PRESSED =
- G(GS_SCROLL, 0, TS_PRESSED, false),
-
GST_SCROLL_SECOND_PRESSED =
G(GS_SCROLL, 1, TS_PRESSED, false),
@@ -179,6 +179,8 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture(
++point_count_;
}
+ GestureState last_state = state_;
+
scoped_ptr<Gestures> gestures(new Gestures());
GesturePoint& point = GesturePointForEvent(event);
point.UpdateValues(event);
@@ -195,9 +197,10 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture(
break;
case GST_PENDING_SYNTHETIC_CLICK_FIRST_MOVED:
case GST_PENDING_SYNTHETIC_CLICK_FIRST_STATIONARY:
- if (InClickOrScroll(event, point, gestures.get())) {
- point.UpdateForScroll();
+ if (ScrollStart(event, point, gestures.get())) {
set_state(GS_SCROLL);
+ if (ScrollUpdate(event, point, gestures.get()))
+ point.UpdateForScroll();
}
break;
case GST_PENDING_SYNTHETIC_CLICK_FIRST_CANCELLED:
@@ -205,7 +208,10 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture(
break;
case GST_SCROLL_FIRST_MOVED:
case GST_SCROLL_SECOND_MOVED:
- if (InScroll(event, point, gestures.get()))
+ if (scroll_type_ == ST_VERTICAL ||
+ scroll_type_ == ST_HORIZONTAL)
+ BreakRailScroll(event, point, gestures.get());
+ if (ScrollUpdate(event, point, gestures.get()))
point.UpdateForScroll();
break;
case GST_SCROLL_FIRST_RELEASED:
@@ -215,10 +221,9 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture(
ScrollEnd(event, point, gestures.get());
set_state(GS_NO_GESTURE);
break;
-
- case GST_PENDING_SYNTHETIC_CLICK_SECOND_PRESSED:
case GST_SCROLL_FIRST_PRESSED:
case GST_SCROLL_SECOND_PRESSED:
+ case GST_PENDING_SYNTHETIC_CLICK_SECOND_PRESSED:
PinchStart(event, point, gestures.get());
set_state(GS_PINCH);
break;
@@ -237,10 +242,16 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture(
// Once pinch ends, it should still be possible to scroll with the
// remaining finger on the screen.
+ scroll_type_ = ST_FREE;
set_state(GS_SCROLL);
break;
}
+ if (state_ != last_state)
+ VLOG(4) << "Gesture Sequence"
+ << " State: " << state_
+ << " touch id: " << event.touch_id();
+
if (event.type() == ui::ET_TOUCH_RELEASED)
--point_count_;
@@ -323,13 +334,21 @@ void GestureSequence::AppendScrollGestureEnd(const GesturePoint& point,
void GestureSequence::AppendScrollGestureUpdate(const GesturePoint& point,
const gfx::Point& location,
Gestures* gestures) {
+ int dx = point.x_delta();
+ int dy = point.y_delta();
+
+ if (scroll_type_ == ST_HORIZONTAL)
+ dy = 0;
+ else if (scroll_type_ == ST_VERTICAL)
+ dx = 0;
+
gestures->push_back(linked_ptr<GestureEvent>(new GestureEvent(
ui::ET_GESTURE_SCROLL_UPDATE,
location.x(),
location.y(),
flags_,
base::Time::FromDoubleT(point.last_touch_time()),
- point.x_delta(), point.y_delta())));
+ dx, dy)));
}
void GestureSequence::AppendPinchGestureBegin(const GesturePoint& p1,
@@ -377,6 +396,7 @@ void GestureSequence::AppendPinchGestureUpdate(const GesturePoint& p1,
bool GestureSequence::Click(const TouchEvent& event,
const GesturePoint& point, Gestures* gestures) {
+ DCHECK(state_ == GS_PENDING_SYNTHETIC_CLICK);
if (point.IsInClickWindow(event)) {
AppendClickGestureEvent(point, gestures);
if (point.IsInDoubleClickWindow(event))
@@ -386,18 +406,37 @@ bool GestureSequence::Click(const TouchEvent& event,
return false;
}
-bool GestureSequence::InClickOrScroll(const TouchEvent& event,
- const GesturePoint& point, Gestures* gestures) {
- if (point.IsInScrollWindow(event)) {
- AppendScrollGestureBegin(point, point.last_touch_position(), gestures);
- AppendScrollGestureUpdate(point, point.last_touch_position(), gestures);
- return true;
- }
- return false;
+bool GestureSequence::ScrollStart(const TouchEvent& event,
+ GesturePoint& point, Gestures* gestures) {
+ DCHECK(state_ == GS_PENDING_SYNTHETIC_CLICK);
+ if (point.IsInClickWindow(event) ||
+ !point.IsInScrollWindow(event) ||
+ !point.HasEnoughDataToEstablishRail())
+ return false;
+ AppendScrollGestureBegin(point, point.last_touch_position(), gestures);
+ if (point.IsInHorizontalRailWindow())
+ scroll_type_ = ST_HORIZONTAL;
+ else if (point.IsInVerticalRailWindow())
+ scroll_type_ = ST_VERTICAL;
+ else
+ scroll_type_ = ST_FREE;
+ return true;
+}
+
+void GestureSequence::BreakRailScroll(const TouchEvent& event,
+ GesturePoint& point, Gestures* gestures) {
+ DCHECK(state_ == GS_SCROLL);
+ if (scroll_type_ == ST_HORIZONTAL &&
+ point.BreaksHorizontalRail())
+ scroll_type_ = ST_FREE;
+ else if (scroll_type_ == ST_VERTICAL &&
+ point.BreaksVerticalRail())
+ scroll_type_ = ST_FREE;
}
-bool GestureSequence::InScroll(const TouchEvent& event,
+bool GestureSequence::ScrollUpdate(const TouchEvent& event,
const GesturePoint& point, Gestures* gestures) {
+ DCHECK(state_ == GS_SCROLL);
if (!point.DidScroll(event, 0))
return false;
AppendScrollGestureUpdate(point, point.last_touch_position(), gestures);
@@ -412,12 +451,14 @@ bool GestureSequence::NoGesture(const TouchEvent&,
bool GestureSequence::TouchDown(const TouchEvent& event,
const GesturePoint& point, Gestures* gestures) {
+ DCHECK(state_ == GS_NO_GESTURE);
AppendTapDownGestureEvent(point, gestures);
return true;
}
bool GestureSequence::ScrollEnd(const TouchEvent& event,
GesturePoint& point, Gestures* gestures) {
+ DCHECK(state_ == GS_SCROLL);
if (point.IsInFlickWindow(event)) {
AppendScrollGestureEnd(point, point.last_touch_position(), gestures,
point.XVelocity(), point.YVelocity());
@@ -430,6 +471,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);
AppendTapDownGestureEvent(point, gestures);
pinch_distance_current_ = points_[0].Distance(points_[1]);
@@ -447,6 +490,7 @@ 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]);
if (abs(distance - pinch_distance_current_) < kMinimumPinchUpdateDistance) {
// The fingers didn't move towards each other, or away from each other,
@@ -469,6 +513,7 @@ 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],
distance / pinch_distance_start_, gestures);
diff --git a/ui/aura/gestures/gesture_sequence.h b/ui/aura/gestures/gesture_sequence.h
index b1d926e..cef29e4 100644
--- a/ui/aura/gestures/gesture_sequence.h
+++ b/ui/aura/gestures/gesture_sequence.h
@@ -19,7 +19,13 @@ enum GestureState {
GS_NO_GESTURE,
GS_PENDING_SYNTHETIC_CLICK,
GS_SCROLL,
- GS_PINCH,
+ GS_PINCH
+};
+
+enum ScrollType {
+ ST_FREE,
+ ST_HORIZONTAL,
+ ST_VERTICAL,
};
// A GestureSequence recognizes gestures from touch sequences.
@@ -83,12 +89,15 @@ class GestureSequence {
bool Click(const TouchEvent& event,
const GesturePoint& point,
Gestures* gestures);
- bool InClickOrScroll(const TouchEvent& event,
- const GesturePoint& point,
- Gestures* gestures);
- bool InScroll(const TouchEvent& event,
- const GesturePoint& point,
- Gestures* gestures);
+ bool ScrollStart(const TouchEvent& event,
+ GesturePoint& point,
+ Gestures* gestures);
+ void BreakRailScroll(const TouchEvent& event,
+ GesturePoint& point,
+ Gestures* gestures);
+ bool ScrollUpdate(const TouchEvent& event,
+ const GesturePoint& point,
+ Gestures* gestures);
bool NoGesture(const TouchEvent& event,
const GesturePoint& point,
Gestures* gestures);
@@ -120,6 +129,8 @@ class GestureSequence {
// This distance is updated after each PINCH_UPDATE.
float pinch_distance_current_;
+ ScrollType scroll_type_;
+
// Maximum points in a single gesture.
static const int kMaxGesturePoints = 12;