| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "app/animation.h" | 5 #include "app/animation.h" |
| 6 | 6 |
| 7 #include "app/animation_container.h" | 7 #include "app/tween.h" |
| 8 #include "gfx/rect.h" | 8 #include "gfx/rect.h" |
| 9 | 9 |
| 10 #if defined(OS_WIN) | 10 #if defined(OS_WIN) |
| 11 #include "base/win_util.h" | 11 #include "base/win_util.h" |
| 12 #endif | 12 #endif |
| 13 | 13 |
| 14 using base::Time; | 14 Animation::Animation(base::TimeDelta timer_interval) |
| 15 using base::TimeDelta; | 15 : timer_interval_(timer_interval), |
| 16 | 16 is_animating_(false), |
| 17 Animation::Animation(int frame_rate, | 17 delegate_(NULL) { |
| 18 AnimationDelegate* delegate) | |
| 19 : animating_(false), | |
| 20 frame_rate_(frame_rate), | |
| 21 timer_interval_(CalculateInterval(frame_rate)), | |
| 22 state_(0.0), | |
| 23 delegate_(delegate) { | |
| 24 } | |
| 25 | |
| 26 Animation::Animation(int duration, | |
| 27 int frame_rate, | |
| 28 AnimationDelegate* delegate) | |
| 29 : animating_(false), | |
| 30 frame_rate_(frame_rate), | |
| 31 timer_interval_(CalculateInterval(frame_rate)), | |
| 32 duration_(TimeDelta::FromMilliseconds(duration)), | |
| 33 state_(0.0), | |
| 34 delegate_(delegate) { | |
| 35 | |
| 36 SetDuration(duration); | |
| 37 } | 18 } |
| 38 | 19 |
| 39 Animation::~Animation() { | 20 Animation::~Animation() { |
| 40 if (animating_) | 21 // Don't send out notification from the destructor. Chances are the delegate |
| 22 // owns us and is being deleted as well. |
| 23 if (is_animating_) |
| 41 container_->Stop(this); | 24 container_->Stop(this); |
| 42 } | 25 } |
| 43 | 26 |
| 44 double Animation::GetCurrentValue() const { | 27 void Animation::Start() { |
| 45 // Default is linear relationship, subclass to adapt. | 28 if (is_animating_) |
| 46 return state_; | 29 return; |
| 30 |
| 31 if (!container_.get()) |
| 32 container_ = new AnimationContainer(); |
| 33 |
| 34 is_animating_ = true; |
| 35 |
| 36 container_->Start(this); |
| 37 |
| 38 AnimationStarted(); |
| 39 } |
| 40 |
| 41 void Animation::Stop() { |
| 42 if (!is_animating_) |
| 43 return; |
| 44 |
| 45 is_animating_ = false; |
| 46 |
| 47 // Notify the container first as the delegate may delete us. |
| 48 container_->Stop(this); |
| 49 |
| 50 AnimationStopped(); |
| 51 |
| 52 if (delegate_) { |
| 53 if (ShouldSendCanceledFromStop()) |
| 54 delegate_->AnimationCanceled(this); |
| 55 else |
| 56 delegate_->AnimationEnded(this); |
| 57 } |
| 47 } | 58 } |
| 48 | 59 |
| 49 double Animation::CurrentValueBetween(double start, double target) const { | 60 double Animation::CurrentValueBetween(double start, double target) const { |
| 50 return start + (target - start) * GetCurrentValue(); | 61 return Tween::ValueBetween(GetCurrentValue(), start, target); |
| 51 } | 62 } |
| 52 | 63 |
| 53 int Animation::CurrentValueBetween(int start, int target) const { | 64 int Animation::CurrentValueBetween(int start, int target) const { |
| 54 return static_cast<int>(CurrentValueBetween(static_cast<double>(start), | 65 return Tween::ValueBetween(GetCurrentValue(), start, target); |
| 55 static_cast<double>(target))); | 66 |
| 56 } | 67 } |
| 57 | 68 |
| 58 gfx::Rect Animation::CurrentValueBetween(const gfx::Rect& start_bounds, | 69 gfx::Rect Animation::CurrentValueBetween(const gfx::Rect& start_bounds, |
| 59 const gfx::Rect& target_bounds) const { | 70 const gfx::Rect& target_bounds) const { |
| 60 return gfx::Rect(CurrentValueBetween(start_bounds.x(), target_bounds.x()), | 71 return Tween::ValueBetween(GetCurrentValue(), start_bounds, target_bounds); |
| 61 CurrentValueBetween(start_bounds.y(), target_bounds.y()), | |
| 62 CurrentValueBetween(start_bounds.width(), | |
| 63 target_bounds.width()), | |
| 64 CurrentValueBetween(start_bounds.height(), | |
| 65 target_bounds.height())); | |
| 66 } | 72 } |
| 67 | 73 |
| 68 void Animation::Start() { | 74 void Animation::SetContainer(AnimationContainer* container) { |
| 69 if (!animating_) { | 75 if (container == container_.get()) |
| 70 if (!container_.get()) | 76 return; |
| 71 container_ = new AnimationContainer(); | |
| 72 | 77 |
| 73 animating_ = true; | 78 if (is_animating_) |
| 74 | |
| 75 container_->Start(this); | |
| 76 | |
| 77 if (delegate_) | |
| 78 delegate_->AnimationStarted(this); | |
| 79 } | |
| 80 } | |
| 81 | |
| 82 void Animation::Stop() { | |
| 83 if (animating_) { | |
| 84 animating_ = false; | |
| 85 | |
| 86 // Notify the container first as the delegate may delete us. | |
| 87 container_->Stop(this); | 79 container_->Stop(this); |
| 88 | 80 |
| 89 if (delegate_) { | 81 if (container) |
| 90 if (state_ >= 1.0) | 82 container_ = container; |
| 91 delegate_->AnimationEnded(this); | 83 else |
| 92 else | 84 container_ = new AnimationContainer(); |
| 93 delegate_->AnimationCanceled(this); | |
| 94 } | |
| 95 } | |
| 96 } | |
| 97 | 85 |
| 98 void Animation::End() { | 86 if (is_animating_) |
| 99 if (animating_) { | 87 container_->Start(this); |
| 100 animating_ = false; | |
| 101 | |
| 102 // Notify the container first as the delegate may delete us. | |
| 103 container_->Stop(this); | |
| 104 | |
| 105 AnimateToState(1.0); | |
| 106 if (delegate_) | |
| 107 delegate_->AnimationEnded(this); | |
| 108 } | |
| 109 } | |
| 110 | |
| 111 bool Animation::IsAnimating() const { | |
| 112 return animating_; | |
| 113 } | |
| 114 | |
| 115 void Animation::SetDuration(int duration) { | |
| 116 duration_ = TimeDelta::FromMilliseconds(duration); | |
| 117 if (duration_ < timer_interval_) | |
| 118 duration_ = timer_interval_; | |
| 119 if (animating_) | |
| 120 start_time_ = container_->last_tick_time(); | |
| 121 } | 88 } |
| 122 | 89 |
| 123 // static | 90 // static |
| 124 bool Animation::ShouldRenderRichAnimation() { | 91 bool Animation::ShouldRenderRichAnimation() { |
| 125 #if defined(OS_WIN) | 92 #if defined(OS_WIN) |
| 126 if (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA) { | 93 if (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA) { |
| 127 BOOL result; | 94 BOOL result; |
| 128 // Get "Turn off all unnecessary animations" value. | 95 // Get "Turn off all unnecessary animations" value. |
| 129 if (::SystemParametersInfo(SPI_GETCLIENTAREAANIMATION, 0, &result, 0)) { | 96 if (::SystemParametersInfo(SPI_GETCLIENTAREAANIMATION, 0, &result, 0)) { |
| 130 // There seems to be a typo in the MSDN document (as of May 2009): | 97 // There seems to be a typo in the MSDN document (as of May 2009): |
| 131 // http://msdn.microsoft.com/en-us/library/ms724947(VS.85).aspx | 98 // http://msdn.microsoft.com/en-us/library/ms724947(VS.85).aspx |
| 132 // The document states that the result is TRUE when animations are | 99 // The document states that the result is TRUE when animations are |
| 133 // _disabled_, but in fact, it is TRUE when they are _enabled_. | 100 // _disabled_, but in fact, it is TRUE when they are _enabled_. |
| 134 return !!result; | 101 return !!result; |
| 135 } | 102 } |
| 136 } | 103 } |
| 137 return !::GetSystemMetrics(SM_REMOTESESSION); | 104 return !::GetSystemMetrics(SM_REMOTESESSION); |
| 138 #endif | 105 #endif |
| 139 return true; | 106 return true; |
| 140 } | 107 } |
| 141 | 108 |
| 142 void Animation::SetContainer(AnimationContainer* container) { | 109 void Animation::SetStartTime(base::TimeTicks start_time) { |
| 143 if (container == container_.get()) | 110 start_time_ = start_time; |
| 144 return; | |
| 145 | |
| 146 if (animating_) | |
| 147 container_->Stop(this); | |
| 148 | |
| 149 if (container) | |
| 150 container_ = container; | |
| 151 else | |
| 152 container_ = new AnimationContainer(); | |
| 153 | |
| 154 if (animating_) | |
| 155 container_->Start(this); | |
| 156 } | 111 } |
| 157 | |
| 158 void Animation::Step(base::TimeTicks time_now) { | |
| 159 TimeDelta elapsed_time = time_now - start_time_; | |
| 160 state_ = static_cast<double>(elapsed_time.InMicroseconds()) / | |
| 161 static_cast<double>(duration_.InMicroseconds()); | |
| 162 if (state_ >= 1.0) | |
| 163 state_ = 1.0; | |
| 164 | |
| 165 AnimateToState(state_); | |
| 166 | |
| 167 if (delegate_) | |
| 168 delegate_->AnimationProgressed(this); | |
| 169 | |
| 170 if (state_ == 1.0) | |
| 171 Stop(); | |
| 172 } | |
| 173 | |
| 174 TimeDelta Animation::CalculateInterval(int frame_rate) { | |
| 175 int timer_interval = 1000000 / frame_rate; | |
| 176 if (timer_interval < 10000) | |
| 177 timer_interval = 10000; | |
| 178 return TimeDelta::FromMicroseconds(timer_interval); | |
| 179 } | |
| OLD | NEW |