| Index: app/animation_container.cc
|
| diff --git a/app/animation_container.cc b/app/animation_container.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b0cc86a8271fbf7db66df124fdc063cbb28e1c71
|
| --- /dev/null
|
| +++ b/app/animation_container.cc
|
| @@ -0,0 +1,93 @@
|
| +// 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.
|
| +
|
| +#include "app/animation_container.h"
|
| +
|
| +#include "app/animation.h"
|
| +
|
| +using base::TimeDelta;
|
| +using base::TimeTicks;
|
| +
|
| +AnimationContainer::AnimationContainer()
|
| + : last_tick_time_(TimeTicks::Now()),
|
| + observer_(NULL) {
|
| +}
|
| +
|
| +AnimationContainer::~AnimationContainer() {
|
| + // The animations own us and stop themselves before being deleted. If
|
| + // animations_ is not empty, something is wrong.
|
| + DCHECK(animations_.empty());
|
| +}
|
| +
|
| +void AnimationContainer::Start(Animation* animation) {
|
| + DCHECK(animations_.count(animation) == 0); // Start should only be invoked
|
| + // if the animation isn't running.
|
| +
|
| + if (animations_.empty()) {
|
| + last_tick_time_ = TimeTicks::Now();
|
| + SetMinTimerInterval(animation->timer_interval());
|
| + } else if (animation->timer_interval() < min_timer_interval_) {
|
| + SetMinTimerInterval(animation->timer_interval());
|
| + }
|
| +
|
| + animation->set_start_time(last_tick_time_);
|
| + animations_.insert(animation);
|
| +}
|
| +
|
| +void AnimationContainer::Stop(Animation* animation) {
|
| + DCHECK(animations_.count(animation) > 0); // The animation must be running.
|
| +
|
| + animations_.erase(animation);
|
| +
|
| + if (animations_.empty()) {
|
| + timer_.Stop();
|
| + if (observer_)
|
| + observer_->AnimationContainerEmpty(this);
|
| + } else {
|
| + TimeDelta min_timer_interval = GetMinInterval();
|
| + if (min_timer_interval > min_timer_interval_)
|
| + SetMinTimerInterval(min_timer_interval);
|
| + }
|
| +}
|
| +
|
| +void AnimationContainer::Run() {
|
| + TimeTicks current_time = TimeTicks::Now();
|
| +
|
| + last_tick_time_ = current_time;
|
| +
|
| + // Make a copy of the animations to iterate over so that if any animations
|
| + // are removed as part of invoking Step there aren't any problems.
|
| + Animations animations = animations_;
|
| +
|
| + for (Animations::const_iterator i = animations.begin();
|
| + i != animations.end(); ++i) {
|
| + // Make sure the animation is still valid.
|
| + if (animations_.find(*i) != animations_.end())
|
| + (*i)->Step(current_time);
|
| + }
|
| +
|
| + if (observer_)
|
| + observer_->AnimationContainerProgressed(this);
|
| +}
|
| +
|
| +void AnimationContainer::SetMinTimerInterval(base::TimeDelta delta) {
|
| + // This doesn't take into account how far along current animation is, but that
|
| + // shouldn't be a problem for uses of Animation/AnimationContainer.
|
| + timer_.Stop();
|
| + min_timer_interval_ = delta;
|
| + timer_.Start(min_timer_interval_, this, &AnimationContainer::Run);
|
| +}
|
| +
|
| +TimeDelta AnimationContainer::GetMinInterval() {
|
| + DCHECK(!animations_.empty());
|
| +
|
| + TimeDelta min;
|
| + Animations::const_iterator i = animations_.begin();
|
| + min = (*i)->timer_interval();
|
| + for (++i; i != animations_.end(); ++i) {
|
| + if ((*i)->timer_interval() < min)
|
| + min = (*i)->timer_interval();
|
| + }
|
| + return min;
|
| +}
|
|
|