Home | History | Annotate | Download | only in compositor
      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 
      9 namespace ui {
     10 
     11 ////////////////////////////////////////////////////////////////////////////////
     12 // LayerAnimationObserver
     13 
     14 LayerAnimationObserver::LayerAnimationObserver() {
     15 }
     16 
     17 LayerAnimationObserver::~LayerAnimationObserver() {
     18   StopObserving();
     19 }
     20 
     21 bool LayerAnimationObserver::RequiresNotificationWhenAnimatorDestroyed() const {
     22   return false;
     23 }
     24 
     25 void LayerAnimationObserver::OnAttachedToSequence(
     26     LayerAnimationSequence* sequence) {
     27 }
     28 
     29 void LayerAnimationObserver::OnDetachedFromSequence(
     30     LayerAnimationSequence* sequence) {
     31 }
     32 
     33 void LayerAnimationObserver::StopObserving() {
     34   while (!attached_sequences_.empty()) {
     35     LayerAnimationSequence* sequence = *attached_sequences_.begin();
     36     sequence->RemoveObserver(this);
     37   }
     38 }
     39 
     40 void LayerAnimationObserver::AttachedToSequence(
     41     LayerAnimationSequence* sequence) {
     42   DCHECK(attached_sequences_.find(sequence) == attached_sequences_.end());
     43   attached_sequences_.insert(sequence);
     44   OnAttachedToSequence(sequence);
     45 }
     46 
     47 void 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 
     58 ImplicitAnimationObserver::ImplicitAnimationObserver()
     59     : active_(false),
     60       destroyed_(NULL),
     61       first_sequence_scheduled_(false) {
     62 }
     63 
     64 ImplicitAnimationObserver::~ImplicitAnimationObserver() {
     65   if (destroyed_)
     66     *destroyed_ = true;
     67 }
     68 
     69 void ImplicitAnimationObserver::SetActive(bool active) {
     70   active_ = active;
     71   CheckCompleted();
     72 }
     73 
     74 void ImplicitAnimationObserver::StopObservingImplicitAnimations() {
     75   SetActive(false);
     76   StopObserving();
     77 }
     78 
     79 bool ImplicitAnimationObserver::WasAnimationAbortedForProperty(
     80     LayerAnimationElement::AnimatableProperty property) const {
     81   return AnimationStatusForProperty(property) == ANIMATION_STATUS_ABORTED;
     82 }
     83 
     84 bool ImplicitAnimationObserver::WasAnimationCompletedForProperty(
     85     LayerAnimationElement::AnimatableProperty property) const {
     86   return AnimationStatusForProperty(property) == ANIMATION_STATUS_COMPLETED;
     87 }
     88 
     89 void 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 
    102 void 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 
    115 void ImplicitAnimationObserver::OnLayerAnimationScheduled(
    116     LayerAnimationSequence* sequence) {
    117   if (!first_sequence_scheduled_) {
    118     first_sequence_scheduled_ = true;
    119     OnImplicitAnimationsScheduled();
    120   }
    121 }
    122 
    123 void ImplicitAnimationObserver::OnAttachedToSequence(
    124     LayerAnimationSequence* sequence) {
    125 }
    126 
    127 void ImplicitAnimationObserver::OnDetachedFromSequence(
    128     LayerAnimationSequence* sequence) {
    129   DCHECK(attached_sequences().find(sequence) == attached_sequences().end());
    130   CheckCompleted();
    131 }
    132 
    133 void ImplicitAnimationObserver::CheckCompleted() {
    134   if (active_ && attached_sequences().empty()) {
    135     active_ = false;
    136     OnImplicitAnimationsCompleted();
    137   }
    138 }
    139 
    140 void ImplicitAnimationObserver::UpdatePropertyAnimationStatus(
    141     LayerAnimationSequence* sequence,
    142     AnimationStatus status) {
    143   const LayerAnimationElement::AnimatableProperties& properties =
    144       sequence->properties();
    145   for (LayerAnimationElement::AnimatableProperties::const_iterator i =
    146            properties.begin(); i != properties.end(); ++i) {
    147     property_animation_status_[(*i)] = status;
    148   }
    149 }
    150 
    151 ImplicitAnimationObserver::AnimationStatus
    152 ImplicitAnimationObserver::AnimationStatusForProperty(
    153     LayerAnimationElement::AnimatableProperty property) const {
    154   PropertyAnimationStatusMap::const_iterator iter =
    155       property_animation_status_.find(property);
    156   return iter == property_animation_status_.end() ? ANIMATION_STATUS_UNKNOWN :
    157       iter->second;
    158 }
    159 
    160 }  // namespace ui
    161