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 |