summaryrefslogtreecommitdiffstats
path: root/ui/gfx/compositor/layer_animation_manager.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ui/gfx/compositor/layer_animation_manager.cc')
-rw-r--r--ui/gfx/compositor/layer_animation_manager.cc187
1 files changed, 187 insertions, 0 deletions
diff --git a/ui/gfx/compositor/layer_animation_manager.cc b/ui/gfx/compositor/layer_animation_manager.cc
new file mode 100644
index 0000000..0301ba4
--- /dev/null
+++ b/ui/gfx/compositor/layer_animation_manager.cc
@@ -0,0 +1,187 @@
+// Copyright (c) 2011 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/gfx/compositor/layer_animation_manager.h"
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "ui/base/animation/animation_container.h"
+#include "ui/base/animation/animation.h"
+#include "ui/base/animation/tween.h"
+#include "ui/gfx/compositor/compositor.h"
+#include "ui/gfx/compositor/layer.h"
+#include "ui/gfx/compositor/layer_animator_delegate.h"
+#include "ui/gfx/transform.h"
+#include "ui/gfx/rect.h"
+
+namespace {
+
+void SetMatrixElement(SkMatrix44& matrix, int index, SkMScalar value) {
+ int row = index / 4;
+ int col = index % 4;
+ matrix.set(row, col, value);
+}
+
+SkMScalar GetMatrixElement(const SkMatrix44& matrix, int index) {
+ int row = index / 4;
+ int col = index % 4;
+ return matrix.get(row, col);
+}
+
+} // anonymous namespace
+
+namespace ui {
+
+LayerAnimationManager::LayerAnimationManager(Layer* layer)
+ : layer_(layer),
+ got_initial_tick_(false) {
+}
+
+LayerAnimationManager::~LayerAnimationManager() {
+}
+
+void LayerAnimationManager::SetAnimation(Animation* animation) {
+ animation_.reset(animation);
+ if (animation_.get()) {
+ static ui::AnimationContainer* container = NULL;
+ if (!container) {
+ container = new AnimationContainer;
+ container->AddRef();
+ }
+ animation_->set_delegate(this);
+ animation_->SetContainer(container);
+ got_initial_tick_ = false;
+ }
+}
+
+void LayerAnimationManager::AnimateToPoint(const gfx::Point& target) {
+ StopAnimating(LOCATION);
+ const gfx::Rect& layer_bounds = layer_->bounds();
+ if (target == layer_bounds.origin())
+ return; // Already there.
+
+ Params& element = elements_[LOCATION];
+ element.location.target_x = target.x();
+ element.location.target_y = target.y();
+ element.location.start_x = layer_bounds.origin().x();
+ element.location.start_y = layer_bounds.origin().y();
+}
+
+void LayerAnimationManager::AnimateTransform(const Transform& transform) {
+ StopAnimating(TRANSFORM);
+ const Transform& layer_transform = layer_->transform();
+ if (transform == layer_transform)
+ return; // Already there.
+
+ Params& element = elements_[TRANSFORM];
+ for (int i = 0; i < 16; ++i) {
+ element.transform.start[i] =
+ GetMatrixElement(layer_transform.matrix(), i);
+ element.transform.target[i] =
+ GetMatrixElement(transform.matrix(), i);
+ }
+}
+
+void LayerAnimationManager::AnimateOpacity(float target_opacity) {
+ StopAnimating(OPACITY);
+ if (layer_->opacity() == target_opacity)
+ return;
+
+ Params& element = elements_[OPACITY];
+ element.opacity.start = layer_->opacity();
+ element.opacity.target = target_opacity;
+}
+
+gfx::Point LayerAnimationManager::GetTargetPoint() {
+ return IsAnimating(LOCATION) ?
+ gfx::Point(elements_[LOCATION].location.target_x,
+ elements_[LOCATION].location.target_y) :
+ layer_->bounds().origin();
+}
+
+float LayerAnimationManager::GetTargetOpacity() {
+ return IsAnimating(OPACITY) ?
+ elements_[OPACITY].opacity.target : layer_->opacity();
+}
+
+ui::Transform LayerAnimationManager::GetTargetTransform() {
+ if (IsAnimating(TRANSFORM)) {
+ Transform transform;
+ for (int i = 0; i < 16; ++i) {
+ SetMatrixElement(transform.matrix(), i,
+ elements_[TRANSFORM].transform.target[i]);
+ }
+ return transform;
+ }
+ return layer_->transform();
+}
+
+bool LayerAnimationManager::IsAnimating(AnimationProperty property) const {
+ return elements_.count(property) > 0;
+}
+
+bool LayerAnimationManager::IsRunning() const {
+ return animation_.get() && animation_->is_animating();
+}
+
+void LayerAnimationManager::AnimationProgressed(
+ const ui::Animation* animation) {
+ got_initial_tick_ = true;
+ for (Elements::const_iterator i = elements_.begin(); i != elements_.end();
+ ++i) {
+ switch (i->first) {
+ case LOCATION: {
+ const gfx::Rect& current_bounds(layer_->bounds());
+ gfx::Rect new_bounds = animation_->CurrentValueBetween(
+ gfx::Rect(gfx::Point(i->second.location.start_x,
+ i->second.location.start_y),
+ current_bounds.size()),
+ gfx::Rect(gfx::Point(i->second.location.target_x,
+ i->second.location.target_y),
+ current_bounds.size()));
+ delegate()->SetBoundsFromAnimator(new_bounds);
+ break;
+ }
+
+ case TRANSFORM: {
+ Transform transform;
+ for (int j = 0; j < 16; ++j) {
+ SkMScalar value = animation_->CurrentValueBetween(
+ i->second.transform.start[j],
+ i->second.transform.target[j]);
+ SetMatrixElement(transform.matrix(), j, value);
+ }
+ delegate()->SetTransformFromAnimator(transform);
+ break;
+ }
+
+ case OPACITY: {
+ delegate()->SetOpacityFromAnimator(animation_->CurrentValueBetween(
+ i->second.opacity.start, i->second.opacity.target));
+ break;
+ }
+
+ default:
+ NOTREACHED();
+ }
+ }
+ layer_->ScheduleDraw();
+}
+
+void LayerAnimationManager::AnimationEnded(const ui::Animation* animation) {
+ AnimationProgressed(animation);
+}
+
+void LayerAnimationManager::StopAnimating(AnimationProperty property) {
+ if (!IsAnimating(property))
+ return;
+
+ elements_.erase(property);
+}
+
+LayerAnimatorDelegate* LayerAnimationManager::delegate() {
+ return static_cast<LayerAnimatorDelegate*>(layer_);
+}
+
+} // namespace ui