root/ui/compositor/scoped_layer_animation_settings.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. SetLayer
  2. layer
  3. AddInverselyAnimatedLayer
  4. OnImplicitAnimationsCompleted
  5. OnLayerAnimationScheduled
  6. GetInverseElement
  7. inverse_observer_
  8. AddObserver
  9. SetTransitionDuration
  10. LockTransitionDuration
  11. GetTransitionDuration
  12. SetTweenType
  13. GetTweenType
  14. SetPreemptionStrategy
  15. GetPreemptionStrategy
  16. SetInverselyAnimatedBaseLayer
  17. AddInverselyAnimatedLayer

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/compositor/scoped_layer_animation_settings.h"

#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/layer_animation_sequence.h"
#include "ui/compositor/layer_animator.h"

namespace {

const int kDefaultTransitionDurationMs = 200;

}  // namespace

namespace ui {

// InvertingObserver -----------------------------------------------------------
class InvertingObserver : public ImplicitAnimationObserver {
  public:
    InvertingObserver()
      : base_layer_(NULL) {
    }

    virtual ~InvertingObserver() {}

    void SetLayer(Layer* base_layer) { base_layer_ = base_layer; }

    Layer* layer() { return base_layer_; }

    void AddInverselyAnimatedLayer(Layer* inverse_layer) {
      inverse_layers_.push_back(inverse_layer);
    }

    virtual void OnImplicitAnimationsCompleted() OVERRIDE {}

    virtual void OnLayerAnimationScheduled(
        LayerAnimationSequence* sequence) OVERRIDE {
      DCHECK(base_layer_  != NULL)
        << "Must set base layer with ScopedLayerAnimationSettings::"
        << "SetInverslyAnimatedBaseLayer";
      gfx::Transform base_transform = base_layer_->transform();
      scoped_ptr<LayerAnimationElement> inverse = GetInverseElement(sequence,
          base_transform);

      for (std::vector<Layer*>::const_iterator i =
          inverse_layers_.begin(); i != inverse_layers_.end(); ++i) {
        (*i)->GetAnimator()->StartAnimation(new LayerAnimationSequence(
            LayerAnimationElement::CloneInverseTransformElement(
                inverse.get())));
      }
    }
  private:
    scoped_ptr<LayerAnimationElement> GetInverseElement(
        LayerAnimationSequence* sequence,
        gfx::Transform base) const {
      const size_t expected_size = 1;
      DCHECK_EQ(expected_size, sequence->size()) <<
        "Inverse supported only for single element sequences.";

      LayerAnimationElement* element = sequence->FirstElement();
      DCHECK_EQ(static_cast<LayerAnimationElement::AnimatableProperties>(
                    LayerAnimationElement::TRANSFORM),
                element->properties())
          << "Only transform animations are currently invertible.";

      scoped_ptr<LayerAnimationElement> to_return(
          LayerAnimationElement::CreateInverseTransformElement(base, element));
      return to_return.Pass();
    }

    Layer* base_layer_;
    // child layers
    std::vector<Layer*> inverse_layers_;
};


// ScopedLayerAnimationSettings ------------------------------------------------
ScopedLayerAnimationSettings::ScopedLayerAnimationSettings(
    scoped_refptr<LayerAnimator> animator)
    : animator_(animator),
      old_is_transition_duration_locked_(
          animator->is_transition_duration_locked_),
      old_transition_duration_(animator->GetTransitionDuration()),
      old_tween_type_(animator->tween_type()),
      old_preemption_strategy_(animator->preemption_strategy()),
      inverse_observer_(new InvertingObserver()) {
  SetTransitionDuration(
      base::TimeDelta::FromMilliseconds(kDefaultTransitionDurationMs));
}

ScopedLayerAnimationSettings::~ScopedLayerAnimationSettings() {
  animator_->is_transition_duration_locked_ =
      old_is_transition_duration_locked_;
  animator_->SetTransitionDuration(old_transition_duration_);
  animator_->set_tween_type(old_tween_type_);
  animator_->set_preemption_strategy(old_preemption_strategy_);

  for (std::set<ImplicitAnimationObserver*>::const_iterator i =
       observers_.begin(); i != observers_.end(); ++i) {
    animator_->observers_.RemoveObserver(*i);
    (*i)->SetActive(true);
  }

  if (inverse_observer_->layer()) {
    animator_->observers_.RemoveObserver(inverse_observer_.get());
  }
}

void ScopedLayerAnimationSettings::AddObserver(
    ImplicitAnimationObserver* observer) {
  observers_.insert(observer);
  animator_->AddObserver(observer);
}

void ScopedLayerAnimationSettings::SetTransitionDuration(
    base::TimeDelta duration) {
  animator_->SetTransitionDuration(duration);
}

void ScopedLayerAnimationSettings::LockTransitionDuration() {
  animator_->is_transition_duration_locked_ = true;
}

base::TimeDelta ScopedLayerAnimationSettings::GetTransitionDuration() const {
  return animator_->GetTransitionDuration();
}

void ScopedLayerAnimationSettings::SetTweenType(gfx::Tween::Type tween_type) {
  animator_->set_tween_type(tween_type);
}

gfx::Tween::Type ScopedLayerAnimationSettings::GetTweenType() const {
  return animator_->tween_type();
}

void ScopedLayerAnimationSettings::SetPreemptionStrategy(
    LayerAnimator::PreemptionStrategy strategy) {
  animator_->set_preemption_strategy(strategy);
}

LayerAnimator::PreemptionStrategy
ScopedLayerAnimationSettings::GetPreemptionStrategy() const {
  return animator_->preemption_strategy();
}

void ScopedLayerAnimationSettings::SetInverselyAnimatedBaseLayer(Layer* base) {
  if (inverse_observer_->layer() && !base) {
      animator_->RemoveObserver(inverse_observer_.get());
  } else if (base && !(inverse_observer_->layer())) {
      animator_->AddObserver(inverse_observer_.get());
  }
  inverse_observer_->SetLayer(base);
}

void ScopedLayerAnimationSettings::AddInverselyAnimatedLayer(
    Layer* inverse_layer) {
  inverse_observer_->AddInverselyAnimatedLayer(inverse_layer);
}

}  // namespace ui

/* [<][>][^][v][top][bottom][index][help] */