• 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   explicit BoundsAnimator(View* view);
42   virtual ~BoundsAnimator();
43 
44   // Starts animating |view| from its current bounds to |target|. If there is
45   // already an animation running for the view it's stopped and a new one
46   // started. If an AnimationDelegate has been set for |view| it is removed
47   // (after being notified that the animation was canceled).
48   void AnimateViewTo(View* view, const gfx::Rect& target);
49 
50   // Similar to |AnimateViewTo|, but does not reset the animation, only the
51   // target bounds. If |view| is not being animated this is the same as
52   // invoking |AnimateViewTo|.
53   void SetTargetBounds(View* view, const gfx::Rect& target);
54 
55   // Returns the target bounds for the specified view. If |view| is not
56   // animating its current bounds is returned.
57   gfx::Rect GetTargetBounds(View* view);
58 
59   // Sets the animation for the specified view. BoundsAnimator takes ownership
60   // of the specified animation.
61   void SetAnimationForView(View* view, gfx::SlideAnimation* animation);
62 
63   // Returns the animation for the specified view. BoundsAnimator owns the
64   // returned Animation.
65   const gfx::SlideAnimation* GetAnimationForView(View* view);
66 
67   // Stops animating the specified view.
68   void StopAnimatingView(View* view);
69 
70   // Sets the delegate for the animation for the specified view.
71   void SetAnimationDelegate(View* view,
72                             scoped_ptr<gfx::AnimationDelegate> delegate);
73 
74   // Returns true if BoundsAnimator is animating the bounds of |view|.
75   bool IsAnimating(View* view) const;
76 
77   // Returns true if BoundsAnimator is animating any view.
78   bool IsAnimating() const;
79 
80   // Cancels all animations, leaving the views at their current location and
81   // size. Any views marked for deletion are deleted.
82   void Cancel();
83 
84   // Overrides default animation duration. |duration_ms| is the new duration in
85   // milliseconds.
86   void SetAnimationDuration(int duration_ms);
87 
88   // Gets the currently used animation duration.
GetAnimationDuration()89   int GetAnimationDuration() const { return animation_duration_ms_; }
90 
91   // Sets the tween type for new animations. Default is EASE_OUT.
set_tween_type(gfx::Tween::Type type)92   void set_tween_type(gfx::Tween::Type type) { tween_type_ = type; }
93 
94   void AddObserver(BoundsAnimatorObserver* observer);
95   void RemoveObserver(BoundsAnimatorObserver* observer);
96 
97  protected:
98   // Creates the animation to use for animating views.
99   virtual gfx::SlideAnimation* CreateAnimation();
100 
101  private:
102   // Tracks data about the view being animated.
103   struct Data {
DataData104     Data() : animation(NULL), delegate(NULL) {}
105 
106     // The initial bounds.
107     gfx::Rect start_bounds;
108 
109     // Target bounds.
110     gfx::Rect target_bounds;
111 
112     // The animation. We own this.
113     gfx::SlideAnimation* animation;
114 
115     // Delegate for the animation, may be null. We own this.
116     gfx::AnimationDelegate* delegate;
117   };
118 
119   // Used by AnimationEndedOrCanceled.
120   enum AnimationEndType {
121     ANIMATION_ENDED,
122     ANIMATION_CANCELED
123   };
124 
125   typedef std::map<View*, Data> ViewToDataMap;
126 
127   typedef std::map<const gfx::Animation*, View*> AnimationToViewMap;
128 
129   // Removes references to |view| and its animation. This does NOT delete the
130   // animation or delegate.
131   void RemoveFromMaps(View* view);
132 
133   // Does the necessary cleanup for |data|. If |send_cancel| is true and a
134   // delegate has been installed on |data| AnimationCanceled is invoked on it.
135   void CleanupData(bool send_cancel, Data* data, View* view);
136 
137   // Used when changing the animation for a view. This resets the maps for
138   // the animation used by view and returns the current animation. Ownership
139   // of the returned animation passes to the caller.
140   gfx::Animation* ResetAnimationForView(View* view);
141 
142   // Invoked from AnimationEnded and AnimationCanceled.
143   void AnimationEndedOrCanceled(const gfx::Animation* animation,
144                                 AnimationEndType type);
145 
146   // gfx::AnimationDelegate overrides.
147   virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
148   virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE;
149   virtual void AnimationCanceled(const gfx::Animation* animation) OVERRIDE;
150 
151   // gfx::AnimationContainerObserver overrides.
152   virtual void AnimationContainerProgressed(
153       gfx::AnimationContainer* container) OVERRIDE;
154   virtual void AnimationContainerEmpty(
155       gfx::AnimationContainer* container) OVERRIDE;
156 
157   // Parent of all views being animated.
158   View* parent_;
159 
160   ObserverList<BoundsAnimatorObserver> observers_;
161 
162   // All animations we create up with the same container.
163   scoped_refptr<gfx::AnimationContainer> container_;
164 
165   // Maps from view being animated to info about the view.
166   ViewToDataMap data_;
167 
168   // Maps from animation to view.
169   AnimationToViewMap animation_to_view_;
170 
171   // As the animations we create update (AnimationProgressed is invoked) this
172   // is updated. When all the animations have completed for a given tick of
173   // the timer (AnimationContainerProgressed is invoked) the parent_ is asked
174   // to repaint these bounds.
175   gfx::Rect repaint_bounds_;
176 
177   int animation_duration_ms_;
178 
179   gfx::Tween::Type tween_type_;
180 
181   DISALLOW_COPY_AND_ASSIGN(BoundsAnimator);
182 };
183 
184 }  // namespace views
185 
186 #endif  // UI_VIEWS_ANIMATION_BOUNDS_ANIMATOR_H_
187