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

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: Fixed nits. 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 37%
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..5bd82cac069ae42bc7f2cb6e7b51dd24a6754896 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"
@@ -23,37 +23,42 @@ gfx::Vector2d CeilFromZero(const gfx::Vector2dF& vector) {
}
gfx::Vector2dF ProjectScalarOntoVector(
- float scalar, const gfx::Vector2d& vector) {
+ float scalar, const gfx::Vector2dF& vector) {
return gfx::ScaleVector2d(vector, scalar / vector.Length());
}
} // namespace
-SyntheticSmoothScrollGesture::SyntheticSmoothScrollGesture(
- const SyntheticSmoothScrollGestureParams& params)
- : params_(params),
- gesture_source_type_(SyntheticGestureParams::DEFAULT_INPUT),
- state_(SETUP) {}
+SyntheticSmoothMoveGesture::SyntheticSmoothMoveGesture(
+ InputType input_type,
+ gfx::PointF start_point,
+ std::vector<gfx::Vector2dF> move_distances,
+ int speed_in_pixels_s,
+ bool prevent_fling)
+ : current_move_segment_start_position_(start_point),
+ input_type_(input_type),
+ state_(SETUP),
+ move_distances_(move_distances),
+ speed_in_pixels_s_(speed_in_pixels_s),
+ prevent_fling_(prevent_fling) {
+}
-SyntheticSmoothScrollGesture::~SyntheticSmoothScrollGesture() {}
+SyntheticSmoothMoveGesture::~SyntheticSmoothMoveGesture() {}
-SyntheticGesture::Result SyntheticSmoothScrollGesture::ForwardInputEvents(
+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)
+ if (input_type_ == TOUCH_SCROLL_INPUT || input_type_ == TOUCH_DRAG_INPUT)
ForwardTouchInputEvents(timestamp, target);
- else if (gesture_source_type_ == SyntheticGestureParams::MOUSE_INPUT)
- ForwardMouseInputEvents(timestamp, target);
+ else if (input_type_ == MOUSE_DRAG_INPUT)
+ ForwardMouseClickInputEvents(timestamp, target);
+ else if (input_type_ == MOUSE_WHEEL_INPUT)
+ ForwardMouseWheelInputEvents(timestamp, target);
else
return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_IMPLEMENTED;
@@ -61,18 +66,21 @@ SyntheticGesture::Result SyntheticSmoothScrollGesture::ForwardInputEvents(
: SyntheticGesture::GESTURE_RUNNING;
}
-void SyntheticSmoothScrollGesture::ForwardTouchInputEvents(
+// TODO (ssid) clean up the switch statements by adding functions, instead of
+// large code, in the Forward*Events functions.
+
+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 (input_type_ == TOUCH_SCROLL_INPUT)
+ AddTouchSlopToFirstDistance(target);
+ ComputeNextMoveSegment();
PressTouchPoint(target, event_timestamp);
state_ = MOVING;
break;
@@ -81,12 +89,12 @@ 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();
- } else if (params_.prevent_fling) {
+ if (FinishedCurrentMoveSegment(event_timestamp)) {
+ if (!IsLastMoveSegment()) {
+ current_move_segment_start_position_ +=
+ move_distances_[current_move_segment_];
+ ComputeNextMoveSegment();
+ } else if (prevent_fling_) {
state_ = STOPPING;
} else {
ReleaseTouchPoint(target, event_timestamp);
@@ -95,9 +103,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 +113,22 @@ 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(
+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,19 +138,19 @@ 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;
}
@@ -150,121 +158,198 @@ void SyntheticSmoothScrollGesture::ForwardMouseInputEvents(
} break;
case SETUP:
NOTREACHED()
- << "State STARTED invalid for synthetic scroll using touch input.";
+ << "State SETUP invalid for synthetic scroll using mouse "
+ "wheel input.";
case STOPPING:
NOTREACHED()
- << "State STOPPING invalid for synthetic scroll using touch input.";
+ << "State STOPPING invalid for synthetic scroll using mouse "
+ "wheel input.";
case DONE:
NOTREACHED()
- << "State DONE 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.
+ 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_ +=
+ move_distances_[current_move_segment_];
+ ComputeNextMoveSegment();
+ } else {
+ ReleaseMousePoint(target, event_timestamp);
+ state_ = DONE;
+ }
+ }
+ } break;
+ case STOPPING:
+ NOTREACHED()
+ << "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 drag using mouse input.";
}
}
-void SyntheticSmoothScrollGesture::ForwardTouchEvent(
+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(
+void SyntheticSmoothMoveGesture::PressTouchPoint(
SyntheticGestureTarget* target, const base::TimeTicks& timestamp) {
- DCHECK_EQ(current_scroll_segment_, 0);
- touch_event_.PressPoint(params_.anchor.x(), params_.anchor.y());
+ 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>(move_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(
+void SyntheticSmoothMoveGesture::ReleaseTouchPoint(
SyntheticGestureTarget* target, const base::TimeTicks& timestamp) {
- DCHECK_EQ(current_scroll_segment_,
- static_cast<int>(params_.distances.size()) - 1);
+ DCHECK_EQ(current_move_segment_,
+ static_cast<int>(move_distances_.size()) - 1);
touch_event_.ReleasePoint(0);
ForwardTouchEvent(target, timestamp);
}
-void SyntheticSmoothScrollGesture::AddTouchSlopToFirstDistance(
+void SyntheticSmoothMoveGesture::PressMousePoint(SyntheticGestureTarget* target,
+ const base::TimeTicks& timestamp) {
+ DCHECK(input_type_ == 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(input_type_ == 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(input_type_ == 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;
+ 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));
+ DCHECK_GE(move_distances_.size(), 1ul);
+ gfx::Vector2dF& first_move_distance = move_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 move_distances_[current_move_segment_];
float delta_length =
- params_.speed_in_pixels_s *
- (timestamp - current_scroll_segment_start_time_).InSecondsF();
+ speed_in_pixels_s_ *
+ (timestamp - current_move_segment_start_time_).InSecondsF();
return ProjectScalarOntoVector(delta_length,
- params_.distances[current_scroll_segment_]);
+ move_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>(move_distances_.size()));
int64 total_duration_in_us = static_cast<int64>(
- 1e6 * (params_.distances[current_scroll_segment_].Length() /
- params_.speed_in_pixels_s));
+ 1e6 *
+ (move_distances_[current_move_segment_].Length() / 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_ ==
- static_cast<int>(params_.distances.size()) - 1;
+bool SyntheticSmoothMoveGesture::IsLastMoveSegment() const {
+ DCHECK_LT(current_move_segment_, static_cast<int>(move_distances_.size()));
+ return current_move_segment_ == static_cast<int>(move_distances_.size()) - 1;
}
-bool SyntheticSmoothScrollGesture::ScrollIsNoOp() const {
- return params_.distances.size() == 0 || params_.distances[0].IsZero();
+bool SyntheticSmoothMoveGesture::MoveIsNoOp() const {
+ return move_distances_.size() == 0 || move_distances_[0].IsZero();
}
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698