Index: content/browser/renderer_host/input/fling/flinger.cc |
diff --git a/content/browser/renderer_host/input/fling/flinger.cc b/content/browser/renderer_host/input/fling/flinger.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ce80e922c6dfd6c1e03962739c1e0cc8977c3da8 |
--- /dev/null |
+++ b/content/browser/renderer_host/input/fling/flinger.cc |
@@ -0,0 +1,172 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// 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/fling/flinger.h" |
+ |
+namespace content { |
+ |
+const float kFrameRate = 60; |
+ |
+Flinger::Flinger(FlingHelper* helper) |
+ : helper_(helper), |
+ fling_in_progress_(false), |
+ ignore_next_tap_(false), |
+ ignore_next_click_(false), |
+ fling_start_time_secs_(0), |
+ fling_source_(blink::WebGestureEvent::Touchscreen) {} |
+ |
+bool Flinger::HandleGestureEvent( |
+ const GestureEventWithLatencyInfo& gesture_event) { |
+ switch (gesture_event.event.type) { |
+ case blink::WebInputEvent::GestureTap: |
+ if (ignore_next_tap_) { |
+ ignore_next_tap_ = false; |
+ return true; |
+ } |
+ break; |
+ case blink::WebInputEvent::GestureFlingStart: |
+ // Ignore zero velocity fling starts |
+ if (gesture_event.event.data.flingStart.velocityX == 0 && |
+ gesture_event.event.data.flingStart.velocityY == 0) |
+ return true; |
+ fling_modifier_ = gesture_event.event.modifiers; |
+ fling_start_position_ = gfx::Point(gesture_event.event.x, |
+ gesture_event.event.y); |
+ fling_start_global_position_ = gfx::Point(gesture_event.event.globalX, |
+ gesture_event.event.globalY); |
+ fling_start_time_secs_ = (base::TimeTicks::Now() - |
+ base::TimeTicks()).InSecondsF(); |
+ fling_source_ = gesture_event.event.sourceDevice; |
+ fling_curve_.reset(FlingCurve::Create( |
+ gesture_event.event.sourceDevice, |
+ gfx::PointF(gesture_event.event.data.flingStart.velocityX, |
+ gesture_event.event.data.flingStart.velocityY), |
+ gfx::Point())); |
+ fling_in_progress_ = true; |
+ // TODO(varunjain): Use vsync instead of this timer. |
+ StartCurveTimer(); |
+ return true; |
+ case blink::WebInputEvent::GestureShowPress: |
+ case blink::WebInputEvent::GestureTapDown: |
+ return ignore_next_tap_; |
+ case blink::WebInputEvent::GestureFlingCancel: |
+ ignore_next_tap_ = false; |
+ ignore_next_click_ = false; |
+ if (fling_in_progress_) { |
+ if (gesture_event.event.sourceDevice == |
+ blink::WebGestureEvent::Touchscreen) |
+ ignore_next_tap_ = true; |
+ else |
+ ignore_next_click_ = true; |
+ } |
+ StopFlingAndCleanup(); |
+ return true; |
+ default: |
+ ignore_next_tap_ = false; |
+ break; |
+ } |
+ return false; |
+} |
+ |
+bool Flinger::HandleMouseEvent(const MouseEventWithLatencyInfo& mouse_event) { |
+ switch (mouse_event.event.type) { |
+ case blink::WebInputEvent::MouseDown: |
+ case blink::WebInputEvent::MouseUp: |
+ return ignore_next_click_; |
+ default: |
+ StopFlingAndCleanup(); |
+ ignore_next_click_ = false; |
+ break; |
+ } |
+ return false; |
+} |
+ |
+bool Flinger::HandleWheelEvent( |
+ const MouseWheelEventWithLatencyInfo& wheel_event) { |
+ StopFlingAndCleanup(); |
+ return false; |
+} |
+ |
+bool Flinger::HandleKeyboardEvent() { |
+ StopFlingAndCleanup(); |
+ return false; |
+} |
+ |
+void Flinger::ProcessEventAck(blink::WebInputEvent::Type type, |
+ InputEventAckState ack_result, |
+ const ui::LatencyInfo& latency) { |
+ if (!fling_in_progress_) |
+ return; |
+ |
+ if ((type == blink::WebInputEvent::GestureScrollUpdate || |
+ type == blink::WebInputEvent::MouseWheel) && |
+ ack_result == content::INPUT_EVENT_ACK_STATE_NOT_CONSUMED) |
+ StopFlingAndCleanup(); |
+} |
+ |
+void Flinger::ScrollBy(const gfx::PointF& delta) { |
+ if (fling_source_ == blink::WebGestureEvent::Touchpad) { |
+ blink::WebMouseWheelEvent synthetic_wheel; |
+ const float tick_divisor = 120; |
+ synthetic_wheel.type = blink::WebInputEvent::MouseWheel; |
+ synthetic_wheel.deltaX = delta.x(); |
+ synthetic_wheel.deltaY = delta.y(); |
+ synthetic_wheel.wheelTicksX = delta.x() / tick_divisor; |
+ synthetic_wheel.wheelTicksY = delta.y() / tick_divisor; |
+ synthetic_wheel.hasPreciseScrollingDeltas = true; |
+ synthetic_wheel.x = fling_start_position_.x(); |
+ synthetic_wheel.y = fling_start_position_.y(); |
+ synthetic_wheel.globalX = fling_start_global_position_.x(); |
+ synthetic_wheel.globalY = fling_start_global_position_.y(); |
+ synthetic_wheel.modifiers = fling_modifier_; |
+ helper_->SendEventForFling(synthetic_wheel); |
+ } else { |
+ blink::WebGestureEvent synthetic_gesture; |
+ synthetic_gesture.type = blink::WebInputEvent::GestureScrollUpdate; |
+ synthetic_gesture.data.scrollUpdate.deltaX = delta.x(); |
+ synthetic_gesture.data.scrollUpdate.deltaY = delta.y(); |
+ synthetic_gesture.x = fling_start_position_.x(); |
+ synthetic_gesture.y = fling_start_position_.y(); |
+ synthetic_gesture.globalX = fling_start_global_position_.x(); |
+ synthetic_gesture.globalY = fling_start_global_position_.y(); |
+ synthetic_gesture.modifiers = fling_modifier_; |
+ synthetic_gesture.sourceDevice = blink::WebGestureEvent::Touchscreen; |
+ helper_->SendEventForFling(synthetic_gesture); |
+ } |
+} |
+ |
+void Flinger::NotifyCurrentFlingVelocity(const gfx::PointF& velocity) { |
+} |
+ |
+void Flinger::StartCurveTimer() { |
+ if (curve_timer_.IsRunning()) |
+ curve_timer_.Stop(); |
+ // TODO(varunjain): Use vsync instead of this timer. |
+ curve_timer_.Start(FROM_HERE, |
+ base::TimeDelta::FromMilliseconds(1000.0 / kFrameRate), |
+ this, |
+ &Flinger::CurveTimerFired); |
+} |
+ |
+void Flinger::CurveTimerFired() { |
+ if (!fling_in_progress_) |
+ return; |
+ double now = (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); |
+ bool curve_done = !fling_curve_->Apply(now - fling_start_time_secs_, this); |
+ if (!curve_done) |
+ StartCurveTimer(); |
+ else |
+ StopFlingAndCleanup(); |
+} |
+ |
+void Flinger::StopFlingAndCleanup() { |
+ if (!fling_in_progress_) |
+ return; |
+ curve_timer_.Stop(); |
+ fling_curve_.reset(); |
+ fling_in_progress_ = false; |
+ helper_->FlingFinished(fling_source_); |
+} |
+ |
+} // namespace content |