Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1147)

Unified Diff: ui/events/gesture_detection/gesture_detector.cc

Issue 243403002: Add multi-finger swipe detection to GestureDetector (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix M_PI Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/events/gesture_detection/gesture_detector.h ('k') | ui/events/gesture_detection/gesture_provider.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/events/gesture_detection/gesture_detector.cc
diff --git a/ui/events/gesture_detection/gesture_detector.cc b/ui/events/gesture_detection/gesture_detector.cc
index e086ef0745d6bcb6c6d30685bed1aca8bbf27402..bf049d9591fc19c16385a8eb1c0647822bf9b88b 100644
--- a/ui/events/gesture_detection/gesture_detector.cc
+++ b/ui/events/gesture_detection/gesture_detector.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// MSVC++ requires this to be set before any other includes to get M_PI.
+#define _USE_MATH_DEFINES
+
#include "ui/events/gesture_detection/gesture_detector.h"
#include <cmath>
@@ -21,6 +24,8 @@ const float kSlopEpsilon = .05f;
// to trigger an |OnScroll| callback.
const float kScrollEpsilon = .1f;
+const float kDegreesToRadians = static_cast<float>(M_PI) / 180.0f;
+
// Constants used by TimeoutGestureHandler.
enum TimeoutEvent {
SHOW_PRESS = 0,
@@ -40,7 +45,11 @@ GestureDetector::Config::Config()
touch_slop(8),
double_tap_slop(100),
minimum_fling_velocity(50),
- maximum_fling_velocity(8000) {}
+ maximum_fling_velocity(8000),
+ swipe_enabled(false),
+ minimum_swipe_velocity(20),
+ maximum_swipe_deviation_angle(20.f) {
+}
GestureDetector::Config::~Config() {}
@@ -74,6 +83,13 @@ bool GestureDetector::SimpleGestureListener::OnFling(const MotionEvent& e1,
return false;
}
+bool GestureDetector::SimpleGestureListener::OnSwipe(const MotionEvent& e1,
+ const MotionEvent& e2,
+ float velocity_x,
+ float velocity_y) {
+ return false;
+}
+
bool GestureDetector::SimpleGestureListener::OnSingleTapConfirmed(
const MotionEvent& e) {
return false;
@@ -158,7 +174,7 @@ GestureDetector::GestureDetector(
last_focus_y_(0),
down_focus_x_(0),
down_focus_y_(0),
- is_longpress_enabled_(true) {
+ longpress_enabled_(true) {
DCHECK(listener_);
Init(config);
}
@@ -206,21 +222,50 @@ bool GestureDetector::OnTouchEvent(const MotionEvent& ev) {
{
const int up_index = ev.GetActionIndex();
const int id1 = ev.GetPointerId(up_index);
- const float x1 = velocity_tracker_.GetXVelocity(id1);
- const float y1 = velocity_tracker_.GetYVelocity(id1);
+ const float vx1 = velocity_tracker_.GetXVelocity(id1);
+ const float vy1 = velocity_tracker_.GetYVelocity(id1);
+ float vx_total = vx1;
+ float vy_total = vy1;
for (int i = 0; i < count; i++) {
if (i == up_index)
continue;
const int id2 = ev.GetPointerId(i);
- const float x = x1 * velocity_tracker_.GetXVelocity(id2);
- const float y = y1 * velocity_tracker_.GetYVelocity(id2);
-
- const float dot = x + y;
+ const float vx2 = velocity_tracker_.GetXVelocity(id2);
+ const float vy2 = velocity_tracker_.GetYVelocity(id2);
+ const float dot = vx1 * vx2 + vy1 * vy2;
if (dot < 0) {
+ vx_total = 0;
+ vy_total = 0;
velocity_tracker_.Clear();
break;
}
+ vx_total += vx2;
+ vy_total += vy2;
+ }
+
+ if (swipe_enabled_ && (vx_total || vy_total)) {
+ float vx = vx_total / count;
+ float vy = vy_total / count;
+ float vx_abs = std::abs(vx);
+ float vy_abs = std::abs(vy);
+
+ if (vx_abs < min_swipe_velocity_)
+ vx_abs = vx = 0;
+ if (vy_abs < min_swipe_velocity_)
+ vy_abs = vy = 0;
+
+ // Note that the ratio will be 0 if both velocites are below the min.
+ float ratio = vx_abs > vy_abs ? vx_abs / std::max(vy_abs, 0.001f)
+ : vy_abs / std::max(vx_abs, 0.001f);
+ if (ratio > min_swipe_direction_component_ratio_) {
+ if (vx_abs > vy_abs)
+ vy = 0;
+ else
+ vx = 0;
+
+ handled = listener_->OnSwipe(*current_down_event_, ev, vx, vy);
+ }
}
}
break;
@@ -259,7 +304,7 @@ bool GestureDetector::OnTouchEvent(const MotionEvent& ev) {
// Always start the SHOW_PRESS timer before the LONG_PRESS timer to ensure
// proper timeout ordering.
timeout_handler_->StartTimeout(SHOW_PRESS);
- if (is_longpress_enabled_)
+ if (longpress_enabled_)
timeout_handler_->StartTimeout(LONG_PRESS);
handled |= listener_->OnDown(ev);
break;
@@ -377,6 +422,15 @@ void GestureDetector::Init(const Config& config) {
double_tap_timeout_ = config.double_tap_timeout;
min_fling_velocity_ = config.minimum_fling_velocity;
max_fling_velocity_ = config.maximum_fling_velocity;
+
+ swipe_enabled_ = config.swipe_enabled;
+ min_swipe_velocity_ = config.minimum_swipe_velocity;
+ DCHECK_GT(config.maximum_swipe_deviation_angle, 0);
+ DCHECK_LE(config.maximum_swipe_deviation_angle, 45);
+ const float maximum_swipe_deviation_angle =
+ std::min(45.f, std::max(0.001f, config.maximum_swipe_deviation_angle));
+ min_swipe_direction_component_ratio_ =
+ 1.f / tan(maximum_swipe_deviation_angle * kDegreesToRadians);
}
void GestureDetector::OnShowPressTimeout() {
« no previous file with comments | « ui/events/gesture_detection/gesture_detector.h ('k') | ui/events/gesture_detection/gesture_provider.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698