diff options
Diffstat (limited to 'chromium/content/browser/renderer_host/input/synthetic_pinch_gesture.cc')
-rw-r--r-- | chromium/content/browser/renderer_host/input/synthetic_pinch_gesture.cc | 169 |
1 files changed, 84 insertions, 85 deletions
diff --git a/chromium/content/browser/renderer_host/input/synthetic_pinch_gesture.cc b/chromium/content/browser/renderer_host/input/synthetic_pinch_gesture.cc index dfe5cf474e7..53e15d78fda 100644 --- a/chromium/content/browser/renderer_host/input/synthetic_pinch_gesture.cc +++ b/chromium/content/browser/renderer_host/input/synthetic_pinch_gesture.cc @@ -7,7 +7,6 @@ #include <cmath> #include "base/logging.h" -#include "content/common/input/input_event.h" #include "ui/events/latency_info.h" namespace content { @@ -15,33 +14,30 @@ namespace content { SyntheticPinchGesture::SyntheticPinchGesture( const SyntheticPinchGestureParams& params) : params_(params), - current_y_0_(0.0f), - current_y_1_(0.0f), - target_y_0_(0.0f), - target_y_1_(0.0f), + start_y_0_(0.0f), + start_y_1_(0.0f), + max_pointer_delta_0_(0.0f), gesture_source_type_(SyntheticGestureParams::DEFAULT_INPUT), state_(SETUP) { - DCHECK_GE(params_.total_num_pixels_covered, 0); + DCHECK_GT(params_.scale_factor, 0.0f); } 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) gesture_source_type_ = target->GetDefaultSyntheticGestureSourceType(); - if (!target->SupportsSyntheticGestureSourceType(gesture_source_type_)) - 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,26 +46,27 @@ 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. - if (params_.total_num_pixels_covered == 0) { + if (params_.scale_factor == 1.0f) { state_ = DONE; break; } - SetupCoordinates(target); - PressTouchPoints(target); + SetupCoordinatesAndStopTime(target); + PressTouchPoints(target, timestamp); state_ = MOVING; break; - case MOVING: - UpdateTouchPoints(interval); - MoveTouchPoints(target); - if (HasReachedTarget()) { - ReleaseTouchPoints(target); + case MOVING: { + base::TimeTicks event_timestamp = ClampTimestamp(timestamp); + float delta = GetDeltaForPointer0AtTime(event_timestamp); + MoveTouchPoints(target, delta, event_timestamp); + if (HasReachedTarget(event_timestamp)) { + ReleaseTouchPoints(target, event_timestamp); state_ = DONE; } - break; + } break; case SETUP: NOTREACHED() << "State SETUP invalid for synthetic pinch."; case DONE: @@ -77,90 +74,92 @@ 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(), current_y_0); + touch_event_.MovePoint(1, params_.anchor.x(), 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 { - target->DispatchInputEventToPlatform( - InputEvent(touch_event_, ui::LatencyInfo(), false)); +void SyntheticPinchGesture::ForwardTouchEvent( + SyntheticGestureTarget* target, const base::TimeTicks& timestamp) { + touch_event_.timeStampSeconds = ConvertTimestampToSeconds(timestamp); + target->DispatchInputEventToPlatform(touch_event_); } -void SyntheticPinchGesture::SetupCoordinates(SyntheticGestureTarget* target) { - const float kTouchSlopInDips = target->GetTouchSlopInDips(); - float inner_distance_to_anchor = 2 * kTouchSlopInDips; - float outer_distance_to_anchor = inner_distance_to_anchor + - params_.total_num_pixels_covered / 2.0f + - kTouchSlopInDips; - - // 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; - 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; - target_y_0_ = params_.anchor.y() - inner_distance_to_anchor; - target_y_1_ = params_.anchor.y() + inner_distance_to_anchor; +void SyntheticPinchGesture::SetupCoordinatesAndStopTime( + SyntheticGestureTarget* target) { + // To achieve the specified scaling factor, the ratio of the final to the + // initial span (distance between the pointers) has to be equal to the scaling + // factor. Since we're moving both pointers at the same speed, each pointer's + // distance to the anchor is half the span. + float initial_distance_to_anchor, final_distance_to_anchor; + if (params_.scale_factor > 1.0f) { // zooming in + initial_distance_to_anchor = target->GetMinScalingSpanInDips() / 2.0f; + final_distance_to_anchor = + (initial_distance_to_anchor + target->GetTouchSlopInDips()) * + params_.scale_factor; + } else { // zooming out + final_distance_to_anchor = target->GetMinScalingSpanInDips() / 2.0f; + initial_distance_to_anchor = + (final_distance_to_anchor / params_.scale_factor) + + target->GetTouchSlopInDips(); } -} -float SyntheticPinchGesture::GetDeltaForPointer0( - const base::TimeDelta& interval) const { - float total_abs_delta = - params_.relative_pointer_speed_in_pixels_s * interval.InSecondsF(); + start_y_0_ = params_.anchor.y() - initial_distance_to_anchor; + start_y_1_ = params_.anchor.y() + initial_distance_to_anchor; - // Make sure we're not moving too far in the final step. - total_abs_delta = - std::min(total_abs_delta, ComputeAbsoluteRemainingDistance()); + max_pointer_delta_0_ = initial_distance_to_anchor - final_distance_to_anchor; - float abs_delta_pointer_0 = total_abs_delta / 2; - return params_.zoom_in ? -abs_delta_pointer_0 : abs_delta_pointer_0; + int64 total_duration_in_us = static_cast<int64>( + 1e6 * (static_cast<double>(std::abs(2 * max_pointer_delta_0_)) / + params_.relative_pointer_speed_in_pixels_s)); + DCHECK_GT(total_duration_in_us, 0); + stop_time_ = + start_time_ + base::TimeDelta::FromMicroseconds(total_duration_in_us); } -float SyntheticPinchGesture::ComputeAbsoluteRemainingDistance() const { - float distance_0 = params_.zoom_in ? (current_y_0_ - target_y_0_) - : (target_y_0_ - current_y_0_); - DCHECK_GE(distance_0, 0); +float SyntheticPinchGesture::GetDeltaForPointer0AtTime( + 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 (HasReachedTarget(timestamp)) + return max_pointer_delta_0_; + + float total_abs_delta = params_.relative_pointer_speed_in_pixels_s * + (timestamp - start_time_).InSecondsF(); + float abs_delta_pointer_0 = total_abs_delta / 2.0f; + return (params_.scale_factor > 1.0f) ? -abs_delta_pointer_0 + : abs_delta_pointer_0; +} - // Both pointers move the same overall distance at the same speed. - return 2 * distance_0; +base::TimeTicks SyntheticPinchGesture::ClampTimestamp( + const base::TimeTicks& timestamp) const { + return std::min(timestamp, stop_time_); } -bool SyntheticPinchGesture::HasReachedTarget() const { - return ComputeAbsoluteRemainingDistance() == 0; +bool SyntheticPinchGesture::HasReachedTarget(const base::TimeTicks& timestamp) + const { + return timestamp >= stop_time_; } } // namespace content |