1// Copyright (c) 2012 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_VIEWS_ANIMATION_BOUNDS_ANIMATOR_H_
6#define UI_VIEWS_ANIMATION_BOUNDS_ANIMATOR_H_
7
8#include <map>
9
10#include "base/compiler_specific.h"
11#include "base/memory/ref_counted.h"
12#include "base/observer_list.h"
13#include "ui/base/animation/animation_container_observer.h"
14#include "ui/base/animation/animation_delegate.h"
15#include "ui/base/animation/tween.h"
16#include "ui/gfx/rect.h"
17#include "ui/views/views_export.h"
18
19namespace ui {
20class SlideAnimation;
21}
22
23namespace views {
24
25class BoundsAnimatorObserver;
26class View;
27
28// Bounds animator is responsible for animating the bounds of a view from the
29// the views current location and size to a target position and size. To use
30// BoundsAnimator invoke AnimateViewTo for the set of views you want to
31// animate.
32//
33// BoundsAnimator internally creates an animation for each view. If you need
34// a specific animation invoke SetAnimationForView after invoking AnimateViewTo.
35// You can attach an AnimationDelegate to the individual animation for a view
36// by way of SetAnimationDelegate. Additionally you can attach an observer to
37// the BoundsAnimator that is notified when all animations are complete.
38class VIEWS_EXPORT BoundsAnimator : public ui::AnimationDelegate,
39                                    public ui::AnimationContainerObserver {
40 public:
41  // If |delete_when_done| is set to true in |SetAnimationDelegate| the
42  // |AnimationDelegate| must subclass this class.
43  class OwnedAnimationDelegate : public ui::AnimationDelegate {
44   public:
45    virtual ~OwnedAnimationDelegate() {}
46  };
47
48  explicit BoundsAnimator(View* view);
49  virtual ~BoundsAnimator();
50
51  // Starts animating |view| from its current bounds to |target|. If there is
52  // already an animation running for the view it's stopped and a new one
53  // started. If an AnimationDelegate has been set for |view| it is removed
54  // (after being notified that the animation was canceled).
55  void AnimateViewTo(View* view, const gfx::Rect& target);
56
57  // Similar to |AnimateViewTo|, but does not reset the animation, only the
58  // target bounds. If |view| is not being animated this is the same as
59  // invoking |AnimateViewTo|.
60  void SetTargetBounds(View* view, const gfx::Rect& target);
61
62  // Returns the target bounds for the specified view. If |view| is not
63  // animating its current bounds is returned.
64  gfx::Rect GetTargetBounds(View* view);
65
66  // Sets the animation for the specified view. BoundsAnimator takes ownership
67  // of the specified animation.
68  void SetAnimationForView(View* view, ui::SlideAnimation* animation);
69
70  // Returns the animation for the specified view. BoundsAnimator owns the
71  // returned Animation.
72  const ui::SlideAnimation* GetAnimationForView(View* view);
73
74  // Stops animating the specified view.
75  void StopAnimatingView(View* view);
76
77  // Sets the delegate for the animation created for the specified view. If
78  // |delete_when_done| is true the |delegate| is deleted when done and
79  // |delegate| must subclass OwnedAnimationDelegate.
80  void SetAnimationDelegate(View* view,
81                            ui::AnimationDelegate* delegate,
82                            bool delete_when_done);
83
84  // Returns true if BoundsAnimator is animating the bounds of |view|.
85  bool IsAnimating(View* view) const;
86
87  // Returns true if BoundsAnimator is animating any view.
88  bool IsAnimating() const;
89
90  // Cancels all animations, leaving the views at their current location and
91  // size. Any views marked for deletion are deleted.
92  void Cancel();
93
94  // Overrides default animation duration. |duration_ms| is the new duration in
95  // milliseconds.
96  void SetAnimationDuration(int duration_ms);
97
98  // Sets the tween type for new animations. Default is EASE_OUT.
99  void set_tween_type(ui::Tween::Type type) { tween_type_ = type; }
100
101  void AddObserver(BoundsAnimatorObserver* observer);
102  void RemoveObserver(BoundsAnimatorObserver* observer);
103
104 protected:
105  // Creates the animation to use for animating views.
106  virtual ui::SlideAnimation* CreateAnimation();
107
108 private:
109  // Tracks data about the view being animated.
110  struct Data {
111    Data()
112        : delete_delegate_when_done(false),
113          animation(NULL),
114          delegate(NULL) {}
115
116    // If true the delegate is deleted when done.
117    bool delete_delegate_when_done;
118
119    // The initial bounds.
120    gfx::Rect start_bounds;
121
122    // Target bounds.
123    gfx::Rect target_bounds;
124
125    // The animation. We own this.
126    ui::SlideAnimation* animation;
127
128    // Additional delegate for the animation, may be null.
129    ui::AnimationDelegate* delegate;
130  };
131
132  // Used by AnimationEndedOrCanceled.
133  enum AnimationEndType {
134    ANIMATION_ENDED,
135    ANIMATION_CANCELED
136  };
137
138  typedef std::map<View*, Data> ViewToDataMap;
139
140  typedef std::map<const ui::Animation*, View*> AnimationToViewMap;
141
142  // Removes references to |view| and its animation. This does NOT delete the
143  // animation or delegate.
144  void RemoveFromMaps(View* view);
145
146  // Does the necessary cleanup for |data|. If |send_cancel| is true and a
147  // delegate has been installed on |data| AnimationCanceled is invoked on it.
148  void CleanupData(bool send_cancel, Data* data, View* view);
149
150  // Used when changing the animation for a view. This resets the maps for
151  // the animation used by view and returns the current animation. Ownership
152  // of the returned animation passes to the caller.
153  ui::Animation* ResetAnimationForView(View* view);
154
155  // Invoked from AnimationEnded and AnimationCanceled.
156  void AnimationEndedOrCanceled(const ui::Animation* animation,
157                                AnimationEndType type);
158
159  // ui::AnimationDelegate overrides.
160  virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE;
161  virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE;
162  virtual void AnimationCanceled(const ui::Animation* animation) OVERRIDE;
163
164  // ui::AnimationContainerObserver overrides.
165  virtual void AnimationContainerProgressed(
166      ui::AnimationContainer* container) OVERRIDE;
167  virtual void AnimationContainerEmpty(
168      ui::AnimationContainer* container) OVERRIDE;
169
170  // Parent of all views being animated.
171  View* parent_;
172
173  ObserverList<BoundsAnimatorObserver> observers_;
174
175  // All animations we create up with the same container.
176  scoped_refptr<ui::AnimationContainer> container_;
177
178  // Maps from view being animated to info about the view.
179  ViewToDataMap data_;
180
181  // Maps from animation to view.
182  AnimationToViewMap animation_to_view_;
183
184  // As the animations we create update (AnimationProgressed is invoked) this
185  // is updated. When all the animations have completed for a given tick of
186  // the timer (AnimationContainerProgressed is invoked) the parent_ is asked
187  // to repaint these bounds.
188  gfx::Rect repaint_bounds_;
189
190  int animation_duration_ms_;
191
192  ui::Tween::Type tween_type_;
193
194  DISALLOW_COPY_AND_ASSIGN(BoundsAnimator);
195};
196
197}  // namespace views
198
199#endif  // UI_VIEWS_ANIMATION_BOUNDS_ANIMATOR_H_
200