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