Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.h " | |
| 6 | |
| 7 #include <cmath> | |
| 8 | |
| 9 #include "base/logging.h" | |
| 10 #include "ui/events/latency_info.h" | |
|
jdduke (slow)
2015/09/22 18:52:37
Do we need the latency_info include?
ericrk
2015/09/22 21:46:26
nope.
| |
| 11 | |
| 12 namespace content { | |
| 13 namespace { | |
| 14 | |
| 15 float Lerp(float start, float end, float progress) { | |
| 16 return start + progress * (end - start); | |
| 17 } | |
| 18 | |
| 19 } // namespace | |
| 20 | |
| 21 SyntheticTouchpadPinchGesture::SyntheticTouchpadPinchGesture( | |
| 22 const SyntheticPinchGestureParams& params) | |
| 23 : params_(params), | |
| 24 gesture_source_type_(SyntheticGestureParams::DEFAULT_INPUT), | |
| 25 state_(SETUP), | |
| 26 current_scale_(1.0f) { | |
| 27 DCHECK_GT(params_.scale_factor, 0.0f); | |
| 28 } | |
| 29 | |
| 30 SyntheticTouchpadPinchGesture::~SyntheticTouchpadPinchGesture() {} | |
| 31 | |
| 32 SyntheticGesture::Result SyntheticTouchpadPinchGesture::ForwardInputEvents( | |
| 33 const base::TimeTicks& timestamp, | |
| 34 SyntheticGestureTarget* target) { | |
| 35 if (state_ == SETUP) { | |
| 36 gesture_source_type_ = params_.gesture_source_type; | |
| 37 if (gesture_source_type_ == SyntheticGestureParams::DEFAULT_INPUT) | |
| 38 gesture_source_type_ = target->GetDefaultSyntheticGestureSourceType(); | |
| 39 | |
| 40 state_ = STARTED; | |
| 41 start_time_ = timestamp; | |
| 42 } | |
| 43 | |
| 44 DCHECK_NE(gesture_source_type_, SyntheticGestureParams::DEFAULT_INPUT); | |
| 45 if (gesture_source_type_ == SyntheticGestureParams::MOUSE_INPUT) { | |
| 46 ForwardGestureEvents(timestamp, target); | |
| 47 } else { | |
| 48 // Touch input should be using SyntheticTouchscreenPinchGesture. | |
| 49 return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_IMPLEMENTED; | |
| 50 } | |
| 51 | |
| 52 return (state_ == DONE) ? SyntheticGesture::GESTURE_FINISHED | |
| 53 : SyntheticGesture::GESTURE_RUNNING; | |
| 54 } | |
| 55 | |
| 56 void SyntheticTouchpadPinchGesture::ForwardGestureEvents( | |
| 57 const base::TimeTicks& timestamp, | |
| 58 SyntheticGestureTarget* target) { | |
| 59 switch (state_) { | |
| 60 case STARTED: | |
| 61 // Check for an early finish. | |
| 62 if (params_.scale_factor == 1.0f) { | |
| 63 state_ = DONE; | |
| 64 break; | |
| 65 } | |
| 66 | |
| 67 CalculateEndTime(target); | |
| 68 | |
| 69 // Send the start event. | |
| 70 target->DispatchInputEventToPlatform( | |
| 71 SyntheticWebGestureEventBuilder::Build( | |
| 72 blink::WebGestureEvent::GesturePinchBegin, | |
| 73 blink::WebGestureDeviceTouchpad)); | |
| 74 state_ = IN_PROGRESS; | |
| 75 break; | |
| 76 case IN_PROGRESS: { | |
| 77 base::TimeTicks event_timestamp = ClampTimestamp(timestamp); | |
| 78 | |
| 79 float target_scale = CalculateTargetScale(event_timestamp); | |
| 80 float incremental_scale = target_scale / current_scale_; | |
| 81 current_scale_ = target_scale; | |
| 82 | |
| 83 // Send the incremental scale event. | |
| 84 target->DispatchInputEventToPlatform( | |
| 85 SyntheticWebGestureEventBuilder::BuildPinchUpdate( | |
| 86 incremental_scale, params_.anchor.x(), params_.anchor.y(), | |
| 87 0 /* modifierFlags */, blink::WebGestureDeviceTouchpad)); | |
| 88 | |
| 89 if (HasReachedTarget(event_timestamp)) { | |
| 90 target->DispatchInputEventToPlatform( | |
| 91 SyntheticWebGestureEventBuilder::Build( | |
| 92 blink::WebGestureEvent::GesturePinchEnd, | |
| 93 blink::WebGestureDeviceTouchpad)); | |
| 94 state_ = DONE; | |
| 95 } | |
| 96 break; | |
| 97 } | |
| 98 case SETUP: | |
| 99 NOTREACHED() << "State SETUP invalid for synthetic pinch."; | |
| 100 case DONE: | |
| 101 NOTREACHED() << "State DONE invalid for synthetic pinch."; | |
| 102 } | |
| 103 } | |
| 104 | |
| 105 float SyntheticTouchpadPinchGesture::CalculateTargetScale( | |
| 106 const base::TimeTicks& timestamp) const { | |
| 107 // Make sure the final delta is correct. Using the computation below can lead | |
| 108 // to issues with floating point precision. | |
| 109 if (HasReachedTarget(timestamp)) | |
| 110 return params_.scale_factor; | |
| 111 | |
| 112 float progress = (timestamp - start_time_).InSecondsF() / | |
| 113 (stop_time_ - start_time_).InSecondsF(); | |
| 114 return Lerp(1.0f, params_.scale_factor, progress); | |
| 115 } | |
| 116 | |
| 117 // Calculate an end time based on the amount of scaling to be done and the | |
| 118 // |relative_pointer_speed_in_pixels_s|. Because we don't have an actual pixel | |
| 119 // delta, we assume that a pinch of 200 pixels is needed to double the screen | |
| 120 // size and generate a stop time based on that. | |
| 121 void SyntheticTouchpadPinchGesture::CalculateEndTime( | |
| 122 SyntheticGestureTarget* target) { | |
| 123 const int kPixelsNeededToDoubleOrHalve = 200; | |
| 124 | |
| 125 float scale_factor = params_.scale_factor; | |
| 126 if (scale_factor < 1.0f) { | |
| 127 // If we are scaling down, calculate the time based on the inverse so that | |
| 128 // halving or doubling the scale takes the same amount of time. | |
| 129 scale_factor = 1.0f / scale_factor; | |
| 130 } | |
| 131 float scale_factor_delta = | |
| 132 (scale_factor - 1.0f) * kPixelsNeededToDoubleOrHalve; | |
| 133 | |
| 134 int64 total_duration_in_us = | |
| 135 static_cast<int64>(1e6 * (static_cast<double>(scale_factor_delta) / | |
| 136 params_.relative_pointer_speed_in_pixels_s)); | |
|
jdduke (slow)
2015/09/22 18:52:37
Hmm, yeah, this parameter should really have just
ericrk
2015/09/22 21:46:26
Done - filed a bug as well.
| |
| 137 DCHECK_GT(total_duration_in_us, 0); | |
| 138 stop_time_ = | |
| 139 start_time_ + base::TimeDelta::FromMicroseconds(total_duration_in_us); | |
| 140 } | |
| 141 | |
| 142 base::TimeTicks SyntheticTouchpadPinchGesture::ClampTimestamp( | |
| 143 const base::TimeTicks& timestamp) const { | |
| 144 return std::min(timestamp, stop_time_); | |
| 145 } | |
| 146 | |
| 147 bool SyntheticTouchpadPinchGesture::HasReachedTarget( | |
| 148 const base::TimeTicks& timestamp) const { | |
| 149 return timestamp >= stop_time_; | |
| 150 } | |
| 151 | |
| 152 } // namespace content | |
| OLD | NEW |