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

Unified Diff: content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc

Issue 929333002: Adding synthetic touch/mouse drag [Part1] (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Adderessed comments. Created 5 years, 10 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
Index: content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc
diff --git a/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc b/content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc
similarity index 33%
copy from content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc
copy to content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc
index 59f4af31fd891bafa6b19d6532dd1855a0f4d499..8ef090dfc0158b348f321020a5d48f44509b078c 100644
--- a/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc
+++ b/content/browser/renderer_host/input/synthetic_smooth_move_gesture.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h"
+#include "content/browser/renderer_host/input/synthetic_smooth_move_gesture.h"
#include "base/logging.h"
#include "ui/gfx/geometry/point_f.h"
@@ -22,57 +22,75 @@ gfx::Vector2d CeilFromZero(const gfx::Vector2dF& vector) {
return gfx::Vector2d(x, y);
}
-gfx::Vector2dF ProjectScalarOntoVector(
- float scalar, const gfx::Vector2d& vector) {
+gfx::Vector2dF ProjectScalarOntoVector(float scalar,
+ const gfx::Vector2dF& vector) {
return gfx::ScaleVector2d(vector, scalar / vector.Length());
}
+const int kDefaultSpeedInPixelsPerSec = 800;
+
} // namespace
-SyntheticSmoothScrollGesture::SyntheticSmoothScrollGesture(
- const SyntheticSmoothScrollGestureParams& params)
+SyntheticSmoothMoveGestureParams::SyntheticSmoothMoveGestureParams()
+ : speed_in_pixels_s(kDefaultSpeedInPixelsPerSec),
+ prevent_fling(true),
+ add_slop(true) {}
+
+SyntheticSmoothMoveGestureParams::~SyntheticSmoothMoveGestureParams() {}
+
+SyntheticSmoothMoveGesture::SyntheticSmoothMoveGesture(
+ SyntheticSmoothMoveGestureParams params)
: params_(params),
- gesture_source_type_(SyntheticGestureParams::DEFAULT_INPUT),
- state_(SETUP) {}
+ current_move_segment_start_position_(params.start_point),
+ state_(SETUP) {
+}
-SyntheticSmoothScrollGesture::~SyntheticSmoothScrollGesture() {}
+SyntheticSmoothMoveGesture::~SyntheticSmoothMoveGesture() {}
-SyntheticGesture::Result SyntheticSmoothScrollGesture::ForwardInputEvents(
- const base::TimeTicks& timestamp, SyntheticGestureTarget* target) {
+SyntheticGesture::Result SyntheticSmoothMoveGesture::ForwardInputEvents(
+ const base::TimeTicks& timestamp,
+ SyntheticGestureTarget* target) {
if (state_ == SETUP) {
- gesture_source_type_ = params_.gesture_source_type;
- if (gesture_source_type_ == SyntheticGestureParams::DEFAULT_INPUT)
- gesture_source_type_ = target->GetDefaultSyntheticGestureSourceType();
-
state_ = STARTED;
- current_scroll_segment_ = -1;
- current_scroll_segment_stop_time_ = timestamp;
+ current_move_segment_ = -1;
+ current_move_segment_stop_time_ = timestamp;
}
- DCHECK_NE(gesture_source_type_, SyntheticGestureParams::DEFAULT_INPUT);
- if (gesture_source_type_ == SyntheticGestureParams::TOUCH_INPUT)
- ForwardTouchInputEvents(timestamp, target);
- else if (gesture_source_type_ == SyntheticGestureParams::MOUSE_INPUT)
- ForwardMouseInputEvents(timestamp, target);
- else
- return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_IMPLEMENTED;
-
+ switch (params_.input_type) {
+ case SyntheticSmoothMoveGestureParams::TOUCH_INPUT:
+ ForwardTouchInputEvents(timestamp, target);
+ break;
+ case SyntheticSmoothMoveGestureParams::MOUSE_DRAG_INPUT:
+ ForwardMouseClickInputEvents(timestamp, target);
+ break;
+ case SyntheticSmoothMoveGestureParams::MOUSE_WHEEL_INPUT:
+ ForwardMouseWheelInputEvents(timestamp, target);
+ break;
+ default:
+ return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_IMPLEMENTED;
+ }
return (state_ == DONE) ? SyntheticGesture::GESTURE_FINISHED
: SyntheticGesture::GESTURE_RUNNING;
}
-void SyntheticSmoothScrollGesture::ForwardTouchInputEvents(
- const base::TimeTicks& timestamp, SyntheticGestureTarget* target) {
+// TODO(ssid): Clean up the switch statements by adding functions instead of
jdduke (slow) 2015/02/25 15:58:25 Thanks, could you also file a bug for this and lin
+// large code, in the Forward*Events functions. Move the actions for all input
+// types to different class (SyntheticInputDevice) which generates input events
+// for all input types. The gesture class can use instance of device actions.
+
+void SyntheticSmoothMoveGesture::ForwardTouchInputEvents(
+ const base::TimeTicks& timestamp,
+ SyntheticGestureTarget* target) {
base::TimeTicks event_timestamp = timestamp;
switch (state_) {
case STARTED:
- if (ScrollIsNoOp()) {
+ if (MoveIsNoOp()) {
state_ = DONE;
break;
}
- AddTouchSlopToFirstDistance(target);
- ComputeNextScrollSegment();
- current_scroll_segment_start_position_ = params_.anchor;
+ if (params_.add_slop)
+ AddTouchSlopToFirstDistance(target);
+ ComputeNextMoveSegment();
PressTouchPoint(target, event_timestamp);
state_ = MOVING;
break;
@@ -81,11 +99,11 @@ void SyntheticSmoothScrollGesture::ForwardTouchInputEvents(
gfx::Vector2dF delta = GetPositionDeltaAtTime(event_timestamp);
MoveTouchPoint(target, delta, event_timestamp);
- if (FinishedCurrentScrollSegment(event_timestamp)) {
- if (!IsLastScrollSegment()) {
- current_scroll_segment_start_position_ +=
- params_.distances[current_scroll_segment_];
- ComputeNextScrollSegment();
+ if (FinishedCurrentMoveSegment(event_timestamp)) {
+ if (!IsLastMoveSegment()) {
+ current_move_segment_start_position_ +=
+ params_.distances[current_move_segment_];
+ ComputeNextMoveSegment();
} else if (params_.prevent_fling) {
state_ = STOPPING;
} else {
@@ -95,9 +113,9 @@ void SyntheticSmoothScrollGesture::ForwardTouchInputEvents(
}
} break;
case STOPPING:
- if (timestamp - current_scroll_segment_stop_time_ >=
+ if (timestamp - current_move_segment_stop_time_ >=
target->PointerAssumedStoppedTime()) {
- event_timestamp = current_scroll_segment_stop_time_ +
+ event_timestamp = current_move_segment_stop_time_ +
target->PointerAssumedStoppedTime();
ReleaseTouchPoint(target, event_timestamp);
state_ = DONE;
@@ -105,22 +123,23 @@ void SyntheticSmoothScrollGesture::ForwardTouchInputEvents(
break;
case SETUP:
NOTREACHED()
- << "State STARTED invalid for synthetic scroll using touch input.";
+ << "State SETUP invalid for synthetic scroll using touch input.";
case DONE:
NOTREACHED()
<< "State DONE invalid for synthetic scroll using touch input.";
}
}
-void SyntheticSmoothScrollGesture::ForwardMouseInputEvents(
- const base::TimeTicks& timestamp, SyntheticGestureTarget* target) {
+void SyntheticSmoothMoveGesture::ForwardMouseWheelInputEvents(
+ const base::TimeTicks& timestamp,
+ SyntheticGestureTarget* target) {
switch (state_) {
case STARTED:
- if (ScrollIsNoOp()) {
+ if (MoveIsNoOp()) {
state_ = DONE;
break;
}
- ComputeNextScrollSegment();
+ ComputeNextMoveSegment();
state_ = MOVING;
// Fall through to forward the first event.
case MOVING: {
@@ -130,140 +149,224 @@ void SyntheticSmoothScrollGesture::ForwardMouseInputEvents(
// internal scrolling state. This ensures that when the gesture has
// finished we've scrolled exactly the specified distance.
base::TimeTicks event_timestamp = ClampTimestamp(timestamp);
- gfx::Vector2dF current_scroll_segment_total_delta =
+ gfx::Vector2dF current_move_segment_total_delta =
GetPositionDeltaAtTime(event_timestamp);
gfx::Vector2d delta_discrete =
- FloorTowardZero(current_scroll_segment_total_delta -
- current_scroll_segment_total_delta_discrete_);
+ FloorTowardZero(current_move_segment_total_delta -
+ current_move_segment_total_delta_discrete_);
ForwardMouseWheelEvent(target, delta_discrete, event_timestamp);
- current_scroll_segment_total_delta_discrete_ += delta_discrete;
+ current_move_segment_total_delta_discrete_ += delta_discrete;
- if (FinishedCurrentScrollSegment(event_timestamp)) {
- if (!IsLastScrollSegment()) {
- current_scroll_segment_total_delta_discrete_ = gfx::Vector2d();
- ComputeNextScrollSegment();
- ForwardMouseInputEvents(timestamp, target);
+ if (FinishedCurrentMoveSegment(event_timestamp)) {
+ if (!IsLastMoveSegment()) {
+ current_move_segment_total_delta_discrete_ = gfx::Vector2d();
+ ComputeNextMoveSegment();
+ ForwardMouseWheelInputEvents(timestamp, target);
} else {
state_ = DONE;
}
}
} break;
case SETUP:
+ NOTREACHED() << "State SETUP invalid for synthetic scroll using mouse "
+ "wheel input.";
+ case STOPPING:
+ NOTREACHED() << "State STOPPING invalid for synthetic scroll using mouse "
+ "wheel input.";
+ case DONE:
NOTREACHED()
- << "State STARTED invalid for synthetic scroll using touch input.";
+ << "State DONE invalid for synthetic scroll using mouse wheel input.";
+ }
+}
+
+void SyntheticSmoothMoveGesture::ForwardMouseClickInputEvents(
+ const base::TimeTicks& timestamp,
+ SyntheticGestureTarget* target) {
+ base::TimeTicks event_timestamp = timestamp;
+ switch (state_) {
+ case STARTED:
+ if (MoveIsNoOp()) {
+ state_ = DONE;
+ break;
+ }
+ ComputeNextMoveSegment();
+ PressMousePoint(target, event_timestamp);
+ state_ = MOVING;
+ // Fall through to forward the first event.
jdduke (slow) 2015/02/25 15:58:25 Why fall through? We don't do that for touch event
ssid 2015/02/25 16:25:42 It was added because we do it in mouse wheel scrol
+ case MOVING: {
+ base::TimeTicks event_timestamp = ClampTimestamp(timestamp);
+ gfx::Vector2dF delta = GetPositionDeltaAtTime(event_timestamp);
+ MoveMousePoint(target, delta, event_timestamp);
+
+ if (FinishedCurrentMoveSegment(event_timestamp)) {
+ if (!IsLastMoveSegment()) {
+ current_move_segment_start_position_ +=
+ params_.distances[current_move_segment_];
+ ComputeNextMoveSegment();
+ } else {
+ ReleaseMousePoint(target, event_timestamp);
+ state_ = DONE;
+ }
+ }
+ } break;
case STOPPING:
NOTREACHED()
- << "State STOPPING invalid for synthetic scroll using touch input.";
+ << "State STOPPING invalid for synthetic drag using mouse input.";
+ case SETUP:
+ NOTREACHED()
+ << "State SETUP invalid for synthetic drag using mouse input.";
case DONE:
NOTREACHED()
- << "State DONE invalid for synthetic scroll using touch input.";
+ << "State DONE invalid for synthetic drag using mouse input.";
}
}
-void SyntheticSmoothScrollGesture::ForwardTouchEvent(
- SyntheticGestureTarget* target, const base::TimeTicks& timestamp) {
+void SyntheticSmoothMoveGesture::ForwardTouchEvent(
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) {
touch_event_.timeStampSeconds = ConvertTimestampToSeconds(timestamp);
target->DispatchInputEventToPlatform(touch_event_);
}
-void SyntheticSmoothScrollGesture::ForwardMouseWheelEvent(
+void SyntheticSmoothMoveGesture::ForwardMouseWheelEvent(
SyntheticGestureTarget* target,
const gfx::Vector2dF& delta,
const base::TimeTicks& timestamp) const {
blink::WebMouseWheelEvent mouse_wheel_event =
SyntheticWebMouseWheelEventBuilder::Build(delta.x(), delta.y(), 0, false);
- mouse_wheel_event.x = params_.anchor.x();
- mouse_wheel_event.y = params_.anchor.y();
+ mouse_wheel_event.x = current_move_segment_start_position_.x();
+ mouse_wheel_event.y = current_move_segment_start_position_.y();
mouse_wheel_event.timeStampSeconds = ConvertTimestampToSeconds(timestamp);
target->DispatchInputEventToPlatform(mouse_wheel_event);
}
-void SyntheticSmoothScrollGesture::PressTouchPoint(
- SyntheticGestureTarget* target, const base::TimeTicks& timestamp) {
- DCHECK_EQ(current_scroll_segment_, 0);
- touch_event_.PressPoint(params_.anchor.x(), params_.anchor.y());
+void SyntheticSmoothMoveGesture::PressTouchPoint(
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) {
+ DCHECK_EQ(current_move_segment_, 0);
+ touch_event_.PressPoint(current_move_segment_start_position_.x(),
+ current_move_segment_start_position_.y());
ForwardTouchEvent(target, timestamp);
}
-void SyntheticSmoothScrollGesture::MoveTouchPoint(
+void SyntheticSmoothMoveGesture::MoveTouchPoint(
SyntheticGestureTarget* target,
const gfx::Vector2dF& delta,
const base::TimeTicks& timestamp) {
- DCHECK_GE(current_scroll_segment_, 0);
- DCHECK_LT(current_scroll_segment_,
- static_cast<int>(params_.distances.size()));
- gfx::PointF touch_position = current_scroll_segment_start_position_ + delta;
+ DCHECK_GE(current_move_segment_, 0);
+ DCHECK_LT(current_move_segment_, static_cast<int>(params_.distances.size()));
+ gfx::PointF touch_position = current_move_segment_start_position_ + delta;
touch_event_.MovePoint(0, touch_position.x(), touch_position.y());
ForwardTouchEvent(target, timestamp);
}
-void SyntheticSmoothScrollGesture::ReleaseTouchPoint(
- SyntheticGestureTarget* target, const base::TimeTicks& timestamp) {
- DCHECK_EQ(current_scroll_segment_,
+void SyntheticSmoothMoveGesture::ReleaseTouchPoint(
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) {
+ DCHECK_EQ(current_move_segment_,
static_cast<int>(params_.distances.size()) - 1);
touch_event_.ReleasePoint(0);
ForwardTouchEvent(target, timestamp);
}
-void SyntheticSmoothScrollGesture::AddTouchSlopToFirstDistance(
+void SyntheticSmoothMoveGesture::PressMousePoint(
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) {
+ DCHECK(params_.input_type ==
jdduke (slow) 2015/02/25 15:58:25 Nit: DCHECK_EQ
ssid 2015/02/25 16:25:42 Done.
+ SyntheticSmoothMoveGestureParams::MOUSE_DRAG_INPUT);
+ blink::WebMouseEvent mouse_event = SyntheticWebMouseEventBuilder::Build(
+ blink::WebInputEvent::MouseDown, current_move_segment_start_position_.x(),
+ current_move_segment_start_position_.y(), 0);
+ mouse_event.clickCount = 1;
+ mouse_event.timeStampSeconds = ConvertTimestampToSeconds(timestamp);
+ target->DispatchInputEventToPlatform(mouse_event);
+}
+
+void SyntheticSmoothMoveGesture::ReleaseMousePoint(
+ SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) {
+ DCHECK(params_.input_type ==
jdduke (slow) 2015/02/25 15:58:25 DCHECK_EQ
ssid 2015/02/25 16:25:42 Done.
+ SyntheticSmoothMoveGestureParams::MOUSE_DRAG_INPUT);
+ gfx::PointF mouse_position =
+ current_move_segment_start_position_ + GetPositionDeltaAtTime(timestamp);
+ blink::WebMouseEvent mouse_event = SyntheticWebMouseEventBuilder::Build(
+ blink::WebInputEvent::MouseUp, mouse_position.x(), mouse_position.y(), 0);
+ mouse_event.timeStampSeconds = ConvertTimestampToSeconds(timestamp);
+ target->DispatchInputEventToPlatform(mouse_event);
+}
+
+void SyntheticSmoothMoveGesture::MoveMousePoint(
+ SyntheticGestureTarget* target,
+ const gfx::Vector2dF& delta,
+ const base::TimeTicks& timestamp) {
+ gfx::PointF mouse_position = current_move_segment_start_position_ + delta;
+ DCHECK(params_.input_type ==
jdduke (slow) 2015/02/25 15:58:25 DCHECK_EQ
ssid 2015/02/25 16:25:42 Done.
+ SyntheticSmoothMoveGestureParams::MOUSE_DRAG_INPUT);
+ blink::WebMouseEvent mouse_event = SyntheticWebMouseEventBuilder::Build(
+ blink::WebInputEvent::MouseMove, mouse_position.x(), mouse_position.y(),
+ 0);
+ mouse_event.button = blink::WebMouseEvent::ButtonLeft;
jdduke (slow) 2015/02/25 15:58:25 Would we ever want to simulate mouse movement with
ssid 2015/02/25 16:25:42 The current consumer for the drag gestures will be
+ mouse_event.timeStampSeconds = ConvertTimestampToSeconds(timestamp);
+ target->DispatchInputEventToPlatform(mouse_event);
+}
+
+void SyntheticSmoothMoveGesture::AddTouchSlopToFirstDistance(
SyntheticGestureTarget* target) {
DCHECK_GE(params_.distances.size(), 1ul);
- gfx::Vector2d& first_scroll_distance = params_.distances[0];
- DCHECK_GT(first_scroll_distance.Length(), 0);
- first_scroll_distance += CeilFromZero(ProjectScalarOntoVector(
- target->GetTouchSlopInDips(), first_scroll_distance));
+ gfx::Vector2dF& first_move_distance = params_.distances[0];
+ DCHECK_GT(first_move_distance.Length(), 0);
+ first_move_distance += CeilFromZero(ProjectScalarOntoVector(
+ target->GetTouchSlopInDips(), first_move_distance));
}
-gfx::Vector2dF SyntheticSmoothScrollGesture::GetPositionDeltaAtTime(
+gfx::Vector2dF SyntheticSmoothMoveGesture::GetPositionDeltaAtTime(
const base::TimeTicks& timestamp) const {
// Make sure the final delta is correct. Using the computation below can lead
// to issues with floating point precision.
- if (FinishedCurrentScrollSegment(timestamp))
- return params_.distances[current_scroll_segment_];
+ if (FinishedCurrentMoveSegment(timestamp))
+ return params_.distances[current_move_segment_];
float delta_length =
params_.speed_in_pixels_s *
- (timestamp - current_scroll_segment_start_time_).InSecondsF();
+ (timestamp - current_move_segment_start_time_).InSecondsF();
return ProjectScalarOntoVector(delta_length,
- params_.distances[current_scroll_segment_]);
+ params_.distances[current_move_segment_]);
}
-void SyntheticSmoothScrollGesture::ComputeNextScrollSegment() {
- current_scroll_segment_++;
- DCHECK_LT(current_scroll_segment_,
- static_cast<int>(params_.distances.size()));
+void SyntheticSmoothMoveGesture::ComputeNextMoveSegment() {
+ current_move_segment_++;
+ DCHECK_LT(current_move_segment_, static_cast<int>(params_.distances.size()));
int64 total_duration_in_us = static_cast<int64>(
- 1e6 * (params_.distances[current_scroll_segment_].Length() /
+ 1e6 * (params_.distances[current_move_segment_].Length() /
params_.speed_in_pixels_s));
DCHECK_GT(total_duration_in_us, 0);
- current_scroll_segment_start_time_ = current_scroll_segment_stop_time_;
- current_scroll_segment_stop_time_ =
- current_scroll_segment_start_time_ +
+ current_move_segment_start_time_ = current_move_segment_stop_time_;
+ current_move_segment_stop_time_ =
+ current_move_segment_start_time_ +
base::TimeDelta::FromMicroseconds(total_duration_in_us);
}
-base::TimeTicks SyntheticSmoothScrollGesture::ClampTimestamp(
+base::TimeTicks SyntheticSmoothMoveGesture::ClampTimestamp(
const base::TimeTicks& timestamp) const {
- return std::min(timestamp, current_scroll_segment_stop_time_);
+ return std::min(timestamp, current_move_segment_stop_time_);
}
-bool SyntheticSmoothScrollGesture::FinishedCurrentScrollSegment(
+bool SyntheticSmoothMoveGesture::FinishedCurrentMoveSegment(
const base::TimeTicks& timestamp) const {
- return timestamp >= current_scroll_segment_stop_time_;
+ return timestamp >= current_move_segment_stop_time_;
}
-bool SyntheticSmoothScrollGesture::IsLastScrollSegment() const {
- DCHECK_LT(current_scroll_segment_,
- static_cast<int>(params_.distances.size()));
- return current_scroll_segment_ ==
+bool SyntheticSmoothMoveGesture::IsLastMoveSegment() const {
+ DCHECK_LT(current_move_segment_, static_cast<int>(params_.distances.size()));
+ return current_move_segment_ ==
static_cast<int>(params_.distances.size()) - 1;
}
-bool SyntheticSmoothScrollGesture::ScrollIsNoOp() const {
+bool SyntheticSmoothMoveGesture::MoveIsNoOp() const {
return params_.distances.size() == 0 || params_.distances[0].IsZero();
}

Powered by Google App Engine
This is Rietveld 408576698