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

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: merge with master 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 "base/observer_list.h"
sky 2011/10/27 19:29:19 don't need this since in header.
10 #include "ui/base/animation/animation_container.h" 11 #include "ui/base/animation/animation_container.h"
11 #include "ui/gfx/compositor/compositor.h" 12 #include "ui/gfx/compositor/compositor.h"
12 #include "ui/gfx/compositor/layer.h" 13 #include "ui/gfx/compositor/layer.h"
13 #include "ui/gfx/compositor/layer_animator_delegate.h" 14 #include "ui/gfx/compositor/layer_animation_delegate.h"
15 #include "ui/gfx/compositor/layer_animation_observer.h"
14 #include "ui/gfx/compositor/layer_animation_sequence.h" 16 #include "ui/gfx/compositor/layer_animation_sequence.h"
15 17
16 namespace ui { 18 namespace ui {
17 19
18 class LayerAnimator; 20 class LayerAnimator;
19 21
20 namespace { 22 namespace {
21 23
22 static const base::TimeDelta kDefaultTransitionDuration = 24 static const base::TimeDelta kDefaultTransitionDuration =
23 base::TimeDelta::FromMilliseconds(200); 25 base::TimeDelta::FromMilliseconds(200);
(...skipping 24 matching lines...) Expand all
48 50
49 // static 51 // static
50 LayerAnimator* LayerAnimator::CreateImplicitAnimator() { 52 LayerAnimator* LayerAnimator::CreateImplicitAnimator() {
51 return new LayerAnimator(kDefaultTransitionDuration); 53 return new LayerAnimator(kDefaultTransitionDuration);
52 } 54 }
53 55
54 void LayerAnimator::SetTransform(const Transform& transform) { 56 void LayerAnimator::SetTransform(const Transform& transform) {
55 if (transition_duration_ == base::TimeDelta()) 57 if (transition_duration_ == base::TimeDelta())
56 delegate_->SetTransformFromAnimation(transform); 58 delegate_->SetTransformFromAnimation(transform);
57 else 59 else
58 StartAnimationElement(LayerAnimationElement::CreateTransformElement( 60 StartAnimation(new LayerAnimationSequence(
59 transform, transition_duration_)); 61 LayerAnimationElement::CreateTransformElement(
62 transform, transition_duration_)));
60 } 63 }
61 64
62 Transform LayerAnimator::GetTargetTransform() const { 65 Transform LayerAnimator::GetTargetTransform() const {
63 LayerAnimationElement::TargetValue target; 66 LayerAnimationElement::TargetValue target;
64 GetTargetValue(&target); 67 GetTargetValue(&target);
65 return target.transform; 68 return target.transform;
66 } 69 }
67 70
68 void LayerAnimator::SetBounds(const gfx::Rect& bounds) { 71 void LayerAnimator::SetBounds(const gfx::Rect& bounds) {
69 if (transition_duration_ == base::TimeDelta()) 72 if (transition_duration_ == base::TimeDelta())
70 delegate_->SetBoundsFromAnimation(bounds); 73 delegate_->SetBoundsFromAnimation(bounds);
71 else 74 else
72 StartAnimationElement(LayerAnimationElement::CreateBoundsElement( 75 StartAnimation(new LayerAnimationSequence(
73 bounds, transition_duration_)); 76 LayerAnimationElement::CreateBoundsElement(
77 bounds, transition_duration_)));
74 } 78 }
75 79
76 gfx::Rect LayerAnimator::GetTargetBounds() const { 80 gfx::Rect LayerAnimator::GetTargetBounds() const {
77 LayerAnimationElement::TargetValue target; 81 LayerAnimationElement::TargetValue target;
78 GetTargetValue(&target); 82 GetTargetValue(&target);
79 return target.bounds; 83 return target.bounds;
80 } 84 }
81 85
82 void LayerAnimator::SetOpacity(float opacity) { 86 void LayerAnimator::SetOpacity(float opacity) {
83 if (transition_duration_ == base::TimeDelta()) 87 if (transition_duration_ == base::TimeDelta())
84 delegate_->SetOpacityFromAnimation(opacity); 88 delegate_->SetOpacityFromAnimation(opacity);
85 else 89 else
86 StartAnimationElement(LayerAnimationElement::CreateOpacityElement( 90 StartAnimation(new LayerAnimationSequence(
87 opacity, transition_duration_)); 91 LayerAnimationElement::CreateOpacityElement(
92 opacity, transition_duration_)));
88 } 93 }
89 94
90 float LayerAnimator::GetTargetOpacity() const { 95 float LayerAnimator::GetTargetOpacity() const {
91 LayerAnimationElement::TargetValue target; 96 LayerAnimationElement::TargetValue target;
92 GetTargetValue(&target); 97 GetTargetValue(&target);
93 return target.opacity; 98 return target.opacity;
94 } 99 }
95 100
96 void LayerAnimator::SetDelegate(LayerAnimatorDelegate* delegate) { 101 void LayerAnimator::SetDelegate(LayerAnimationDelegate* delegate) {
97 DCHECK(delegate); 102 DCHECK(delegate);
98 delegate_ = delegate; 103 delegate_ = delegate;
99 } 104 }
100 105
101 void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) { 106 void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) {
107 AddObserversToSequence(animation);
102 if (!StartSequenceImmediately(animation)) { 108 if (!StartSequenceImmediately(animation)) {
103 // Attempt to preempt a running animation. 109 // Attempt to preempt a running animation.
104 switch (preemption_strategy_) { 110 switch (preemption_strategy_) {
105 case IMMEDIATELY_SET_NEW_TARGET: 111 case IMMEDIATELY_SET_NEW_TARGET:
106 ImmediatelySetNewTarget(animation); 112 ImmediatelySetNewTarget(animation);
107 break; 113 break;
108 case IMMEDIATELY_ANIMATE_TO_NEW_TARGET: 114 case IMMEDIATELY_ANIMATE_TO_NEW_TARGET:
109 ImmediatelyAnimateToNewTarget(animation); 115 ImmediatelyAnimateToNewTarget(animation);
110 break; 116 break;
111 case ENQUEUE_NEW_ANIMATION: 117 case ENQUEUE_NEW_ANIMATION:
112 EnqueueNewAnimation(animation); 118 EnqueueNewAnimation(animation);
113 break; 119 break;
114 case REPLACE_QUEUED_ANIMATIONS: 120 case REPLACE_QUEUED_ANIMATIONS:
115 ReplaceQueuedAnimations(animation); 121 ReplaceQueuedAnimations(animation);
116 break; 122 break;
117 case BLEND_WITH_CURRENT_ANIMATION: { 123 case BLEND_WITH_CURRENT_ANIMATION: {
118 // TODO(vollick) Add support for blended sequences and use them here. 124 // TODO(vollick) Add support for blended sequences and use them here.
119 NOTIMPLEMENTED(); 125 NOTIMPLEMENTED();
120 break; 126 break;
121 } 127 }
122 } 128 }
123 } 129 }
124 FinishAnyAnimationWithZeroDuration(); 130 FinishAnyAnimationWithZeroDuration();
125 UpdateAnimationState(); 131 UpdateAnimationState();
126 } 132 }
127 133
128 void LayerAnimator::ScheduleAnimation(LayerAnimationSequence* animation) { 134 void LayerAnimator::ScheduleAnimation(LayerAnimationSequence* animation) {
135 AddObserversToSequence(animation);
129 if (is_animating()) { 136 if (is_animating()) {
130 animation_queue_.push_back(make_linked_ptr(animation)); 137 animation_queue_.push_back(make_linked_ptr(animation));
131 ProcessQueue(); 138 ProcessQueue();
132 } else { 139 } else {
133 StartSequenceImmediately(animation); 140 StartSequenceImmediately(animation);
134 } 141 }
135 UpdateAnimationState(); 142 UpdateAnimationState();
136 } 143 }
137 144
138 void LayerAnimator::ScheduleTogether( 145 void LayerAnimator::ScheduleTogether(
(...skipping 16 matching lines...) Expand all
155 162
156 // These animations (provided they don't animate any common properties) will 163 // These animations (provided they don't animate any common properties) will
157 // now animate together if trivially scheduled. 164 // now animate together if trivially scheduled.
158 for (iter = animations.begin(); iter != animations.end(); ++iter) { 165 for (iter = animations.begin(); iter != animations.end(); ++iter) {
159 ScheduleAnimation(*iter); 166 ScheduleAnimation(*iter);
160 } 167 }
161 168
162 UpdateAnimationState(); 169 UpdateAnimationState();
163 } 170 }
164 171
165 void LayerAnimator::StartAnimationElement(LayerAnimationElement* animation) {
166 StartAnimation(new LayerAnimationSequence(animation));
167 }
168
169 void LayerAnimator::ScheduleAnimationElement(LayerAnimationElement* animation) {
170 ScheduleAnimation(new LayerAnimationSequence(animation));
171 }
172
173 void LayerAnimator::ScheduleElementsTogether(
174 const std::vector<LayerAnimationElement*>& animations) {
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 }
180
181 void LayerAnimator::StopAnimatingProperty( 172 void LayerAnimator::StopAnimatingProperty(
182 LayerAnimationElement::AnimatableProperty property) { 173 LayerAnimationElement::AnimatableProperty property) {
183 while (true) { 174 while (true) {
184 RunningAnimation* running = GetRunningAnimation(property); 175 RunningAnimation* running = GetRunningAnimation(property);
185 if (!running) 176 if (!running)
186 break; 177 break;
187 FinishAnimation(running->sequence); 178 FinishAnimation(running->sequence);
188 } 179 }
189 } 180 }
190 181
191 void LayerAnimator::StopAnimating() { 182 void LayerAnimator::StopAnimating() {
192 while (is_animating()) 183 while (is_animating())
193 FinishAnimation(running_animations_[0].sequence); 184 FinishAnimation(running_animations_[0].sequence);
194 } 185 }
195 186
187 void LayerAnimator::AddObserver(LayerAnimationObserver* observer) {
188 if (!observers_.HasObserver(observer))
189 observers_.AddObserver(observer);
190 }
191
192 void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) {
193 observers_.RemoveObserver(observer);
194 }
195
196 LayerAnimator::ScopedSettings::ScopedSettings(LayerAnimator* animator) 196 LayerAnimator::ScopedSettings::ScopedSettings(LayerAnimator* animator)
197 : animator_(animator), 197 : animator_(animator),
198 old_transition_duration_(animator->transition_duration_) { 198 old_transition_duration_(animator->transition_duration_) {
199 SetTransitionDuration(kDefaultTransitionDuration); 199 SetTransitionDuration(kDefaultTransitionDuration);
200 } 200 }
201 201
202 LayerAnimator::ScopedSettings::~ScopedSettings() { 202 LayerAnimator::ScopedSettings::~ScopedSettings() {
203 animator_->transition_duration_ = old_transition_duration_; 203 animator_->transition_duration_ = old_transition_duration_;
204 for (size_t i = 0; i < observers_.size(); ++i)
205 animator_->RemoveObserver(observers_[i]);
206 }
207
208 void LayerAnimator::ScopedSettings::AddObserver(
209 LayerAnimationObserver* observer) {
210 observers_.push_back(observer);
211 animator_->AddObserver(observer);
sky 2011/10/27 19:29:19 I believe this means the observer is notified of e
204 } 212 }
205 213
206 void LayerAnimator::ScopedSettings::SetTransitionDuration( 214 void LayerAnimator::ScopedSettings::SetTransitionDuration(
207 base::TimeDelta duration) { 215 base::TimeDelta duration) {
208 animator_->transition_duration_ = duration; 216 animator_->transition_duration_ = duration;
209 } 217 }
210 218
211 // LayerAnimator private ------------------------------------------------------- 219 // LayerAnimator private -------------------------------------------------------
212 220
213 void LayerAnimator::Step(base::TimeTicks now) { 221 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) { 278 queue_iter != animation_queue_.end(); ++queue_iter) {
271 if ((*queue_iter) == sequence) { 279 if ((*queue_iter) == sequence) {
272 animation_queue_.erase(queue_iter); 280 animation_queue_.erase(queue_iter);
273 break; 281 break;
274 } 282 }
275 } 283 }
276 } 284 }
277 285
278 void LayerAnimator::FinishAnimation(LayerAnimationSequence* sequence) { 286 void LayerAnimator::FinishAnimation(LayerAnimationSequence* sequence) {
279 sequence->Progress(sequence->duration(), delegate()); 287 sequence->Progress(sequence->duration(), delegate());
280 delegate()->OnLayerAnimationEnded(sequence); 288 NotifyAnimationEnded(sequence);
281 RemoveAnimation(sequence); 289 RemoveAnimation(sequence);
282 ProcessQueue(); 290 ProcessQueue();
283 UpdateAnimationState(); 291 UpdateAnimationState();
284 } 292 }
285 293
286 void LayerAnimator::FinishAnyAnimationWithZeroDuration() { 294 void LayerAnimator::FinishAnyAnimationWithZeroDuration() {
287 // Special case: if we've started a 0 duration animation, just finish it now 295 // 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 296 // 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 297 // i or remove an element from running_animations_, so
290 // running_animations_.size() - i is always decreasing and we are always 298 // running_animations_.size() - i is always decreasing and we are always
291 // progressing towards the termination of the loop. 299 // progressing towards the termination of the loop.
292 for (size_t i = 0; i < running_animations_.size();) { 300 for (size_t i = 0; i < running_animations_.size();) {
293 if (running_animations_[i].sequence->duration() == base::TimeDelta()) { 301 if (running_animations_[i].sequence->duration() == base::TimeDelta()) {
294 running_animations_[i].sequence->Progress( 302 running_animations_[i].sequence->Progress(
295 running_animations_[i].sequence->duration(), delegate()); 303 running_animations_[i].sequence->duration(), delegate());
296 delegate()->OnLayerAnimationEnded(running_animations_[i].sequence); 304 NotifyAnimationEnded(running_animations_[i].sequence);
sky 2011/10/27 19:29:19 Can't progress recognize it's at the end and notif
297 RemoveAnimation(running_animations_[i].sequence); 305 RemoveAnimation(running_animations_[i].sequence);
298 } else { 306 } else {
299 ++i; 307 ++i;
300 } 308 }
301 } 309 }
302 ProcessQueue(); 310 ProcessQueue();
303 UpdateAnimationState(); 311 UpdateAnimationState();
304 } 312 }
305 313
306 void LayerAnimator::ClearAnimations() { 314 void LayerAnimator::ClearAnimations() {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 // progress towards the loop terminating. 357 // progress towards the loop terminating.
350 for (size_t i = 0; i < running_animations_.size();) { 358 for (size_t i = 0; i < running_animations_.size();) {
351 if (running_animations_[i].sequence->HasCommonProperty( 359 if (running_animations_[i].sequence->HasCommonProperty(
352 sequence->properties())) { 360 sequence->properties())) {
353 // Finish the animation. 361 // Finish the animation.
354 if (abort){ 362 if (abort){
355 running_animations_[i].sequence->Abort(); 363 running_animations_[i].sequence->Abort();
356 } else { 364 } else {
357 running_animations_[i].sequence->Progress( 365 running_animations_[i].sequence->Progress(
358 running_animations_[i].sequence->duration(), delegate()); 366 running_animations_[i].sequence->duration(), delegate());
359 delegate()->OnLayerAnimationEnded(running_animations_[i].sequence); 367 NotifyAnimationEnded(running_animations_[i].sequence);
360 } 368 }
361 RemoveAnimation(running_animations_[i].sequence); 369 RemoveAnimation(running_animations_[i].sequence);
362 } else { 370 } else {
363 ++i; 371 ++i;
364 } 372 }
365 } 373 }
366 374
367 // Same for the queued animations. See comment above about loop termination. 375 // Same for the queued animations. See comment above about loop termination.
368 for (size_t i = 0; i < animation_queue_.size();) { 376 for (size_t i = 0; i < animation_queue_.size();) {
369 if (animation_queue_[i]->HasCommonProperty(sequence->properties())) { 377 if (animation_queue_[i]->HasCommonProperty(sequence->properties())) {
370 // Finish the animation. 378 // Finish the animation.
371 if (abort) 379 if (abort)
372 animation_queue_[i]->Abort(); 380 animation_queue_[i]->Abort();
373 else 381 else
374 animation_queue_[i]->Progress(animation_queue_[i]->duration(), 382 animation_queue_[i]->Progress(animation_queue_[i]->duration(),
375 delegate()); 383 delegate());
376 RemoveAnimation(animation_queue_[i].get()); 384 RemoveAnimation(animation_queue_[i].get());
377 } else { 385 } else {
378 ++i; 386 ++i;
379 } 387 }
380 } 388 }
381 } 389 }
382 390
383 void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) { 391 void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) {
384 const bool abort = false; 392 const bool abort = false;
385 RemoveAllAnimationsWithACommonProperty(sequence, abort); 393 RemoveAllAnimationsWithACommonProperty(sequence, abort);
386 sequence->Progress(sequence->duration(), delegate()); 394 sequence->Progress(sequence->duration(), delegate());
387 delegate()->OnLayerAnimationEnded(sequence); 395 NotifyAnimationEnded(sequence);
388 RemoveAnimation(sequence); 396 RemoveAnimation(sequence);
389 } 397 }
390 398
391 void LayerAnimator::ImmediatelyAnimateToNewTarget( 399 void LayerAnimator::ImmediatelyAnimateToNewTarget(
392 LayerAnimationSequence* sequence) { 400 LayerAnimationSequence* sequence) {
393 const bool abort = true; 401 const bool abort = true;
394 RemoveAllAnimationsWithACommonProperty(sequence, abort); 402 RemoveAllAnimationsWithACommonProperty(sequence, abort);
395 AddToQueueIfNotPresent(sequence); 403 AddToQueueIfNotPresent(sequence);
396 StartSequenceImmediately(sequence); 404 StartSequenceImmediately(sequence);
397 } 405 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 } 501 }
494 502
495 void LayerAnimator::GetTargetValue( 503 void LayerAnimator::GetTargetValue(
496 LayerAnimationElement::TargetValue* target) const { 504 LayerAnimationElement::TargetValue* target) const {
497 for (RunningAnimations::const_iterator iter = running_animations_.begin(); 505 for (RunningAnimations::const_iterator iter = running_animations_.begin();
498 iter != running_animations_.end(); ++iter) { 506 iter != running_animations_.end(); ++iter) {
499 (*iter).sequence->GetTargetValue(target); 507 (*iter).sequence->GetTargetValue(target);
500 } 508 }
501 } 509 }
502 510
511 void LayerAnimator::NotifyAnimationEnded(LayerAnimationSequence* sequence) {
512 sequence->NotifyEnded();
513 }
514
515 void LayerAnimator::AddObserversToSequence(LayerAnimationSequence* sequence) {
516 if (observers_.might_have_observers()) {
517 ObserverListBase<LayerAnimationObserver>::Iterator it(observers_);
518 LayerAnimationObserver* obs;
519 while ((obs = it.GetNext()) != NULL)
520 sequence->AddObserver(obs);
521 }
522 }
523
503 } // namespace ui 524 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698