| 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
|
|
|