summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-11 23:06:45 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-11 23:06:45 +0000
commite81480f1fd21a75545b1c5dda31a1e7c8abf847f (patch)
tree8d641760c07be0b750e8ab019e7849b097769774
parentf3b63bc8ea7b4ef0aa474fde036a526c7ef68d59 (diff)
downloadchromium_src-e81480f1fd21a75545b1c5dda31a1e7c8abf847f.zip
chromium_src-e81480f1fd21a75545b1c5dda31a1e7c8abf847f.tar.gz
chromium_src-e81480f1fd21a75545b1c5dda31a1e7c8abf847f.tar.bz2
Adds ability to animate the color of a layer.
BUG=155179 TEST=none R=vollick@chromium.org Review URL: https://codereview.chromium.org/11103037 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@161432 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ui/compositor/layer.cc25
-rw-r--r--ui/compositor/layer.h3
-rw-r--r--ui/compositor/layer_animation_delegate.h3
-rw-r--r--ui/compositor/layer_animation_element.cc90
-rw-r--r--ui/compositor/layer_animation_element.h11
-rw-r--r--ui/compositor/layer_animator.cc14
-rw-r--r--ui/compositor/layer_animator.h4
-rw-r--r--ui/compositor/layer_animator_unittest.cc48
-rw-r--r--ui/compositor/test/test_layer_animation_delegate.cc14
-rw-r--r--ui/compositor/test/test_layer_animation_delegate.h3
10 files changed, 198 insertions, 17 deletions
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc
index e71cbd5..950c309 100644
--- a/ui/compositor/layer.cc
+++ b/ui/compositor/layer.cc
@@ -425,10 +425,7 @@ void Layer::SetExternalTexture(Texture* texture) {
}
void Layer::SetColor(SkColor color) {
- DCHECK_EQ(type_, LAYER_SOLID_COLOR);
- // WebColor is equivalent to SkColor, per WebColor.h.
- solid_color_layer_->setBackgroundColor(static_cast<WebKit::WebColor>(color));
- SetFillsBoundsOpaquely(SkColorGetA(color) == 0xFF);
+ GetAnimator()->SetColor(color);
}
bool Layer::SchedulePaint(const gfx::Rect& invalid_rect) {
@@ -655,6 +652,13 @@ void Layer::SetGrayscaleImmediately(float grayscale) {
SetLayerFilters();
}
+void Layer::SetColorImmediately(SkColor color) {
+ DCHECK_EQ(type_, LAYER_SOLID_COLOR);
+ // WebColor is equivalent to SkColor, per WebColor.h.
+ solid_color_layer_->setBackgroundColor(static_cast<WebKit::WebColor>(color));
+ SetFillsBoundsOpaquely(SkColorGetA(color) == 0xFF);
+}
+
void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) {
SetBoundsImmediately(bounds);
}
@@ -674,10 +678,15 @@ void Layer::SetVisibilityFromAnimation(bool visibility) {
void Layer::SetBrightnessFromAnimation(float brightness) {
SetBrightnessImmediately(brightness);
}
+
void Layer::SetGrayscaleFromAnimation(float grayscale) {
SetGrayscaleImmediately(grayscale);
}
+void Layer::SetColorFromAnimation(SkColor color) {
+ SetColorImmediately(color);
+}
+
void Layer::ScheduleDrawForAnimation() {
ScheduleDraw();
}
@@ -706,6 +715,14 @@ float Layer::GetGrayscaleForAnimation() const {
return layer_grayscale();
}
+SkColor Layer::GetColorForAnimation() const {
+ // WebColor is equivalent to SkColor, per WebColor.h.
+ // The NULL check is here since this is invoked regardless of whether we have
+ // been configured as LAYER_SOLID_COLOR.
+ return solid_color_layer_.get() ?
+ solid_color_layer_->layer()->backgroundColor() : SK_ColorBLACK;
+}
+
void Layer::CreateWebLayer() {
WebKit::WebCompositorSupport* compositor_support =
WebKit::Platform::current()->compositorSupport();
diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h
index f9fcbc9..984bc39 100644
--- a/ui/compositor/layer.h
+++ b/ui/compositor/layer.h
@@ -302,6 +302,7 @@ class COMPOSITOR_EXPORT Layer
void SetVisibilityImmediately(bool visibility);
void SetBrightnessImmediately(float brightness);
void SetGrayscaleImmediately(float grayscale);
+ void SetColorImmediately(SkColor color);
// Implementation of LayerAnimatorDelegate
virtual void SetBoundsFromAnimation(const gfx::Rect& bounds) OVERRIDE;
@@ -310,6 +311,7 @@ class COMPOSITOR_EXPORT Layer
virtual void SetVisibilityFromAnimation(bool visibility) OVERRIDE;
virtual void SetBrightnessFromAnimation(float brightness) OVERRIDE;
virtual void SetGrayscaleFromAnimation(float grayscale) OVERRIDE;
+ virtual void SetColorFromAnimation(SkColor color) OVERRIDE;
virtual void ScheduleDrawForAnimation() OVERRIDE;
virtual const gfx::Rect& GetBoundsForAnimation() const OVERRIDE;
virtual const Transform& GetTransformForAnimation() const OVERRIDE;
@@ -317,6 +319,7 @@ class COMPOSITOR_EXPORT Layer
virtual bool GetVisibilityForAnimation() const OVERRIDE;
virtual float GetBrightnessForAnimation() const OVERRIDE;
virtual float GetGrayscaleForAnimation() const OVERRIDE;
+ virtual SkColor GetColorForAnimation() const OVERRIDE;
void CreateWebLayer();
void RecomputeTransform();
diff --git a/ui/compositor/layer_animation_delegate.h b/ui/compositor/layer_animation_delegate.h
index 08485a0..0b61fa7 100644
--- a/ui/compositor/layer_animation_delegate.h
+++ b/ui/compositor/layer_animation_delegate.h
@@ -5,6 +5,7 @@
#ifndef UI_COMPOSITOR_LAYER_ANIMATION_DELEGATE_H_
#define UI_COMPOSITOR_LAYER_ANIMATION_DELEGATE_H_
+#include "third_party/skia/include/core/SkColor.h"
#include "ui/compositor/compositor_export.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/transform.h"
@@ -20,6 +21,7 @@ class COMPOSITOR_EXPORT LayerAnimationDelegate {
virtual void SetVisibilityFromAnimation(bool visibility) = 0;
virtual void SetBrightnessFromAnimation(float brightness) = 0;
virtual void SetGrayscaleFromAnimation(float grayscale) = 0;
+ virtual void SetColorFromAnimation(SkColor color) = 0;
virtual void ScheduleDrawForAnimation() = 0;
virtual const gfx::Rect& GetBoundsForAnimation() const = 0;
virtual const Transform& GetTransformForAnimation() const = 0;
@@ -27,6 +29,7 @@ class COMPOSITOR_EXPORT LayerAnimationDelegate {
virtual bool GetVisibilityForAnimation() const = 0;
virtual float GetBrightnessForAnimation() const = 0;
virtual float GetGrayscaleForAnimation() const = 0;
+ virtual SkColor GetColorForAnimation() const = 0;
protected:
virtual ~LayerAnimationDelegate() {}
diff --git a/ui/compositor/layer_animation_element.cc b/ui/compositor/layer_animation_element.cc
index 98326d2..c48a81c 100644
--- a/ui/compositor/layer_animation_element.cc
+++ b/ui/compositor/layer_animation_element.cc
@@ -314,6 +314,59 @@ class GrayscaleTransition : public LayerAnimationElement {
DISALLOW_COPY_AND_ASSIGN(GrayscaleTransition);
};
+// ColorTransition -------------------------------------------------------------
+
+class ColorTransition : public LayerAnimationElement {
+ public:
+ ColorTransition(SkColor target, base::TimeDelta duration)
+ : LayerAnimationElement(GetProperties(), duration),
+ start_(SK_ColorBLACK),
+ target_(target) {
+ }
+ virtual ~ColorTransition() {}
+
+ protected:
+ virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
+ start_ = delegate->GetColorForAnimation();
+ }
+
+ virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
+ delegate->SetColorFromAnimation(
+ SkColorSetARGB(
+ Tween::ValueBetween(t,
+ static_cast<int>(SkColorGetA(start_)),
+ static_cast<int>(SkColorGetA(target_))),
+ Tween::ValueBetween(t,
+ static_cast<int>(SkColorGetR(start_)),
+ static_cast<int>(SkColorGetR(target_))),
+ Tween::ValueBetween(t,
+ static_cast<int>(SkColorGetG(start_)),
+ static_cast<int>(SkColorGetG(target_))),
+ Tween::ValueBetween(t,
+ static_cast<int>(SkColorGetB(start_)),
+ static_cast<int>(SkColorGetB(target_)))));
+ return true;
+ }
+
+ virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
+ target->color = target_;
+ }
+
+ virtual void OnAbort() OVERRIDE {}
+
+ private:
+ static AnimatableProperties GetProperties() {
+ AnimatableProperties properties;
+ properties.insert(LayerAnimationElement::COLOR);
+ return properties;
+ }
+
+ SkColor start_;
+ const SkColor target_;
+
+ DISALLOW_COPY_AND_ASSIGN(ColorTransition);
+};
+
} // namespace
// LayerAnimationElement::TargetValue ------------------------------------------
@@ -322,7 +375,8 @@ LayerAnimationElement::TargetValue::TargetValue()
: opacity(0.0f),
visibility(false),
brightness(0.0f),
- grayscale(0.0f) {
+ grayscale(0.0f),
+ color(SK_ColorBLACK) {
}
LayerAnimationElement::TargetValue::TargetValue(
@@ -332,7 +386,8 @@ LayerAnimationElement::TargetValue::TargetValue(
opacity(delegate ? delegate->GetOpacityForAnimation() : 0.0f),
visibility(delegate ? delegate->GetVisibilityForAnimation() : false),
brightness(delegate ? delegate->GetBrightnessForAnimation() : 0.0f),
- grayscale(delegate ? delegate->GetGrayscaleForAnimation() : 0.0f) {
+ grayscale(delegate ? delegate->GetGrayscaleForAnimation() : 0.0f),
+ color(delegate ? delegate->GetColorForAnimation() : 0.0f) {
}
// LayerAnimationElement -------------------------------------------------------
@@ -381,51 +436,66 @@ base::TimeDelta LayerAnimationElement::GetEffectiveDuration(
// static
LayerAnimationElement* LayerAnimationElement::CreateTransformElement(
- const Transform& transform, base::TimeDelta duration) {
+ const Transform& transform,
+ base::TimeDelta duration) {
return new TransformTransition(transform, duration);
}
// static
LayerAnimationElement*
LayerAnimationElement::CreateInterpolatedTransformElement(
- InterpolatedTransform* interpolated_transform, base::TimeDelta duration) {
+ InterpolatedTransform* interpolated_transform,
+ base::TimeDelta duration) {
return new InterpolatedTransformTransition(interpolated_transform, duration);
}
// static
LayerAnimationElement* LayerAnimationElement::CreateBoundsElement(
- const gfx::Rect& bounds, base::TimeDelta duration) {
+ const gfx::Rect& bounds,
+ base::TimeDelta duration) {
return new BoundsTransition(bounds, duration);
}
// static
LayerAnimationElement* LayerAnimationElement::CreateOpacityElement(
- float opacity, base::TimeDelta duration) {
+ float opacity,
+ base::TimeDelta duration) {
return new OpacityTransition(opacity, duration);
}
// static
LayerAnimationElement* LayerAnimationElement::CreateVisibilityElement(
- bool visibility, base::TimeDelta duration) {
+ bool visibility,
+ base::TimeDelta duration) {
return new VisibilityTransition(visibility, duration);
}
// static
LayerAnimationElement* LayerAnimationElement::CreateBrightnessElement(
- float brightness, base::TimeDelta duration) {
+ float brightness,
+ base::TimeDelta duration) {
return new BrightnessTransition(brightness, duration);
}
// static
LayerAnimationElement* LayerAnimationElement::CreateGrayscaleElement(
- float grayscale, base::TimeDelta duration) {
+ float grayscale,
+ base::TimeDelta duration) {
return new GrayscaleTransition(grayscale, duration);
}
// static
LayerAnimationElement* LayerAnimationElement::CreatePauseElement(
- const AnimatableProperties& properties, base::TimeDelta duration) {
+ const AnimatableProperties& properties,
+ base::TimeDelta duration) {
return new Pause(properties, duration);
}
+// static
+LayerAnimationElement* LayerAnimationElement::CreateColorElement(
+ SkColor color,
+ base::TimeDelta duration) {
+ return new ColorTransition(color, duration);
+}
+
} // namespace ui
diff --git a/ui/compositor/layer_animation_element.h b/ui/compositor/layer_animation_element.h
index 89bf26f..870f005 100644
--- a/ui/compositor/layer_animation_element.h
+++ b/ui/compositor/layer_animation_element.h
@@ -8,6 +8,7 @@
#include <set>
#include "base/time.h"
+#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/animation/tween.h"
#include "ui/compositor/compositor_export.h"
#include "ui/gfx/rect.h"
@@ -30,7 +31,8 @@ class COMPOSITOR_EXPORT LayerAnimationElement {
OPACITY,
VISIBILITY,
BRIGHTNESS,
- GRAYSCALE
+ GRAYSCALE,
+ COLOR,
};
struct COMPOSITOR_EXPORT TargetValue {
@@ -44,6 +46,7 @@ class COMPOSITOR_EXPORT LayerAnimationElement {
bool visibility;
float brightness;
float grayscale;
+ SkColor color;
};
typedef std::set<AnimatableProperty> AnimatableProperties;
@@ -105,6 +108,12 @@ class COMPOSITOR_EXPORT LayerAnimationElement {
const AnimatableProperties& properties,
base::TimeDelta duration);
+ // Creates an element that transitions to the given color. The caller owns the
+ // return value.
+ static LayerAnimationElement* CreateColorElement(
+ SkColor color,
+ base::TimeDelta duration);
+
// Updates the delegate to the appropriate value for |t|, which is in the
// range [0, 1] (0 for initial, and 1 for final). If the animation is not
// aborted, it is guaranteed that Progress will eventually be called with
diff --git a/ui/compositor/layer_animator.cc b/ui/compositor/layer_animator.cc
index 2cf25dc..0524586 100644
--- a/ui/compositor/layer_animator.cc
+++ b/ui/compositor/layer_animator.cc
@@ -158,6 +158,20 @@ float LayerAnimator::GetTargetGrayscale() const {
return target.grayscale;
}
+void LayerAnimator::SetColor(SkColor color) {
+ base::TimeDelta duration = GetTransitionDuration();
+ scoped_ptr<LayerAnimationElement> element(
+ LayerAnimationElement::CreateColorElement(color, duration));
+ element->set_tween_type(tween_type_);
+ StartAnimation(new LayerAnimationSequence(element.release()));
+}
+
+SkColor LayerAnimator::GetTargetColor() const {
+ LayerAnimationElement::TargetValue target(delegate());
+ GetTargetValue(&target);
+ return target.color;
+}
+
void LayerAnimator::SetDelegate(LayerAnimationDelegate* delegate) {
delegate_ = delegate;
}
diff --git a/ui/compositor/layer_animator.h b/ui/compositor/layer_animator.h
index 0c92a81..783d6cb 100644
--- a/ui/compositor/layer_animator.h
+++ b/ui/compositor/layer_animator.h
@@ -83,6 +83,10 @@ class COMPOSITOR_EXPORT LayerAnimator
virtual void SetGrayscale(float grayscale);
float GetTargetGrayscale() const;
+ // Sets the color on the delegate. May cause an implicit animation.
+ virtual void SetColor(SkColor color);
+ SkColor GetTargetColor() const;
+
// Sets the layer animation delegate the animator is associated with. The
// animator does not own the delegate. The layer animator expects a non-NULL
// delegate for most of its operations, so do not call any methods without
diff --git a/ui/compositor/layer_animator_unittest.cc b/ui/compositor/layer_animator_unittest.cc
index d60fc319..d1219a15 100644
--- a/ui/compositor/layer_animator_unittest.cc
+++ b/ui/compositor/layer_animator_unittest.cc
@@ -7,6 +7,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
+#include "base/stringprintf.h"
#include "base/time.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/compositor/layer_animation_delegate.h"
@@ -23,6 +24,14 @@ namespace ui {
namespace {
+// Converts |color| to a string. Each component of the color is separated by a
+// space and the order if A R G B.
+std::string ColorToString(SkColor color) {
+ return base::StringPrintf("%d %d %d %d", SkColorGetA(color),
+ SkColorGetR(color), SkColorGetG(color),
+ SkColorGetB(color));
+}
+
class TestImplicitAnimationObserver : public ImplicitAnimationObserver {
public:
explicit TestImplicitAnimationObserver(bool notify_when_animator_destructed)
@@ -1164,6 +1173,45 @@ TEST(LayerAnimatorTest, GetTargetGrayscale) {
}
}
+// Verifies color property is modified appropriately.
+TEST(LayerAnimatorTest, Color) {
+ scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
+ AnimationContainerElement* element = animator.get();
+ animator->set_disable_timer_for_test(true);
+ TestLayerAnimationDelegate delegate;
+ animator->SetDelegate(&delegate);
+
+ SkColor start_color = SkColorSetARGB( 0, 20, 40, 60);
+ SkColor middle_color = SkColorSetARGB(127, 30, 60, 100);
+ SkColor target_color = SkColorSetARGB(254, 40, 80, 140);
+
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
+
+ delegate.SetColorFromAnimation(start_color);
+
+ animator->ScheduleAnimation(
+ new LayerAnimationSequence(
+ LayerAnimationElement::CreateColorElement(target_color, delta)));
+
+ EXPECT_TRUE(animator->is_animating());
+ EXPECT_EQ(ColorToString(start_color),
+ ColorToString(delegate.GetColorForAnimation()));
+
+ base::TimeTicks start_time = animator->last_step_time();
+
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(500));
+
+ EXPECT_TRUE(animator->is_animating());
+ EXPECT_EQ(ColorToString(middle_color),
+ ColorToString(delegate.GetColorForAnimation()));
+
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
+
+ EXPECT_FALSE(animator->is_animating());
+ EXPECT_EQ(ColorToString(target_color),
+ ColorToString(delegate.GetColorForAnimation()));
+}
+
// Verifies SchedulePauseForProperties().
TEST(LayerAnimatorTest, SchedulePauseForProperties) {
scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
diff --git a/ui/compositor/test/test_layer_animation_delegate.cc b/ui/compositor/test/test_layer_animation_delegate.cc
index bb5cdc5..f5e9262 100644
--- a/ui/compositor/test/test_layer_animation_delegate.cc
+++ b/ui/compositor/test/test_layer_animation_delegate.cc
@@ -10,7 +10,8 @@ TestLayerAnimationDelegate::TestLayerAnimationDelegate()
: opacity_(1.0f),
visibility_(true),
brightness_(0.0f),
- grayscale_(0.0f) {
+ grayscale_(0.0f),
+ color_(SK_ColorBLACK) {
}
TestLayerAnimationDelegate::TestLayerAnimationDelegate(
@@ -18,7 +19,8 @@ TestLayerAnimationDelegate::TestLayerAnimationDelegate(
: bounds_(other.GetBoundsForAnimation()),
transform_(other.GetTransformForAnimation()),
opacity_(other.GetOpacityForAnimation()),
- visibility_(other.GetVisibilityForAnimation()) {
+ visibility_(other.GetVisibilityForAnimation()),
+ color_(SK_ColorBLACK) {
}
TestLayerAnimationDelegate::~TestLayerAnimationDelegate() {
@@ -50,6 +52,10 @@ void TestLayerAnimationDelegate::SetGrayscaleFromAnimation(float grayscale) {
grayscale_ = grayscale;
}
+void TestLayerAnimationDelegate::SetColorFromAnimation(SkColor color) {
+ color_ = color;
+}
+
void TestLayerAnimationDelegate::ScheduleDrawForAnimation() {
}
@@ -77,4 +83,8 @@ float TestLayerAnimationDelegate::GetGrayscaleForAnimation() const {
return grayscale_;
}
+SkColor TestLayerAnimationDelegate::GetColorForAnimation() const {
+ return color_;
+}
+
} // namespace ui
diff --git a/ui/compositor/test/test_layer_animation_delegate.h b/ui/compositor/test/test_layer_animation_delegate.h
index a17fbf3..e492d4a 100644
--- a/ui/compositor/test/test_layer_animation_delegate.h
+++ b/ui/compositor/test/test_layer_animation_delegate.h
@@ -25,6 +25,7 @@ class TestLayerAnimationDelegate : public LayerAnimationDelegate {
virtual void SetVisibilityFromAnimation(bool visibility) OVERRIDE;
virtual void SetBrightnessFromAnimation(float brightness) OVERRIDE;
virtual void SetGrayscaleFromAnimation(float grayscale) OVERRIDE;
+ virtual void SetColorFromAnimation(SkColor color) OVERRIDE;
virtual void ScheduleDrawForAnimation() OVERRIDE;
virtual const gfx::Rect& GetBoundsForAnimation() const OVERRIDE;
virtual const Transform& GetTransformForAnimation() const OVERRIDE;
@@ -32,6 +33,7 @@ class TestLayerAnimationDelegate : public LayerAnimationDelegate {
virtual bool GetVisibilityForAnimation() const OVERRIDE;
virtual float GetBrightnessForAnimation() const OVERRIDE;
virtual float GetGrayscaleForAnimation() const OVERRIDE;
+ virtual SkColor GetColorForAnimation() const OVERRIDE;
private:
gfx::Rect bounds_;
@@ -40,6 +42,7 @@ class TestLayerAnimationDelegate : public LayerAnimationDelegate {
bool visibility_;
float brightness_;
float grayscale_;
+ SkColor color_;
// Allow copy and assign.
};