Chromium Code Reviews| Index: content/browser/renderer_host/input/synthetic_pinch_gesture.cc |
| diff --git a/content/browser/renderer_host/input/synthetic_pinch_gesture.cc b/content/browser/renderer_host/input/synthetic_pinch_gesture.cc |
| index dfe5cf474e7a72957ed5f4f7ac1c258440ecc8d5..14713635c70b69851ad65db7af80869da75284f0 100644 |
| --- a/content/browser/renderer_host/input/synthetic_pinch_gesture.cc |
| +++ b/content/browser/renderer_host/input/synthetic_pinch_gesture.cc |
| @@ -15,8 +15,8 @@ namespace content { |
| SyntheticPinchGesture::SyntheticPinchGesture( |
| const SyntheticPinchGestureParams& params) |
| : params_(params), |
| - current_y_0_(0.0f), |
| - current_y_1_(0.0f), |
| + start_y_0_(0.0f), |
| + start_y_1_(0.0f), |
| target_y_0_(0.0f), |
| target_y_1_(0.0f), |
| gesture_source_type_(SyntheticGestureParams::DEFAULT_INPUT), |
| @@ -27,7 +27,7 @@ SyntheticPinchGesture::SyntheticPinchGesture( |
| SyntheticPinchGesture::~SyntheticPinchGesture() {} |
| SyntheticGesture::Result SyntheticPinchGesture::ForwardInputEvents( |
| - const base::TimeDelta& interval, SyntheticGestureTarget* target) { |
| + const base::TimeTicks& timestamp, SyntheticGestureTarget* target) { |
| if (state_ == SETUP) { |
| gesture_source_type_ = params_.gesture_source_type; |
| if (gesture_source_type_ == SyntheticGestureParams::DEFAULT_INPUT) |
| @@ -37,11 +37,12 @@ SyntheticGesture::Result SyntheticPinchGesture::ForwardInputEvents( |
| return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_SUPPORTED_BY_PLATFORM; |
| state_ = STARTED; |
| + start_time_ = timestamp; |
| } |
| DCHECK_NE(gesture_source_type_, SyntheticGestureParams::DEFAULT_INPUT); |
| if (gesture_source_type_ == SyntheticGestureParams::TOUCH_INPUT) |
| - ForwardTouchInputEvents(interval, target); |
| + ForwardTouchInputEvents(timestamp, target); |
| else |
| return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_IMPLEMENTED; |
| @@ -50,7 +51,7 @@ SyntheticGesture::Result SyntheticPinchGesture::ForwardInputEvents( |
| } |
| void SyntheticPinchGesture::ForwardTouchInputEvents( |
| - const base::TimeDelta& interval, SyntheticGestureTarget* target) { |
| + const base::TimeTicks& timestamp, SyntheticGestureTarget* target) { |
| switch (state_) { |
| case STARTED: |
| // Check for an early finish. |
| @@ -59,17 +60,18 @@ void SyntheticPinchGesture::ForwardTouchInputEvents( |
| break; |
| } |
| SetupCoordinates(target); |
| - PressTouchPoints(target); |
| + PressTouchPoints(target, timestamp); |
| state_ = MOVING; |
| break; |
| - case MOVING: |
| - UpdateTouchPoints(interval); |
| - MoveTouchPoints(target); |
| - if (HasReachedTarget()) { |
| - ReleaseTouchPoints(target); |
| + case MOVING: { |
| + base::TimeTicks event_timestamp = timestamp; |
| + float delta = GetDeltaForPointer0AndUpdateTimestamp(&event_timestamp); |
| + MoveTouchPoints(target, delta, event_timestamp); |
| + if (HasReachedTarget(delta)) { |
| + ReleaseTouchPoints(target, event_timestamp); |
| state_ = DONE; |
| } |
| - break; |
| + } break; |
| case SETUP: |
| NOTREACHED() << "State SETUP invalid for synthetic pinch."; |
| case DONE: |
| @@ -77,40 +79,40 @@ void SyntheticPinchGesture::ForwardTouchInputEvents( |
| } |
| } |
| -void SyntheticPinchGesture::UpdateTouchPoints(base::TimeDelta interval) { |
| - // Compute the delta for the first pointer. The other one moves exactly |
| - // the same but in the opposite direction. |
| - float delta = GetDeltaForPointer0(interval); |
| - current_y_0_ += delta; |
| - current_y_1_ -= delta; |
| +void SyntheticPinchGesture::PressTouchPoints(SyntheticGestureTarget* target, |
| + const base::TimeTicks& timestamp) { |
| + touch_event_.PressPoint(params_.anchor.x(), start_y_0_); |
| + touch_event_.PressPoint(params_.anchor.x(), start_y_1_); |
| + ForwardTouchEvent(target, timestamp); |
| } |
| -void SyntheticPinchGesture::PressTouchPoints(SyntheticGestureTarget* target) { |
| - touch_event_.PressPoint(params_.anchor.x(), current_y_0_); |
| - touch_event_.PressPoint(params_.anchor.x(), current_y_1_); |
| - ForwardTouchEvent(target); |
| -} |
| +void SyntheticPinchGesture::MoveTouchPoints(SyntheticGestureTarget* target, |
| + float delta, |
| + const base::TimeTicks& timestamp) { |
| + // The two pointers move in opposite directions. |
| + float current_y_0 = start_y_0_ + delta; |
| + float current_y_1 = start_y_1_ - delta; |
| -void SyntheticPinchGesture::MoveTouchPoints(SyntheticGestureTarget* target) { |
| // The current pointer positions are stored as float but the pointer |
| // coordinates of the input event are integers. Floor both positions so that |
| // in case of an odd distance one of the pointers (the one whose position goes |
| // down) moves one pixel further than the other. The explicit flooring is only |
| // needed for negative values. |
| - touch_event_.MovePoint(0, params_.anchor.x(), floor(current_y_0_)); |
| - touch_event_.MovePoint(1, params_.anchor.x(), floor(current_y_1_)); |
| - ForwardTouchEvent(target); |
| + touch_event_.MovePoint(0, params_.anchor.x(), floor(current_y_0)); |
| + touch_event_.MovePoint(1, params_.anchor.x(), floor(current_y_1)); |
| + ForwardTouchEvent(target, timestamp); |
| } |
| -void SyntheticPinchGesture::ReleaseTouchPoints(SyntheticGestureTarget* target) { |
| +void SyntheticPinchGesture::ReleaseTouchPoints( |
| + SyntheticGestureTarget* target, const base::TimeTicks& timestamp) { |
| touch_event_.ReleasePoint(0); |
| touch_event_.ReleasePoint(1); |
| - ForwardTouchEvent(target); |
| + ForwardTouchEvent(target, timestamp); |
| } |
| - |
| -void SyntheticPinchGesture::ForwardTouchEvent(SyntheticGestureTarget* target) |
| - const { |
| +void SyntheticPinchGesture::ForwardTouchEvent( |
| + SyntheticGestureTarget* target, const base::TimeTicks& timestamp) { |
| + touch_event_.timeStampSeconds = ConvertTimestampToSeconds(timestamp); |
| target->DispatchInputEventToPlatform( |
| InputEvent(touch_event_, ui::LatencyInfo(), false)); |
| } |
| @@ -125,42 +127,49 @@ void SyntheticPinchGesture::SetupCoordinates(SyntheticGestureTarget* target) { |
| // Move pointers away from each other to zoom in |
| // or towards each other to zoom out. |
| if (params_.zoom_in) { |
| - current_y_0_ = params_.anchor.y() - inner_distance_to_anchor; |
| - current_y_1_ = params_.anchor.y() + inner_distance_to_anchor; |
| + start_y_0_ = params_.anchor.y() - inner_distance_to_anchor; |
| + start_y_1_ = params_.anchor.y() + inner_distance_to_anchor; |
| target_y_0_ = params_.anchor.y() - outer_distance_to_anchor; |
| target_y_1_ = params_.anchor.y() + outer_distance_to_anchor; |
| } else { |
| - current_y_0_ = params_.anchor.y() - outer_distance_to_anchor; |
| - current_y_1_ = params_.anchor.y() + outer_distance_to_anchor; |
| + start_y_0_ = params_.anchor.y() - outer_distance_to_anchor; |
| + start_y_1_ = params_.anchor.y() + outer_distance_to_anchor; |
| target_y_0_ = params_.anchor.y() - inner_distance_to_anchor; |
| target_y_1_ = params_.anchor.y() + inner_distance_to_anchor; |
| } |
| } |
| -float SyntheticPinchGesture::GetDeltaForPointer0( |
| - const base::TimeDelta& interval) const { |
| - float total_abs_delta = |
| - params_.relative_pointer_speed_in_pixels_s * interval.InSecondsF(); |
| +float SyntheticPinchGesture::GetDeltaForPointer0AndUpdateTimestamp( |
| + base::TimeTicks* timestamp) const { |
| + float total_abs_delta = params_.relative_pointer_speed_in_pixels_s * |
|
jdduke (slow)
2014/01/03 18:24:30
DCHECK(timestamp);
Dominik Grewe
2014/01/06 11:46:07
Done.
|
| + (*timestamp - start_time_).InSecondsF(); |
| // Make sure we're not moving too far in the final step. |
| - total_abs_delta = |
| - std::min(total_abs_delta, ComputeAbsoluteRemainingDistance()); |
| + if (total_abs_delta > ComputeAbsoluteDistance()) { |
| + total_abs_delta = ComputeAbsoluteDistance(); |
| + |
| + // Update timestamp to match the end of the gesture. |
| + int total_duration_in_ms = (1000.0f * ComputeAbsoluteDistance()) / |
|
jdduke (slow)
2014/01/03 18:24:30
Nit: This may be slightly more readable as:
1000
Dominik Grewe
2014/01/06 11:46:07
Done.
|
| + params_.relative_pointer_speed_in_pixels_s; |
| + *timestamp = |
| + start_time_ + base::TimeDelta::FromMilliseconds(total_duration_in_ms); |
| + } |
| float abs_delta_pointer_0 = total_abs_delta / 2; |
| return params_.zoom_in ? -abs_delta_pointer_0 : abs_delta_pointer_0; |
| } |
| -float SyntheticPinchGesture::ComputeAbsoluteRemainingDistance() const { |
| - float distance_0 = params_.zoom_in ? (current_y_0_ - target_y_0_) |
| - : (target_y_0_ - current_y_0_); |
| +float SyntheticPinchGesture::ComputeAbsoluteDistance() const { |
| + float distance_0 = |
| + params_.zoom_in ? (start_y_0_ - target_y_0_) : (target_y_0_ - start_y_0_); |
| DCHECK_GE(distance_0, 0); |
| // Both pointers move the same overall distance at the same speed. |
| return 2 * distance_0; |
| } |
| -bool SyntheticPinchGesture::HasReachedTarget() const { |
| - return ComputeAbsoluteRemainingDistance() == 0; |
| +bool SyntheticPinchGesture::HasReachedTarget(float delta) const { |
| + return start_y_0_ + delta == target_y_0_; |
|
jdduke (slow)
2014/01/03 18:24:30
Is it possible we'd run into floating point precis
Dominik Grewe
2014/01/06 11:46:07
I don't think that this could cause problems. In t
|
| } |
| } // namespace content |