Home | History | Annotate | Download | only in animation
      1 // Copyright (c) 2011 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 #include "ui/base/animation/linear_animation.h"
      6 
      7 #include <math.h>
      8 
      9 #include "ui/base/animation/animation_container.h"
     10 #include "ui/base/animation/animation_delegate.h"
     11 
     12 using base::Time;
     13 using base::TimeDelta;
     14 
     15 namespace ui {
     16 
     17 static TimeDelta CalculateInterval(int frame_rate) {
     18   int timer_interval = 1000000 / frame_rate;
     19   if (timer_interval < 10000)
     20     timer_interval = 10000;
     21   return TimeDelta::FromMicroseconds(timer_interval);
     22 }
     23 
     24 LinearAnimation::LinearAnimation(int frame_rate,
     25                                  AnimationDelegate* delegate)
     26     : Animation(CalculateInterval(frame_rate)),
     27       state_(0.0),
     28       in_end_(false) {
     29   set_delegate(delegate);
     30 }
     31 
     32 LinearAnimation::LinearAnimation(int duration,
     33                                  int frame_rate,
     34                                  AnimationDelegate* delegate)
     35     : Animation(CalculateInterval(frame_rate)),
     36       duration_(TimeDelta::FromMilliseconds(duration)),
     37       state_(0.0),
     38       in_end_(false) {
     39   set_delegate(delegate);
     40   SetDuration(duration);
     41 }
     42 
     43 double LinearAnimation::GetCurrentValue() const {
     44   // Default is linear relationship, subclass to adapt.
     45   return state_;
     46 }
     47 
     48 void LinearAnimation::SetCurrentValue(double new_value) {
     49   new_value = std::max(0.0, std::min(1.0, new_value));
     50   base::TimeDelta time_delta = base::TimeDelta::FromMicroseconds(
     51       duration_.InMicroseconds() * (new_value - state_));
     52   SetStartTime(start_time() - time_delta);
     53   state_ = new_value;
     54 }
     55 
     56 void LinearAnimation::End() {
     57   if (!is_animating())
     58     return;
     59 
     60   // NOTE: We don't use AutoReset here as Stop may end up deleting us (by way
     61   // of the delegate).
     62   in_end_ = true;
     63   Stop();
     64 }
     65 
     66 void LinearAnimation::SetDuration(int duration) {
     67   duration_ = TimeDelta::FromMilliseconds(duration);
     68   if (duration_ < timer_interval())
     69     duration_ = timer_interval();
     70   if (is_animating())
     71     SetStartTime(container()->last_tick_time());
     72 }
     73 
     74 void LinearAnimation::Step(base::TimeTicks time_now) {
     75   TimeDelta elapsed_time = time_now - start_time();
     76   state_ = static_cast<double>(elapsed_time.InMicroseconds()) /
     77            static_cast<double>(duration_.InMicroseconds());
     78   if (state_ >= 1.0)
     79     state_ = 1.0;
     80 
     81   AnimateToState(state_);
     82 
     83   if (delegate())
     84     delegate()->AnimationProgressed(this);
     85 
     86   if (state_ == 1.0)
     87     Stop();
     88 }
     89 
     90 void LinearAnimation::AnimationStarted() {
     91   state_ = 0.0;
     92 }
     93 
     94 void LinearAnimation::AnimationStopped() {
     95   if (!in_end_)
     96     return;
     97 
     98   in_end_ = false;
     99   // Set state_ to ensure we send ended to delegate and not canceled.
    100   state_ = 1;
    101   AnimateToState(1.0);
    102 }
    103 
    104 bool LinearAnimation::ShouldSendCanceledFromStop() {
    105   return state_ != 1;
    106 }
    107 
    108 }  // namespace ui
    109