// 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/gestures/gesture_sequence.h"
#include <stdlib.h>
TS_RELEASED,
TS_PRESSED,
TS_MOVED,
- TS_STATIONARY,
TS_CANCELLED,
TS_UNKNOWN,
};
return TS_PRESSED;
case ui::ET_TOUCH_MOVED:
return TS_MOVED;
- case ui::ET_TOUCH_STATIONARY:
- return TS_STATIONARY;
case ui::ET_TOUCH_CANCELLED:
return TS_CANCELLED;
default:
GST_PENDING_SYNTHETIC_CLICK_FIRST_MOVED_PROCESSED =
G(GS_PENDING_SYNTHETIC_CLICK, 0, TS_MOVED, TSI_PROCESSED),
- GST_PENDING_SYNTHETIC_CLICK_FIRST_STATIONARY =
- G(GS_PENDING_SYNTHETIC_CLICK, 0, TS_STATIONARY, TSI_NOT_PROCESSED),
-
GST_PENDING_SYNTHETIC_CLICK_FIRST_CANCELLED =
G(GS_PENDING_SYNTHETIC_CLICK, 0, TS_CANCELLED, TSI_ALWAYS),
GST_PENDING_SYNTHETIC_CLICK_NO_SCROLL_FIRST_MOVED =
G(GS_PENDING_SYNTHETIC_CLICK_NO_SCROLL, 0, TS_MOVED, TSI_ALWAYS),
- GST_PENDING_SYNTHETIC_CLICK_NO_SCROLL_FIRST_STATIONARY =
- G(GS_PENDING_SYNTHETIC_CLICK_NO_SCROLL, 0, TS_STATIONARY, TSI_ALWAYS),
-
GST_PENDING_SYNTHETIC_CLICK_NO_SCROLL_FIRST_CANCELLED =
G(GS_PENDING_SYNTHETIC_CLICK_NO_SCROLL, 0, TS_CANCELLED, TSI_ALWAYS),
case GST_PENDING_SYNTHETIC_CLICK_FIRST_RELEASED_HANDLED:
case GST_PENDING_SYNTHETIC_CLICK_FIRST_MOVED:
case GST_PENDING_SYNTHETIC_CLICK_FIRST_MOVED_PROCESSED:
- case GST_PENDING_SYNTHETIC_CLICK_FIRST_STATIONARY:
case GST_PENDING_SYNTHETIC_CLICK_FIRST_CANCELLED:
case GST_PENDING_SYNTHETIC_CLICK_SECOND_PRESSED:
case GST_PENDING_SYNTHETIC_CLICK_NO_SCROLL_FIRST_RELEASED:
case GST_PENDING_SYNTHETIC_CLICK_NO_SCROLL_FIRST_RELEASED_HANDLED:
case GST_PENDING_SYNTHETIC_CLICK_NO_SCROLL_FIRST_MOVED:
- case GST_PENDING_SYNTHETIC_CLICK_NO_SCROLL_FIRST_STATIONARY:
case GST_PENDING_SYNTHETIC_CLICK_NO_SCROLL_FIRST_CANCELLED:
case GST_PENDING_SYNTHETIC_CLICK_NO_SCROLL_SECOND_PRESSED:
case GST_SYNTHETIC_CLICK_ABORTED_FIRST_RELEASED:
return sqrt(width + height);
}
-unsigned int ComputeTouchBitmask(const GesturePoint* points) {
- unsigned int touch_bitmask = 0;
- for (int i = 0; i < GestureSequence::kMaxGesturePoints; ++i) {
- if (points[i].in_use())
- touch_bitmask |= 1 << points[i].touch_id();
- }
- return touch_bitmask;
-}
-
const float kFlingCurveNormalization = 1.0f / 1875.f;
float CalibrateFlingVelocity(float velocity) {
set_state(GS_NO_GESTURE);
break;
case GST_PENDING_SYNTHETIC_CLICK_FIRST_MOVED:
- case GST_PENDING_SYNTHETIC_CLICK_FIRST_STATIONARY:
if (ScrollStart(event, point, gestures.get())) {
PrependTapCancelGestureEvent(point, gestures.get());
set_state(GS_SCROLL);
break;
case GST_PENDING_SYNTHETIC_CLICK_FIRST_MOVED_PROCESSED:
case GST_PENDING_SYNTHETIC_CLICK_NO_SCROLL_FIRST_MOVED:
- case GST_PENDING_SYNTHETIC_CLICK_NO_SCROLL_FIRST_STATIONARY:
if (point.IsInScrollWindow(event)) {
PrependTapCancelGestureEvent(point, gestures.get());
set_state(GS_SYNTHETIC_CLICK_ABORTED);
case GST_PINCH_THIRD_MOVED_HANDLED:
case GST_PINCH_FOURTH_MOVED_HANDLED:
case GST_PINCH_FIFTH_MOVED_HANDLED:
+ // If touches are consumed for a while, and then left unconsumed, we don't
+ // want a PinchUpdate or ScrollUpdate with a massive delta.
+ latest_multi_scroll_update_location_ = bounding_box_.CenterPoint();
+ pinch_distance_current_ = BoundingBoxDiagonal(bounding_box_);
break;
case GST_PINCH_FIRST_MOVED:
case GST_PINCH_SECOND_MOVED:
const gfx::PointF& location,
int flags,
base::Time timestamp,
- unsigned int touch_id_bitmask) {
+ int oldest_touch_id) {
GestureEventDetails gesture_details(details);
gesture_details.set_touch_points(point_count_);
gesture_details.set_bounding_box(bounding_box_);
+ gesture_details.set_oldest_touch_id(oldest_touch_id);
base::TimeDelta time_stamp =
base::TimeDelta::FromMicroseconds(timestamp.ToDoubleT() * 1000000);
- return new GestureEvent(gesture_details.type(), location.x(), location.y(),
- flags, time_stamp, gesture_details,
- touch_id_bitmask);
+ return new GestureEvent(location.x(), location.y(),
+ flags, time_stamp, gesture_details);
}
void GestureSequence::AppendTapDownGestureEvent(const GesturePoint& point,
point.first_touch_position(),
flags_,
base::Time::FromDoubleT(point.last_touch_time()),
- 1 << point.touch_id()));
+ point.touch_id()));
}
void GestureSequence::PrependTapCancelGestureEvent(const GesturePoint& point,
point.first_touch_position(),
flags_,
base::Time::FromDoubleT(point.last_touch_time()),
- 1 << point.touch_id()));
+ point.touch_id()));
}
void GestureSequence::AppendBeginGestureEvent(const GesturePoint& point,
point.first_touch_position(),
flags_,
base::Time::FromDoubleT(point.last_touch_time()),
- 1 << point.touch_id()));
+ point.touch_id()));
}
void GestureSequence::AppendEndGestureEvent(const GesturePoint& point,
point.last_touch_position(),
flags_,
base::Time::FromDoubleT(point.last_touch_time()),
- 1 << point.touch_id()));
+ point.touch_id()));
}
void GestureSequence::AppendClickGestureEvent(const GesturePoint& point,
center,
flags_,
base::Time::FromDoubleT(point.last_touch_time()),
- 1 << point.touch_id()));
+ point.touch_id()));
}
void GestureSequence::AppendScrollGestureBegin(const GesturePoint& point,
location,
flags_,
base::Time::FromDoubleT(point.last_touch_time()),
- 1 << point.touch_id()));
+ point.touch_id()));
}
void GestureSequence::AppendScrollGestureEnd(const GesturePoint& point,
gestures->push_back(CreateGestureEvent(
GestureEventDetails(ui::ET_SCROLL_FLING_START,
CalibrateFlingVelocity(railed_x_velocity),
- CalibrateFlingVelocity(railed_y_velocity),
- CalibrateFlingVelocity(x_velocity),
- CalibrateFlingVelocity(y_velocity)),
+ CalibrateFlingVelocity(railed_y_velocity)),
location,
flags_,
base::Time::FromDoubleT(point.last_touch_time()),
- 1 << point.touch_id()));
+ point.touch_id()));
} else {
gestures->push_back(CreateGestureEvent(
GestureEventDetails(ui::ET_GESTURE_SCROLL_END, 0, 0),
location,
flags_,
base::Time::FromDoubleT(point.last_touch_time()),
- 1 << point.touch_id()));
+ point.touch_id()));
}
}
d.set_y(d.y() * ratio);
}
- gfx::Vector2dF o = d;
-
if (scroll_type_ == ST_HORIZONTAL)
d.set_y(0);
else if (scroll_type_ == ST_VERTICAL)
if (d.IsZero())
return;
- GestureEventDetails details(ui::ET_GESTURE_SCROLL_UPDATE,
- d.x(), d.y(), o.x(), o.y());
- details.SetScrollVelocity(
- scroll_type_ == ST_VERTICAL ? 0 : point.XVelocity(),
- scroll_type_ == ST_HORIZONTAL ? 0 : point.YVelocity(),
- point.XVelocity(),
- point.YVelocity());
+ GestureEventDetails details(ui::ET_GESTURE_SCROLL_UPDATE, d.x(), d.y());
gestures->push_back(CreateGestureEvent(
details,
location,
flags_,
base::Time::FromDoubleT(point.last_touch_time()),
- ComputeTouchBitmask(points_)));
+ point.touch_id()));
}
void GestureSequence::AppendPinchGestureBegin(const GesturePoint& p1,
center,
flags_,
base::Time::FromDoubleT(p1.last_touch_time()),
- 1 << p1.touch_id() | 1 << p2.touch_id()));
+ p1.touch_id()));
}
void GestureSequence::AppendPinchGestureEnd(const GesturePoint& p1,
center,
flags_,
base::Time::FromDoubleT(p1.last_touch_time()),
- 1 << p1.touch_id() | 1 << p2.touch_id()));
+ p1.touch_id()));
}
void GestureSequence::AppendPinchGestureUpdate(const GesturePoint& point,
bounding_box_.CenterPoint(),
flags_,
base::Time::FromDoubleT(point.last_touch_time()),
- ComputeTouchBitmask(points_)));
+ point.touch_id()));
}
void GestureSequence::AppendSwipeGesture(const GesturePoint& point,
int swipe_y,
Gestures* gestures) {
gestures->push_back(CreateGestureEvent(
- GestureEventDetails(ui::ET_GESTURE_MULTIFINGER_SWIPE, swipe_x, swipe_y),
+ GestureEventDetails(ui::ET_GESTURE_SWIPE, swipe_x, swipe_y),
bounding_box_.CenterPoint(),
flags_,
base::Time::FromDoubleT(point.last_touch_time()),
- ComputeTouchBitmask(points_)));
+ point.touch_id()));
}
void GestureSequence::AppendTwoFingerTapGestureEvent(Gestures* gestures) {
point->enclosing_rectangle().CenterPoint(),
flags_,
base::Time::FromDoubleT(point->last_touch_time()),
- 1 << point->touch_id()));
+ point->touch_id()));
}
bool GestureSequence::Click(const TouchEvent& event,
point->first_touch_position(),
flags_,
base::Time::FromDoubleT(point->last_touch_time()),
- 1 << point->touch_id()));
+ point->touch_id()));
delegate_->DispatchPostponedGestureEvent(gesture.get());
}
point->first_touch_position(),
flags_,
base::Time::FromDoubleT(point->last_touch_time()),
- 1 << point->touch_id()));
+ point->touch_id()));
delegate_->DispatchPostponedGestureEvent(gesture.get());
}
point.enclosing_rectangle().CenterPoint(),
flags_,
base::Time::FromDoubleT(point.last_touch_time()),
- 1 << point.touch_id()));
+ point.touch_id()));
}
bool GestureSequence::ScrollEnd(const TouchEvent& event,
bool GestureSequence::PinchUpdate(const TouchEvent& event,
GesturePoint& point,
Gestures* gestures) {
+ static double min_pinch_update_distance =
+ CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kCompensateForUnstablePinchZoom)
+ ? GestureConfiguration::min_pinch_update_distance_in_pixels()
+ : 0;
DCHECK(state_ == GS_PINCH);
// It is possible that the none of the touch-points changed their position,
float distance = BoundingBoxDiagonal(bounding_box_);
if (std::abs(distance - pinch_distance_current_) >=
- GestureConfiguration::min_pinch_update_distance_in_pixels()) {
+ min_pinch_update_distance) {
AppendPinchGestureUpdate(point,
distance / pinch_distance_current_, gestures);
pinch_distance_current_ = distance;
}
float min_velocity = GestureConfiguration::min_swipe_speed();
- min_velocity *= min_velocity;
velocity_x = fabs(velocity_x / point_count_);
velocity_y = fabs(velocity_y / point_count_);
if (!swipe_y)
velocity_y = 0.001f;
- float ratio = velocity_x > velocity_y ? velocity_x / velocity_y :
+ float ratio = velocity_x < velocity_y ? velocity_x / velocity_y :
velocity_y / velocity_x;
- if (ratio < GestureConfiguration::max_swipe_deviation_ratio())
+ float angle = atan(ratio) * 180.0f / static_cast<float>(M_PI);
+
+ if (angle > GestureConfiguration::max_swipe_deviation_angle())
return false;
if (velocity_x > velocity_y)