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 
5 #ifndef CC_INPUT_SNAP_FLING_CONTROLLER_H_
6 #define CC_INPUT_SNAP_FLING_CONTROLLER_H_
7 
8 #include <memory>
9 
10 #include "base/time/time.h"
11 #include "cc/cc_export.h"
12 #include "ui/gfx/geometry/vector2d_f.h"
13 
14 namespace cc {
15 namespace test {
16 class SnapFlingControllerTest;
17 }
18 
19 class SnapFlingCurve;
20 
21 // A client that provides information to the controller. It also executes the
22 // scroll operations and requests animation frames. All the inputs and outputs
23 // are in the same coordinate space.
24 class SnapFlingClient {
25  public:
26   virtual bool GetSnapFlingInfoAndSetAnimatingSnapTarget(
27       const gfx::Vector2dF& natural_displacement,
28       gfx::Vector2dF* out_initial_position,
29       gfx::Vector2dF* out_target_position) const = 0;
30   virtual gfx::Vector2dF ScrollByForSnapFling(const gfx::Vector2dF& delta) = 0;
31   virtual void ScrollEndForSnapFling(bool did_finish) = 0;
32   virtual void RequestAnimationForSnapFling() = 0;
33 };
34 
35 // SnapFlingController ensures that an incoming fling event (or inertial-phase
36 // scroll event) would land on a snap position if there is a valid one nearby.
37 // It takes an input event, filters it if it conflicts with the current fling,
38 // or generates a curve if the SnapFlingClient finds a valid snap position.
39 // It also animates the curve by notifying the client to scroll when clock
40 // ticks.
41 class CC_EXPORT SnapFlingController {
42  public:
43   enum class GestureScrollType { kBegin, kUpdate, kEnd };
44 
45   struct GestureScrollUpdateInfo {
46     gfx::Vector2dF delta;
47     bool is_in_inertial_phase;
48     base::TimeTicks event_time;
49   };
50 
51   explicit SnapFlingController(SnapFlingClient* client);
52 
53   static std::unique_ptr<SnapFlingController> CreateForTests(
54       SnapFlingClient* client,
55       std::unique_ptr<SnapFlingCurve> curve);
56 
57   SnapFlingController(const SnapFlingController&) = delete;
58   ~SnapFlingController();
59 
60   SnapFlingController& operator=(const SnapFlingController&) = delete;
61 
62   // Returns true if the event should be consumed for snapping and should not be
63   // processed further.
64   bool FilterEventForSnap(GestureScrollType gesture_scroll_type);
65 
66   // Creates the snap fling curve from the first inertial GSU. Returns true if
67   // the event if a snap fling curve has been created and the event should not
68   // be processed further.
69   bool HandleGestureScrollUpdate(const GestureScrollUpdateInfo& info);
70 
71   // Notifies the snap fling controller to update or end the scroll animation.
72   void Animate(base::TimeTicks time);
73 
74  private:
75   friend class test::SnapFlingControllerTest;
76 
77   enum class State {
78     // We haven't received an inertial GSU in this scroll sequence.
79     kIdle,
80     // We have received an inertial GSU but decided not to snap for this scroll
81     // sequence.
82     kIgnored,
83     // We have received an inertial GSU and decided to snap and animate it for
84     // this scroll sequence. So subsequent GSUs and GSE in the scroll sequence
85     // are consumed for snapping.
86     kActive,
87     // The animation of the snap fling has finished for this scroll sequence.
88     // Subsequent GSUs and GSE in the scroll sequence are ignored.
89     kFinished,
90   };
91 
92   SnapFlingController(SnapFlingClient* client,
93                       std::unique_ptr<SnapFlingCurve> curve);
94   void ClearSnapFling();
95 
96   // Sets the |curve_| to |curve| and the |state| to |kActive|.
97   void SetCurveForTest(std::unique_ptr<SnapFlingCurve> curve);
98 
SetActiveStateForTest()99   void SetActiveStateForTest() { state_ = State::kActive; }
100 
101   SnapFlingClient* client_;
102   State state_ = State::kIdle;
103   std::unique_ptr<SnapFlingCurve> curve_;
104 };
105 
106 }  // namespace cc
107 
108 #endif  // CC_INPUT_SNAP_FLING_CONTROLLER_H_
109