| // 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. |
| |
| #ifndef UI_COMPOSITOR_LAYER_ANIMATION_OBSERVER_H_ |
| #define UI_COMPOSITOR_LAYER_ANIMATION_OBSERVER_H_ |
| |
| #include <map> |
| #include <set> |
| |
| #include "base/compiler_specific.h" |
| #include "ui/compositor/compositor_export.h" |
| #include "ui/compositor/layer_animation_element.h" |
| |
| namespace ui { |
| |
| namespace test { |
| class LayerAnimationObserverTestApi; |
| } // namespace test |
| |
| class LayerAnimationSequence; |
| class ScopedLayerAnimationSettings; |
| class ImplicitAnimationObserver; |
| |
| // LayerAnimationObservers are notified when animations complete. |
| class COMPOSITOR_EXPORT LayerAnimationObserver { |
| public: |
| // Called when the |sequence| starts. |
| virtual void OnLayerAnimationStarted(LayerAnimationSequence* sequence); |
| |
| // Called when the |sequence| ends. Not called if |sequence| is aborted. |
| virtual void OnLayerAnimationEnded( |
| LayerAnimationSequence* sequence) = 0; |
| |
| // Called if |sequence| is aborted for any reason. Should never do anything |
| // that may cause another animation to be started. |
| virtual void OnLayerAnimationAborted( |
| LayerAnimationSequence* sequence) = 0; |
| |
| // Called when the animation is scheduled. |
| virtual void OnLayerAnimationScheduled( |
| LayerAnimationSequence* sequence) = 0; |
| |
| protected: |
| typedef std::set<LayerAnimationSequence*> AttachedSequences; |
| |
| LayerAnimationObserver(); |
| virtual ~LayerAnimationObserver(); |
| |
| // If the LayerAnimator is destroyed during an animation, the animations are |
| // aborted. The resulting NotifyAborted notifications will NOT be sent to |
| // this observer if this function returns false. An observer who wants to |
| // receive the NotifyAborted notifications during destruction can override |
| // this function to return true. |
| // |
| // *** IMPORTANT ***: If a class overrides this function to return true and |
| // that class is a direct or indirect owner of the LayerAnimationSequence |
| // being observed, then the class must explicitly remove itself as an |
| // observer during destruction of the LayerAnimationObserver! This is to |
| // ensure that a partially destroyed observer isn't notified with an |
| // OnLayerAnimationAborted() call when the LayerAnimator is destroyed. |
| // |
| // This opt-in pattern is used because it is common for a class to be the |
| // observer of a LayerAnimationSequence that it owns indirectly because it |
| // owns the Layer which owns the LayerAnimator which owns the |
| // LayerAnimationSequence. |
| virtual bool RequiresNotificationWhenAnimatorDestroyed() const; |
| |
| // Called when |this| is added to |sequence|'s observer list. |
| virtual void OnAttachedToSequence(LayerAnimationSequence* sequence); |
| |
| // Called when |this| is removed to |sequence|'s observer list. |
| virtual void OnDetachedFromSequence(LayerAnimationSequence* sequence); |
| |
| // Detaches this observer from all sequences it is currently observing. |
| void StopObserving(); |
| |
| const AttachedSequences& attached_sequences() const { |
| return attached_sequences_; |
| } |
| |
| private: |
| friend class LayerAnimationSequence; |
| friend class test::LayerAnimationObserverTestApi; |
| |
| // Called when |this| is added to |sequence|'s observer list. |
| void AttachedToSequence(LayerAnimationSequence* sequence); |
| |
| // Called when |this| is removed to |sequence|'s observer list. |
| // This will only result in notifications if |send_notification| is true. |
| void DetachedFromSequence(LayerAnimationSequence* sequence, |
| bool send_notification); |
| |
| AttachedSequences attached_sequences_; |
| }; |
| |
| // An implicit animation observer is intended to be used in conjunction with a |
| // ScopedLayerAnimationSettings object in order to receive a notification when |
| // all implicit animations complete. |
| // TODO(bruthig): Unify the ImplicitAnimationObserver with the |
| // CallbackLayerAnimationObserver. (See www.crbug.com/542825). |
| class COMPOSITOR_EXPORT ImplicitAnimationObserver |
| : public LayerAnimationObserver { |
| public: |
| ImplicitAnimationObserver(); |
| ~ImplicitAnimationObserver() override; |
| |
| // Called when the first animation sequence has started. |
| virtual void OnImplicitAnimationsScheduled() {} |
| |
| virtual void OnImplicitAnimationsCompleted() = 0; |
| |
| protected: |
| // Deactivates the observer and clears the collection of animations it is |
| // waiting for. |
| void StopObservingImplicitAnimations(); |
| |
| // Returns whether animation for |property| was aborted. |
| // Note that if the property wasn't animated, then it couldn't have been |
| // aborted, so this will return false for that property. |
| bool WasAnimationAbortedForProperty( |
| LayerAnimationElement::AnimatableProperty property) const; |
| |
| // Returns whether animation for |property| was completed successfully. |
| // Note that if the property wasn't animated, then it couldn't have been |
| // completed, so this will return false for that property. |
| bool WasAnimationCompletedForProperty( |
| LayerAnimationElement::AnimatableProperty property) const; |
| |
| private: |
| enum AnimationStatus { |
| ANIMATION_STATUS_UNKNOWN, |
| ANIMATION_STATUS_COMPLETED, |
| ANIMATION_STATUS_ABORTED, |
| }; |
| |
| friend class ScopedLayerAnimationSettings; |
| |
| // LayerAnimationObserver implementation |
| void OnLayerAnimationEnded(LayerAnimationSequence* sequence) override; |
| void OnLayerAnimationAborted(LayerAnimationSequence* sequence) override; |
| void OnLayerAnimationScheduled(LayerAnimationSequence* sequence) override; |
| void OnAttachedToSequence(LayerAnimationSequence* sequence) override; |
| void OnDetachedFromSequence(LayerAnimationSequence* sequence) override; |
| |
| // OnImplicitAnimationsCompleted is not fired unless the observer is active. |
| bool active() const { return active_; } |
| void SetActive(bool active); |
| |
| void CheckCompleted(); |
| |
| void UpdatePropertyAnimationStatus(LayerAnimationSequence* sequence, |
| AnimationStatus status); |
| AnimationStatus AnimationStatusForProperty( |
| LayerAnimationElement::AnimatableProperty property) const; |
| |
| bool active_; |
| |
| // Set to true in the destructor (if non-NULL). Used to detect deletion while |
| // calling out. |
| bool* destroyed_; |
| |
| typedef std::map<LayerAnimationElement::AnimatableProperty, |
| AnimationStatus> PropertyAnimationStatusMap; |
| PropertyAnimationStatusMap property_animation_status_; |
| |
| // True if OnLayerAnimationScheduled() has been called at least once. |
| bool first_sequence_scheduled_; |
| }; |
| |
| } // namespace ui |
| |
| #endif // UI_COMPOSITOR_LAYER_ANIMATION_OBSERVER_H_ |