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/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 
     19 namespace ui {
     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 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