snap_fling_controller.cc 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // Copyright 2018 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. #include "cc/input/snap_fling_controller.h"
  5. #include <utility>
  6. #include "cc/input/snap_fling_curve.h"
  7. namespace cc {
  8. SnapFlingController::SnapFlingController(SnapFlingClient* client)
  9. : client_(client), state_(State::kIdle) {}
  10. SnapFlingController::~SnapFlingController() = default;
  11. bool SnapFlingController::FilterEventForSnap(
  12. SnapFlingController::GestureScrollType gesture_scroll_type) {
  13. switch (gesture_scroll_type) {
  14. case GestureScrollType::kBegin: {
  15. ClearSnapFling();
  16. return false;
  17. }
  18. // TODO(sunyunjia): Need to update the existing snap curve if the GSU is
  19. // from a fling boosting event.
  20. case GestureScrollType::kUpdate:
  21. case GestureScrollType::kEnd: {
  22. return state_ == State::kActive || state_ == State::kFinished;
  23. }
  24. }
  25. }
  26. void SnapFlingController::ClearSnapFling() {
  27. if (state_ == State::kActive)
  28. client_->ScrollEndForSnapFling(false /* did_finish */);
  29. curve_.reset();
  30. state_ = State::kIdle;
  31. }
  32. bool SnapFlingController::HandleGestureScrollUpdate(
  33. const SnapFlingController::GestureScrollUpdateInfo& info) {
  34. DCHECK(state_ != State::kActive && state_ != State::kFinished);
  35. if (state_ != State::kIdle)
  36. return false;
  37. if (!info.is_in_inertial_phase)
  38. return false;
  39. gfx::Vector2dF ending_displacement =
  40. SnapFlingCurve::EstimateDisplacement(info.delta);
  41. gfx::PointF target_offset, start_offset;
  42. if (!client_->GetSnapFlingInfoAndSetAnimatingSnapTarget(
  43. ending_displacement, &start_offset, &target_offset)) {
  44. state_ = State::kIgnored;
  45. return false;
  46. }
  47. if (start_offset == target_offset) {
  48. client_->ScrollEndForSnapFling(true /* did_finish */);
  49. state_ = State::kFinished;
  50. return true;
  51. }
  52. curve_ = std::make_unique<SnapFlingCurve>(start_offset, target_offset,
  53. info.event_time);
  54. state_ = State::kActive;
  55. Animate(info.event_time);
  56. return true;
  57. }
  58. void SnapFlingController::Animate(base::TimeTicks time) {
  59. if (state_ != State::kActive)
  60. return;
  61. if (curve_->IsFinished()) {
  62. client_->ScrollEndForSnapFling(true /* did_finish */);
  63. state_ = State::kFinished;
  64. return;
  65. }
  66. gfx::Vector2dF snapped_delta = curve_->GetScrollDelta(time);
  67. gfx::PointF current_offset = client_->ScrollByForSnapFling(snapped_delta);
  68. curve_->UpdateCurrentOffset(current_offset);
  69. client_->RequestAnimationForSnapFling();
  70. }
  71. void SnapFlingController::SetCurveForTest(
  72. std::unique_ptr<SnapFlingCurve> curve) {
  73. curve_ = std::move(curve);
  74. state_ = State::kActive;
  75. }
  76. } // namespace cc