Home | History | Annotate | Download | only in animation
      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.
     89   int GetAnimationDuration() const { return animation_duration_ms_; }
     90 
     91   // Sets the tween type for new animations. Default is EASE_OUT.
     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 {
    104     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