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(); |
} |