summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorvollick@chromium.org <vollick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-02 16:42:45 +0000
committervollick@chromium.org <vollick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-02 16:42:45 +0000
commite876c27118d298051d2245d67f05aacee88adc48 (patch)
tree957216c69b83f2f27116eca07d6c64a387ee792a /ui
parent893e281de8adc1821f0ea842a3476e0ccbb6c5ca (diff)
downloadchromium_src-e876c27118d298051d2245d67f05aacee88adc48.zip
chromium_src-e876c27118d298051d2245d67f05aacee88adc48.tar.gz
chromium_src-e876c27118d298051d2245d67f05aacee88adc48.tar.bz2
Allows observers to be notified when layer animations complete.
Depends on http://codereview.chromium.org/8362006/ BUG=101595 TEST=None Review URL: http://codereview.chromium.org/8395046 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@108307 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/aura/desktop.cc14
-rw-r--r--ui/aura/desktop.h10
-rw-r--r--ui/aura/window.cc4
-rw-r--r--ui/aura/window.h2
-rw-r--r--ui/gfx/compositor/compositor.gyp9
-rw-r--r--ui/gfx/compositor/dummy_layer_animation_delegate.cc55
-rw-r--r--ui/gfx/compositor/layer.cc5
-rw-r--r--ui/gfx/compositor/layer.h5
-rw-r--r--ui/gfx/compositor/layer_animation_element_unittest.cc12
-rw-r--r--ui/gfx/compositor/layer_animation_observer.h36
-rw-r--r--ui/gfx/compositor/layer_animation_sequence.cc34
-rw-r--r--ui/gfx/compositor/layer_animation_sequence.h22
-rw-r--r--ui/gfx/compositor/layer_animation_sequence_unittest.cc49
-rw-r--r--ui/gfx/compositor/layer_animator.cc79
-rw-r--r--ui/gfx/compositor/layer_animator.h44
-rw-r--r--ui/gfx/compositor/layer_animator_delegate.h33
-rw-r--r--ui/gfx/compositor/layer_animator_unittest.cc111
-rw-r--r--ui/gfx/compositor/layer_delegate.h5
-rw-r--r--ui/gfx/compositor/layer_unittest.cc13
-rw-r--r--ui/gfx/compositor/test_layer_animation_delegate.cc51
-rw-r--r--ui/gfx/compositor/test_layer_animation_delegate.h (renamed from ui/gfx/compositor/dummy_layer_animation_delegate.h)21
-rw-r--r--ui/gfx/compositor/test_layer_animation_observer.cc35
-rw-r--r--ui/gfx/compositor/test_layer_animation_observer.h57
23 files changed, 489 insertions, 217 deletions
diff --git a/ui/aura/desktop.cc b/ui/aura/desktop.cc
index a6c909a..7595b1d 100644
--- a/ui/aura/desktop.cc
+++ b/ui/aura/desktop.cc
@@ -305,8 +305,10 @@ bool Desktop::DispatchKeyEvent(KeyEvent* event) {
if (degrees != 0) {
layer()->GetAnimator()->set_preemption_strategy(
ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
- layer()->GetAnimator()->ScheduleAnimationElement(
- new ScreenRotation(degrees));
+ scoped_ptr<ui::LayerAnimationSequence> screen_rotation(
+ new ui::LayerAnimationSequence(new ScreenRotation(degrees)));
+ screen_rotation->AddObserver(this);
+ layer()->GetAnimator()->ScheduleAnimation(screen_rotation.release());
return true;
}
}
@@ -566,6 +568,14 @@ void Desktop::OnLayerAnimationEnded(
OnHostResized(host_->GetSize());
}
+void Desktop::OnLayerAnimationScheduled(
+ const ui::LayerAnimationSequence* animation) {
+}
+
+void Desktop::OnLayerAnimationAborted(
+ const ui::LayerAnimationSequence* animation) {
+}
+
void Desktop::SetFocusedWindow(Window* focused_window) {
if (focused_window == focused_window_ ||
(focused_window && !focused_window->CanFocus())) {
diff --git a/ui/aura/desktop.h b/ui/aura/desktop.h
index 9ee5c1d..7a58b48 100644
--- a/ui/aura/desktop.h
+++ b/ui/aura/desktop.h
@@ -17,6 +17,7 @@
#include "ui/aura/window.h"
#include "ui/base/events.h"
#include "ui/gfx/compositor/compositor.h"
+#include "ui/gfx/compositor/layer_animation_observer.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/point.h"
@@ -42,7 +43,8 @@ class TouchEvent;
// Desktop is responsible for hosting a set of windows.
class AURA_EXPORT Desktop : public ui::CompositorDelegate,
public Window,
- public internal::FocusManager {
+ public internal::FocusManager,
+ public ui::LayerAnimationObserver {
public:
Desktop();
virtual ~Desktop();
@@ -146,9 +148,13 @@ class AURA_EXPORT Desktop : public ui::CompositorDelegate,
virtual internal::FocusManager* GetFocusManager() OVERRIDE;
virtual Desktop* GetDesktop() OVERRIDE;
- // Overridden from ui::LayerDelegate:
+ // Overridden from ui::LayerAnimationObserver:
virtual void OnLayerAnimationEnded(
const ui::LayerAnimationSequence* animation) OVERRIDE;
+ virtual void OnLayerAnimationScheduled(
+ const ui::LayerAnimationSequence* animation) OVERRIDE;
+ virtual void OnLayerAnimationAborted(
+ const ui::LayerAnimationSequence* animation) OVERRIDE;
// Overridden from FocusManager:
virtual void SetFocusedWindow(Window* window) OVERRIDE;
diff --git a/ui/aura/window.cc b/ui/aura/window.cc
index 7d94342..f7291f2 100644
--- a/ui/aura/window.cc
+++ b/ui/aura/window.cc
@@ -487,8 +487,4 @@ void Window::OnPaintLayer(gfx::Canvas* canvas) {
delegate_->OnPaint(canvas);
}
-void Window::OnLayerAnimationEnded(
- const ui::LayerAnimationSequence* animation) {
-}
-
} // namespace aura
diff --git a/ui/aura/window.h b/ui/aura/window.h
index ed261b4..b376914 100644
--- a/ui/aura/window.h
+++ b/ui/aura/window.h
@@ -297,8 +297,6 @@ class AURA_EXPORT Window : public ui::LayerDelegate {
// Overridden from ui::LayerDelegate:
virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE;
- virtual void OnLayerAnimationEnded(
- const ui::LayerAnimationSequence* animation) OVERRIDE;
WindowType type_;
diff --git a/ui/gfx/compositor/compositor.gyp b/ui/gfx/compositor/compositor.gyp
index d5fa818..5a940ae 100644
--- a/ui/gfx/compositor/compositor.gyp
+++ b/ui/gfx/compositor/compositor.gyp
@@ -45,13 +45,12 @@
'compositor_observer.h',
'compositor_stub.cc',
'compositor_win.cc',
- 'dummy_layer_animation_delegate.cc',
- 'dummy_layer_animation_delegate.h',
'layer.cc',
'layer.h',
'layer_animation_delegate.h',
'layer_animation_element.cc',
'layer_animation_element.h',
+ 'layer_animation_observer.h',
'layer_animation_sequence.cc',
'layer_animation_sequence.h',
'layer_animator.cc',
@@ -149,6 +148,10 @@
'test_compositor_host.h',
'test_compositor_host_linux.cc',
'test_compositor_host_win.cc',
+ 'test_layer_animation_delegate.cc',
+ 'test_layer_animation_delegate.h',
+ 'test_layer_animation_observer.cc',
+ 'test_layer_animation_observer.h',
'test_suite.cc',
'test_suite.h',
'test_utils.cc',
@@ -191,7 +194,7 @@
'test_compositor.h',
'test_texture.cc',
'test_texture.h',
- ],
+ ],
}],
],
},
diff --git a/ui/gfx/compositor/dummy_layer_animation_delegate.cc b/ui/gfx/compositor/dummy_layer_animation_delegate.cc
deleted file mode 100644
index ea026dc..0000000
--- a/ui/gfx/compositor/dummy_layer_animation_delegate.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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/dummy_layer_animation_delegate.h"
-
-namespace ui {
-
-DummyLayerAnimationDelegate::DummyLayerAnimationDelegate() : opacity_(1.0f) {
-}
-
-DummyLayerAnimationDelegate::DummyLayerAnimationDelegate(
- const LayerAnimationDelegate& other)
- : bounds_(other.GetBoundsForAnimation()),
- transform_(other.GetTransformForAnimation()),
- opacity_(other.GetOpacityForAnimation()) {
-}
-
-DummyLayerAnimationDelegate::~DummyLayerAnimationDelegate() {
-}
-
-void DummyLayerAnimationDelegate::SetBoundsFromAnimation(
- const gfx::Rect& bounds) {
- bounds_ = bounds;
-}
-
-void DummyLayerAnimationDelegate::SetTransformFromAnimation(
- const Transform& transform) {
- transform_ = transform;
-}
-
-void DummyLayerAnimationDelegate::SetOpacityFromAnimation(float opacity) {
- opacity_ = opacity;
-}
-
-void DummyLayerAnimationDelegate::ScheduleDrawForAnimation() {
-}
-
-const gfx::Rect& DummyLayerAnimationDelegate::GetBoundsForAnimation() const {
- return bounds_;
-}
-
-const Transform& DummyLayerAnimationDelegate::GetTransformForAnimation() const {
- return transform_;
-}
-
-float DummyLayerAnimationDelegate::GetOpacityForAnimation() const {
- return opacity_;
-}
-
-void DummyLayerAnimationDelegate::OnLayerAnimationEnded(
- LayerAnimationSequence* sequence) {
-}
-
-} // namespace ui
diff --git a/ui/gfx/compositor/layer.cc b/ui/gfx/compositor/layer.cc
index 4afee17..f632c65 100644
--- a/ui/gfx/compositor/layer.cc
+++ b/ui/gfx/compositor/layer.cc
@@ -654,11 +654,6 @@ float Layer::GetOpacityForAnimation() const {
return opacity();
}
-void Layer::OnLayerAnimationEnded(LayerAnimationSequence* sequence) {
- if (delegate_)
- delegate_->OnLayerAnimationEnded(sequence);
-}
-
#if defined(USE_WEBKIT_COMPOSITOR)
void Layer::CreateWebLayer() {
web_layer_ = WebKit::WebContentLayer::create(this, this);
diff --git a/ui/gfx/compositor/layer.h b/ui/gfx/compositor/layer.h
index 1bb51e9..2d0a975 100644
--- a/ui/gfx/compositor/layer.h
+++ b/ui/gfx/compositor/layer.h
@@ -18,7 +18,7 @@
#include "ui/gfx/rect.h"
#include "ui/gfx/transform.h"
#include "ui/gfx/compositor/compositor.h"
-#include "ui/gfx/compositor/layer_animator_delegate.h"
+#include "ui/gfx/compositor/layer_animation_delegate.h"
#include "ui/gfx/compositor/layer_delegate.h"
class SkCanvas;
@@ -39,7 +39,7 @@ class Texture;
// delete a Layer and it has children, the parent of each child layer is set to
// NULL, but the children are not deleted.
class COMPOSITOR_EXPORT Layer :
- public LayerAnimatorDelegate,
+ public LayerAnimationDelegate,
NON_EXPORTED_BASE(public WebKit::WebLayerClient),
NON_EXPORTED_BASE(public WebKit::WebContentLayerClient) {
public:
@@ -281,7 +281,6 @@ class COMPOSITOR_EXPORT Layer :
virtual const gfx::Rect& GetBoundsForAnimation() const OVERRIDE;
virtual const Transform& GetTransformForAnimation() const OVERRIDE;
virtual float GetOpacityForAnimation() const OVERRIDE;
- virtual void OnLayerAnimationEnded(LayerAnimationSequence* sequence) OVERRIDE;
#if defined(USE_WEBKIT_COMPOSITOR)
void CreateWebLayer();
diff --git a/ui/gfx/compositor/layer_animation_element_unittest.cc b/ui/gfx/compositor/layer_animation_element_unittest.cc
index 483817c..27940d4 100644
--- a/ui/gfx/compositor/layer_animation_element_unittest.cc
+++ b/ui/gfx/compositor/layer_animation_element_unittest.cc
@@ -11,8 +11,8 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/transform.h"
-#include "ui/gfx/compositor/dummy_layer_animation_delegate.h"
#include "ui/gfx/compositor/layer_animation_delegate.h"
+#include "ui/gfx/compositor/test_layer_animation_delegate.h"
#include "ui/gfx/compositor/test_utils.h"
namespace ui {
@@ -22,7 +22,7 @@ namespace {
// Check that the transformation element progresses the delegate as expected and
// that the element can be reused after it completes.
TEST(LayerAnimationElementTest, TransformElement) {
- DummyLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate delegate;
Transform start_transform, target_transform, middle_transform;
start_transform.SetRotate(-90);
target_transform.SetRotate(90);
@@ -54,7 +54,7 @@ TEST(LayerAnimationElementTest, TransformElement) {
// Check that the bounds element progresses the delegate as expected and
// that the element can be reused after it completes.
TEST(LayerAnimationElementTest, BoundsElement) {
- DummyLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate delegate;
gfx::Rect start, target, middle;
start = target = middle = gfx::Rect(0, 0, 50, 50);
start.set_x(-90);
@@ -84,7 +84,7 @@ TEST(LayerAnimationElementTest, BoundsElement) {
// Check that the opacity element progresses the delegate as expected and
// that the element can be reused after it completes.
TEST(LayerAnimationElementTest, OpacityElement) {
- DummyLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate delegate;
float start = 0.0;
float middle = 0.5;
float target = 1.0;
@@ -121,8 +121,8 @@ TEST(LayerAnimationElementTest, PauseElement) {
scoped_ptr<LayerAnimationElement> element(
LayerAnimationElement::CreatePauseElement(properties, delta));
- DummyLayerAnimationDelegate delegate;
- DummyLayerAnimationDelegate copy = delegate;
+ TestLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate copy = delegate;
element->Progress(1.0, &delegate);
diff --git a/ui/gfx/compositor/layer_animation_observer.h b/ui/gfx/compositor/layer_animation_observer.h
new file mode 100644
index 0000000..1fe031e
--- /dev/null
+++ b/ui/gfx/compositor/layer_animation_observer.h
@@ -0,0 +1,36 @@
+// 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.
+
+#ifndef UI_GFX_COMPOSITOR_LAYER_ANIMATION_OBSERVER_H_
+#define UI_GFX_COMPOSITOR_LAYER_ANIMATION_OBSERVER_H_
+#pragma once
+
+#include "ui/gfx/compositor/compositor_export.h"
+
+namespace ui {
+
+class LayerAnimationSequence;
+
+// LayerAnimationObservers are notified when animations complete.
+class COMPOSITOR_EXPORT LayerAnimationObserver {
+ public:
+ // Called when the |sequence| ends. Not called if |sequence| is aborted.
+ virtual void OnLayerAnimationEnded(
+ const LayerAnimationSequence* sequence) = 0;
+
+ // Called if |sequence| is aborted for any reason.
+ virtual void OnLayerAnimationAborted(
+ const LayerAnimationSequence* sequence) = 0;
+
+ // Called when the animation is scheduled.
+ virtual void OnLayerAnimationScheduled(
+ const LayerAnimationSequence* sequence) = 0;
+
+ protected:
+ virtual ~LayerAnimationObserver() {}
+};
+
+} // namespace ui
+
+#endif // UI_GFX_COMPOSITOR_LAYER_ANIMATION_OBSERVER_H_
diff --git a/ui/gfx/compositor/layer_animation_sequence.cc b/ui/gfx/compositor/layer_animation_sequence.cc
index 8f34969..f2e362b 100644
--- a/ui/gfx/compositor/layer_animation_sequence.cc
+++ b/ui/gfx/compositor/layer_animation_sequence.cc
@@ -10,6 +10,7 @@
#include "base/debug/trace_event.h"
#include "ui/gfx/compositor/layer_animation_delegate.h"
#include "ui/gfx/compositor/layer_animation_element.h"
+#include "ui/gfx/compositor/layer_animation_observer.h"
namespace ui {
@@ -65,6 +66,7 @@ void LayerAnimationSequence::Progress(base::TimeDelta elapsed,
if (!is_cyclic_ && elapsed == duration_) {
last_element_ = 0;
last_start_ = base::TimeDelta::FromMilliseconds(0);
+ NotifyEnded();
}
}
@@ -85,6 +87,7 @@ void LayerAnimationSequence::Abort() {
}
last_element_ = 0;
last_start_ = base::TimeDelta::FromMilliseconds(0);
+ NotifyAborted();
}
void LayerAnimationSequence::AddElement(LayerAnimationElement* element) {
@@ -106,4 +109,35 @@ bool LayerAnimationSequence::HasCommonProperty(
return intersection.size() > 0;
}
+void LayerAnimationSequence::AddObserver(LayerAnimationObserver* observer) {
+ if (!observers_.HasObserver(observer))
+ observers_.AddObserver(observer);
+}
+
+void LayerAnimationSequence::RemoveObserver(LayerAnimationObserver* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+void LayerAnimationSequence::OnScheduled() {
+ NotifyScheduled();
+}
+
+void LayerAnimationSequence::NotifyScheduled() {
+ FOR_EACH_OBSERVER(LayerAnimationObserver,
+ observers_,
+ OnLayerAnimationScheduled(this));
+}
+
+void LayerAnimationSequence::NotifyEnded() {
+ FOR_EACH_OBSERVER(LayerAnimationObserver,
+ observers_,
+ OnLayerAnimationEnded(this));
+}
+
+void LayerAnimationSequence::NotifyAborted() {
+ FOR_EACH_OBSERVER(LayerAnimationObserver,
+ observers_,
+ OnLayerAnimationAborted(this));
+}
+
} // namespace ui
diff --git a/ui/gfx/compositor/layer_animation_sequence.h b/ui/gfx/compositor/layer_animation_sequence.h
index 4670587..6441a41 100644
--- a/ui/gfx/compositor/layer_animation_sequence.h
+++ b/ui/gfx/compositor/layer_animation_sequence.h
@@ -9,6 +9,7 @@
#include <vector>
#include "base/memory/linked_ptr.h"
+#include "base/observer_list.h"
#include "base/time.h"
#include "ui/gfx/compositor/compositor_export.h"
#include "ui/gfx/compositor/layer_animation_element.h"
@@ -16,6 +17,7 @@
namespace ui {
class LayerAnimationDelegate;
+class LayerAnimationObserver;
// Contains a collection of layer animation elements to be played one after
// another. Although it has a similar interface to LayerAnimationElement, it is
@@ -67,9 +69,26 @@ class COMPOSITOR_EXPORT LayerAnimationSequence {
bool HasCommonProperty(
const LayerAnimationElement::AnimatableProperties& other) const;
+ // These functions are used for adding or removing observers from the observer
+ // list. The observers are notified when animations end.
+ void AddObserver(LayerAnimationObserver* observer);
+ void RemoveObserver(LayerAnimationObserver* observer);
+
+ // Called when the animator schedules this sequence.
+ void OnScheduled();
+
private:
typedef std::vector<linked_ptr<LayerAnimationElement> > Elements;
+ // Notifies the observers that this sequence has been scheduled.
+ void NotifyScheduled();
+
+ // Notifies the observers that this sequence has ended.
+ void NotifyEnded();
+
+ // Notifies the observers that this sequence has been aborted.
+ void NotifyAborted();
+
// The sum of the durations of all the elements in the sequence.
base::TimeDelta duration_;
@@ -86,6 +105,9 @@ class COMPOSITOR_EXPORT LayerAnimationSequence {
size_t last_element_;
base::TimeDelta last_start_;
+ // These parties are notified when layer animations end.
+ ObserverList<LayerAnimationObserver> observers_;
+
DISALLOW_COPY_AND_ASSIGN(LayerAnimationSequence);
};
diff --git a/ui/gfx/compositor/layer_animation_sequence_unittest.cc b/ui/gfx/compositor/layer_animation_sequence_unittest.cc
index a80a5f1..ff44b58 100644
--- a/ui/gfx/compositor/layer_animation_sequence_unittest.cc
+++ b/ui/gfx/compositor/layer_animation_sequence_unittest.cc
@@ -11,9 +11,10 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/transform.h"
-#include "ui/gfx/compositor/dummy_layer_animation_delegate.h"
#include "ui/gfx/compositor/layer_animation_delegate.h"
#include "ui/gfx/compositor/layer_animation_element.h"
+#include "ui/gfx/compositor/test_layer_animation_delegate.h"
+#include "ui/gfx/compositor/test_layer_animation_observer.h"
#include "ui/gfx/compositor/test_utils.h"
namespace ui {
@@ -33,10 +34,10 @@ TEST(LayerAnimationSequenceTest, NoElement) {
// a single element.
TEST(LayerAnimationSequenceTest, SingleElement) {
LayerAnimationSequence sequence;
- DummyLayerAnimationDelegate delegate;
- float start = 0.0;
- float middle = 0.5;
- float target = 1.0;
+ TestLayerAnimationDelegate delegate;
+ float start = 0.0f;
+ float middle = 0.5f;
+ float target = 1.0f;
base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
sequence.AddElement(
LayerAnimationElement::CreateOpacityElement(target, delta));
@@ -61,10 +62,10 @@ TEST(LayerAnimationSequenceTest, SingleElement) {
// multiple elements. Note, see the layer animator tests for cyclic sequences.
TEST(LayerAnimationSequenceTest, MultipleElement) {
LayerAnimationSequence sequence;
- DummyLayerAnimationDelegate delegate;
- float start_opacity = 0.0;
- float middle_opacity = 0.5;
- float target_opacity = 1.0;
+ TestLayerAnimationDelegate delegate;
+ float start_opacity = 0.0f;
+ float middle_opacity = 0.5f;
+ float target_opacity = 1.0f;
base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
sequence.AddElement(
LayerAnimationElement::CreateOpacityElement(target_opacity, delta));
@@ -93,7 +94,7 @@ TEST(LayerAnimationSequenceTest, MultipleElement) {
EXPECT_FLOAT_EQ(middle_opacity, delegate.GetOpacityForAnimation());
sequence.Progress(base::TimeDelta::FromMilliseconds(1000), &delegate);
EXPECT_FLOAT_EQ(target_opacity, delegate.GetOpacityForAnimation());
- DummyLayerAnimationDelegate copy = delegate;
+ TestLayerAnimationDelegate copy = delegate;
// In the middle of the pause -- nothing should have changed.
sequence.Progress(base::TimeDelta::FromMilliseconds(1500), &delegate);
@@ -129,9 +130,9 @@ TEST(LayerAnimationSequenceTest, MultipleElement) {
// Check that a sequence can still be aborted if it has cycled many times.
TEST(LayerAnimationSequenceTest, AbortingCyclicSequence) {
LayerAnimationSequence sequence;
- DummyLayerAnimationDelegate delegate;
- float start_opacity = 0.0;
- float target_opacity = 1.0;
+ TestLayerAnimationDelegate delegate;
+ float start_opacity = 0.0f;
+ float target_opacity = 1.0f;
base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
sequence.AddElement(
LayerAnimationElement::CreateOpacityElement(target_opacity, delta));
@@ -157,9 +158,9 @@ TEST(LayerAnimationSequenceTest, AbortingCyclicSequence) {
// Also check that this has no effect if the sequence is cyclic.
TEST(LayerAnimationSequenceTest, SetTarget) {
LayerAnimationSequence sequence;
- DummyLayerAnimationDelegate delegate;
- float start_opacity = 0.0;
- float target_opacity = 1.0;
+ TestLayerAnimationDelegate delegate;
+ float start_opacity = 0.0f;
+ float target_opacity = 1.0f;
base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
sequence.AddElement(
LayerAnimationElement::CreateOpacityElement(target_opacity, delta));
@@ -175,6 +176,22 @@ TEST(LayerAnimationSequenceTest, SetTarget) {
EXPECT_FLOAT_EQ(start_opacity, target_value.opacity);
}
+TEST(LayerAnimationSequenceTest, AddObserver) {
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
+ LayerAnimationSequence sequence;
+ sequence.AddElement(
+ LayerAnimationElement::CreateOpacityElement(1.0f, delta));
+ for (int i = 0; i < 2; ++i) {
+ TestLayerAnimationObserver observer;
+ TestLayerAnimationDelegate delegate;
+ sequence.AddObserver(&observer);
+ EXPECT_TRUE(!observer.last_ended_sequence());
+ sequence.Progress(delta, &delegate);
+ EXPECT_EQ(observer.last_ended_sequence(), &sequence);
+ sequence.RemoveObserver(&observer);
+ }
+}
+
} // namespace
} // namespace ui
diff --git a/ui/gfx/compositor/layer_animator.cc b/ui/gfx/compositor/layer_animator.cc
index 8004c5c..14a4bf98 100644
--- a/ui/gfx/compositor/layer_animator.cc
+++ b/ui/gfx/compositor/layer_animator.cc
@@ -10,7 +10,8 @@
#include "ui/base/animation/animation_container.h"
#include "ui/gfx/compositor/compositor.h"
#include "ui/gfx/compositor/layer.h"
-#include "ui/gfx/compositor/layer_animator_delegate.h"
+#include "ui/gfx/compositor/layer_animation_delegate.h"
+#include "ui/gfx/compositor/layer_animation_observer.h"
#include "ui/gfx/compositor/layer_animation_sequence.h"
namespace ui {
@@ -55,8 +56,9 @@ void LayerAnimator::SetTransform(const Transform& transform) {
if (transition_duration_ == base::TimeDelta())
delegate_->SetTransformFromAnimation(transform);
else
- StartAnimationElement(LayerAnimationElement::CreateTransformElement(
- transform, transition_duration_));
+ StartAnimation(new LayerAnimationSequence(
+ LayerAnimationElement::CreateTransformElement(
+ transform, transition_duration_)));
}
Transform LayerAnimator::GetTargetTransform() const {
@@ -69,8 +71,9 @@ void LayerAnimator::SetBounds(const gfx::Rect& bounds) {
if (transition_duration_ == base::TimeDelta())
delegate_->SetBoundsFromAnimation(bounds);
else
- StartAnimationElement(LayerAnimationElement::CreateBoundsElement(
- bounds, transition_duration_));
+ StartAnimation(new LayerAnimationSequence(
+ LayerAnimationElement::CreateBoundsElement(
+ bounds, transition_duration_)));
}
gfx::Rect LayerAnimator::GetTargetBounds() const {
@@ -83,8 +86,9 @@ void LayerAnimator::SetOpacity(float opacity) {
if (transition_duration_ == base::TimeDelta())
delegate_->SetOpacityFromAnimation(opacity);
else
- StartAnimationElement(LayerAnimationElement::CreateOpacityElement(
- opacity, transition_duration_));
+ StartAnimation(new LayerAnimationSequence(
+ LayerAnimationElement::CreateOpacityElement(
+ opacity, transition_duration_)));
}
float LayerAnimator::GetTargetOpacity() const {
@@ -93,12 +97,13 @@ float LayerAnimator::GetTargetOpacity() const {
return target.opacity;
}
-void LayerAnimator::SetDelegate(LayerAnimatorDelegate* delegate) {
+void LayerAnimator::SetDelegate(LayerAnimationDelegate* delegate) {
DCHECK(delegate);
delegate_ = delegate;
}
void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) {
+ OnScheduled(animation);
if (!StartSequenceImmediately(animation)) {
// Attempt to preempt a running animation.
switch (preemption_strategy_) {
@@ -126,6 +131,7 @@ void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) {
}
void LayerAnimator::ScheduleAnimation(LayerAnimationSequence* animation) {
+ OnScheduled(animation);
if (is_animating()) {
animation_queue_.push_back(make_linked_ptr(animation));
ProcessQueue();
@@ -162,20 +168,16 @@ void LayerAnimator::ScheduleTogether(
UpdateAnimationState();
}
-void LayerAnimator::StartAnimationElement(LayerAnimationElement* animation) {
- StartAnimation(new LayerAnimationSequence(animation));
-}
-
-void LayerAnimator::ScheduleAnimationElement(LayerAnimationElement* animation) {
- ScheduleAnimation(new LayerAnimationSequence(animation));
-}
-
-void LayerAnimator::ScheduleElementsTogether(
- const std::vector<LayerAnimationElement*>& animations) {
- std::vector<LayerAnimationSequence*> sequences;
- for (size_t i = 0; i < animations.size(); ++i)
- sequences.push_back(new LayerAnimationSequence(animations[i]));
- ScheduleTogether(sequences);
+bool LayerAnimator::IsAnimatingProperty(
+ LayerAnimationElement::AnimatableProperty property) const {
+ for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin();
+ queue_iter != animation_queue_.end(); ++queue_iter) {
+ if ((*queue_iter)->properties().find(property) !=
+ (*queue_iter)->properties().end()) {
+ return true;
+ }
+ }
+ return false;
}
void LayerAnimator::StopAnimatingProperty(
@@ -193,6 +195,15 @@ void LayerAnimator::StopAnimating() {
FinishAnimation(running_animations_[0].sequence);
}
+void LayerAnimator::AddObserver(LayerAnimationObserver* observer) {
+ if (!observers_.HasObserver(observer))
+ observers_.AddObserver(observer);
+}
+
+void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) {
+ observers_.RemoveObserver(observer);
+}
+
LayerAnimator::ScopedSettings::ScopedSettings(LayerAnimator* animator)
: animator_(animator),
old_transition_duration_(animator->transition_duration_) {
@@ -201,6 +212,15 @@ LayerAnimator::ScopedSettings::ScopedSettings(LayerAnimator* animator)
LayerAnimator::ScopedSettings::~ScopedSettings() {
animator_->transition_duration_ = old_transition_duration_;
+ std::set<LayerAnimationObserver*>::const_iterator i = observers_.begin();
+ for (;i != observers_.end(); ++i)
+ animator_->RemoveObserver(*i);
+}
+
+void LayerAnimator::ScopedSettings::AddObserver(
+ LayerAnimationObserver* observer) {
+ observers_.insert(observer);
+ animator_->AddObserver(observer);
}
void LayerAnimator::ScopedSettings::SetTransitionDuration(
@@ -277,7 +297,6 @@ void LayerAnimator::RemoveAnimation(LayerAnimationSequence* sequence) {
void LayerAnimator::FinishAnimation(LayerAnimationSequence* sequence) {
sequence->Progress(sequence->duration(), delegate());
- delegate()->OnLayerAnimationEnded(sequence);
RemoveAnimation(sequence);
ProcessQueue();
UpdateAnimationState();
@@ -293,7 +312,6 @@ void LayerAnimator::FinishAnyAnimationWithZeroDuration() {
if (running_animations_[i].sequence->duration() == base::TimeDelta()) {
running_animations_[i].sequence->Progress(
running_animations_[i].sequence->duration(), delegate());
- delegate()->OnLayerAnimationEnded(running_animations_[i].sequence);
RemoveAnimation(running_animations_[i].sequence);
} else {
++i;
@@ -356,7 +374,6 @@ void LayerAnimator::RemoveAllAnimationsWithACommonProperty(
} else {
running_animations_[i].sequence->Progress(
running_animations_[i].sequence->duration(), delegate());
- delegate()->OnLayerAnimationEnded(running_animations_[i].sequence);
}
RemoveAnimation(running_animations_[i].sequence);
} else {
@@ -384,7 +401,6 @@ void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) {
const bool abort = false;
RemoveAllAnimationsWithACommonProperty(sequence, abort);
sequence->Progress(sequence->duration(), delegate());
- delegate()->OnLayerAnimationEnded(sequence);
RemoveAnimation(sequence);
}
@@ -500,4 +516,15 @@ void LayerAnimator::GetTargetValue(
}
}
+void LayerAnimator::OnScheduled(LayerAnimationSequence* sequence) {
+ if (observers_.might_have_observers()) {
+ ObserverListBase<LayerAnimationObserver>::Iterator it(observers_);
+ LayerAnimationObserver* obs;
+ while ((obs = it.GetNext()) != NULL) {
+ sequence->AddObserver(obs);
+ }
+ }
+ sequence->OnScheduled();
+}
+
} // namespace ui
diff --git a/ui/gfx/compositor/layer_animator.h b/ui/gfx/compositor/layer_animator.h
index e6751ff..4fca4e5 100644
--- a/ui/gfx/compositor/layer_animator.h
+++ b/ui/gfx/compositor/layer_animator.h
@@ -7,10 +7,12 @@
#pragma once
#include <deque>
+#include <set>
#include <vector>
#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_ptr.h"
+#include "base/observer_list.h"
#include "base/time.h"
#include "ui/base/animation/animation_container_element.h"
#include "ui/gfx/compositor/compositor_export.h"
@@ -24,7 +26,8 @@ namespace ui {
class Animation;
class Layer;
class LayerAnimationSequence;
-class LayerAnimatorDelegate;
+class LayerAnimationDelegate;
+class LayerAnimationObserver;
class Transform;
// When a property of layer needs to be changed it is set by way of
@@ -62,7 +65,7 @@ class COMPOSITOR_EXPORT LayerAnimator : public AnimationContainerElement {
// Sets the layer animation delegate the animator is associated with. The
// animator does not own the delegate.
- void SetDelegate(LayerAnimatorDelegate* delegate);
+ void SetDelegate(LayerAnimationDelegate* delegate);
// Sets the animation preemption strategy. This determines the behaviour if
// a property is set during an animation. The default is
@@ -85,18 +88,16 @@ class COMPOSITOR_EXPORT LayerAnimator : public AnimationContainerElement {
// animation sequences.
void ScheduleTogether(const std::vector<LayerAnimationSequence*>& animations);
- // These are cover functions that create sequences for you to wrap the given
- // elements. These sequences are then passed to the corresponding function
- // above.
- void StartAnimationElement(LayerAnimationElement* element);
- void ScheduleAnimationElement(LayerAnimationElement* element);
- void ScheduleElementsTogether(
- const std::vector<LayerAnimationElement*>& element);
-
// Returns true if there is an animation in the queue (animations remain in
- // the queue until they complete).
+ // the queue until they complete, so this includes running animations).
bool is_animating() const { return !animation_queue_.empty(); }
+ // Returns true if there is an animation in the queue that animates the given
+ // property (animations remain in the queue until they complete, so this
+ // includes running animations).
+ bool IsAnimatingProperty(
+ LayerAnimationElement::AnimatableProperty property) const;
+
// Stops animating the given property. No effect if there is no running
// animation for the given property. Skips to the final state of the
// animation.
@@ -112,6 +113,11 @@ class COMPOSITOR_EXPORT LayerAnimator : public AnimationContainerElement {
}
base::TimeTicks get_last_step_time_for_test() { return last_step_time_; }
+ // These functions are used for adding or removing observers from the observer
+ // list. The observers are notified when animations end.
+ void AddObserver(LayerAnimationObserver* observer);
+ void RemoveObserver(LayerAnimationObserver* observer);
+
// Scoped settings allow you to temporarily change the animator's settings and
// these changes are reverted when the object is destroyed. NOTE: when the
// settings object is created, it applies the default transition duration
@@ -121,20 +127,22 @@ class COMPOSITOR_EXPORT LayerAnimator : public AnimationContainerElement {
explicit ScopedSettings(LayerAnimator* animator);
virtual ~ScopedSettings();
+ void AddObserver(LayerAnimationObserver* observer);
void SetTransitionDuration(base::TimeDelta duration);
private:
LayerAnimator* animator_;
base::TimeDelta old_transition_duration_;
+ std::set<LayerAnimationObserver*> observers_;
DISALLOW_COPY_AND_ASSIGN(ScopedSettings);
};
protected:
- LayerAnimatorDelegate* delegate() { return delegate_; }
+ LayerAnimationDelegate* delegate() { return delegate_; }
private:
- friend class TransientSettings;
+ friend class ScopedSettings;
// We need to keep track of the start time of every running animation.
struct RunningAnimation {
@@ -211,11 +219,15 @@ class COMPOSITOR_EXPORT LayerAnimator : public AnimationContainerElement {
// allowed to finish.
void GetTargetValue(LayerAnimationElement::TargetValue* target) const;
+ // Called whenever an animation is added to the animation queue. Either by
+ // starting the animation or adding to the queue.
+ void OnScheduled(LayerAnimationSequence* sequence);
+
// This is the queue of animations to run.
AnimationQueue animation_queue_;
// The target of all layer animations.
- LayerAnimatorDelegate* delegate_;
+ LayerAnimationDelegate* delegate_;
// The currently running animations.
RunningAnimations running_animations_;
@@ -236,6 +248,10 @@ class COMPOSITOR_EXPORT LayerAnimator : public AnimationContainerElement {
// and allows for manual stepping.
bool disable_timer_for_test_;
+ // Observers are notified when layer animations end, are scheduled or are
+ // aborted.
+ ObserverList<LayerAnimationObserver> observers_;
+
DISALLOW_COPY_AND_ASSIGN(LayerAnimator);
};
diff --git a/ui/gfx/compositor/layer_animator_delegate.h b/ui/gfx/compositor/layer_animator_delegate.h
deleted file mode 100644
index 173584f..0000000
--- a/ui/gfx/compositor/layer_animator_delegate.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// 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.
-
-#ifndef UI_GFX_COMPOSITOR_LAYER_ANIMATOR_DELEGATE_H_
-#define UI_GFX_COMPOSITOR_LAYER_ANIMATOR_DELEGATE_H_
-#pragma once
-
-#include "ui/gfx/rect.h"
-#include "ui/gfx/transform.h"
-#include "ui/gfx/compositor/compositor_export.h"
-#include "ui/gfx/compositor/layer_animation_delegate.h"
-
-namespace ui {
-
-class LayerAnimationSequence;
-
-// Layer animators interact with the layers using this interface.
-class COMPOSITOR_EXPORT LayerAnimatorDelegate : public LayerAnimationDelegate {
- public:
- // Called when the |sequence| ends. Not called if |sequence| is aborted.
- virtual void OnLayerAnimationEnded(LayerAnimationSequence* sequence) = 0;
-
- // if this becomes necessary, this would be the appropriate place to add
- // notifications about elements starting or ending, or sequences starting.
-
- protected:
- virtual ~LayerAnimatorDelegate() {}
-};
-
-} // namespace ui
-
-#endif // UI_GFX_COMPOSITOR_LAYER_ANIMATOR_DELEGATE_H_
diff --git a/ui/gfx/compositor/layer_animator_unittest.cc b/ui/gfx/compositor/layer_animator_unittest.cc
index e92d7c5..7d957cf 100644
--- a/ui/gfx/compositor/layer_animator_unittest.cc
+++ b/ui/gfx/compositor/layer_animator_unittest.cc
@@ -11,10 +11,11 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/transform.h"
-#include "ui/gfx/compositor/dummy_layer_animation_delegate.h"
#include "ui/gfx/compositor/layer_animation_delegate.h"
#include "ui/gfx/compositor/layer_animation_element.h"
#include "ui/gfx/compositor/layer_animation_sequence.h"
+#include "ui/gfx/compositor/test_layer_animation_delegate.h"
+#include "ui/gfx/compositor/test_layer_animation_observer.h"
#include "ui/gfx/compositor/test_utils.h"
namespace ui {
@@ -27,7 +28,7 @@ TEST(LayerAnimatorTest, ImplicitAnimation) {
scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateImplicitAnimator());
AnimationContainerElement* element = animator.get();
animator->set_disable_timer_for_test(true);
- DummyLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate delegate;
animator->SetDelegate(&delegate);
base::TimeTicks now = base::TimeTicks::Now();
animator->SetOpacity(0.5);
@@ -41,7 +42,7 @@ TEST(LayerAnimatorTest, ImplicitAnimation) {
TEST(LayerAnimatorTest, NoImplicitAnimation) {
scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
animator->set_disable_timer_for_test(true);
- DummyLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate delegate;
animator->SetDelegate(&delegate);
base::TimeTicks now = base::TimeTicks::Now();
animator->SetOpacity(0.5);
@@ -54,7 +55,7 @@ TEST(LayerAnimatorTest, NoImplicitAnimation) {
TEST(LayerAnimatorTest, StopAnimatingProperty) {
scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateImplicitAnimator());
animator->set_disable_timer_for_test(true);
- DummyLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate delegate;
animator->SetDelegate(&delegate);
base::TimeTicks now = base::TimeTicks::Now();
double target_opacity(0.5);
@@ -74,7 +75,7 @@ TEST(LayerAnimatorTest, StopAnimatingProperty) {
TEST(LayerAnimatorTest, StopAnimating) {
scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateImplicitAnimator());
animator->set_disable_timer_for_test(true);
- DummyLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate delegate;
animator->SetDelegate(&delegate);
base::TimeTicks now = base::TimeTicks::Now();
double target_opacity(0.5);
@@ -94,7 +95,7 @@ TEST(LayerAnimatorTest, ScheduleAnimationThatCanRunImmediately) {
scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
AnimationContainerElement* element = animator.get();
animator->set_disable_timer_for_test(true);
- DummyLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate delegate;
animator->SetDelegate(&delegate);
double start_opacity(0.0);
@@ -131,7 +132,7 @@ TEST(LayerAnimatorTest, ScheduleTwoAnimationsThatCanRunImmediately) {
scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
AnimationContainerElement* element = animator.get();
animator->set_disable_timer_for_test(true);
- DummyLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate delegate;
animator->SetDelegate(&delegate);
double start_opacity(0.0);
@@ -181,7 +182,7 @@ TEST(LayerAnimatorTest, ScheduleTwoAnimationsOnSameProperty) {
scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
AnimationContainerElement* element = animator.get();
animator->set_disable_timer_for_test(true);
- DummyLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate delegate;
animator->SetDelegate(&delegate);
double start_opacity(0.0);
@@ -233,7 +234,7 @@ TEST(LayerAnimatorTest, ScheduleBlockedAnimation) {
scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
AnimationContainerElement* element = animator.get();
animator->set_disable_timer_for_test(true);
- DummyLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate delegate;
animator->SetDelegate(&delegate);
double start_opacity(0.0);
@@ -311,7 +312,7 @@ TEST(LayerAnimatorTest, ScheduleTogether) {
scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
AnimationContainerElement* element = animator.get();
animator->set_disable_timer_for_test(true);
- DummyLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate delegate;
animator->SetDelegate(&delegate);
double start_opacity(0.0);
@@ -364,7 +365,7 @@ TEST(LayerAnimatorTest, StartAnimationThatCanRunImmediately) {
scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
AnimationContainerElement* element = animator.get();
animator->set_disable_timer_for_test(true);
- DummyLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate delegate;
animator->SetDelegate(&delegate);
double start_opacity(0.0);
@@ -399,7 +400,7 @@ TEST(LayerAnimatorTest, StartAnimationThatCanRunImmediately) {
TEST(LayerAnimatorTest, PreemptBySettingNewTarget) {
scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
animator->set_disable_timer_for_test(true);
- DummyLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate delegate;
animator->SetDelegate(&delegate);
double start_opacity(0.0);
@@ -428,7 +429,7 @@ TEST(LayerAnimatorTest, PreemptByImmediatelyAnimatingToNewTarget) {
scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
AnimationContainerElement* element = animator.get();
animator->set_disable_timer_for_test(true);
- DummyLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate delegate;
animator->SetDelegate(&delegate);
double start_opacity(0.0);
@@ -480,7 +481,7 @@ TEST(LayerAnimatorTest, PreemptEnqueueNewAnimation) {
scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
AnimationContainerElement* element = animator.get();
animator->set_disable_timer_for_test(true);
- DummyLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate delegate;
animator->SetDelegate(&delegate);
double start_opacity(0.0);
@@ -533,7 +534,7 @@ TEST(LayerAnimatorTest, PreemptyByReplacingQueuedAnimations) {
scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
AnimationContainerElement* element = animator.get();
animator->set_disable_timer_for_test(true);
- DummyLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate delegate;
animator->SetDelegate(&delegate);
double start_opacity(0.0);
@@ -588,7 +589,7 @@ TEST(LayerAnimatorTest, CyclicSequences) {
scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
AnimationContainerElement* element = animator.get();
animator->set_disable_timer_for_test(true);
- DummyLayerAnimationDelegate delegate;
+ TestLayerAnimationDelegate delegate;
animator->SetDelegate(&delegate);
double start_opacity(0.0);
@@ -643,6 +644,84 @@ TEST(LayerAnimatorTest, CyclicSequences) {
EXPECT_FALSE(animator->is_animating());
}
+TEST(LayerAnimatorTest, AddObserverExplicit) {
+ scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
+ AnimationContainerElement* element = animator.get();
+ animator->set_disable_timer_for_test(true);
+ TestLayerAnimationObserver observer;
+ TestLayerAnimationDelegate delegate;
+ animator->SetDelegate(&delegate);
+ animator->AddObserver(&observer);
+
+ EXPECT_TRUE(!observer.last_ended_sequence());
+
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
+
+ delegate.SetOpacityFromAnimation(0.0f);
+
+ LayerAnimationSequence* sequence = new LayerAnimationSequence(
+ LayerAnimationElement::CreateOpacityElement(1.0f, delta));
+
+ animator->StartAnimation(sequence);
+
+ EXPECT_EQ(observer.last_scheduled_sequence(), sequence);
+
+ base::TimeTicks start_time = animator->get_last_step_time_for_test();
+
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
+
+ EXPECT_EQ(observer.last_ended_sequence(), sequence);
+
+ // |sequence| has been destroyed. Recreate it to test abort.
+ sequence = new LayerAnimationSequence(
+ LayerAnimationElement::CreateOpacityElement(1.0f, delta));
+
+ animator->StartAnimation(sequence);
+
+ animator.reset();
+
+ EXPECT_EQ(observer.last_aborted_sequence(), sequence);
+}
+
+TEST(LayerAnimatorTest, AddObserverImplicit) {
+ scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
+ AnimationContainerElement* element = animator.get();
+ animator->set_disable_timer_for_test(true);
+ TestLayerAnimationObserver observer;
+ TestLayerAnimationDelegate delegate;
+ animator->SetDelegate(&delegate);
+ animator->AddObserver(&observer);
+
+ // Should not end a sequence with the default animator.
+ EXPECT_TRUE(!observer.last_ended_sequence());
+ animator->SetOpacity(1.0f);
+ base::TimeTicks start_time = base::TimeTicks::Now();
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
+ EXPECT_TRUE(!observer.last_ended_sequence());
+
+ TestLayerAnimationObserver scoped_observer;
+ {
+ LayerAnimator::ScopedSettings settings(animator.get());
+ settings.AddObserver(&scoped_observer);
+ for (int i = 0; i < 2; ++i) {
+ // reset the observer
+ scoped_observer = TestLayerAnimationObserver();
+ EXPECT_TRUE(!scoped_observer.last_ended_sequence());
+ animator->SetOpacity(1.0f);
+ start_time = animator->get_last_step_time_for_test();
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
+ EXPECT_FALSE(!scoped_observer.last_ended_sequence());
+ }
+ }
+
+ scoped_observer = TestLayerAnimationObserver();
+ EXPECT_TRUE(!scoped_observer.last_ended_sequence());
+ animator->SetOpacity(1.0f);
+ start_time = base::TimeTicks::Now();
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
+ EXPECT_TRUE(!scoped_observer.last_ended_sequence());
+}
+
} // namespace
} // namespace ui
diff --git a/ui/gfx/compositor/layer_delegate.h b/ui/gfx/compositor/layer_delegate.h
index 474689e..1f494b1 100644
--- a/ui/gfx/compositor/layer_delegate.h
+++ b/ui/gfx/compositor/layer_delegate.h
@@ -14,8 +14,6 @@ class Canvas;
namespace ui {
-class LayerAnimationSequence;
-
// A delegate interface implemented by an object that renders to a Layer.
class COMPOSITOR_EXPORT LayerDelegate {
public:
@@ -23,9 +21,6 @@ class COMPOSITOR_EXPORT LayerDelegate {
// clipped to the Layer's invalid rect.
virtual void OnPaintLayer(gfx::Canvas* canvas) = 0;
- // Called when |seq| ends.
- virtual void OnLayerAnimationEnded(const LayerAnimationSequence* seq) = 0;
-
protected:
virtual ~LayerDelegate() {}
};
diff --git a/ui/gfx/compositor/layer_unittest.cc b/ui/gfx/compositor/layer_unittest.cc
index 1839cbe..fceb9c6 100644
--- a/ui/gfx/compositor/layer_unittest.cc
+++ b/ui/gfx/compositor/layer_unittest.cc
@@ -42,10 +42,6 @@ class ColoredLayer : public Layer, public LayerDelegate {
canvas->GetSkCanvas()->drawColor(color_);
}
- virtual void OnLayerAnimationEnded(
- const LayerAnimationSequence* animation) OVERRIDE {
- }
-
private:
SkColor color_;
};
@@ -131,9 +127,6 @@ class TestLayerDelegate : public LayerDelegate {
gfx::Rect(gfx::Point(), paint_size_));
color_index_ = (color_index_ + 1) % static_cast<int>(colors_.size());
}
- virtual void OnLayerAnimationEnded(
- const LayerAnimationSequence* animation) OVERRIDE {
- }
private:
std::vector<SkColor> colors_;
@@ -160,9 +153,6 @@ class DrawTreeLayerDelegate : public LayerDelegate {
virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
painted_ = true;
}
- virtual void OnLayerAnimationEnded(
- const LayerAnimationSequence* animation) OVERRIDE {
- }
bool painted_;
@@ -179,9 +169,6 @@ class NullLayerDelegate : public LayerDelegate {
// Overridden from LayerDelegate:
virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
}
- virtual void OnLayerAnimationEnded(
- const LayerAnimationSequence* animation) OVERRIDE {
- }
DISALLOW_COPY_AND_ASSIGN(NullLayerDelegate);
};
diff --git a/ui/gfx/compositor/test_layer_animation_delegate.cc b/ui/gfx/compositor/test_layer_animation_delegate.cc
new file mode 100644
index 0000000..a7aa124
--- /dev/null
+++ b/ui/gfx/compositor/test_layer_animation_delegate.cc
@@ -0,0 +1,51 @@
+// 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/test_layer_animation_delegate.h"
+
+namespace ui {
+
+TestLayerAnimationDelegate::TestLayerAnimationDelegate() : opacity_(1.0f) {
+}
+
+TestLayerAnimationDelegate::TestLayerAnimationDelegate(
+ const LayerAnimationDelegate& other)
+ : bounds_(other.GetBoundsForAnimation()),
+ transform_(other.GetTransformForAnimation()),
+ opacity_(other.GetOpacityForAnimation()) {
+}
+
+TestLayerAnimationDelegate::~TestLayerAnimationDelegate() {
+}
+
+void TestLayerAnimationDelegate::SetBoundsFromAnimation(
+ const gfx::Rect& bounds) {
+ bounds_ = bounds;
+}
+
+void TestLayerAnimationDelegate::SetTransformFromAnimation(
+ const Transform& transform) {
+ transform_ = transform;
+}
+
+void TestLayerAnimationDelegate::SetOpacityFromAnimation(float opacity) {
+ opacity_ = opacity;
+}
+
+void TestLayerAnimationDelegate::ScheduleDrawForAnimation() {
+}
+
+const gfx::Rect& TestLayerAnimationDelegate::GetBoundsForAnimation() const {
+ return bounds_;
+}
+
+const Transform& TestLayerAnimationDelegate::GetTransformForAnimation() const {
+ return transform_;
+}
+
+float TestLayerAnimationDelegate::GetOpacityForAnimation() const {
+ return opacity_;
+}
+
+} // namespace ui
diff --git a/ui/gfx/compositor/dummy_layer_animation_delegate.h b/ui/gfx/compositor/test_layer_animation_delegate.h
index 69b6435..c75d2b1 100644
--- a/ui/gfx/compositor/dummy_layer_animation_delegate.h
+++ b/ui/gfx/compositor/test_layer_animation_delegate.h
@@ -2,26 +2,26 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_GFX_COMPOSITOR_DUMMY_LAYER_ANIMATION_DELEGATE_H_
-#define UI_GFX_COMPOSITOR_DUMMY_LAYER_ANIMATION_DELEGATE_H_
+#ifndef UI_GFX_COMPOSITOR_TEST_LAYER_ANIMATION_DELEGATE_H_
+#define UI_GFX_COMPOSITOR_TEST_LAYER_ANIMATION_DELEGATE_H_
#pragma once
#include "base/compiler_specific.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/transform.h"
#include "ui/gfx/compositor/compositor_export.h"
-#include "ui/gfx/compositor/layer_animator_delegate.h"
+#include "ui/gfx/compositor/layer_animation_delegate.h"
namespace ui {
class LayerAnimationSequence;
-class COMPOSITOR_EXPORT DummyLayerAnimationDelegate
- : public LayerAnimatorDelegate {
+class COMPOSITOR_EXPORT TestLayerAnimationDelegate
+ : public LayerAnimationDelegate {
public:
- DummyLayerAnimationDelegate();
- DummyLayerAnimationDelegate(const LayerAnimationDelegate& other);
- virtual ~DummyLayerAnimationDelegate();
+ TestLayerAnimationDelegate();
+ TestLayerAnimationDelegate(const LayerAnimationDelegate& other);
+ virtual ~TestLayerAnimationDelegate();
// Implementation of LayerAnimationDelegate
virtual void SetBoundsFromAnimation(const gfx::Rect& bounds) OVERRIDE;
@@ -32,9 +32,6 @@ class COMPOSITOR_EXPORT DummyLayerAnimationDelegate
virtual const Transform& GetTransformForAnimation() const OVERRIDE;
virtual float GetOpacityForAnimation() const OVERRIDE;
- // Implementation of LayerAnimatorDelegate
- virtual void OnLayerAnimationEnded(LayerAnimationSequence* sequence) OVERRIDE;
-
private:
gfx::Rect bounds_;
Transform transform_;
@@ -45,4 +42,4 @@ class COMPOSITOR_EXPORT DummyLayerAnimationDelegate
} // namespace ui
-#endif // UI_GFX_COMPOSITOR_DUMMY_LAYER_ANIMATION_DELEGATE_H_
+#endif // UI_GFX_COMPOSITOR_TEST_LAYER_ANIMATION_DELEGATE_H_
diff --git a/ui/gfx/compositor/test_layer_animation_observer.cc b/ui/gfx/compositor/test_layer_animation_observer.cc
new file mode 100644
index 0000000..505d528
--- /dev/null
+++ b/ui/gfx/compositor/test_layer_animation_observer.cc
@@ -0,0 +1,35 @@
+// 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/test_layer_animation_observer.h"
+
+#include <cstddef>
+
+namespace ui {
+
+TestLayerAnimationObserver::TestLayerAnimationObserver()
+ : last_ended_sequence_(NULL),
+ last_scheduled_sequence_(NULL),
+ last_aborted_sequence_(NULL) {
+}
+
+TestLayerAnimationObserver::~TestLayerAnimationObserver() {
+}
+
+void TestLayerAnimationObserver::OnLayerAnimationEnded(
+ const LayerAnimationSequence* sequence) {
+ last_ended_sequence_ = sequence;
+}
+
+void TestLayerAnimationObserver::OnLayerAnimationScheduled(
+ const LayerAnimationSequence* sequence) {
+ last_scheduled_sequence_ = sequence;
+}
+
+void TestLayerAnimationObserver::OnLayerAnimationAborted(
+ const LayerAnimationSequence* sequence) {
+ last_aborted_sequence_ = sequence;
+}
+
+} // namespace ui
diff --git a/ui/gfx/compositor/test_layer_animation_observer.h b/ui/gfx/compositor/test_layer_animation_observer.h
new file mode 100644
index 0000000..879c74b
--- /dev/null
+++ b/ui/gfx/compositor/test_layer_animation_observer.h
@@ -0,0 +1,57 @@
+// 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.
+
+#ifndef UI_GFX_COMPOSITOR_TEST_LAYER_ANIMATION_OBSERVER_
+#define UI_GFX_COMPOSITOR_TEST_LAYER_ANIMATION_OBSERVER_
+#pragma once
+
+#include "base/compiler_specific.h"
+#include "ui/gfx/compositor/compositor_export.h"
+#include "ui/gfx/compositor/layer_animation_observer.h"
+
+namespace ui {
+
+class LayerAnimationSequence;
+
+// Listens to animation ended notifications. Remembers the last sequence that
+// it was notified about.
+class COMPOSITOR_EXPORT TestLayerAnimationObserver
+ : public LayerAnimationObserver {
+ public:
+ TestLayerAnimationObserver();
+ virtual ~TestLayerAnimationObserver();
+
+ virtual void OnLayerAnimationEnded(
+ const LayerAnimationSequence* sequence) OVERRIDE;
+
+ virtual void OnLayerAnimationAborted(
+ const LayerAnimationSequence* sequence) OVERRIDE;
+
+ virtual void OnLayerAnimationScheduled(
+ const LayerAnimationSequence* sequence) OVERRIDE;
+
+
+ const LayerAnimationSequence* last_ended_sequence() const {
+ return last_ended_sequence_;
+ }
+
+ const LayerAnimationSequence* last_scheduled_sequence() const {
+ return last_scheduled_sequence_;
+ }
+
+ const LayerAnimationSequence* last_aborted_sequence() const {
+ return last_aborted_sequence_;
+ }
+
+ private:
+ const LayerAnimationSequence* last_ended_sequence_;
+ const LayerAnimationSequence* last_scheduled_sequence_;
+ const LayerAnimationSequence* last_aborted_sequence_;
+
+ // Copy and assign are allowed.
+};
+
+} // namespace ui
+
+#endif // UI_GFX_COMPOSITOR_TEST_LAYER_ANIMATION_OBSERVER_