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) {
// Check that appropriate touch events generate double tap gesture events.
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(
new GestureEventConsumeDelegate());
const int kWindowWidth = 123;
......@@ -3412,11 +3407,6 @@ TEST_P(GestureRecognizerTest, GestureEventDoubleTap) {
// Check that appropriate touch events generate triple tap gesture events.
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(
new GestureEventConsumeDelegate());
const int kWindowWidth = 123;
......@@ -3457,17 +3447,35 @@ TEST_P(GestureRecognizerTest, GestureEventTripleTap) {
kTouchId, tes.LeapForward(50));
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());
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_EQ(3, delegate->tap_count());
// The behavior for the Aura GR is incorrect.
if (UsingUnifiedGR())
EXPECT_EQ(1 + (i % 3), delegate->tap_count());
else
EXPECT_EQ(3, delegate->tap_count());
}
}
// Check that we don't get a double tap when the two taps are far apart.
......@@ -4267,8 +4275,6 @@ TEST_P(GestureRecognizerTest, GestureEventFlagsPassedFromTouchEvent) {
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,
GestureRecognizerTest,
::testing::Bool());
......
......@@ -187,9 +187,9 @@ GestureDetector::GestureDetector(
last_focus_y_(0),
down_focus_x_(0),
down_focus_y_(0),
longpress_enabled_(true),
swipe_enabled_(false),
two_finger_tap_enabled_(false) {
longpress_enabled_(true),
swipe_enabled_(false),
two_finger_tap_enabled_(false) {
DCHECK(listener_);
Init(config);
}
......@@ -519,14 +519,9 @@ void GestureDetector::OnTapTimeout() {
}
void GestureDetector::Cancel() {
timeout_handler_->Stop();
CancelTaps();
velocity_tracker_.Clear();
is_double_tapping_ = 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() {
......
......@@ -35,79 +35,86 @@ struct EVENTS_BASE_EXPORT GestureEventDetails {
void set_bounding_box(const gfx::RectF& box) { bounding_box_ = box; }
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;
}
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;
}
float scroll_x() const {
DCHECK_EQ(ui::ET_GESTURE_SCROLL_UPDATE, type_);
DCHECK_EQ(ET_GESTURE_SCROLL_UPDATE, type_);
return data.scroll_update.x;
}
float scroll_y() const {
DCHECK_EQ(ui::ET_GESTURE_SCROLL_UPDATE, type_);
DCHECK_EQ(ET_GESTURE_SCROLL_UPDATE, type_);
return data.scroll_update.y;
}
float velocity_x() const {
DCHECK(type_ == ui::ET_SCROLL_FLING_START);
DCHECK_EQ(ET_SCROLL_FLING_START, type_);
return data.fling_velocity.x;
}
float velocity_y() const {
DCHECK(type_ == ui::ET_SCROLL_FLING_START);
DCHECK_EQ(ET_SCROLL_FLING_START, type_);
return data.fling_velocity.y;
}
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;
}
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;
}
float scale() const {
DCHECK_EQ(ui::ET_GESTURE_PINCH_UPDATE, type_);
DCHECK_EQ(ET_GESTURE_PINCH_UPDATE, type_);
return data.scale;
}
bool swipe_left() const {
DCHECK_EQ(ui::ET_GESTURE_MULTIFINGER_SWIPE, type_);
DCHECK_EQ(ET_GESTURE_MULTIFINGER_SWIPE, type_);
return data.swipe.left;
}
bool swipe_right() const {
DCHECK_EQ(ui::ET_GESTURE_MULTIFINGER_SWIPE, type_);
DCHECK_EQ(ET_GESTURE_MULTIFINGER_SWIPE, type_);
return data.swipe.right;
}
bool swipe_up() const {
DCHECK_EQ(ui::ET_GESTURE_MULTIFINGER_SWIPE, type_);
DCHECK_EQ(ET_GESTURE_MULTIFINGER_SWIPE, type_);
return data.swipe.up;
}
bool swipe_down() const {
DCHECK_EQ(ui::ET_GESTURE_MULTIFINGER_SWIPE, type_);
DCHECK_EQ(ET_GESTURE_MULTIFINGER_SWIPE, type_);
return data.swipe.down;
}
int tap_count() const {
DCHECK(type_ == ui::ET_GESTURE_TAP ||
type_ == ui::ET_GESTURE_TAP_UNCONFIRMED ||
DCHECK(type_ == ET_GESTURE_TAP ||
type_ == ET_GESTURE_TAP_UNCONFIRMED ||
type_ == ET_GESTURE_DOUBLE_TAP);
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:
ui::EventType type_;
EventType type_;
union Details {
Details();
struct { // SCROLL start details.
......
......@@ -8,6 +8,7 @@
#include "ui/events/event.h"
#include "ui/events/gesture_detection/gesture_config_helper.h"
#include "ui/events/gesture_detection/gesture_event_data.h"
#include "ui/events/gestures/gesture_configuration.h"
namespace ui {
......@@ -40,6 +41,7 @@ bool GestureProviderAura::OnTouchEvent(const TouchEvent& event) {
}
pointer_state_.OnTouch(event);
bool result = filtered_gesture_provider_.OnTouchEvent(pointer_state_);
pointer_state_.CleanupRemovedTouchPoints(event);
return result;
......@@ -51,12 +53,28 @@ void GestureProviderAura::OnTouchEventAck(bool event_consumed) {
void GestureProviderAura::OnGestureEvent(
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,
gesture.x,
gesture.y,
last_touch_event_flags_,
gesture.time - base::TimeTicks(),
gesture.details,
details,
// ui::GestureEvent stores a bitfield indicating the
// ids of active touch points. This is currently only
// used when one finger is down, and will eventually
......@@ -65,4 +83,22 @@ void GestureProviderAura::OnGestureEvent(
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
......@@ -36,6 +36,11 @@ class EVENTS_EXPORT GestureProviderAura : public GestureProviderClient {
virtual void OnGestureEvent(const GestureEventData& gesture) OVERRIDE;
private:
bool IsConsideredDoubleTap(const GestureEventData& previous_tap,
const GestureEventData& current_tap) const;
scoped_ptr<GestureEventData> previous_tap_;
GestureProviderAuraClient* client_;
MotionEventAura pointer_state_;
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