Animatable.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media / Animation / Animatable.cs / 1305600 / Animatable.cs

                            //------------------------------------------------------------------------------ 
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation, 2003
//
//  File: Animatable.cs 
//-----------------------------------------------------------------------------
 
// Allow suppression of certain presharp messages 
#pragma warning disable 1634, 1691
 
using MS.Internal;
using MS.Utility;
using System;
using System.Collections; 
using System.Collections.Generic;
using System.Diagnostics; 
using System.Windows.Threading; 
using System.Windows.Media.Composition;
 
using SR = MS.Internal.PresentationCore.SR;
using SRID = MS.Internal.PresentationCore.SRID;

namespace System.Windows.Media.Animation 
{
    ///  
    /// This class derives from Freezable and adds the ability to animate properties. 
    /// 
    public abstract partial class Animatable : Freezable, IAnimatable, DUCE.IResource 
    {
        #region Constructors

        ///  
        ///
        ///  
        protected Animatable() 
        {
        } 

        #endregion

        #region Public 

        ///  
        /// Creates a copy of this Animatable. 
        /// 
        /// The copy. 
        public new Animatable Clone()
        {
            return (Animatable)base.Clone();
        } 

        internal void PropertyChanged(DependencyProperty dp) 
        { 
            AnimationStorage animationStorage = AnimationStorage.GetStorage(this, dp);
            IndependentAnimationStorage independentAnimationStorage = animationStorage as IndependentAnimationStorage; 

            // If this property is independently animated and currently has
            // animations all we need to do is update the animation resource
            // that represents this property value. Otherwise we need to invalidate 
            // and and eventually update this whole object.
            if (independentAnimationStorage != null) 
            { 
                independentAnimationStorage.InvalidateResource();
            } 
            else
            {
                RegisterForAsyncUpdateResource();
            } 
        }
 
        internal virtual void AddRefOnChannelAnimations(DUCE.Channel channel) 
        {
            if (IAnimatable_HasAnimatedProperties) 
            {
                FrugalMap animatedPropertiesMap = AnimationStorage.GetAnimatedPropertiesMap(this);

                Debug.Assert(animatedPropertiesMap.Count > 0); 

                for (int i = 0; i < animatedPropertiesMap.Count; i++) 
                { 
                    Int32   dpGlobalIndex;
                    Object  storageObject; 

                    animatedPropertiesMap.GetKeyValuePair(i, out dpGlobalIndex, out storageObject);

                    DUCE.IResource storage = storageObject as DUCE.IResource; 

                    if (storage != null) 
                    { 
                        storage.AddRefOnChannel(channel);
                    } 
                }
            }
        }
 
        internal virtual void ReleaseOnChannelAnimations(DUCE.Channel channel)
        { 
            if (IAnimatable_HasAnimatedProperties) 
            {
                FrugalMap animatedPropertiesMap = AnimationStorage.GetAnimatedPropertiesMap(this); 

                Debug.Assert(animatedPropertiesMap.Count > 0);

                for (int i = 0; i < animatedPropertiesMap.Count; i++) 
                {
                    Int32 dpGlobalIndex; 
                    Object storageObject; 

                    animatedPropertiesMap.GetKeyValuePair(i, out dpGlobalIndex, out storageObject); 

                    DUCE.IResource storage = storageObject as DUCE.IResource;

                    if (storage != null) 
                    {
                        storage.ReleaseOnChannel(channel); 
                    } 
                }
            } 
        }

        #region LocalProperty/CachedValue stuff
 
        internal static DependencyProperty RegisterProperty(
            string name, 
            Type propertyType, 
            Type ownerType,
            object defaultValue, 
            PropertyChangedCallback changed,
            ValidateValueCallback validate,
            bool isIndependentlyAnimated,
            CoerceValueCallback coerced) 
        {
            // Override metadata for this particular object type. This defines 
            // the methods that will be called when property actions (setting, 
            // getting, invalidating) are taken for this specific object type.
 
            UIPropertyMetadata propertyMetadata;

            // If this property is animated using a property resource, we create
            // AnimatablePropertyMetadata instead of UIPropertyMetadata. 

            if (isIndependentlyAnimated) 
            { 
                propertyMetadata = new IndependentlyAnimatedPropertyMetadata(defaultValue);
            } 
            else
            {
                propertyMetadata = new UIPropertyMetadata(defaultValue);
            } 

            propertyMetadata.PropertyChangedCallback = changed; 
 
            if (coerced != null)
            { 
                propertyMetadata.CoerceValueCallback = coerced;
            }

            // Register property with passed in default metadata.  The type of 
            // defaultMetadata will determine whether this property is animatable.
            DependencyProperty dp = DependencyProperty.Register( 
                name, 
                propertyType,
                ownerType, 
                propertyMetadata,
                validate);

            return dp; 
        }
 
        // Helpers for addref and release of local properties.  Subclasses can provide 
        // overloads.
        internal void AddRefResource(DUCE.IResource resource, DUCE.Channel channel) 
        {
            if (resource != null)
            {
                resource.AddRefOnChannel(channel); 
            }
        } 
 
        internal void ReleaseResource(DUCE.IResource resource, DUCE.Channel channel)
        { 
            if (resource != null)
            {
                resource.ReleaseOnChannel(channel);
            } 
        }
 
        #endregion LocalProperty/CachedValue stuff 

        #endregion 

        #region Protected

        ///  
        /// An Animatable will return false from this method if there are any Clocks
        /// animating any of its properties. If the Animatable has persistent animations 
        /// specified, but all of the Clocks have been removed, it may still return 
        /// true from this method if the Timelines themselves can be frozen.
        ///  
        /// 
        /// True if the Freezable should actually Freeze itself; false if
        /// the Freezable should simply return whether it can be frozen.
        /// True if this object can be frozen; otherwise false. 
        protected override bool FreezeCore(bool isChecking)
        { 
            if (IAnimatable_HasAnimatedProperties) 
            {
                if (TraceFreezable.IsEnabled) 
                {
                    TraceFreezable.Trace(
                        TraceEventType.Warning,
                        TraceFreezable.UnableToFreezeAnimatedProperties, 
                        this);
                } 
 
                return false;
            } 

            return base.FreezeCore(isChecking);
        }
 
        #endregion
 
        #region IResource 

        ///  
        /// Derived classes implement this function.
        /// 
        DUCE.ResourceHandle DUCE.IResource.AddRefOnChannel(DUCE.Channel channel)
        { 
            // Just return null instead of throwing an exception, since some
            // derived classes like BitmapEffect do their own addref/release. 
            return DUCE.ResourceHandle.Null; 
        }
 
        /// 
        /// Derived classes implement this function.
        /// 
        void DUCE.IResource.ReleaseOnChannel(DUCE.Channel channel) 
        {
            // Just return instead of throwing an exception, since some 
            // derived classes like BitmapEffect do their own addref/release. 
        }
 
        /// 
        /// Derived classes implement this function.
        /// 
        DUCE.ResourceHandle DUCE.IResource.GetHandle(DUCE.Channel channel) 
        {
            // Just return null instead of throwing an exception, since some 
            // derived classes like BitmapEffect do their own addref/release. 
            return DUCE.ResourceHandle.Null;
        } 

        /// 
        /// Derived classes implement this function.
        ///  
        int DUCE.IResource.GetChannelCount()
        { 
            return 0; 
        }
 
        /// 
        /// Derived classes implement this function.
        /// 
        DUCE.Channel DUCE.IResource.GetChannel(int index) 
        {
            return null; 
        } 

        ///  
        /// This is only implemented by Visual and Visual3D.
        /// 
        DUCE.ResourceHandle DUCE.IResource.Get3DHandle(DUCE.Channel channel)
        { 
            throw new NotImplementedException();
        } 
 
        /// 
        /// This is only implemented by Visual and Visual3D. 
        /// 
        void DUCE.IResource.RemoveChildFromParent(DUCE.IResource parent, DUCE.Channel channel)
        {
            throw new NotImplementedException(); 
        }
 
        #endregion 

 
        #region Internal


        internal DUCE.ResourceHandle GetAnimationResourceHandle(DependencyProperty dp, DUCE.Channel channel) 
        {
            if (channel != null && IAnimatable_HasAnimatedProperties) 
            { 
                return IndependentAnimationStorage.GetResourceHandle(this, dp, channel);
            } 
            else
            {
                return DUCE.ResourceHandle.Null;
            } 
        }
 
        ///  
        /// Returns a WeakReference to this Animatable that can be used by
        /// anyone who needs one. 
        /// 
        /// 
        /// The WeakReference isn't created or stored until this method is
        /// called. 
        /// 
        /// A WeakReference to this Animtable. 
        internal WeakReference GetWeakReference() 
        {
            object reference = StoredWeakReferenceField.GetValue(this); 

            if (reference == null)
            {
                reference = new WeakReference(this); 

                StoredWeakReferenceField.SetValue(this, (WeakReference)reference); 
            } 

            Debug.Assert(reference is WeakReference); 

            return (WeakReference)reference;
        }
 
        /// 
        /// IsBaseValueDefault returns true if there is no local value specified for this DP. 
        ///  
        /// The property for which the local value is checked.
        internal bool IsBaseValueDefault(DependencyProperty dp) 
        {
            return ReadLocalValue(dp) == DependencyProperty.UnsetValue;
        }
 
        /// 
        /// Every time something changes, we don't want to send resource 
        /// updates to the UCE, we only really want to do it once per UIThread 
        /// render.
        /// Calling this will make sure that a resource update request 
        /// is registered with the MediaContext.
        /// If this object doesn't have context affinity, it's unlikely
        /// that resource update requests would ever be made, however if they
        /// are the request will happen immediately. 
        /// 
        internal void RegisterForAsyncUpdateResource() 
        { 
            DUCE.IResource resource = this as DUCE.IResource;
 
            if (resource != null)
            {
                if ((Dispatcher != null) && Animatable_IsResourceInvalidationNecessary)
                { 
                    MediaContext mediaContext = MediaContext.From(Dispatcher);
 
                    // 
                    // Only register for a deferred resource update if this
                    // is actually on the channel. 
                    //
                    if (!resource.GetHandle(mediaContext.Channel).IsNull)
                    {
 
                        // Add this handler to this event means that the handler will be
                        // called on the next UIThread render for this Dispatcher. 
                        mediaContext.ResourcesUpdated += new MediaContext.ResourcesUpdatedHandler(UpdateResource); 
                        Animatable_IsResourceInvalidationNecessary = false;
                    } 
                }
            }
        }
 
        /// 
        /// UpdateResource - this implements the prototype required by ResourcesUpdatedHandler 
        /// The method which implements this prototype is also often called in situations where 
        /// the resource is known to be "on channel" - in those cases, "true" is passed for the second
        /// parameter (allowing the implementation to skip the check). 
        /// 
        internal virtual void UpdateResource(DUCE.Channel channel, bool skipOnChannelCheck)
        {
            Animatable_IsResourceInvalidationNecessary = true; 
        }
 
        ///  
        /// WritePreamble for objects such as AnimationCollection and
        /// TimelineCollection which modify an Animatable from the outside. 
        /// 
        internal void InternalWritePreamble()
        {
            WritePreamble(); 
        }
 
        #endregion 

        #region Private 

        /// 
        /// We use this property to store the a WeakReference to this Animatable
        /// that can be used by anyone who needs a WeakReference.  It won't be 
        /// created until its requested using the GetWeakReference method.
        ///  
        private static readonly UncommonField StoredWeakReferenceField 
            = new UncommonField();
 
        /// 
        /// This method is used by TypeDescriptor to determine if this property should
        /// be serialized.
        ///  
        [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
        public static bool ShouldSerializeStoredWeakReference(DependencyObject target) 
        { 
            return false;
        } 

        #endregion
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------ 
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation, 2003
//
//  File: Animatable.cs 
//-----------------------------------------------------------------------------
 
// Allow suppression of certain presharp messages 
#pragma warning disable 1634, 1691
 
using MS.Internal;
using MS.Utility;
using System;
using System.Collections; 
using System.Collections.Generic;
using System.Diagnostics; 
using System.Windows.Threading; 
using System.Windows.Media.Composition;
 
using SR = MS.Internal.PresentationCore.SR;
using SRID = MS.Internal.PresentationCore.SRID;

namespace System.Windows.Media.Animation 
{
    ///  
    /// This class derives from Freezable and adds the ability to animate properties. 
    /// 
    public abstract partial class Animatable : Freezable, IAnimatable, DUCE.IResource 
    {
        #region Constructors

        ///  
        ///
        ///  
        protected Animatable() 
        {
        } 

        #endregion

        #region Public 

        ///  
        /// Creates a copy of this Animatable. 
        /// 
        /// The copy. 
        public new Animatable Clone()
        {
            return (Animatable)base.Clone();
        } 

        internal void PropertyChanged(DependencyProperty dp) 
        { 
            AnimationStorage animationStorage = AnimationStorage.GetStorage(this, dp);
            IndependentAnimationStorage independentAnimationStorage = animationStorage as IndependentAnimationStorage; 

            // If this property is independently animated and currently has
            // animations all we need to do is update the animation resource
            // that represents this property value. Otherwise we need to invalidate 
            // and and eventually update this whole object.
            if (independentAnimationStorage != null) 
            { 
                independentAnimationStorage.InvalidateResource();
            } 
            else
            {
                RegisterForAsyncUpdateResource();
            } 
        }
 
        internal virtual void AddRefOnChannelAnimations(DUCE.Channel channel) 
        {
            if (IAnimatable_HasAnimatedProperties) 
            {
                FrugalMap animatedPropertiesMap = AnimationStorage.GetAnimatedPropertiesMap(this);

                Debug.Assert(animatedPropertiesMap.Count > 0); 

                for (int i = 0; i < animatedPropertiesMap.Count; i++) 
                { 
                    Int32   dpGlobalIndex;
                    Object  storageObject; 

                    animatedPropertiesMap.GetKeyValuePair(i, out dpGlobalIndex, out storageObject);

                    DUCE.IResource storage = storageObject as DUCE.IResource; 

                    if (storage != null) 
                    { 
                        storage.AddRefOnChannel(channel);
                    } 
                }
            }
        }
 
        internal virtual void ReleaseOnChannelAnimations(DUCE.Channel channel)
        { 
            if (IAnimatable_HasAnimatedProperties) 
            {
                FrugalMap animatedPropertiesMap = AnimationStorage.GetAnimatedPropertiesMap(this); 

                Debug.Assert(animatedPropertiesMap.Count > 0);

                for (int i = 0; i < animatedPropertiesMap.Count; i++) 
                {
                    Int32 dpGlobalIndex; 
                    Object storageObject; 

                    animatedPropertiesMap.GetKeyValuePair(i, out dpGlobalIndex, out storageObject); 

                    DUCE.IResource storage = storageObject as DUCE.IResource;

                    if (storage != null) 
                    {
                        storage.ReleaseOnChannel(channel); 
                    } 
                }
            } 
        }

        #region LocalProperty/CachedValue stuff
 
        internal static DependencyProperty RegisterProperty(
            string name, 
            Type propertyType, 
            Type ownerType,
            object defaultValue, 
            PropertyChangedCallback changed,
            ValidateValueCallback validate,
            bool isIndependentlyAnimated,
            CoerceValueCallback coerced) 
        {
            // Override metadata for this particular object type. This defines 
            // the methods that will be called when property actions (setting, 
            // getting, invalidating) are taken for this specific object type.
 
            UIPropertyMetadata propertyMetadata;

            // If this property is animated using a property resource, we create
            // AnimatablePropertyMetadata instead of UIPropertyMetadata. 

            if (isIndependentlyAnimated) 
            { 
                propertyMetadata = new IndependentlyAnimatedPropertyMetadata(defaultValue);
            } 
            else
            {
                propertyMetadata = new UIPropertyMetadata(defaultValue);
            } 

            propertyMetadata.PropertyChangedCallback = changed; 
 
            if (coerced != null)
            { 
                propertyMetadata.CoerceValueCallback = coerced;
            }

            // Register property with passed in default metadata.  The type of 
            // defaultMetadata will determine whether this property is animatable.
            DependencyProperty dp = DependencyProperty.Register( 
                name, 
                propertyType,
                ownerType, 
                propertyMetadata,
                validate);

            return dp; 
        }
 
        // Helpers for addref and release of local properties.  Subclasses can provide 
        // overloads.
        internal void AddRefResource(DUCE.IResource resource, DUCE.Channel channel) 
        {
            if (resource != null)
            {
                resource.AddRefOnChannel(channel); 
            }
        } 
 
        internal void ReleaseResource(DUCE.IResource resource, DUCE.Channel channel)
        { 
            if (resource != null)
            {
                resource.ReleaseOnChannel(channel);
            } 
        }
 
        #endregion LocalProperty/CachedValue stuff 

        #endregion 

        #region Protected

        ///  
        /// An Animatable will return false from this method if there are any Clocks
        /// animating any of its properties. If the Animatable has persistent animations 
        /// specified, but all of the Clocks have been removed, it may still return 
        /// true from this method if the Timelines themselves can be frozen.
        ///  
        /// 
        /// True if the Freezable should actually Freeze itself; false if
        /// the Freezable should simply return whether it can be frozen.
        /// True if this object can be frozen; otherwise false. 
        protected override bool FreezeCore(bool isChecking)
        { 
            if (IAnimatable_HasAnimatedProperties) 
            {
                if (TraceFreezable.IsEnabled) 
                {
                    TraceFreezable.Trace(
                        TraceEventType.Warning,
                        TraceFreezable.UnableToFreezeAnimatedProperties, 
                        this);
                } 
 
                return false;
            } 

            return base.FreezeCore(isChecking);
        }
 
        #endregion
 
        #region IResource 

        ///  
        /// Derived classes implement this function.
        /// 
        DUCE.ResourceHandle DUCE.IResource.AddRefOnChannel(DUCE.Channel channel)
        { 
            // Just return null instead of throwing an exception, since some
            // derived classes like BitmapEffect do their own addref/release. 
            return DUCE.ResourceHandle.Null; 
        }
 
        /// 
        /// Derived classes implement this function.
        /// 
        void DUCE.IResource.ReleaseOnChannel(DUCE.Channel channel) 
        {
            // Just return instead of throwing an exception, since some 
            // derived classes like BitmapEffect do their own addref/release. 
        }
 
        /// 
        /// Derived classes implement this function.
        /// 
        DUCE.ResourceHandle DUCE.IResource.GetHandle(DUCE.Channel channel) 
        {
            // Just return null instead of throwing an exception, since some 
            // derived classes like BitmapEffect do their own addref/release. 
            return DUCE.ResourceHandle.Null;
        } 

        /// 
        /// Derived classes implement this function.
        ///  
        int DUCE.IResource.GetChannelCount()
        { 
            return 0; 
        }
 
        /// 
        /// Derived classes implement this function.
        /// 
        DUCE.Channel DUCE.IResource.GetChannel(int index) 
        {
            return null; 
        } 

        ///  
        /// This is only implemented by Visual and Visual3D.
        /// 
        DUCE.ResourceHandle DUCE.IResource.Get3DHandle(DUCE.Channel channel)
        { 
            throw new NotImplementedException();
        } 
 
        /// 
        /// This is only implemented by Visual and Visual3D. 
        /// 
        void DUCE.IResource.RemoveChildFromParent(DUCE.IResource parent, DUCE.Channel channel)
        {
            throw new NotImplementedException(); 
        }
 
        #endregion 

 
        #region Internal


        internal DUCE.ResourceHandle GetAnimationResourceHandle(DependencyProperty dp, DUCE.Channel channel) 
        {
            if (channel != null && IAnimatable_HasAnimatedProperties) 
            { 
                return IndependentAnimationStorage.GetResourceHandle(this, dp, channel);
            } 
            else
            {
                return DUCE.ResourceHandle.Null;
            } 
        }
 
        ///  
        /// Returns a WeakReference to this Animatable that can be used by
        /// anyone who needs one. 
        /// 
        /// 
        /// The WeakReference isn't created or stored until this method is
        /// called. 
        /// 
        /// A WeakReference to this Animtable. 
        internal WeakReference GetWeakReference() 
        {
            object reference = StoredWeakReferenceField.GetValue(this); 

            if (reference == null)
            {
                reference = new WeakReference(this); 

                StoredWeakReferenceField.SetValue(this, (WeakReference)reference); 
            } 

            Debug.Assert(reference is WeakReference); 

            return (WeakReference)reference;
        }
 
        /// 
        /// IsBaseValueDefault returns true if there is no local value specified for this DP. 
        ///  
        /// The property for which the local value is checked.
        internal bool IsBaseValueDefault(DependencyProperty dp) 
        {
            return ReadLocalValue(dp) == DependencyProperty.UnsetValue;
        }
 
        /// 
        /// Every time something changes, we don't want to send resource 
        /// updates to the UCE, we only really want to do it once per UIThread 
        /// render.
        /// Calling this will make sure that a resource update request 
        /// is registered with the MediaContext.
        /// If this object doesn't have context affinity, it's unlikely
        /// that resource update requests would ever be made, however if they
        /// are the request will happen immediately. 
        /// 
        internal void RegisterForAsyncUpdateResource() 
        { 
            DUCE.IResource resource = this as DUCE.IResource;
 
            if (resource != null)
            {
                if ((Dispatcher != null) && Animatable_IsResourceInvalidationNecessary)
                { 
                    MediaContext mediaContext = MediaContext.From(Dispatcher);
 
                    // 
                    // Only register for a deferred resource update if this
                    // is actually on the channel. 
                    //
                    if (!resource.GetHandle(mediaContext.Channel).IsNull)
                    {
 
                        // Add this handler to this event means that the handler will be
                        // called on the next UIThread render for this Dispatcher. 
                        mediaContext.ResourcesUpdated += new MediaContext.ResourcesUpdatedHandler(UpdateResource); 
                        Animatable_IsResourceInvalidationNecessary = false;
                    } 
                }
            }
        }
 
        /// 
        /// UpdateResource - this implements the prototype required by ResourcesUpdatedHandler 
        /// The method which implements this prototype is also often called in situations where 
        /// the resource is known to be "on channel" - in those cases, "true" is passed for the second
        /// parameter (allowing the implementation to skip the check). 
        /// 
        internal virtual void UpdateResource(DUCE.Channel channel, bool skipOnChannelCheck)
        {
            Animatable_IsResourceInvalidationNecessary = true; 
        }
 
        ///  
        /// WritePreamble for objects such as AnimationCollection and
        /// TimelineCollection which modify an Animatable from the outside. 
        /// 
        internal void InternalWritePreamble()
        {
            WritePreamble(); 
        }
 
        #endregion 

        #region Private 

        /// 
        /// We use this property to store the a WeakReference to this Animatable
        /// that can be used by anyone who needs a WeakReference.  It won't be 
        /// created until its requested using the GetWeakReference method.
        ///  
        private static readonly UncommonField StoredWeakReferenceField 
            = new UncommonField();
 
        /// 
        /// This method is used by TypeDescriptor to determine if this property should
        /// be serialized.
        ///  
        [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
        public static bool ShouldSerializeStoredWeakReference(DependencyObject target) 
        { 
            return false;
        } 

        #endregion
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK