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_ANIMATION_H_
6#define UI_GFX_ANIMATION_ANIMATION_H_
7
8#include "base/compiler_specific.h"
9#include "base/memory/ref_counted.h"
10#include "base/time/time.h"
11#include "ui/gfx/animation/animation_container_element.h"
12
13namespace gfx {
14class Rect;
15}
16
17namespace gfx {
18
19class AnimationContainer;
20class AnimationDelegate;
21
22// Base class used in implementing animations. You only need use this class if
23// you're implementing a new animation type, otherwise you'll likely want one of
24// LinearAnimation, SlideAnimation, ThrobAnimation or MultiAnimation.
25//
26// To subclass override Step, which is invoked as the animation progresses and
27// GetCurrentValue() to return the value appropriate to the animation.
28class GFX_EXPORT Animation : public AnimationContainerElement {
29 public:
30  explicit Animation(base::TimeDelta timer_interval);
31  virtual ~Animation();
32
33  // Starts the animation. Does nothing if the animation is already running.
34  void Start();
35
36  // Stops the animation. Does nothing if the animation is not running.
37  void Stop();
38
39  // Gets the value for the current state, according to the animation
40  // curve in use.
41  virtual double GetCurrentValue() const = 0;
42
43  // Convenience for returning a value between |start| and |target| based on
44  // the current value. This is (target - start) * GetCurrentValue() + start.
45  double CurrentValueBetween(double start, double target) const;
46  int CurrentValueBetween(int start, int target) const;
47  gfx::Rect CurrentValueBetween(const gfx::Rect& start_bounds,
48                                const gfx::Rect& target_bounds) const;
49
50  // Sets the delegate.
51  void set_delegate(AnimationDelegate* delegate) { delegate_ = delegate; }
52
53  // Sets the container used to manage the timer. A value of NULL results in
54  // creating a new AnimationContainer.
55  void SetContainer(AnimationContainer* container);
56
57  bool is_animating() const { return is_animating_; }
58
59  base::TimeDelta timer_interval() const { return timer_interval_; }
60
61  // Returns true if rich animations should be rendered.
62  // Looks at session type (e.g. remote desktop) and accessibility settings
63  // to give guidance for heavy animations such as "start download" arrow.
64  static bool ShouldRenderRichAnimation();
65
66 protected:
67  // Invoked from Start to allow subclasses to prepare for the animation.
68  virtual void AnimationStarted() {}
69
70  // Invoked from Stop after we're removed from the container but before the
71  // delegate has been invoked.
72  virtual void AnimationStopped() {}
73
74  // Invoked from stop to determine if cancel should be invoked. If this returns
75  // true the delegate is notified the animation was canceled, otherwise the
76  // delegate is notified the animation stopped.
77  virtual bool ShouldSendCanceledFromStop();
78
79  AnimationContainer* container() { return container_.get(); }
80  base::TimeTicks start_time() const { return start_time_; }
81  AnimationDelegate* delegate() { return delegate_; }
82
83  // AnimationContainer::Element overrides
84  virtual void SetStartTime(base::TimeTicks start_time) OVERRIDE;
85  virtual void Step(base::TimeTicks time_now) = 0;
86  virtual base::TimeDelta GetTimerInterval() const OVERRIDE;
87
88 private:
89  // Interval for the animation.
90  const base::TimeDelta timer_interval_;
91
92  // If true we're running.
93  bool is_animating_;
94
95  // Our delegate; may be null.
96  AnimationDelegate* delegate_;
97
98  // Container we're in. If non-null we're animating.
99  scoped_refptr<AnimationContainer> container_;
100
101  // Time we started at.
102  base::TimeTicks start_time_;
103
104  DISALLOW_COPY_AND_ASSIGN(Animation);
105};
106
107}  // namespace gfx
108
109#endif  // UI_GFX_ANIMATION_ANIMATION_H_
110