summaryrefslogtreecommitdiffstats
path: root/ui/events/android/scroller.h
blob: 37d41cd3e1bfa127dbe0c50234982bb1740e6485 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright 2014 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.

#ifndef UI_EVENTS_ANDROID_SCROLLER_H_
#define UI_EVENTS_ANDROID_SCROLLER_H_

#include "base/time/time.h"
#include "ui/events/events_base_export.h"
#include "ui/events/gesture_curve.h"
#include "ui/gfx/geometry/vector2d_f.h"

namespace ui {

// Native port of android.widget.Scroller.
// * Change-Id: I4365946f890a76fcfa78ca9d69f2a8e0848095a9
// * Please update the Change-Id as upstream Android changes are pulled.
class EVENTS_BASE_EXPORT Scroller : public GestureCurve {
 public:
  struct Config {
    Config();

    // Controls fling deceleration. Defaults to 0.015f.
    float fling_friction;

    // Controls fling accumulation. Defaults to disabled.
    bool flywheel_enabled;
  };

  explicit Scroller(const Config& config);
  ~Scroller() override;

  // GestureCurve implementation.
  bool ComputeScrollOffset(base::TimeTicks time,
                           gfx::Vector2dF* offset,
                           gfx::Vector2dF* velocity) override;

  // Start scrolling by providing a starting point and the distance to travel.
  // The default value of 250 milliseconds will be used for the duration.
  void StartScroll(float start_x,
                   float start_y,
                   float dx,
                   float dy,
                   base::TimeTicks start_time);

  // Start scrolling by providing a starting point, the distance to travel,
  // and the duration of the scroll.
  void StartScroll(float start_x,
                   float start_y,
                   float dx,
                   float dy,
                   base::TimeTicks start_time,
                   base::TimeDelta duration);

  // Start scrolling based on a fling gesture. The distance travelled will
  // depend on the initial velocity of the fling.
  void Fling(float start_x,
             float start_y,
             float velocity_x,
             float velocity_y,
             float min_x,
             float max_x,
             float min_y,
             float max_y,
             base::TimeTicks start_time);

  // Extend the scroll animation by |extend|. This allows a running animation
  // to scroll further and longer when used with |SetFinalX()| or |SetFinalY()|.
  void ExtendDuration(base::TimeDelta extend);
  void SetFinalX(float new_x);
  void SetFinalY(float new_y);

  // Stops the animation. Contrary to |ForceFinished()|, aborting the animation
  // causes the scroller to move to the final x and y position.
  void AbortAnimation();

  // Terminate the scroll without affecting the current x and y positions.
  void ForceFinished(bool finished);

  // Returns whether the scroller has finished scrolling.
  bool IsFinished() const;

  // Returns the time elapsed since the beginning of the scrolling.
  base::TimeDelta GetTimePassed() const;

  // Returns how long the scroll event will take.
  base::TimeDelta GetDuration() const;

  float GetStartX() const;
  float GetStartY() const;
  float GetCurrX() const;
  float GetCurrY() const;
  float GetCurrVelocity() const;
  float GetCurrVelocityX() const;
  float GetCurrVelocityY() const;
  float GetFinalX() const;
  float GetFinalY() const;

  bool IsScrollingInDirection(float xvel, float yvel) const;

 private:
  enum Mode {
    UNDEFINED,
    SCROLL_MODE,
    FLING_MODE,
  };

  bool ComputeScrollOffsetInternal(base::TimeTicks time);
  void RecomputeDeltas();

  double GetSplineDeceleration(float velocity) const;
  base::TimeDelta GetSplineFlingDuration(float velocity) const;
  double GetSplineFlingDistance(float velocity) const;

  Mode mode_;

  float start_x_;
  float start_y_;
  float final_x_;
  float final_y_;

  float min_x_;
  float max_x_;
  float min_y_;
  float max_y_;

  float curr_x_;
  float curr_y_;
  base::TimeTicks start_time_;
  base::TimeTicks curr_time_;
  base::TimeDelta duration_;
  double duration_seconds_reciprocal_;
  float delta_x_;
  float delta_x_norm_;
  float delta_y_;
  float delta_y_norm_;
  bool finished_;
  bool flywheel_enabled_;

  float velocity_;
  float curr_velocity_;
  float distance_;

  float fling_friction_;
  float deceleration_;
  float tuning_coeff_;
};

}  // namespace ui

#endif  // UI_EVENTS_ANDROID_SCROLLER_H_