summaryrefslogtreecommitdiffstats
path: root/views/animation/bounds_animator.h
blob: ab2fde9b1a0471a00265d18e254220608d6022bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef VIEWS_ANIMATION_BOUNDS_ANIMATOR_H_
#define VIEWS_ANIMATION_BOUNDS_ANIMATOR_H_

#include <map>

#include "app/animation.h"
#include "app/animation_container.h"
#include "gfx/rect.h"

class SlideAnimation;

namespace views {

class BoundsAnimator;
class View;

class BoundsAnimatorObserver {
 public:
  // Invoked when all animations are complete.
  virtual void OnBoundsAnimatorDone(BoundsAnimator* animator) = 0;
};

// Bounds animator is responsible for animating the bounds of a view from the
// the views current location and size to a target position and size. To use
// BoundsAnimator invoke AnimateViewTo for the set of views you want to
// animate.
//
// BoundsAnimator internally creates an animation for each view. If you need
// a specific animation invoke SetAnimationForView after invoking AnimateViewTo.
// You can attach an AnimationDelegate to the individual animation for a view
// by way of SetAnimationDelegate. Additionally you can attach an observer to
// the BoundsAnimator that is notified when all animations are complete.
class BoundsAnimator : public AnimationDelegate,
                       public AnimationContainer::Observer {
 public:
  // If |delete_when_done| is set to true in |SetAnimationDelegate| the
  // |AnimationDelegate| must subclass this class.
  class OwnedAnimationDelegate : public AnimationDelegate {
   public:
    virtual ~OwnedAnimationDelegate() {}
  };

  explicit BoundsAnimator(View* view);
  ~BoundsAnimator();

  // Starts animating |view| from its current bounds to |target|. If
  // |delete_when_done| is true the view is deleted when the animation
  // completes. If there is already an animation running for the view it's
  // stopped and a new one started.
  void AnimateViewTo(View* view,
                     const gfx::Rect& target,
                     bool delete_when_done);

  // Sets the animation for the specified view. BoundsAnimator takes ownership
  // of the specified animation.
  void SetAnimationForView(View* view, SlideAnimation* animation);

  // Returns the animation for the specified view. BoundsAnimator owns the
  // returned Animation.
  const SlideAnimation* GetAnimationForView(View* view);

  // Stops animating the specified view. If the view was scheduled for deletion
  // it is deleted.
  void StopAnimatingView(View* view);

  // Sets the delegate for the animation created for the specified view. If
  // |delete_when_done| is true the |delegate| is deleted when done and
  // |delegate| must subclass OwnedAnimationDelegate.
  void SetAnimationDelegate(View* view,
                            AnimationDelegate* delegate,
                            bool delete_when_done);

  // Returns true if BoundsAnimator is animating the bounds of |view|.
  bool IsAnimating(View* view) const;

  // Returns true if BoundsAnimator is animating any view.
  bool IsAnimating() const;

  // Cancels all animations, leaving the views at their current location and
  // size. Any views marked for deletion are deleted.
  void Cancel();

  void set_observer(BoundsAnimatorObserver* observer) {
    observer_ = observer;
  }

 private:
  // Tracks data about the view being animated.
  struct Data {
    Data()
        : delete_when_done(false),
          delete_delegate_when_done(false),
          animation(NULL),
          delegate(NULL) {}

    // Should the view be deleted when done?
    bool delete_when_done;

    // If true the delegate is deleted when done.
    bool delete_delegate_when_done;

    // The initial bounds.
    gfx::Rect start_bounds;

    // Target bounds.
    gfx::Rect target_bounds;

    // The animation. We own this.
    SlideAnimation* animation;

    // Additional delegate for the animation, may be null.
    AnimationDelegate* delegate;
  };

  typedef std::map<View*, Data> ViewToDataMap;

  typedef std::map<const Animation*, View*> AnimationToViewMap;

  // Creates the animation to use for animating views.
  SlideAnimation* CreateAnimation();

  // Removes references to |view| and its animation as well as deleting |view|
  // (if necessary). This does NOT delete the animation or delegate.
  void RemoveFromMapsAndDelete(View* view);

  // Does the necessary cleanup for |data|.
  void CleanupData(Data* data);

  // Used when changing the animation for a view. This resets the maps for
  // the animation used by view and returns the current animation. Ownership
  // of the returned animation passes to the caller.
  Animation* ResetAnimationForView(View* view);

  // AnimationDelegate overrides.
  virtual void AnimationProgressed(const Animation* animation);
  virtual void AnimationEnded(const Animation* animation);
  virtual void AnimationCanceled(const Animation* animation);

  // AnimationContainer::Observer overrides.
  virtual void AnimationContainerProgressed(AnimationContainer* container);
  virtual void AnimationContainerEmpty(AnimationContainer* container);

  // Parent of all views being animated.
  View* parent_;

  BoundsAnimatorObserver* observer_;

  // All animations we create up with the same container.
  scoped_refptr<AnimationContainer> container_;

  // Maps from view being animated to info about the view.
  ViewToDataMap data_;

  // Makes from animation to view.
  AnimationToViewMap animation_to_view_;

  // As the animations we created update (AnimationProgressed is invoked) this
  // is updated. When all the animations have completed for a given tick of
  // the timer (AnimationContainerProgressed is invoked) the parent_ is asked
  // to repaint these bounds.
  gfx::Rect repaint_bounds_;

  DISALLOW_COPY_AND_ASSIGN(BoundsAnimator);
};

}  // namespace views

#endif  // VIEWS_ANIMATION_BOUNDS_ANIMATOR_H_