// Copyright 2018 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 "cc/input/snap_fling_controller.h" #include "cc/input/snap_fling_curve.h" namespace cc { SnapFlingController::SnapFlingController(SnapFlingClient* client) : client_(client), state_(State::kIdle) {} SnapFlingController::~SnapFlingController() = default; bool SnapFlingController::FilterEventForSnap( SnapFlingController::GestureScrollType gesture_scroll_type) { switch (gesture_scroll_type) { case GestureScrollType::kBegin: { ClearSnapFling(); return false; } // TODO(sunyunjia): Need to update the existing snap curve if the GSU is // from a fling boosting event. case GestureScrollType::kUpdate: case GestureScrollType::kEnd: { return state_ == State::kActive || state_ == State::kFinished; } } } void SnapFlingController::ClearSnapFling() { if (state_ == State::kActive) client_->ScrollEndForSnapFling(false /* did_finish */); curve_.reset(); state_ = State::kIdle; } bool SnapFlingController::HandleGestureScrollUpdate( const SnapFlingController::GestureScrollUpdateInfo& info) { DCHECK(state_ != State::kActive && state_ != State::kFinished); if (state_ != State::kIdle) return false; if (!info.is_in_inertial_phase) return false; gfx::Vector2dF ending_displacement = SnapFlingCurve::EstimateDisplacement(info.delta); gfx::Vector2dF target_offset, start_offset; if (!client_->GetSnapFlingInfoAndSetAnimatingSnapTarget( ending_displacement, &start_offset, &target_offset)) { state_ = State::kIgnored; return false; } if (start_offset == target_offset) { state_ = State::kFinished; return true; } curve_ = std::make_unique(start_offset, target_offset, info.event_time); state_ = State::kActive; Animate(info.event_time); return true; } void SnapFlingController::Animate(base::TimeTicks time) { if (state_ != State::kActive) return; if (curve_->IsFinished()) { client_->ScrollEndForSnapFling(true /* did_finish */); state_ = State::kFinished; return; } gfx::Vector2dF snapped_delta = curve_->GetScrollDelta(time); gfx::Vector2dF current_offset = client_->ScrollByForSnapFling(snapped_delta); curve_->UpdateCurrentOffset(current_offset); client_->RequestAnimationForSnapFling(); } void SnapFlingController::SetCurveForTest( std::unique_ptr curve) { curve_ = std::move(curve); state_ = State::kActive; } } // namespace cc