Commit fc449a93 authored by tdresser@chromium.org's avatar tdresser@chromium.org

Support tap_count in ui::GestureProvider.

BUG=357270
TEST=GestureProviderTest.AuraTripleTap

Review URL: https://codereview.chromium.org/289373009

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@272310 0039d316-1c4b-4281-b951-d872f2087c98
parent 184002e4
...@@ -3366,11 +3366,6 @@ TEST_P(GestureRecognizerTest, GestureEventScrollTouchMovePartialConsumed) { ...@@ -3366,11 +3366,6 @@ TEST_P(GestureRecognizerTest, GestureEventScrollTouchMovePartialConsumed) {
// Check that appropriate touch events generate double tap gesture events. // Check that appropriate touch events generate double tap gesture events.
TEST_P(GestureRecognizerTest, GestureEventDoubleTap) { TEST_P(GestureRecognizerTest, GestureEventDoubleTap) {
// TODO(tdresser): enable this test with unified GR once double / triple tap
// gestures work. See crbug.com/357270.
if (UsingUnifiedGR())
return;
scoped_ptr<GestureEventConsumeDelegate> delegate( scoped_ptr<GestureEventConsumeDelegate> delegate(
new GestureEventConsumeDelegate()); new GestureEventConsumeDelegate());
const int kWindowWidth = 123; const int kWindowWidth = 123;
...@@ -3412,11 +3407,6 @@ TEST_P(GestureRecognizerTest, GestureEventDoubleTap) { ...@@ -3412,11 +3407,6 @@ TEST_P(GestureRecognizerTest, GestureEventDoubleTap) {
// Check that appropriate touch events generate triple tap gesture events. // Check that appropriate touch events generate triple tap gesture events.
TEST_P(GestureRecognizerTest, GestureEventTripleTap) { TEST_P(GestureRecognizerTest, GestureEventTripleTap) {
// TODO(tdresser): enable this test with unified GR once double / triple tap
// gestures work. See crbug.com/357270.
if (UsingUnifiedGR())
return;
scoped_ptr<GestureEventConsumeDelegate> delegate( scoped_ptr<GestureEventConsumeDelegate> delegate(
new GestureEventConsumeDelegate()); new GestureEventConsumeDelegate());
const int kWindowWidth = 123; const int kWindowWidth = 123;
...@@ -3457,17 +3447,35 @@ TEST_P(GestureRecognizerTest, GestureEventTripleTap) { ...@@ -3457,17 +3447,35 @@ TEST_P(GestureRecognizerTest, GestureEventTripleTap) {
kTouchId, tes.LeapForward(50)); kTouchId, tes.LeapForward(50));
DispatchEventUsingWindowDispatcher(&release3); DispatchEventUsingWindowDispatcher(&release3);
// Third, Fourth and Fifth Taps. Taps after the third should have their
// |tap_count| wrap around back to 1.
for (int i = 3; i < 5; ++i) {
ui::TouchEvent press3(ui::ET_TOUCH_PRESSED,
gfx::Point(102, 206),
kTouchId,
tes.LeapForward(200));
DispatchEventUsingWindowDispatcher(&press3);
ui::TouchEvent release3(ui::ET_TOUCH_RELEASED,
gfx::Point(102, 206),
kTouchId,
tes.LeapForward(50));
DispatchEventUsingWindowDispatcher(&release3);
EXPECT_TRUE(delegate->tap());
EXPECT_TRUE(delegate->tap_down());
EXPECT_FALSE(delegate->tap_cancel());
EXPECT_TRUE(delegate->begin());
EXPECT_TRUE(delegate->end());
EXPECT_FALSE(delegate->scroll_begin());
EXPECT_FALSE(delegate->scroll_update());
EXPECT_FALSE(delegate->scroll_end());
EXPECT_TRUE(delegate->tap()); // The behavior for the Aura GR is incorrect.
EXPECT_TRUE(delegate->tap_down()); if (UsingUnifiedGR())
EXPECT_FALSE(delegate->tap_cancel()); EXPECT_EQ(1 + (i % 3), delegate->tap_count());
EXPECT_TRUE(delegate->begin()); else
EXPECT_TRUE(delegate->end()); EXPECT_EQ(3, delegate->tap_count());
EXPECT_FALSE(delegate->scroll_begin()); }
EXPECT_FALSE(delegate->scroll_update());
EXPECT_FALSE(delegate->scroll_end());
EXPECT_EQ(3, delegate->tap_count());
} }
// Check that we don't get a double tap when the two taps are far apart. // Check that we don't get a double tap when the two taps are far apart.
...@@ -4267,8 +4275,6 @@ TEST_P(GestureRecognizerTest, GestureEventFlagsPassedFromTouchEvent) { ...@@ -4267,8 +4275,6 @@ TEST_P(GestureRecognizerTest, GestureEventFlagsPassedFromTouchEvent) {
EXPECT_NE(default_flags, delegate->flags()); EXPECT_NE(default_flags, delegate->flags());
} }
// TODO - re-enable these tests once memory management issues have been sorted
// out. See crbug.com/371990.
INSTANTIATE_TEST_CASE_P(GestureRecognizer, INSTANTIATE_TEST_CASE_P(GestureRecognizer,
GestureRecognizerTest, GestureRecognizerTest,
::testing::Bool()); ::testing::Bool());
......
...@@ -187,9 +187,9 @@ GestureDetector::GestureDetector( ...@@ -187,9 +187,9 @@ GestureDetector::GestureDetector(
last_focus_y_(0), last_focus_y_(0),
down_focus_x_(0), down_focus_x_(0),
down_focus_y_(0), down_focus_y_(0),
longpress_enabled_(true), longpress_enabled_(true),
swipe_enabled_(false), swipe_enabled_(false),
two_finger_tap_enabled_(false) { two_finger_tap_enabled_(false) {
DCHECK(listener_); DCHECK(listener_);
Init(config); Init(config);
} }
...@@ -519,14 +519,9 @@ void GestureDetector::OnTapTimeout() { ...@@ -519,14 +519,9 @@ void GestureDetector::OnTapTimeout() {
} }
void GestureDetector::Cancel() { void GestureDetector::Cancel() {
timeout_handler_->Stop(); CancelTaps();
velocity_tracker_.Clear(); velocity_tracker_.Clear();
is_double_tapping_ = false;
still_down_ = false; still_down_ = false;
always_in_tap_region_ = false;
always_in_bigger_tap_region_ = false;
defer_confirm_single_tap_ = false;
in_longpress_ = false;
} }
void GestureDetector::CancelTaps() { void GestureDetector::CancelTaps() {
......
...@@ -35,79 +35,86 @@ struct EVENTS_BASE_EXPORT GestureEventDetails { ...@@ -35,79 +35,86 @@ struct EVENTS_BASE_EXPORT GestureEventDetails {
void set_bounding_box(const gfx::RectF& box) { bounding_box_ = box; } void set_bounding_box(const gfx::RectF& box) { bounding_box_ = box; }
float scroll_x_hint() const { float scroll_x_hint() const {
DCHECK_EQ(ui::ET_GESTURE_SCROLL_BEGIN, type_); DCHECK_EQ(ET_GESTURE_SCROLL_BEGIN, type_);
return data.scroll_begin.x_hint; return data.scroll_begin.x_hint;
} }
float scroll_y_hint() const { float scroll_y_hint() const {
DCHECK_EQ(ui::ET_GESTURE_SCROLL_BEGIN, type_); DCHECK_EQ(ET_GESTURE_SCROLL_BEGIN, type_);
return data.scroll_begin.y_hint; return data.scroll_begin.y_hint;
} }
float scroll_x() const { float scroll_x() const {
DCHECK_EQ(ui::ET_GESTURE_SCROLL_UPDATE, type_); DCHECK_EQ(ET_GESTURE_SCROLL_UPDATE, type_);
return data.scroll_update.x; return data.scroll_update.x;
} }
float scroll_y() const { float scroll_y() const {
DCHECK_EQ(ui::ET_GESTURE_SCROLL_UPDATE, type_); DCHECK_EQ(ET_GESTURE_SCROLL_UPDATE, type_);
return data.scroll_update.y; return data.scroll_update.y;
} }
float velocity_x() const { float velocity_x() const {
DCHECK(type_ == ui::ET_SCROLL_FLING_START); DCHECK_EQ(ET_SCROLL_FLING_START, type_);
return data.fling_velocity.x; return data.fling_velocity.x;
} }
float velocity_y() const { float velocity_y() const {
DCHECK(type_ == ui::ET_SCROLL_FLING_START); DCHECK_EQ(ET_SCROLL_FLING_START, type_);
return data.fling_velocity.y; return data.fling_velocity.y;
} }
float first_finger_width() const { float first_finger_width() const {
DCHECK_EQ(ui::ET_GESTURE_TWO_FINGER_TAP, type_); DCHECK_EQ(ET_GESTURE_TWO_FINGER_TAP, type_);
return data.first_finger_enclosing_rectangle.width; return data.first_finger_enclosing_rectangle.width;
} }
float first_finger_height() const { float first_finger_height() const {
DCHECK_EQ(ui::ET_GESTURE_TWO_FINGER_TAP, type_); DCHECK_EQ(ET_GESTURE_TWO_FINGER_TAP, type_);
return data.first_finger_enclosing_rectangle.height; return data.first_finger_enclosing_rectangle.height;
} }
float scale() const { float scale() const {
DCHECK_EQ(ui::ET_GESTURE_PINCH_UPDATE, type_); DCHECK_EQ(ET_GESTURE_PINCH_UPDATE, type_);
return data.scale; return data.scale;
} }
bool swipe_left() const { bool swipe_left() const {
DCHECK_EQ(ui::ET_GESTURE_MULTIFINGER_SWIPE, type_); DCHECK_EQ(ET_GESTURE_MULTIFINGER_SWIPE, type_);
return data.swipe.left; return data.swipe.left;
} }
bool swipe_right() const { bool swipe_right() const {
DCHECK_EQ(ui::ET_GESTURE_MULTIFINGER_SWIPE, type_); DCHECK_EQ(ET_GESTURE_MULTIFINGER_SWIPE, type_);
return data.swipe.right; return data.swipe.right;
} }
bool swipe_up() const { bool swipe_up() const {
DCHECK_EQ(ui::ET_GESTURE_MULTIFINGER_SWIPE, type_); DCHECK_EQ(ET_GESTURE_MULTIFINGER_SWIPE, type_);
return data.swipe.up; return data.swipe.up;
} }
bool swipe_down() const { bool swipe_down() const {
DCHECK_EQ(ui::ET_GESTURE_MULTIFINGER_SWIPE, type_); DCHECK_EQ(ET_GESTURE_MULTIFINGER_SWIPE, type_);
return data.swipe.down; return data.swipe.down;
} }
int tap_count() const { int tap_count() const {
DCHECK(type_ == ui::ET_GESTURE_TAP || DCHECK(type_ == ET_GESTURE_TAP ||
type_ == ui::ET_GESTURE_TAP_UNCONFIRMED || type_ == ET_GESTURE_TAP_UNCONFIRMED ||
type_ == ET_GESTURE_DOUBLE_TAP); type_ == ET_GESTURE_DOUBLE_TAP);
return data.tap_count; return data.tap_count;
} }
void set_tap_count(int tap_count) {
DCHECK(type_ == ET_GESTURE_TAP ||
type_ == ET_GESTURE_TAP_UNCONFIRMED ||
type_ == ET_GESTURE_DOUBLE_TAP);
data.tap_count = tap_count;
}
private: private:
ui::EventType type_; EventType type_;
union Details { union Details {
Details(); Details();
struct { // SCROLL start details. struct { // SCROLL start details.
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "ui/events/event.h" #include "ui/events/event.h"
#include "ui/events/gesture_detection/gesture_config_helper.h" #include "ui/events/gesture_detection/gesture_config_helper.h"
#include "ui/events/gesture_detection/gesture_event_data.h" #include "ui/events/gesture_detection/gesture_event_data.h"
#include "ui/events/gestures/gesture_configuration.h"
namespace ui { namespace ui {
...@@ -40,6 +41,7 @@ bool GestureProviderAura::OnTouchEvent(const TouchEvent& event) { ...@@ -40,6 +41,7 @@ bool GestureProviderAura::OnTouchEvent(const TouchEvent& event) {
} }
pointer_state_.OnTouch(event); pointer_state_.OnTouch(event);
bool result = filtered_gesture_provider_.OnTouchEvent(pointer_state_); bool result = filtered_gesture_provider_.OnTouchEvent(pointer_state_);
pointer_state_.CleanupRemovedTouchPoints(event); pointer_state_.CleanupRemovedTouchPoints(event);
return result; return result;
...@@ -51,12 +53,28 @@ void GestureProviderAura::OnTouchEventAck(bool event_consumed) { ...@@ -51,12 +53,28 @@ void GestureProviderAura::OnTouchEventAck(bool event_consumed) {
void GestureProviderAura::OnGestureEvent( void GestureProviderAura::OnGestureEvent(
const GestureEventData& gesture) { const GestureEventData& gesture) {
GestureEventDetails details = gesture.details;
if (gesture.type == ET_GESTURE_TAP) {
int tap_count = 1;
if (previous_tap_ && IsConsideredDoubleTap(*previous_tap_, gesture))
tap_count = 1 + (previous_tap_->details.tap_count() % 3);
details.set_tap_count(tap_count);
if (!previous_tap_)
previous_tap_.reset(new GestureEventData(gesture));
else
*previous_tap_ = gesture;
previous_tap_->details = details;
} else if (gesture.type == ET_GESTURE_TAP_CANCEL) {
previous_tap_.reset();
}
ui::GestureEvent event(gesture.type, ui::GestureEvent event(gesture.type,
gesture.x, gesture.x,
gesture.y, gesture.y,
last_touch_event_flags_, last_touch_event_flags_,
gesture.time - base::TimeTicks(), gesture.time - base::TimeTicks(),
gesture.details, details,
// ui::GestureEvent stores a bitfield indicating the // ui::GestureEvent stores a bitfield indicating the
// ids of active touch points. This is currently only // ids of active touch points. This is currently only
// used when one finger is down, and will eventually // used when one finger is down, and will eventually
...@@ -65,4 +83,22 @@ void GestureProviderAura::OnGestureEvent( ...@@ -65,4 +83,22 @@ void GestureProviderAura::OnGestureEvent(
client_->OnGestureEvent(&event); client_->OnGestureEvent(&event);
} }
bool GestureProviderAura::IsConsideredDoubleTap(
const GestureEventData& previous_tap,
const GestureEventData& current_tap) const {
if (current_tap.time - previous_tap.time >
base::TimeDelta::FromMilliseconds(
ui::GestureConfiguration::max_seconds_between_double_click() *
1000)) {
return false;
}
double double_tap_slop_square =
GestureConfiguration::max_distance_between_taps_for_double_tap();
double_tap_slop_square *= double_tap_slop_square;
const float delta_x = previous_tap.x - current_tap.x;
const float delta_y = previous_tap.y - current_tap.y;
return (delta_x * delta_x + delta_y * delta_y < double_tap_slop_square);
}
} // namespace content } // namespace content
...@@ -36,6 +36,11 @@ class EVENTS_EXPORT GestureProviderAura : public GestureProviderClient { ...@@ -36,6 +36,11 @@ class EVENTS_EXPORT GestureProviderAura : public GestureProviderClient {
virtual void OnGestureEvent(const GestureEventData& gesture) OVERRIDE; virtual void OnGestureEvent(const GestureEventData& gesture) OVERRIDE;
private: private:
bool IsConsideredDoubleTap(const GestureEventData& previous_tap,
const GestureEventData& current_tap) const;
scoped_ptr<GestureEventData> previous_tap_;
GestureProviderAuraClient* client_; GestureProviderAuraClient* client_;
MotionEventAura pointer_state_; MotionEventAura pointer_state_;
FilteredGestureProvider filtered_gesture_provider_; FilteredGestureProvider filtered_gesture_provider_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment