summaryrefslogtreecommitdiffstats
path: root/views/animation
diff options
context:
space:
mode:
Diffstat (limited to 'views/animation')
-rw-r--r--views/animation/bounds_animator.cc86
-rw-r--r--views/animation/bounds_animator.h30
-rw-r--r--views/animation/bounds_animator_unittest.cc10
3 files changed, 67 insertions, 59 deletions
diff --git a/views/animation/bounds_animator.cc b/views/animation/bounds_animator.cc
index aee3675..40cae9c 100644
--- a/views/animation/bounds_animator.cc
+++ b/views/animation/bounds_animator.cc
@@ -31,14 +31,13 @@ BoundsAnimator::~BoundsAnimator() {
CleanupData(false, &(i->second), i->first);
}
-void BoundsAnimator::AnimateViewTo(View* view,
- const gfx::Rect& target,
- bool delete_when_done) {
+void BoundsAnimator::AnimateViewTo(View* view, const gfx::Rect& target) {
+ DCHECK(view);
DCHECK_EQ(view->GetParent(), parent_);
Data existing_data;
- if (data_.count(view) > 0) {
+ if (IsAnimating(view)) {
// Don't immediatly delete the animation, that might trigger a callback from
// the animationcontainer.
existing_data = data_[view];
@@ -55,7 +54,6 @@ void BoundsAnimator::AnimateViewTo(View* view,
data.start_bounds = view->bounds();
data.target_bounds = target;
data.animation = CreateAnimation();
- data.delete_when_done = delete_when_done;
animation_to_view_[data.animation] = view;
@@ -66,8 +64,11 @@ void BoundsAnimator::AnimateViewTo(View* view,
void BoundsAnimator::SetAnimationForView(View* view,
SlideAnimation* animation) {
+ DCHECK(animation);
+
scoped_ptr<SlideAnimation> animation_wrapper(animation);
- if (data_.find(view) == data_.end())
+
+ if (!IsAnimating(view))
return;
// We delay deleting the animation until the end so that we don't prematurely
@@ -83,19 +84,20 @@ void BoundsAnimator::SetAnimationForView(View* view,
}
const SlideAnimation* BoundsAnimator::GetAnimationForView(View* view) {
- return data_.find(view) == data_.end() ? NULL : data_[view].animation;
+ return !IsAnimating(view) ? NULL : data_[view].animation;
}
void BoundsAnimator::SetAnimationDelegate(View* view,
AnimationDelegate* delegate,
bool delete_when_done) {
DCHECK(IsAnimating(view));
+
data_[view].delegate = delegate;
data_[view].delete_delegate_when_done = delete_when_done;
}
void BoundsAnimator::StopAnimatingView(View* view) {
- if (data_.find(view) == data_.end())
+ if (!IsAnimating(view))
return;
data_[view].animation->Stop();
@@ -130,6 +132,7 @@ SlideAnimation* BoundsAnimator::CreateAnimation() {
void BoundsAnimator::RemoveFromMaps(View* view) {
DCHECK(data_.count(view) > 0);
+ DCHECK(animation_to_view_.count(data_[view].animation) > 0);
animation_to_view_.erase(data_[view].animation);
data_.erase(view);
@@ -144,15 +147,15 @@ void BoundsAnimator::CleanupData(bool send_cancel, Data* data, View* view) {
data->delegate = NULL;
}
- if (data->delete_when_done)
- delete view;
-
- delete data->animation;
- data->animation = NULL;
+ if (data->animation) {
+ data->animation->set_delegate(NULL);
+ delete data->animation;
+ data->animation = NULL;
+ }
}
Animation* BoundsAnimator::ResetAnimationForView(View* view) {
- if (data_.find(view) == data_.end())
+ if (!IsAnimating(view))
return NULL;
Animation* old_animation = data_[view].animation;
@@ -164,10 +167,35 @@ Animation* BoundsAnimator::ResetAnimationForView(View* view) {
return old_animation;
}
+void BoundsAnimator::AnimationEndedOrCanceled(const Animation* animation,
+ AnimationEndType type) {
+ DCHECK(animation_to_view_.find(animation) != animation_to_view_.end());
+
+ View* view = animation_to_view_[animation];
+ DCHECK(view);
+
+ // Make a copy of the data as Remove empties out the maps.
+ Data data = data_[view];
+
+ RemoveFromMaps(view);
+
+ if (data.delegate) {
+ if (type == ANIMATION_ENDED) {
+ data.delegate->AnimationEnded(animation);
+ } else {
+ DCHECK_EQ(ANIMATION_CANCELED, type);
+ data.delegate->AnimationCanceled(animation);
+ }
+ }
+
+ CleanupData(false, &data, view);
+}
+
void BoundsAnimator::AnimationProgressed(const Animation* animation) {
DCHECK(animation_to_view_.find(animation) != animation_to_view_.end());
View* view = animation_to_view_[animation];
+ DCHECK(view);
const Data& data = data_[view];
gfx::Rect new_bounds =
animation->CurrentValueBetween(data.start_bounds, data.target_bounds);
@@ -184,38 +212,16 @@ void BoundsAnimator::AnimationProgressed(const Animation* animation) {
view->SetBounds(new_bounds);
}
- if (data_[view].delegate)
- data_[view].delegate->AnimationProgressed(animation);
+ if (data.delegate)
+ data.delegate->AnimationProgressed(animation);
}
void BoundsAnimator::AnimationEnded(const Animation* animation) {
- View* view = animation_to_view_[animation];
- AnimationDelegate* delegate = data_[view].delegate;
-
- // Make a copy of the data as Remove empties out the maps.
- Data data = data_[view];
-
- RemoveFromMaps(view);
-
- if (delegate)
- delegate->AnimationEnded(animation);
-
- CleanupData(false, &data, view);
+ AnimationEndedOrCanceled(animation, ANIMATION_ENDED);
}
void BoundsAnimator::AnimationCanceled(const Animation* animation) {
- View* view = animation_to_view_[animation];
- AnimationDelegate* delegate = data_[view].delegate;
-
- // Make a copy of the data as Remove empties out the maps.
- Data data = data_[view];
-
- RemoveFromMaps(view);
-
- if (delegate)
- delegate->AnimationCanceled(animation);
-
- CleanupData(false, &data, view);
+ AnimationEndedOrCanceled(animation, ANIMATION_CANCELED);
}
void BoundsAnimator::AnimationContainerProgressed(
diff --git a/views/animation/bounds_animator.h b/views/animation/bounds_animator.h
index 606c05f..e63bbaa 100644
--- a/views/animation/bounds_animator.h
+++ b/views/animation/bounds_animator.h
@@ -47,15 +47,11 @@ class BoundsAnimator : public AnimationDelegate,
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. If an AnimationDelegate has been set for
- // |view| it is removed (after being notified that the animation was
- // canceled).
- void AnimateViewTo(View* view,
- const gfx::Rect& target,
- bool delete_when_done);
+ // Starts animating |view| from its current bounds to |target|. If there is
+ // already an animation running for the view it's stopped and a new one
+ // started. If an AnimationDelegate has been set for |view| it is removed
+ // (after being notified that the animation was canceled).
+ void AnimateViewTo(View* view, const gfx::Rect& target);
// Sets the animation for the specified view. BoundsAnimator takes ownership
// of the specified animation.
@@ -98,14 +94,10 @@ class BoundsAnimator : public AnimationDelegate,
// Tracks data about the view being animated.
struct Data {
Data()
- : delete_when_done(false),
- delete_delegate_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;
@@ -122,6 +114,12 @@ class BoundsAnimator : public AnimationDelegate,
AnimationDelegate* delegate;
};
+ // Used by AnimationEndedOrCanceled.
+ enum AnimationEndType {
+ ANIMATION_ENDED,
+ ANIMATION_CANCELED
+ };
+
typedef std::map<View*, Data> ViewToDataMap;
typedef std::map<const Animation*, View*> AnimationToViewMap;
@@ -139,6 +137,10 @@ class BoundsAnimator : public AnimationDelegate,
// of the returned animation passes to the caller.
Animation* ResetAnimationForView(View* view);
+ // Invoked from AnimationEnded and AnimationCanceled.
+ void AnimationEndedOrCanceled(const Animation* animation,
+ AnimationEndType type);
+
// AnimationDelegate overrides.
virtual void AnimationProgressed(const Animation* animation);
virtual void AnimationEnded(const Animation* animation);
diff --git a/views/animation/bounds_animator_unittest.cc b/views/animation/bounds_animator_unittest.cc
index 74ea5f2..d85b185 100644
--- a/views/animation/bounds_animator_unittest.cc
+++ b/views/animation/bounds_animator_unittest.cc
@@ -114,7 +114,7 @@ TEST_F(BoundsAnimatorTest, AnimateViewTo) {
gfx::Rect initial_bounds(0, 0, 10, 10);
child()->SetBounds(initial_bounds);
gfx::Rect target_bounds(10, 10, 20, 20);
- animator()->AnimateViewTo(child(), target_bounds, false);
+ animator()->AnimateViewTo(child(), target_bounds);
animator()->SetAnimationDelegate(child(), &delegate, false);
// The animator should be animating now.
@@ -134,7 +134,7 @@ TEST_F(BoundsAnimatorTest, AnimateViewTo) {
// Make sure an AnimationDelegate is deleted when canceled.
TEST_F(BoundsAnimatorTest, DeleteDelegateOnCancel) {
- animator()->AnimateViewTo(child(), gfx::Rect(0, 0, 10, 10), false);
+ animator()->AnimateViewTo(child(), gfx::Rect(0, 0, 10, 10));
animator()->SetAnimationDelegate(child(), new OwnedDelegate(), true);
animator()->Cancel();
@@ -150,10 +150,10 @@ TEST_F(BoundsAnimatorTest, DeleteDelegateOnCancel) {
// Make sure an AnimationDelegate is deleted when another animation is
// scheduled.
TEST_F(BoundsAnimatorTest, DeleteDelegateOnNewAnimate) {
- animator()->AnimateViewTo(child(), gfx::Rect(0, 0, 10, 10), false);
+ animator()->AnimateViewTo(child(), gfx::Rect(0, 0, 10, 10));
animator()->SetAnimationDelegate(child(), new OwnedDelegate(), true);
- animator()->AnimateViewTo(child(), gfx::Rect(0, 0, 10, 10), false);
+ animator()->AnimateViewTo(child(), gfx::Rect(0, 0, 10, 10));
// Starting a new animation should both cancel the delegate and delete it.
EXPECT_TRUE(OwnedDelegate::get_and_clear_deleted());
@@ -164,7 +164,7 @@ TEST_F(BoundsAnimatorTest, DeleteDelegateOnNewAnimate) {
TEST_F(BoundsAnimatorTest, StopAnimating) {
scoped_ptr<OwnedDelegate> delegate(new OwnedDelegate());
- animator()->AnimateViewTo(child(), gfx::Rect(0, 0, 10, 10), false);
+ animator()->AnimateViewTo(child(), gfx::Rect(0, 0, 10, 10));
animator()->SetAnimationDelegate(child(), new OwnedDelegate(), true);
animator()->StopAnimatingView(child());