• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/gfx/animation/animation_container_observer.h"
14 #include "ui/gfx/animation/animation_delegate.h"
15 #include "ui/gfx/animation/tween.h"
16 #include "ui/gfx/rect.h"
17 #include "ui/views/views_export.h"
18 
19 namespace gfx {
20 class SlideAnimation;
21 }
22 
23 namespace views {
24 
25 class BoundsAnimatorObserver;
26 class 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.
38 class VIEWS_EXPORT BoundsAnimator : public gfx::AnimationDelegate,
39                                     public gfx::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 gfx::AnimationDelegate {
44    public:
~OwnedAnimationDelegate()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, gfx::SlideAnimation* animation);
69 
70   // Returns the animation for the specified view. BoundsAnimator owns the
71   // returned Animation.
72   const gfx::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                             gfx::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.
set_tween_type(gfx::Tween::Type type)99   void set_tween_type(gfx::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 gfx::SlideAnimation* CreateAnimation();
107 
108  private:
109   // Tracks data about the view being animated.
110   struct Data {
DataData111     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     gfx::SlideAnimation* animation;
127 
128     // Additional delegate for the animation, may be null.
129     gfx::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 gfx::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   gfx::Animation* ResetAnimationForView(View* view);
154 
155   // Invoked from AnimationEnded and AnimationCanceled.
156   void AnimationEndedOrCanceled(const gfx::Animation* animation,
157                                 AnimationEndType type);
158 
159   // gfx::AnimationDelegate overrides.
160   virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
161   virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE;
162   virtual void AnimationCanceled(const gfx::Animation* animation) OVERRIDE;
163 
164   // gfx::AnimationContainerObserver overrides.
165   virtual void AnimationContainerProgressed(
166       gfx::AnimationContainer* container) OVERRIDE;
167   virtual void AnimationContainerEmpty(
168       gfx::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<gfx::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   gfx::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