Chromium Code Reviews| 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..cdece1da45ec0884536c2f3c7702911e53924961 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" |
| @@ -29,31 +29,36 @@ gfx::Vector2dF ProjectScalarOntoVector( |
| } // namespace |
| -SyntheticSmoothScrollGesture::SyntheticSmoothScrollGesture( |
| - const SyntheticSmoothScrollGestureParams& params) |
| - : params_(params), |
| - gesture_source_type_(SyntheticGestureParams::DEFAULT_INPUT), |
| - state_(SETUP) {} |
| +SyntheticSmoothMoveGesture::SyntheticSmoothMoveGesture( |
| + InputType gesture_source_type, |
|
Sami
2015/02/19 11:59:05
input_type would be a better name for this paramet
ssid
2015/02/20 10:58:54
Done.
|
| + gfx::PointF start_point, |
| + std::vector<gfx::Vector2d> move_distances, |
| + int speed_in_pixels_s, |
| + bool prevent_fling) |
| + : current_move_segment_start_position_(start_point), |
| + gesture_source_type_(gesture_source_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 (gesture_source_type_ == TOUCH_INPUT) |
|
Sami
2015/02/19 11:59:05
I think this would be a little neater as a switch
ssid
2015/02/20 10:58:54
Done.
|
| ForwardTouchInputEvents(timestamp, target); |
| - else if (gesture_source_type_ == SyntheticGestureParams::MOUSE_INPUT) |
| - ForwardMouseInputEvents(timestamp, target); |
| + else if (gesture_source_type_ == MOUSE_CLICK) |
| + ForwardMouseClickInputEvents(timestamp, target); |
| + else if (gesture_source_type_ == MOUSE_WHEEL) |
| + ForwardMouseWheelInputEvents(timestamp, target); |
| else |
| return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_IMPLEMENTED; |
| @@ -61,18 +66,17 @@ SyntheticGesture::Result SyntheticSmoothScrollGesture::ForwardInputEvents( |
| : SyntheticGesture::GESTURE_RUNNING; |
| } |
| -void SyntheticSmoothScrollGesture::ForwardTouchInputEvents( |
| +void SyntheticSmoothMoveGesture::ForwardTouchInputEvents( |
| const base::TimeTicks& timestamp, SyntheticGestureTarget* target) { |
| base::TimeTicks event_timestamp = timestamp; |
| switch (state_) { |
| case STARTED: |
| - if (ScrollIsNoOp()) { |
| + if (MoveIsNoOp()) { |
|
picksi
2015/02/19 11:50:18
As discussed, switch statements that contain code
ssid
2015/02/20 10:58:54
This cleanup can be done in the next CL :). which
|
| state_ = DONE; |
| break; |
| } |
| AddTouchSlopToFirstDistance(target); |
|
Sami
2015/02/19 11:59:05
I think we need to make this configurable too, sin
ssid
2015/02/20 10:58:54
Done.
|
| - ComputeNextScrollSegment(); |
| - current_scroll_segment_start_position_ = params_.anchor; |
| + ComputeNextMoveSegment(); |
| PressTouchPoint(target, event_timestamp); |
| state_ = MOVING; |
| break; |
| @@ -81,12 +85,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 +99,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,24 +109,24 @@ 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. |
| + // Fall through to forward the first event. |
| case MOVING: { |
| // Even though WebMouseWheelEvents take floating point deltas, |
| // internally the scroll position is stored as an integer. We therefore |
| @@ -130,19 +134,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 +154,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. |
|
Sami
2015/02/19 11:59:05
Thanks for adding this comment.
|
| + 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."; |
| } |
| } |
|
picksi
2015/02/19 11:50:18
Design thought: Is this case statement inside out?
ssid
2015/02/20 10:58:54
Each of the switch statements does mostly differen
picksi
2015/02/20 11:51:18
If/When a later refactor removes the 'case' code o
|
| -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(gesture_source_type_ == MOUSE_CLICK); |
| + 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(gesture_source_type_ == MOUSE_CLICK); |
| + 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(gesture_source_type_ == MOUSE_CLICK); |
| + 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::Vector2d& 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_++; |
|
picksi
2015/02/19 11:50:18
Nit/Comment: FYI This feels dangerous to me! It wo
|
| + 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 |