1// Copyright (c) 2012 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/compositor/layer_animation_observer.h" 6 7#include "ui/compositor/layer_animation_sequence.h" 8 9namespace ui { 10 11//////////////////////////////////////////////////////////////////////////////// 12// LayerAnimationObserver 13 14LayerAnimationObserver::LayerAnimationObserver() { 15} 16 17LayerAnimationObserver::~LayerAnimationObserver() { 18 StopObserving(); 19} 20 21bool LayerAnimationObserver::RequiresNotificationWhenAnimatorDestroyed() const { 22 return false; 23} 24 25void LayerAnimationObserver::OnAttachedToSequence( 26 LayerAnimationSequence* sequence) { 27} 28 29void LayerAnimationObserver::OnDetachedFromSequence( 30 LayerAnimationSequence* sequence) { 31} 32 33void LayerAnimationObserver::StopObserving() { 34 while (!attached_sequences_.empty()) { 35 LayerAnimationSequence* sequence = *attached_sequences_.begin(); 36 sequence->RemoveObserver(this); 37 } 38} 39 40void LayerAnimationObserver::AttachedToSequence( 41 LayerAnimationSequence* sequence) { 42 DCHECK(attached_sequences_.find(sequence) == attached_sequences_.end()); 43 attached_sequences_.insert(sequence); 44 OnAttachedToSequence(sequence); 45} 46 47void LayerAnimationObserver::DetachedFromSequence( 48 LayerAnimationSequence* sequence, bool send_notification) { 49 if (attached_sequences_.find(sequence) != attached_sequences_.end()) 50 attached_sequences_.erase(sequence); 51 if (send_notification) 52 OnDetachedFromSequence(sequence); 53} 54 55//////////////////////////////////////////////////////////////////////////////// 56// ImplicitAnimationObserver 57 58ImplicitAnimationObserver::ImplicitAnimationObserver() 59 : active_(false), 60 destroyed_(NULL), 61 first_sequence_scheduled_(false) { 62} 63 64ImplicitAnimationObserver::~ImplicitAnimationObserver() { 65 if (destroyed_) 66 *destroyed_ = true; 67} 68 69void ImplicitAnimationObserver::SetActive(bool active) { 70 active_ = active; 71 CheckCompleted(); 72} 73 74void ImplicitAnimationObserver::StopObservingImplicitAnimations() { 75 SetActive(false); 76 StopObserving(); 77} 78 79bool ImplicitAnimationObserver::WasAnimationAbortedForProperty( 80 LayerAnimationElement::AnimatableProperty property) const { 81 return AnimationStatusForProperty(property) == ANIMATION_STATUS_ABORTED; 82} 83 84bool ImplicitAnimationObserver::WasAnimationCompletedForProperty( 85 LayerAnimationElement::AnimatableProperty property) const { 86 return AnimationStatusForProperty(property) == ANIMATION_STATUS_COMPLETED; 87} 88 89void ImplicitAnimationObserver::OnLayerAnimationEnded( 90 LayerAnimationSequence* sequence) { 91 UpdatePropertyAnimationStatus(sequence, ANIMATION_STATUS_COMPLETED); 92 bool destroyed = false; 93 destroyed_ = &destroyed; 94 sequence->RemoveObserver(this); 95 if (destroyed) 96 return; 97 destroyed_ = NULL; 98 DCHECK(attached_sequences().find(sequence) == attached_sequences().end()); 99 CheckCompleted(); 100} 101 102void ImplicitAnimationObserver::OnLayerAnimationAborted( 103 LayerAnimationSequence* sequence) { 104 UpdatePropertyAnimationStatus(sequence, ANIMATION_STATUS_ABORTED); 105 bool destroyed = false; 106 destroyed_ = &destroyed; 107 sequence->RemoveObserver(this); 108 if (destroyed) 109 return; 110 destroyed_ = NULL; 111 DCHECK(attached_sequences().find(sequence) == attached_sequences().end()); 112 CheckCompleted(); 113} 114 115void ImplicitAnimationObserver::OnLayerAnimationScheduled( 116 LayerAnimationSequence* sequence) { 117 if (!first_sequence_scheduled_) { 118 first_sequence_scheduled_ = true; 119 OnImplicitAnimationsScheduled(); 120 } 121} 122 123void ImplicitAnimationObserver::OnAttachedToSequence( 124 LayerAnimationSequence* sequence) { 125} 126 127void ImplicitAnimationObserver::OnDetachedFromSequence( 128 LayerAnimationSequence* sequence) { 129 DCHECK(attached_sequences().find(sequence) == attached_sequences().end()); 130 CheckCompleted(); 131} 132 133void ImplicitAnimationObserver::CheckCompleted() { 134 if (active_ && attached_sequences().empty()) { 135 active_ = false; 136 OnImplicitAnimationsCompleted(); 137 } 138} 139 140void ImplicitAnimationObserver::UpdatePropertyAnimationStatus( 141 LayerAnimationSequence* sequence, 142 AnimationStatus status) { 143 LayerAnimationElement::AnimatableProperties properties = 144 sequence->properties(); 145 for (unsigned i = LayerAnimationElement::FIRST_PROPERTY; 146 i != LayerAnimationElement::SENTINEL; 147 i = i << 1) { 148 if (i & properties) { 149 LayerAnimationElement::AnimatableProperty property = 150 static_cast<LayerAnimationElement::AnimatableProperty>(i); 151 property_animation_status_[property] = status; 152 } 153 } 154} 155 156ImplicitAnimationObserver::AnimationStatus 157ImplicitAnimationObserver::AnimationStatusForProperty( 158 LayerAnimationElement::AnimatableProperty property) const { 159 PropertyAnimationStatusMap::const_iterator iter = 160 property_animation_status_.find(property); 161 return iter == property_animation_status_.end() ? ANIMATION_STATUS_UNKNOWN : 162 iter->second; 163} 164 165} // namespace ui 166