1// Copyright 2014 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 UI_GFX_ANDROID_SCROLLER_H_
6#define UI_GFX_ANDROID_SCROLLER_H_
7
8#include "base/time/time.h"
9#include "ui/gfx/gfx_export.h"
10
11namespace gfx {
12
13// Native port of android.widget.Scroller.
14// * Change-Id: I4365946f890a76fcfa78ca9d69f2a8e0848095a9
15// * Please update the Change-Id as upstream Android changes are pulled.
16class GFX_EXPORT Scroller {
17 public:
18  struct Config {
19    Config();
20
21    // Controls fling deceleration. Defaults to 0.015f.
22    float fling_friction;
23
24    // Controls fling accumulation. Defaults to disabled.
25    bool flywheel_enabled;
26  };
27
28  explicit Scroller(const Config& config);
29  ~Scroller();
30
31  // Start scrolling by providing a starting point and the distance to travel.
32  // The default value of 250 milliseconds will be used for the duration.
33  void StartScroll(float start_x,
34                   float start_y,
35                   float dx,
36                   float dy,
37                   base::TimeTicks start_time);
38
39  // Start scrolling by providing a starting point, the distance to travel,
40  // and the duration of the scroll.
41  void StartScroll(float start_x,
42                   float start_y,
43                   float dx,
44                   float dy,
45                   base::TimeTicks start_time,
46                   base::TimeDelta duration);
47
48  // Start scrolling based on a fling gesture. The distance travelled will
49  // depend on the initial velocity of the fling.
50  void Fling(float start_x,
51             float start_y,
52             float velocity_x,
53             float velocity_y,
54             float min_x,
55             float max_x,
56             float min_y,
57             float max_y,
58             base::TimeTicks start_time);
59
60  // Call this when you want to know the new location.  If it returns true,
61  // the animation is not yet finished.
62  bool ComputeScrollOffset(base::TimeTicks time);
63
64  // Extend the scroll animation by |extend|. This allows a running animation
65  // to scroll further and longer when used with |SetFinalX()| or |SetFinalY()|.
66  void ExtendDuration(base::TimeDelta extend);
67  void SetFinalX(float new_x);
68  void SetFinalY(float new_y);
69
70  // Stops the animation. Contrary to |ForceFinished()|, aborting the animation
71  // causes the scroller to move to the final x and y position.
72  void AbortAnimation();
73
74  // Terminate the scroll without affecting the current x and y positions.
75  void ForceFinished(bool finished);
76
77  // Returns whether the scroller has finished scrolling.
78  bool IsFinished() const;
79
80  // Returns the time elapsed since the beginning of the scrolling.
81  base::TimeDelta GetTimePassed() const;
82
83  // Returns how long the scroll event will take.
84  base::TimeDelta GetDuration() const;
85
86  float GetStartX() const;
87  float GetStartY() const;
88  float GetCurrX() const;
89  float GetCurrY() const;
90  float GetCurrVelocity() const;
91  float GetCurrVelocityX() const;
92  float GetCurrVelocityY() const;
93  float GetFinalX() const;
94  float GetFinalY() const;
95
96  bool IsScrollingInDirection(float xvel, float yvel) const;
97
98 private:
99  enum Mode {
100    UNDEFINED,
101    SCROLL_MODE,
102    FLING_MODE,
103  };
104
105  void OnDurationChanged();
106  void RecomputeDeltas();
107
108  double GetSplineDeceleration(float velocity) const;
109  base::TimeDelta GetSplineFlingDuration(float velocity) const;
110  double GetSplineFlingDistance(float velocity) const;
111
112  Mode mode_;
113
114  float start_x_;
115  float start_y_;
116  float final_x_;
117  float final_y_;
118
119  float min_x_;
120  float max_x_;
121  float min_y_;
122  float max_y_;
123
124  float curr_x_;
125  float curr_y_;
126  base::TimeTicks start_time_;
127  base::TimeTicks curr_time_;
128  base::TimeDelta duration_;
129  double duration_seconds_reciprocal_;
130  float delta_x_;
131  float delta_x_norm_;
132  float delta_y_;
133  float delta_y_norm_;
134  bool finished_;
135  bool flywheel_enabled_;
136
137  float velocity_;
138  float curr_velocity_;
139  float distance_;
140
141  float fling_friction_;
142  float deceleration_;
143  float tuning_coeff_;
144};
145
146}  // namespace gfx
147
148#endif  // UI_GFX_ANDROID_SCROLLER_H_
149