Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(311)

Side by Side Diff: ui/gfx/compositor/layer_animator.cc

Issue 8395046: Allows observers to be notified when layer animations complete. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address reviewer comments. Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 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 "ui/gfx/compositor/layer_animator.h" 5 #include "ui/gfx/compositor/layer_animator.h"
6 6
7 #include "base/debug/trace_event.h" 7 #include "base/debug/trace_event.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "ui/base/animation/animation_container.h" 10 #include "ui/base/animation/animation_container.h"
11 #include "ui/gfx/compositor/compositor.h" 11 #include "ui/gfx/compositor/compositor.h"
12 #include "ui/gfx/compositor/layer.h" 12 #include "ui/gfx/compositor/layer.h"
13 #include "ui/gfx/compositor/layer_animator_delegate.h" 13 #include "ui/gfx/compositor/layer_animation_delegate.h"
14 #include "ui/gfx/compositor/layer_animation_observer.h"
14 #include "ui/gfx/compositor/layer_animation_sequence.h" 15 #include "ui/gfx/compositor/layer_animation_sequence.h"
15 16
16 namespace ui { 17 namespace ui {
17 18
18 class LayerAnimator; 19 class LayerAnimator;
19 20
20 namespace { 21 namespace {
21 22
22 static const base::TimeDelta kDefaultTransitionDuration = 23 static const base::TimeDelta kDefaultTransitionDuration =
23 base::TimeDelta::FromMilliseconds(200); 24 base::TimeDelta::FromMilliseconds(200);
(...skipping 24 matching lines...) Expand all
48 49
49 // static 50 // static
50 LayerAnimator* LayerAnimator::CreateImplicitAnimator() { 51 LayerAnimator* LayerAnimator::CreateImplicitAnimator() {
51 return new LayerAnimator(kDefaultTransitionDuration); 52 return new LayerAnimator(kDefaultTransitionDuration);
52 } 53 }
53 54
54 void LayerAnimator::SetTransform(const Transform& transform) { 55 void LayerAnimator::SetTransform(const Transform& transform) {
55 if (transition_duration_ == base::TimeDelta()) 56 if (transition_duration_ == base::TimeDelta())
56 delegate_->SetTransformFromAnimation(transform); 57 delegate_->SetTransformFromAnimation(transform);
57 else 58 else
58 StartAnimationElement(LayerAnimationElement::CreateTransformElement( 59 StartAnimation(new LayerAnimationSequence(
59 transform, transition_duration_)); 60 LayerAnimationElement::CreateTransformElement(
61 transform, transition_duration_)));
60 } 62 }
61 63
62 Transform LayerAnimator::GetTargetTransform() const { 64 Transform LayerAnimator::GetTargetTransform() const {
63 LayerAnimationElement::TargetValue target; 65 LayerAnimationElement::TargetValue target;
64 GetTargetValue(&target); 66 GetTargetValue(&target);
65 return target.transform; 67 return target.transform;
66 } 68 }
67 69
68 void LayerAnimator::SetBounds(const gfx::Rect& bounds) { 70 void LayerAnimator::SetBounds(const gfx::Rect& bounds) {
69 if (transition_duration_ == base::TimeDelta()) 71 if (transition_duration_ == base::TimeDelta())
70 delegate_->SetBoundsFromAnimation(bounds); 72 delegate_->SetBoundsFromAnimation(bounds);
71 else 73 else
72 StartAnimationElement(LayerAnimationElement::CreateBoundsElement( 74 StartAnimation(new LayerAnimationSequence(
73 bounds, transition_duration_)); 75 LayerAnimationElement::CreateBoundsElement(
76 bounds, transition_duration_)));
74 } 77 }
75 78
76 gfx::Rect LayerAnimator::GetTargetBounds() const { 79 gfx::Rect LayerAnimator::GetTargetBounds() const {
77 LayerAnimationElement::TargetValue target; 80 LayerAnimationElement::TargetValue target;
78 GetTargetValue(&target); 81 GetTargetValue(&target);
79 return target.bounds; 82 return target.bounds;
80 } 83 }
81 84
82 void LayerAnimator::SetOpacity(float opacity) { 85 void LayerAnimator::SetOpacity(float opacity) {
83 if (transition_duration_ == base::TimeDelta()) 86 if (transition_duration_ == base::TimeDelta())
84 delegate_->SetOpacityFromAnimation(opacity); 87 delegate_->SetOpacityFromAnimation(opacity);
85 else 88 else
86 StartAnimationElement(LayerAnimationElement::CreateOpacityElement( 89 StartAnimation(new LayerAnimationSequence(
87 opacity, transition_duration_)); 90 LayerAnimationElement::CreateOpacityElement(
91 opacity, transition_duration_)));
88 } 92 }
89 93
90 float LayerAnimator::GetTargetOpacity() const { 94 float LayerAnimator::GetTargetOpacity() const {
91 LayerAnimationElement::TargetValue target; 95 LayerAnimationElement::TargetValue target;
92 GetTargetValue(&target); 96 GetTargetValue(&target);
93 return target.opacity; 97 return target.opacity;
94 } 98 }
95 99
96 void LayerAnimator::SetDelegate(LayerAnimatorDelegate* delegate) { 100 void LayerAnimator::SetDelegate(LayerAnimationDelegate* delegate) {
97 DCHECK(delegate); 101 DCHECK(delegate);
98 delegate_ = delegate; 102 delegate_ = delegate;
99 } 103 }
100 104
101 void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) { 105 void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) {
106 OnScheduled(animation);
102 if (!StartSequenceImmediately(animation)) { 107 if (!StartSequenceImmediately(animation)) {
103 // Attempt to preempt a running animation. 108 // Attempt to preempt a running animation.
104 switch (preemption_strategy_) { 109 switch (preemption_strategy_) {
105 case IMMEDIATELY_SET_NEW_TARGET: 110 case IMMEDIATELY_SET_NEW_TARGET:
106 ImmediatelySetNewTarget(animation); 111 ImmediatelySetNewTarget(animation);
107 break; 112 break;
108 case IMMEDIATELY_ANIMATE_TO_NEW_TARGET: 113 case IMMEDIATELY_ANIMATE_TO_NEW_TARGET:
109 ImmediatelyAnimateToNewTarget(animation); 114 ImmediatelyAnimateToNewTarget(animation);
110 break; 115 break;
111 case ENQUEUE_NEW_ANIMATION: 116 case ENQUEUE_NEW_ANIMATION:
112 EnqueueNewAnimation(animation); 117 EnqueueNewAnimation(animation);
113 break; 118 break;
114 case REPLACE_QUEUED_ANIMATIONS: 119 case REPLACE_QUEUED_ANIMATIONS:
115 ReplaceQueuedAnimations(animation); 120 ReplaceQueuedAnimations(animation);
116 break; 121 break;
117 case BLEND_WITH_CURRENT_ANIMATION: { 122 case BLEND_WITH_CURRENT_ANIMATION: {
118 // TODO(vollick) Add support for blended sequences and use them here. 123 // TODO(vollick) Add support for blended sequences and use them here.
119 NOTIMPLEMENTED(); 124 NOTIMPLEMENTED();
120 break; 125 break;
121 } 126 }
122 } 127 }
123 } 128 }
124 FinishAnyAnimationWithZeroDuration(); 129 FinishAnyAnimationWithZeroDuration();
125 UpdateAnimationState(); 130 UpdateAnimationState();
126 } 131 }
127 132
128 void LayerAnimator::ScheduleAnimation(LayerAnimationSequence* animation) { 133 void LayerAnimator::ScheduleAnimation(LayerAnimationSequence* animation) {
134 OnScheduled(animation);
129 if (is_animating()) { 135 if (is_animating()) {
130 animation_queue_.push_back(make_linked_ptr(animation)); 136 animation_queue_.push_back(make_linked_ptr(animation));
131 ProcessQueue(); 137 ProcessQueue();
132 } else { 138 } else {
133 StartSequenceImmediately(animation); 139 StartSequenceImmediately(animation);
134 } 140 }
135 UpdateAnimationState(); 141 UpdateAnimationState();
136 } 142 }
137 143
138 void LayerAnimator::ScheduleTogether( 144 void LayerAnimator::ScheduleTogether(
(...skipping 16 matching lines...) Expand all
155 161
156 // These animations (provided they don't animate any common properties) will 162 // These animations (provided they don't animate any common properties) will
157 // now animate together if trivially scheduled. 163 // now animate together if trivially scheduled.
158 for (iter = animations.begin(); iter != animations.end(); ++iter) { 164 for (iter = animations.begin(); iter != animations.end(); ++iter) {
159 ScheduleAnimation(*iter); 165 ScheduleAnimation(*iter);
160 } 166 }
161 167
162 UpdateAnimationState(); 168 UpdateAnimationState();
163 } 169 }
164 170
165 void LayerAnimator::StartAnimationElement(LayerAnimationElement* animation) { 171 bool LayerAnimator::IsAnimatingProperty(
166 StartAnimation(new LayerAnimationSequence(animation)); 172 LayerAnimationElement::AnimatableProperty property) const {
167 } 173 for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin();
168 174 queue_iter != animation_queue_.end(); ++queue_iter) {
169 void LayerAnimator::ScheduleAnimationElement(LayerAnimationElement* animation) { 175 if ((*queue_iter)->properties().find(property) !=
170 ScheduleAnimation(new LayerAnimationSequence(animation)); 176 (*queue_iter)->properties().end()) {
171 } 177 return true;
172 178 }
173 void LayerAnimator::ScheduleElementsTogether( 179 }
174 const std::vector<LayerAnimationElement*>& animations) { 180 return false;
175 std::vector<LayerAnimationSequence*> sequences;
176 for (size_t i = 0; i < animations.size(); ++i)
177 sequences.push_back(new LayerAnimationSequence(animations[i]));
178 ScheduleTogether(sequences);
179 } 181 }
180 182
181 void LayerAnimator::StopAnimatingProperty( 183 void LayerAnimator::StopAnimatingProperty(
182 LayerAnimationElement::AnimatableProperty property) { 184 LayerAnimationElement::AnimatableProperty property) {
183 while (true) { 185 while (true) {
184 RunningAnimation* running = GetRunningAnimation(property); 186 RunningAnimation* running = GetRunningAnimation(property);
185 if (!running) 187 if (!running)
186 break; 188 break;
187 FinishAnimation(running->sequence); 189 FinishAnimation(running->sequence);
188 } 190 }
189 } 191 }
190 192
191 void LayerAnimator::StopAnimating() { 193 void LayerAnimator::StopAnimating() {
192 while (is_animating()) 194 while (is_animating())
193 FinishAnimation(running_animations_[0].sequence); 195 FinishAnimation(running_animations_[0].sequence);
194 } 196 }
195 197
198 void LayerAnimator::AddObserver(LayerAnimationObserver* observer) {
199 if (!observers_.HasObserver(observer))
sky 2011/10/28 22:11:38 remove this.
200 observers_.AddObserver(observer);
201 }
202
203 void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) {
204 observers_.RemoveObserver(observer);
sky 2011/10/28 22:11:38 Doesn't this need to remove it from any sequences
205 }
206
196 LayerAnimator::ScopedSettings::ScopedSettings(LayerAnimator* animator) 207 LayerAnimator::ScopedSettings::ScopedSettings(LayerAnimator* animator)
197 : animator_(animator), 208 : animator_(animator),
198 old_transition_duration_(animator->transition_duration_) { 209 old_transition_duration_(animator->transition_duration_) {
199 SetTransitionDuration(kDefaultTransitionDuration); 210 SetTransitionDuration(kDefaultTransitionDuration);
200 } 211 }
201 212
202 LayerAnimator::ScopedSettings::~ScopedSettings() { 213 LayerAnimator::ScopedSettings::~ScopedSettings() {
203 animator_->transition_duration_ = old_transition_duration_; 214 animator_->transition_duration_ = old_transition_duration_;
215 std::set<LayerAnimationObserver*>::const_iterator i = observers_.begin();
sky 2011/10/28 22:11:38 move into loop.
216 for (;i != observers_.end(); ++i)
217 animator_->RemoveObserver(*i);
218 }
219
220 void LayerAnimator::ScopedSettings::AddObserver(
221 LayerAnimationObserver* observer) {
222 observers_.insert(observer);
223 animator_->AddObserver(observer);
204 } 224 }
205 225
206 void LayerAnimator::ScopedSettings::SetTransitionDuration( 226 void LayerAnimator::ScopedSettings::SetTransitionDuration(
207 base::TimeDelta duration) { 227 base::TimeDelta duration) {
208 animator_->transition_duration_ = duration; 228 animator_->transition_duration_ = duration;
209 } 229 }
210 230
211 // LayerAnimator private ------------------------------------------------------- 231 // LayerAnimator private -------------------------------------------------------
212 232
213 void LayerAnimator::Step(base::TimeTicks now) { 233 void LayerAnimator::Step(base::TimeTicks now) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 queue_iter != animation_queue_.end(); ++queue_iter) { 290 queue_iter != animation_queue_.end(); ++queue_iter) {
271 if ((*queue_iter) == sequence) { 291 if ((*queue_iter) == sequence) {
272 animation_queue_.erase(queue_iter); 292 animation_queue_.erase(queue_iter);
273 break; 293 break;
274 } 294 }
275 } 295 }
276 } 296 }
277 297
278 void LayerAnimator::FinishAnimation(LayerAnimationSequence* sequence) { 298 void LayerAnimator::FinishAnimation(LayerAnimationSequence* sequence) {
279 sequence->Progress(sequence->duration(), delegate()); 299 sequence->Progress(sequence->duration(), delegate());
280 delegate()->OnLayerAnimationEnded(sequence);
281 RemoveAnimation(sequence); 300 RemoveAnimation(sequence);
282 ProcessQueue(); 301 ProcessQueue();
283 UpdateAnimationState(); 302 UpdateAnimationState();
284 } 303 }
285 304
286 void LayerAnimator::FinishAnyAnimationWithZeroDuration() { 305 void LayerAnimator::FinishAnyAnimationWithZeroDuration() {
287 // Special case: if we've started a 0 duration animation, just finish it now 306 // Special case: if we've started a 0 duration animation, just finish it now
288 // and get rid of it. Note at each iteration of the loop, we either increment 307 // and get rid of it. Note at each iteration of the loop, we either increment
289 // i or remove an element from running_animations_, so 308 // i or remove an element from running_animations_, so
290 // running_animations_.size() - i is always decreasing and we are always 309 // running_animations_.size() - i is always decreasing and we are always
291 // progressing towards the termination of the loop. 310 // progressing towards the termination of the loop.
292 for (size_t i = 0; i < running_animations_.size();) { 311 for (size_t i = 0; i < running_animations_.size();) {
293 if (running_animations_[i].sequence->duration() == base::TimeDelta()) { 312 if (running_animations_[i].sequence->duration() == base::TimeDelta()) {
294 running_animations_[i].sequence->Progress( 313 running_animations_[i].sequence->Progress(
295 running_animations_[i].sequence->duration(), delegate()); 314 running_animations_[i].sequence->duration(), delegate());
296 delegate()->OnLayerAnimationEnded(running_animations_[i].sequence);
297 RemoveAnimation(running_animations_[i].sequence); 315 RemoveAnimation(running_animations_[i].sequence);
298 } else { 316 } else {
299 ++i; 317 ++i;
300 } 318 }
301 } 319 }
302 ProcessQueue(); 320 ProcessQueue();
303 UpdateAnimationState(); 321 UpdateAnimationState();
304 } 322 }
305 323
306 void LayerAnimator::ClearAnimations() { 324 void LayerAnimator::ClearAnimations() {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 // progress towards the loop terminating. 367 // progress towards the loop terminating.
350 for (size_t i = 0; i < running_animations_.size();) { 368 for (size_t i = 0; i < running_animations_.size();) {
351 if (running_animations_[i].sequence->HasCommonProperty( 369 if (running_animations_[i].sequence->HasCommonProperty(
352 sequence->properties())) { 370 sequence->properties())) {
353 // Finish the animation. 371 // Finish the animation.
354 if (abort){ 372 if (abort){
355 running_animations_[i].sequence->Abort(); 373 running_animations_[i].sequence->Abort();
356 } else { 374 } else {
357 running_animations_[i].sequence->Progress( 375 running_animations_[i].sequence->Progress(
358 running_animations_[i].sequence->duration(), delegate()); 376 running_animations_[i].sequence->duration(), delegate());
359 delegate()->OnLayerAnimationEnded(running_animations_[i].sequence);
360 } 377 }
361 RemoveAnimation(running_animations_[i].sequence); 378 RemoveAnimation(running_animations_[i].sequence);
362 } else { 379 } else {
363 ++i; 380 ++i;
364 } 381 }
365 } 382 }
366 383
367 // Same for the queued animations. See comment above about loop termination. 384 // Same for the queued animations. See comment above about loop termination.
368 for (size_t i = 0; i < animation_queue_.size();) { 385 for (size_t i = 0; i < animation_queue_.size();) {
369 if (animation_queue_[i]->HasCommonProperty(sequence->properties())) { 386 if (animation_queue_[i]->HasCommonProperty(sequence->properties())) {
370 // Finish the animation. 387 // Finish the animation.
371 if (abort) 388 if (abort)
372 animation_queue_[i]->Abort(); 389 animation_queue_[i]->Abort();
373 else 390 else
374 animation_queue_[i]->Progress(animation_queue_[i]->duration(), 391 animation_queue_[i]->Progress(animation_queue_[i]->duration(),
375 delegate()); 392 delegate());
376 RemoveAnimation(animation_queue_[i].get()); 393 RemoveAnimation(animation_queue_[i].get());
377 } else { 394 } else {
378 ++i; 395 ++i;
379 } 396 }
380 } 397 }
381 } 398 }
382 399
383 void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) { 400 void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) {
384 const bool abort = false; 401 const bool abort = false;
385 RemoveAllAnimationsWithACommonProperty(sequence, abort); 402 RemoveAllAnimationsWithACommonProperty(sequence, abort);
386 sequence->Progress(sequence->duration(), delegate()); 403 sequence->Progress(sequence->duration(), delegate());
387 delegate()->OnLayerAnimationEnded(sequence);
388 RemoveAnimation(sequence); 404 RemoveAnimation(sequence);
389 } 405 }
390 406
391 void LayerAnimator::ImmediatelyAnimateToNewTarget( 407 void LayerAnimator::ImmediatelyAnimateToNewTarget(
392 LayerAnimationSequence* sequence) { 408 LayerAnimationSequence* sequence) {
393 const bool abort = true; 409 const bool abort = true;
394 RemoveAllAnimationsWithACommonProperty(sequence, abort); 410 RemoveAllAnimationsWithACommonProperty(sequence, abort);
395 AddToQueueIfNotPresent(sequence); 411 AddToQueueIfNotPresent(sequence);
396 StartSequenceImmediately(sequence); 412 StartSequenceImmediately(sequence);
397 } 413 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 } 509 }
494 510
495 void LayerAnimator::GetTargetValue( 511 void LayerAnimator::GetTargetValue(
496 LayerAnimationElement::TargetValue* target) const { 512 LayerAnimationElement::TargetValue* target) const {
497 for (RunningAnimations::const_iterator iter = running_animations_.begin(); 513 for (RunningAnimations::const_iterator iter = running_animations_.begin();
498 iter != running_animations_.end(); ++iter) { 514 iter != running_animations_.end(); ++iter) {
499 (*iter).sequence->GetTargetValue(target); 515 (*iter).sequence->GetTargetValue(target);
500 } 516 }
501 } 517 }
502 518
519 void LayerAnimator::OnScheduled(LayerAnimationSequence* sequence) {
520 if (observers_.might_have_observers()) {
521 ObserverListBase<LayerAnimationObserver>::Iterator it(observers_);
522 LayerAnimationObserver* obs;
523 while ((obs = it.GetNext()) != NULL) {
524 sequence->AddObserver(obs);
525 }
526 }
527 sequence->OnScheduled();
528 }
529
503 } // namespace ui 530 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698