summaryrefslogtreecommitdiffstats
path: root/chromium/content/browser/renderer_host/input/synthetic_pinch_gesture.cc
diff options
context:
space:
mode:
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.cc169
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