1 // Copyright (c) 2011 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_ANIMATION_MULTI_ANIMATION_H_
6 #define UI_GFX_ANIMATION_MULTI_ANIMATION_H_
7 
8 #include <stddef.h>
9 
10 #include <vector>
11 
12 #include "base/macros.h"
13 #include "base/time/time.h"
14 #include "ui/gfx/animation/animation.h"
15 #include "ui/gfx/animation/tween.h"
16 
17 namespace gfx {
18 
19 // MultiAnimation is an animation that consists of a number of sub animations.
20 // To create a MultiAnimation pass in the parts, invoke Start() and the delegate
21 // is notified as the animation progresses. By default MultiAnimation runs until
22 // Stop is invoked, see |set_continuous()| for details.
23 class ANIMATION_EXPORT MultiAnimation : public Animation {
24  public:
25   // Defines part of the animation. Each part consists of the following:
26   //
27   // part_length: the length of time the part runs.
28   // part_start: the amount of time to offset this part by when calculating the
29   // initial percentage.
30   // total_length: the total length used to calculate the percentange completed.
31   //
32   // In most cases |part_start| is empty and |total_length| = |part_length|. But
33   // you can adjust the start/total for different effects. For example, to run a
34   // part for 200ms with a % between .25 and .75 use the following three values:
35   // part_length = 200, part_start = 100, total_length = 400.
36   struct Part {
PartPart37     Part() : Part(base::TimeDelta(), Tween::ZERO) {}
PartPart38     Part(base::TimeDelta part_length, Tween::Type type)
39         : Part(part_length, base::TimeDelta(), part_length, type) {}
PartPart40     Part(base::TimeDelta part_length,
41          base::TimeDelta part_start,
42          base::TimeDelta total_length,
43          Tween::Type type)
44         : part_length(part_length),
45           part_start(part_start),
46           total_length(total_length),
47           type(type) {}
48 
49     base::TimeDelta part_length;
50     base::TimeDelta part_start;
51     base::TimeDelta total_length;
52     Tween::Type type;
53   };
54   using Parts = std::vector<Part>;
55 
56   static constexpr auto kDefaultTimerInterval =
57       base::TimeDelta::FromMilliseconds(20);
58 
59   MultiAnimation(const Parts& parts, base::TimeDelta timer_interval);
60   ~MultiAnimation() override;
61 
62   // Sets whether the animation continues after it reaches the end. If true, the
63   // animation runs until explicitly stopped. The default is true.
set_continuous(bool continuous)64   void set_continuous(bool continuous) { continuous_ = continuous; }
65 
66   // Returns the current value. The current value for a MultiAnimation is
67   // determined from the tween type of the current part.
68   double GetCurrentValue() const override;
69 
70   // Returns the index of the current part.
current_part_index()71   size_t current_part_index() const { return current_part_index_; }
72 
73  protected:
74   // Animation overrides.
75   void Step(base::TimeTicks time_now) override;
76   void SetStartTime(base::TimeTicks start_time) override;
77 
78  private:
79   // Returns the part containing the specified time. |time| is reset to be
80   // relative to the part containing the time and |part_index| the index of the
81   // part.
82   const Part& GetPart(base::TimeDelta* time, size_t* part_index);
83 
84   // The parts that make up the animation.
85   const Parts parts_;
86 
87   // Total time of all the parts.
88   const base::TimeDelta cycle_time_;
89 
90   // Current value for the animation.
91   double current_value_;
92 
93   // Index of the current part.
94   size_t current_part_index_;
95 
96   // See description above setter.
97   bool continuous_;
98 
99   DISALLOW_COPY_AND_ASSIGN(MultiAnimation);
100 };
101 
102 }  // namespace gfx
103 
104 #endif  // UI_GFX_ANIMATION_MULTI_ANIMATION_H_
105