Exemplo n.º 1
0
 public void BeginAnimation(
     DependencyProperty dp, 
     AnimationTimeline animation, 
     HandoffBehavior handoffBehavior)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 2
0
        /// <summary>
        /// Starts the specified <paramref name="board"/> in the context of the specified
        /// <paramref name="element"/>.
        /// </summary>
        /// <remarks>
        /// Depending on the parameter <paramref name="handoffBehavior"/>, the new storyboard will
        /// be started when the last other storyboard, which occupies a conflicting property,
        /// has finished.
        /// </remarks>
        /// <param name="board">The storyboard to start.</param>
        /// <param name="element">Context element which will be used as
        /// <see cref="TimelineContext.VisualParent"/> for the new <paramref name="board"/>.</param>
        /// <param name="handoffBehavior">Controls how the new storyboard animation will be
        /// attached to already running animations, if there are conflicting properties animated
        /// by an already running anmiation an by the new <paramref name="board"/>.</param>
        public void StartStoryboard(Storyboard board, UIElement element,
                                    HandoffBehavior handoffBehavior)
        {
            lock (_syncObject)
            {
                AnimationContext context = new AnimationContext
                {
                    Timeline        = board,
                    TimelineContext = board.CreateTimelineContext(element)
                };

                IDictionary <IDataDescriptor, object> conflictingProperties;
                ICollection <AnimationContext>        conflictingAnimations;
                FindConflicts(context, out conflictingAnimations, out conflictingProperties);
                ExecuteHandoff(context, conflictingAnimations, handoffBehavior);

                try
                {
                    board.Setup(context.TimelineContext, conflictingProperties);

                    _scheduledAnimations.Add(context);
                    board.Start(context.TimelineContext, SkinContext.SystemTickCount);
                }
                catch (Exception ex)
                {
                    ServiceRegistration.Get <ILogger>().Error("Animator: Error initializing StoryBoard", ex);
                }

                // No animation here - has to be done in the Animate method
            }
        }
Exemplo n.º 3
0
 public void Begin(FrameworkElement containingObject,
                   FrameworkTemplate frameworkTemplate,
                   HandoffBehavior handoffBehavior,
                   bool isControllable)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 4
0
 public void ApplyAnimationClock(
     DependencyProperty dp, 
     AnimationClock clock, 
     HandoffBehavior handoffBehavior)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 5
0
        public static void AnimateDoubleCubicEase(this UIElement target, DependencyProperty propdp, double toVal, int ms, EasingMode ease,
                                                  HandoffBehavior handOff = HandoffBehavior.Compose, int begin = 0, EventHandler completed = null)
        {
            var anim = new DoubleAnimation(toVal, new Duration(TimeSpan.FromMilliseconds(ms)));

            switch (ease)
            {
            case EasingMode.EaseIn:
                anim.EasingFunction = App.CE_EaseIn;
                break;

            case EasingMode.EaseOut:
                anim.EasingFunction = App.CE_EaseOut;
                break;

            case EasingMode.EaseInOut:
                anim.EasingFunction = App.CE_EaseInOut;
                break;
            }
            if (begin > 0)
            {
                anim.BeginTime = TimeSpan.FromMilliseconds(begin);
            }
            if (completed != null)
            {
                anim.Completed += completed;
            }
            target.BeginAnimation(propdp, anim, handOff);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Registers the specified animation instance.
        /// </summary>
        /// <param name="animationInstance">The animation instance.</param>
        /// <param name="handoffBehavior">
        /// A value indicating how the new animations interact with existing ones.
        /// </param>
        /// <param name="previousInstance">
        /// Optional: The animation instance after which <paramref name="animationInstance"/> will be
        /// added in the animation composition chain. If set to <see langword="null"/>
        /// <paramref name="animationInstance"/> will be appended at the end of the composition chain.
        /// This parameter is only relevant when <paramref name="handoffBehavior"/> is
        /// <see cref="HandoffBehavior.Compose"/>.
        /// </param>
        /// <remarks>
        /// <para>
        /// This method adds the specified animation tree (<paramref name="animationInstance"/> and all
        /// of its children) to the animation system. The animation system will from now on
        /// automatically advance and update the animations.
        /// </para>
        /// <para>
        /// Adding and removing animation instances is usually controlled by
        /// <see cref="AnimationTransition"/> instances.
        /// </para>
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="animationInstance" /> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// Cannot add <paramref name="animationInstance"/> to animation system. The animation instance
        /// is already registered, or it is not a root instance.
        /// </exception>
        internal void Add(AnimationInstance animationInstance, HandoffBehavior handoffBehavior, AnimationInstance previousInstance)
        {
            if (animationInstance == null)
            {
                throw new ArgumentNullException("animationInstance");
            }
            if (_rootInstances.Contains(animationInstance))  // TODO: This is slow if there are many animation instances!
            {
                throw new ArgumentException("Cannot add animation instance to animation system. The animation instance is already registered.");
            }
            if (!animationInstance.IsRoot)
            {
                throw new ArgumentException("Cannot add animation instance to animation system because it is not a root instance. You need to disconnect the instance from its parent first.");
            }

            _rootInstances.Add(animationInstance);

            // Normally, the time is NaN and starts to run now. (Unless the user has set a custom
            // time value.)
            if (animationInstance.Time == null)
            {
                animationInstance.Time = TimeSpan.Zero;
            }

            animationInstance.AddToCompositionChains(this, handoffBehavior, previousInstance);
        }
Exemplo n.º 7
0
 public void Begin(FrameworkElement target, HandoffBehavior handoffBehavior)
 {
     NoesisGUI_PINVOKE.Storyboard_Begin__SWIG_3(swigCPtr, FrameworkElement.getCPtr(target), (int)handoffBehavior);
     if (NoesisGUI_PINVOKE.SWIGPendingException.Pending)
     {
         throw NoesisGUI_PINVOKE.SWIGPendingException.Retrieve();
     }
 }
Exemplo n.º 8
0
        /// <summary>
        /// Start animation.
        /// </summary>
        /// <param name="storyBoardName">Name of the story board.</param>
        /// <param name="handoffBehavior">HandoffBehavior.</param>
        private void _StartStoryBoardAtGrid(string storyBoardName, HandoffBehavior handoffBehavior)
        {
            // Find storyboard.
            Storyboard s = (Storyboard)this.FindResource(storyBoardName);

            // Start animation.
            stackPanel.BeginStoryboard(s, handoffBehavior);
        }
Exemplo n.º 9
0
 public void Begin(FrameworkElement target, FrameworkElement nameScope, HandoffBehavior handoffBehavior, bool isControllable)
 {
     NoesisGUI_PINVOKE.Storyboard_Begin__SWIG_8(swigCPtr, FrameworkElement.getCPtr(target), FrameworkElement.getCPtr(nameScope), (int)handoffBehavior, isControllable);
     if (NoesisGUI_PINVOKE.SWIGPendingException.Pending)
     {
         throw NoesisGUI_PINVOKE.SWIGPendingException.Retrieve();
     }
 }
Exemplo n.º 10
0
 public void Begin(FrameworkElement target, HandoffBehavior handoffBehavior, bool isControllable)
 {
     if (target == null)
     {
         throw new ArgumentNullException("target");
     }
     {
         NoesisGUI_PINVOKE.Storyboard_Begin__SWIG_4(swigCPtr, FrameworkElement.getCPtr(target), (int)handoffBehavior, isControllable);
     }
 }
Exemplo n.º 11
0
        public void StartStoryboard(Storyboard board, HandoffBehavior handoffBehavior)
        {
            Screen screen = Screen;

            if (screen == null)
            {
                return;
            }
            screen.Animator.StartStoryboard(board, this, handoffBehavior);
        }
Exemplo n.º 12
0
     public void Begin(FrameworkElement target, FrameworkElement nameScope, HandoffBehavior handoffBehavior)
     {
         NoesisGUI_PINVOKE.Storyboard_Begin__SWIG_7(swigCPtr, FrameworkElement.getCPtr(target), FrameworkElement.getCPtr(nameScope), (int)handoffBehavior);
 #if UNITY_EDITOR || NOESIS_API
         if (NoesisGUI_PINVOKE.SWIGPendingException.Pending)
         {
             throw NoesisGUI_PINVOKE.SWIGPendingException.Retrieve();
         }
 #endif
     }
Exemplo n.º 13
0
     public void Begin(FrameworkElement target, HandoffBehavior handoffBehavior, bool isControllable)
     {
         NoesisGUI_PINVOKE.Storyboard_Begin__SWIG_4(swigCPtr, FrameworkElement.getCPtr(target), (int)handoffBehavior, isControllable);
 #if UNITY_EDITOR || NOESIS_API
         if (NoesisGUI_PINVOKE.SWIGPendingException.Pending)
         {
             throw NoesisGUI_PINVOKE.SWIGPendingException.Retrieve();
         }
 #endif
     }
Exemplo n.º 14
0
        //public static void AnimateDoubleCubicEase(this Animatable target, DependencyProperty propdp, double toVal, int ms, EasingMode ease,
        //    HandoffBehavior handOff = HandoffBehavior.Compose, int begin = 0)
        //{
        //    var anim = new DoubleAnimation(toVal, new Duration(TimeSpan.FromMilliseconds(ms))) { EasingFunction = new CubicEase { EasingMode = ease } };
        //    if (begin > 0) anim.BeginTime = TimeSpan.FromMilliseconds(begin);
        //    target.BeginAnimation(propdp, anim, handOff);
        //}


        public static void AnimateBool(this UIElement target, DependencyProperty propdp, bool fromVal, bool toVal, int ms,
                                       HandoffBehavior handOff = HandoffBehavior.Compose)
        {
            var anim = new BooleanAnimationUsingKeyFrames();

            if (ms > 0)
            {
                anim.KeyFrames.Add(new DiscreteBooleanKeyFrame(fromVal, KeyTime.FromTimeSpan(TimeSpan.Zero)));
            }
            anim.KeyFrames.Add(new DiscreteBooleanKeyFrame(toVal, KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(ms))));
            target.BeginAnimation(propdp, anim, handOff);
        }
Exemplo n.º 15
0
 [FriendAccessAllowed] // Built into Core, also used by Framework.
 internal static bool IsDefined(HandoffBehavior handoffBehavior)
 {
     if (handoffBehavior < HandoffBehavior.SnapshotAndReplace ||
         handoffBehavior > HandoffBehavior.Compose)
     {
         return(false);
     }
     else
     {
         return(true);
     }
 }
Exemplo n.º 16
0
 [FriendAccessAllowed] // Built into Core, also used by Framework.
 internal static bool IsDefined( HandoffBehavior handoffBehavior ) 
 {
     if( handoffBehavior < HandoffBehavior.SnapshotAndReplace ||
         handoffBehavior > HandoffBehavior.Compose )
     { 
         return false;
     } 
     else 
     {
         return true; 
     }
 }
Exemplo n.º 17
0
 public void Begin(FrameworkElement target, FrameworkElement nameScope, HandoffBehavior handoffBehavior)
 {
     if (target == null)
     {
         throw new ArgumentNullException("target");
     }
     if (nameScope == null)
     {
         throw new ArgumentNullException("nameScope");
     }
     {
         NoesisGUI_PINVOKE.Storyboard_Begin__SWIG_7(swigCPtr, FrameworkElement.getCPtr(target), FrameworkElement.getCPtr(nameScope), (int)handoffBehavior);
     }
 }
Exemplo n.º 18
0
        public void Begin(FrameworkElement containingObject, INameScope nameScope = null, HandoffBehavior handoffBehavior = HandoffBehavior.SnapshotAndReplace, object layerOwner = null)
        {
            Stop(containingObject);

            TimelineClock clock = CreateClock();
            clock.Begin(((IAnimatable)containingObject).RootClock);

            clocks[containingObject] = clock;

            ListDictionary<TargetKey, AnimationTimelineClock> targets = GetAnimationClocksTargets(clock, containingObject, nameScope ?? NameScope.GetContainingNameScope(containingObject));
            foreach (TargetKey target in targets.GetKeys())
            {
                target.Target.ApplyAnimationClocks(target.TargetProperty, targets.GetValues(target), handoffBehavior, layerOwner);
            }
        }
Exemplo n.º 19
0
 internal static void ApplyAnimationClock(
     DependencyObject d,
     DependencyProperty dp,
     AnimationClock animationClock,
     HandoffBehavior handoffBehavior)
 {
     if (animationClock == null)
     {
         BeginAnimation(d, dp, null, handoffBehavior);
     }
     else
     {
         // Optimize to avoid allocation of potentially unneeded array.
         ApplyAnimationClocks(d, dp, new AnimationClock[] { animationClock }, handoffBehavior);
     }
 }
        internal static void ApplyAnimationClock(
            DependencyObject d,
            DependencyProperty dp,
            AnimationClock animationClock,
            HandoffBehavior handoffBehavior)
        {
            if (animationClock == null)
            {
                BeginAnimation(d, dp, null, handoffBehavior);
            }
            else
            {
                //

                ApplyAnimationClocks(d, dp, new AnimationClock[] { animationClock }, handoffBehavior);
            }
        }
Exemplo n.º 21
0
        /// <summary>
        /// Handles the handoff between conflicting animations.
        /// This method will, depending on the specified <paramref name="handoffBehavior"/>, stop conflicting
        /// animations (in case see cref="HandoffBehavior.SnapshotAndReplace"/>)
        /// or add them to the wait set for the given <paramref name="animationContext"/>
        /// (in case <see cref="HandoffBehavior.Compose"/>).
        /// The handoff behavior <see cref="HandoffBehavior.TemporaryReplace"/> will stop the conflicting
        /// animations, let the new animation run, and re-schedule the conflicting animations after the new animation.
        /// </summary>
        protected void ExecuteHandoff(AnimationContext animationContext, ICollection <AnimationContext> conflictingAnimations,
                                      HandoffBehavior handoffBehavior)
        {
            // Do the handoff depending on HandoffBehavior
            switch (handoffBehavior)
            {
            case HandoffBehavior.Compose:
                foreach (AnimationContext ac in conflictingAnimations)
                {
                    animationContext.WaitingFor.Add(ac);
                }
                break;

            case HandoffBehavior.TemporaryReplace:
                foreach (AnimationContext ac in conflictingAnimations)
                {
                    ac.WaitingFor.Add(animationContext);
                }
                break;

            case HandoffBehavior.SnapshotAndReplace:
                // Reset values of conflicting animations
                foreach (AnimationContext ac in conflictingAnimations)
                {
                    ResetAllValues(ac);
                }
                // And remove those values which are handled by the new animation -
                // avoids flickering
                IDictionary <IDataDescriptor, object> animProperties = new Dictionary <IDataDescriptor, object>();
                animationContext.Timeline.AddAllAnimatedProperties(animationContext.TimelineContext, animProperties);
                foreach (IDataDescriptor dd in animProperties.Keys)
                {
                    _valuesToSet.Remove(dd);
                }
                break;

            default:
                throw new NotImplementedException("Animator.HandleConflicts: HandoffBehavior '" + handoffBehavior + "' is not implemented");
            }
        }
Exemplo n.º 22
0
        /// <summary>
        /// Applies an AnimationClock to a DependencyProperty. The effect of
        /// the new AnimationClock on any current animations will be determined by
        /// the value of the handoffBehavior parameter.
        /// </summary>
        /// <param name="dp">
        /// The DependencyProperty to animate.
        /// </param>
        /// <param name="clock">
        /// The AnimationClock that will animate the property. If parameter is null
        /// then animations will be removed from the property if handoffBehavior is
        /// SnapshotAndReplace; otherwise the method call will have no result.
        /// </param>
        /// <param name="handoffBehavior">
        /// Determines how the new AnimationClock will transition from or
        /// affect any current animations on the property.
        /// </param>
        public void ApplyAnimationClock(
            DependencyProperty dp,
            AnimationClock clock,
            HandoffBehavior handoffBehavior)
        {
            if (dp == null)
            {
                throw new ArgumentNullException("dp");
            }

            if (!AnimationStorage.IsPropertyAnimatable(this, dp))
            {
        #pragma warning disable 56506 // Suppress presharp warning: Parameter 'dp' to this public method must be validated:  A null-dereference can occur here.
                throw new ArgumentException(SR.Get(SRID.Animation_DependencyPropertyIsNotAnimatable, dp.Name, this.GetType()), "dp");
        #pragma warning restore 56506
            }

            if (clock != null
                && !AnimationStorage.IsAnimationValid(dp, clock.Timeline))
            {
        #pragma warning disable 56506 // Suppress presharp warning: Parameter 'dp' to this public method must be validated:  A null-dereference can occur here.
                throw new ArgumentException(SR.Get(SRID.Animation_AnimationTimelineTypeMismatch, clock.Timeline.GetType(), dp.Name, dp.PropertyType), "clock");
        #pragma warning restore 56506
            }

            if (!HandoffBehaviorEnum.IsDefined(handoffBehavior))
            {
                throw new ArgumentException(SR.Get(SRID.Animation_UnrecognizedHandoffBehavior));
            }

            if (IsSealed)
            {
                throw new InvalidOperationException(SR.Get(SRID.IAnimatable_CantAnimateSealedDO, dp, this.GetType()));
            }                    

            AnimationStorage.ApplyAnimationClock(this, dp, clock, handoffBehavior);
        }
Exemplo n.º 23
0
        /// <summary>
        /// Applies an AnimationClock to a DependencyProperty. The effect of
        /// the new AnimationClock on any current animations will be determined by
        /// the value of the handoffBehavior parameter.
        /// </summary>
        /// <param name="dp">
        /// The DependencyProperty to animate.
        /// </param>
        /// <param name="clock">
        /// The AnimationClock that will animate the property. If parameter is null
        /// then animations will be removed from the property if handoffBehavior is
        /// SnapshotAndReplace; otherwise the method call will have no result.
        /// </param>
        /// <param name="handoffBehavior">
        /// Determines how the new AnimationClock will transition from or
        /// affect any current animations on the property.
        /// </param>
        public void ApplyAnimationClock(
            DependencyProperty dp,
            AnimationClock clock,
            HandoffBehavior handoffBehavior)
        {
            if (dp == null)
            {
                throw new ArgumentNullException("dp");
            }

            if (!AnimationStorage.IsPropertyAnimatable(this, dp))
            {
        #pragma warning disable 56506 // Suppress presharp warning: Parameter 'dp' to this public method must be validated:  A null-dereference can occur here.
                throw new ArgumentException(SR.Get(SRID.Animation_DependencyPropertyIsNotAnimatable, dp.Name, this.GetType()), "dp");
        #pragma warning restore 56506
            }

            if (clock != null &&
                !AnimationStorage.IsAnimationValid(dp, clock.Timeline))
            {
        #pragma warning disable 56506 // Suppress presharp warning: Parameter 'dp' to this public method must be validated:  A null-dereference can occur here.
                throw new ArgumentException(SR.Get(SRID.Animation_AnimationTimelineTypeMismatch, clock.Timeline.GetType(), dp.Name, dp.PropertyType), "clock");
        #pragma warning restore 56506
            }

            if (!HandoffBehaviorEnum.IsDefined(handoffBehavior))
            {
                throw new ArgumentException(SR.Get(SRID.Animation_UnrecognizedHandoffBehavior));
            }

            if (IsSealed)
            {
                throw new InvalidOperationException(SR.Get(SRID.IAnimatable_CantAnimateSealedDO, dp, this.GetType()));
            }

            AnimationStorage.ApplyAnimationClock(this, dp, clock, handoffBehavior);
        }
Exemplo n.º 24
0
        /// <summary>
        /// Starts the specified <paramref name="board"/> in the context of the specified
        /// <paramref name="element"/>.
        /// </summary>
        /// <remarks>
        /// Depending on the parameter <paramref name="handoffBehavior"/>, the new storyboard will
        /// be started when the last other storyboard, which occupies a conflicting property,
        /// has finished.
        /// </remarks>
        /// <param name="board">The storyboard to start.</param>
        /// <param name="element">Context element which will be used as
        /// <see cref="TimelineContext.VisualParent"/> for the new <paramref name="board"/>.</param>
        /// <param name="handoffBehavior">Controls how the new storyboard animation will be
        /// attached to already running animations, if there are conflicting properties animated
        /// by an already running anmiation an by the new <paramref name="board"/>.</param>
        public void StartStoryboard(Storyboard board, UIElement element,
                                    HandoffBehavior handoffBehavior)
        {
            lock (_syncObject)
            {
                AnimationContext context = new AnimationContext
                {
                    Timeline        = board,
                    TimelineContext = board.CreateTimelineContext(element)
                };

                IDictionary <IDataDescriptor, object> conflictingProperties;
                ICollection <AnimationContext>        conflictingAnimations;
                FindConflicts(context, out conflictingAnimations, out conflictingProperties);
                ExecuteHandoff(context, conflictingAnimations, handoffBehavior);

                board.Setup(context.TimelineContext, conflictingProperties);

                _scheduledAnimations.Add(context);
                board.Start(context.TimelineContext, SkinContext.SystemTickCount);

                // No animation here - has to be done in the Animate method
            }
        }
Exemplo n.º 25
0
 public void StartStoryboard(Storyboard board, HandoffBehavior handoffBehavior)
 {
   Screen screen = Screen;
   if (screen == null)
     return;
   screen.Animator.StartStoryboard(board, this, handoffBehavior);
 }
 public void ApplyAnimationClock(System.Windows.DependencyProperty dp, AnimationClock clock, HandoffBehavior handoffBehavior)
 {
 }
        internal static void ApplyAnimationClock(
            DependencyObject d,
            DependencyProperty dp,
            AnimationClock animationClock,
            HandoffBehavior handoffBehavior)
        {
            if (animationClock == null)
            {
                BeginAnimation(d, dp, null, handoffBehavior);
            }
            else
            {
                // 

                ApplyAnimationClocks(d, dp, new AnimationClock[] { animationClock }, handoffBehavior);
            }
        }
Exemplo n.º 28
0
        /// <summary>
        ///     Begins the given Storyboard as a Storyboard with the given handoff
        /// policy, and with the specified state for controllability. 
        /// </summary>
        public void BeginStoryboard(Storyboard storyboard, HandoffBehavior handoffBehavior, bool isControllable) 
        { 
            if( storyboard == null )
            { 
                throw new ArgumentNullException("storyboard");
            }

            // Storyboard.Begin is a public API and needs to be validating handoffBehavior anyway. 

            storyboard.Begin( this, handoffBehavior, isControllable ); 
        } 
        internal static void ApplyAnimationClocksToLayer(
            DependencyObject d,
            DependencyProperty dp,
            IList<AnimationClock> animationClocks,
            HandoffBehavior handoffBehavior,
            Int64 propertyTriggerLayerIndex)
        {
            if( propertyTriggerLayerIndex == 1 )
            {
                // Layer 1 is a special layer, where it gets treated as if there
                //  was no layer specification at all.
                ApplyAnimationClocks( d, dp, animationClocks, handoffBehavior );
                return;
            }

            Debug.Assert(animationClocks != null);
            Debug.Assert(!animationClocks.Contains(null));

            Debug.Assert(HandoffBehaviorEnum.IsDefined(handoffBehavior),
                "Public API caller of this internal method is responsible for validating that the HandoffBehavior value is valid.");

            AnimationStorage storage = GetStorage(d, dp);

            if (storage == null)
            {
                storage = CreateStorage(d, dp);
            }

            SortedList<Int64, AnimationLayer> propertyTriggerLayers = storage._propertyTriggerLayers;

            if (propertyTriggerLayers == null)
            {
                propertyTriggerLayers = new SortedList<Int64, AnimationLayer>(1);
                storage._propertyTriggerLayers = propertyTriggerLayers;
            }

            AnimationLayer layer;

            if (propertyTriggerLayers.ContainsKey(propertyTriggerLayerIndex))
            {
                layer = propertyTriggerLayers[propertyTriggerLayerIndex];
            }
            else
            {
                layer = new AnimationLayer(storage);

                propertyTriggerLayers[propertyTriggerLayerIndex] = layer;
            }

            object defaultDestinationValue = DependencyProperty.UnsetValue;

            if (handoffBehavior == HandoffBehavior.SnapshotAndReplace)
            {
                // 
                defaultDestinationValue = ((IAnimatable)d).GetAnimationBaseValue(dp);

                int count = propertyTriggerLayers.Count;

                if (count > 1)
                {
                    IList<Int64> keys = propertyTriggerLayers.Keys;

                    for (int i = 0; i < count && keys[i] < propertyTriggerLayerIndex; i++)
                    {
                        AnimationLayer currentLayer;

                        propertyTriggerLayers.TryGetValue(keys[i], out currentLayer);

                        defaultDestinationValue = currentLayer.GetCurrentValue(defaultDestinationValue);
                    }
                }
            }

            layer.ApplyAnimationClocks(
                animationClocks,
                handoffBehavior,
                defaultDestinationValue);

            storage.WritePostscript();
        }
Exemplo n.º 30
0
 public void BeginStoryboard(Storyboard storyboard, HandoffBehavior handoffBehavior);
Exemplo n.º 31
0
 public void Begin(System.Windows.FrameworkElement containingObject, System.Windows.FrameworkTemplate frameworkTemplate, HandoffBehavior handoffBehavior)
 {
 }
Exemplo n.º 32
0
        internal void ApplyAnimationClocks(
            IList<AnimationClock> newAnimationClocks,
            HandoffBehavior handoffBehavior,
            object defaultDestinationValue)
        {
            Debug.Assert(
                newAnimationClocks == null
                || (newAnimationClocks.Count > 0
                    && !newAnimationClocks.Contains(null)));

            if (handoffBehavior == HandoffBehavior.SnapshotAndReplace)
            {
                Debug.Assert(defaultDestinationValue != DependencyProperty.UnsetValue,
                    "We need a valid default destination value when peforming a snapshot and replace.");

                EventHandler handler = new EventHandler(OnCurrentStateInvalidated);

                // If we have a sticky snapshot value, the clock that would have
                // unstuck it is being replaced, so we need to remove our event
                // handler from that clock.
                if (_hasStickySnapshotValue)
                {
                    _animationClocks[0].CurrentStateInvalidated -= handler;

                    DetachAnimationClocks();
                }
                // Otherwise if we have at least one clock take a new snapshot
                // value.
                else if (_animationClocks != null)
                {
                    _snapshotValue = GetCurrentValue(defaultDestinationValue);

                    DetachAnimationClocks();
                }
                // Otherwise we can use the defaultDestinationValue as the
                // new snapshot value.
                else
                {
                    _snapshotValue = defaultDestinationValue;
                }

                // If we have a new clock in a stopped state, then the snapshot 
                // value will be sticky.
                if (newAnimationClocks != null
                    && newAnimationClocks[0].CurrentState == ClockState.Stopped)
                {
                    _hasStickySnapshotValue = true;
                    newAnimationClocks[0].CurrentStateInvalidated += handler;
                }
                // Otherwise it won't be sticky.
                else
                {
                    _hasStickySnapshotValue = false;
                }

                SetAnimationClocks(newAnimationClocks);
            }
            else
            {
                Debug.Assert(handoffBehavior == HandoffBehavior.Compose,
                    "Unhandled handoffBehavior value.");
                Debug.Assert(defaultDestinationValue == DependencyProperty.UnsetValue,
                    "We shouldn't take the time to calculate a default destination value when it isn't needed.");

                if (newAnimationClocks == null)
                {
                    return;
                }
                else if (_animationClocks == null)
                {
                    SetAnimationClocks(newAnimationClocks);
                }
                else
                {
                    AppendAnimationClocks(newAnimationClocks);
                }
            }
        }
Exemplo n.º 33
0
		public void ApplyAnimationClock (DependencyProperty dp, AnimationClock clock, HandoffBehavior handoffBehavior)
		{
			throw new NotImplementedException ();
		}
Exemplo n.º 34
0
    /// <summary>
    /// Starts the specified <paramref name="board"/> in the context of the specified
    /// <paramref name="element"/>.
    /// </summary>
    /// <remarks>
    /// Depending on the parameter <paramref name="handoffBehavior"/>, the new storyboard will
    /// be started when the last other storyboard, which occupies a conflicting property,
    /// has finished.
    /// </remarks>
    /// <param name="board">The storyboard to start.</param>
    /// <param name="element">Context element which will be used as
    /// <see cref="TimelineContext.VisualParent"/> for the new <paramref name="board"/>.</param>
    /// <param name="handoffBehavior">Controls how the new storyboard animation will be
    /// attached to already running animations, if there are conflicting properties animated
    /// by an already running anmiation an by the new <paramref name="board"/>.</param>
    public void StartStoryboard(Storyboard board, UIElement element,
        HandoffBehavior handoffBehavior)
    {
      lock (_syncObject)
      {
        AnimationContext context = new AnimationContext
          {
              Timeline = board,
              TimelineContext = board.CreateTimelineContext(element)
          };

        IDictionary<IDataDescriptor, object> conflictingProperties;
        ICollection<AnimationContext> conflictingAnimations;
        FindConflicts(context, out conflictingAnimations, out conflictingProperties);
        ExecuteHandoff(context, conflictingAnimations, handoffBehavior);

        try
        {
          board.Setup(context.TimelineContext, conflictingProperties);

          _scheduledAnimations.Add(context);
          board.Start(context.TimelineContext, SkinContext.SystemTickCount);
        }
        catch (Exception ex)
        {
          ServiceRegistration.Get<ILogger>().Error("Animator: Error initializing StoryBoard", ex);
        }

        // No animation here - has to be done in the Animate method
      }
    }
Exemplo n.º 35
0
 /// <summary>
 ///     Begins all ControlTemplate animations underneath this storyboard, clock tree starts at the given Control.
 /// </summary>
 public void Begin( FrameworkElement containingObject, FrameworkTemplate frameworkTemplate, HandoffBehavior handoffBehavior, bool isControllable )
 {
     BeginCommon(containingObject, frameworkTemplate, handoffBehavior, isControllable, Storyboard.Layers.Code );
 }
Exemplo n.º 36
0
 /// <summary>
 ///     Begins all ControlTemplate animations underneath this storyboard, clock tree starts at the given Control.
 /// </summary>
 public void Begin( FrameworkElement containingObject, FrameworkTemplate frameworkTemplate, HandoffBehavior handoffBehavior )
 {
     Begin( containingObject, frameworkTemplate, handoffBehavior, false );
 }
Exemplo n.º 37
0
		public void BeginAnimation (DependencyProperty dp, AnimationTimeline animation, HandoffBehavior handoffBehavior)
		{
			throw new NotImplementedException ();
		}
 public void ApplyAnimationClock(DependencyProperty dp, AnimationClock clock, HandoffBehavior handoffBehavior);
Exemplo n.º 39
0
 public void BeginStoryboard(Storyboard storyboard, HandoffBehavior handoffBehavior, bool isControllable);
Exemplo n.º 40
0
    /// <summary>
    ///     Takes the built up mapping table for animation clocks and applies
    /// them to the specified property on the specified object.
    /// </summary>
    private static void ApplyAnimationClocks( HybridDictionary clockMappings, HandoffBehavior handoffBehavior, Int64 layer )
    {
        foreach( DictionaryEntry entry in clockMappings )
        {
            ObjectPropertyPair key = (ObjectPropertyPair)entry.Key;
            object value = entry.Value;
            List<AnimationClock> clockList;

            Debug.Assert( value is AnimationClock || value is List<AnimationClock> ,
                "Internal error - clockMappings table contains unexpected object of type" + value.GetType() );

            if( value is AnimationClock )
            {
                clockList = new List<AnimationClock>(1);
                clockList.Add((AnimationClock)value);
            }
            else // if( value is List<AnimationClock> )
            {
                clockList = (List<AnimationClock>)value;
            }

            AnimationStorage.ApplyAnimationClocksToLayer(
                key.DependencyObject,
                key.DependencyProperty,
                clockList,
                handoffBehavior,
                layer);
        }
    }
        internal static void BeginAnimation(
            DependencyObject d,
            DependencyProperty dp,
            AnimationTimeline animation,
            HandoffBehavior handoffBehavior)
        {
            // Caller should be validating animation.
            Debug.Assert(animation == null || IsAnimationValid(dp, animation));
            Debug.Assert(IsPropertyAnimatable(d, dp));

            Debug.Assert(HandoffBehaviorEnum.IsDefined(handoffBehavior),
                "Public API caller of this internal method is responsible for validating that the HandoffBehavior value is valid." );

            AnimationStorage storage = GetStorage(d, dp);

            if (animation == null)
            {
                if (   storage == null
                    || handoffBehavior == HandoffBehavior.Compose)
                {
                    // Composing with a null animation is a no-op.
                    return;
                }
                else
                {
                    // When the incoming animation is passed in as null and
                    // handoffBehavior == HandoffBehavior.SnapshotAndReplace it means
                    // that we should stop any and all animation behavior for
                    // this property.
                    if (storage._hasStickySnapshotValue)
                    {
                        storage._hasStickySnapshotValue = false;
                        storage._animationClocks[0].CurrentStateInvalidated -= new EventHandler(storage.OnCurrentStateInvalidated);
                    }

                    storage._snapshotValue = DependencyProperty.UnsetValue;
                    storage.ClearAnimations();
                }
            }
            else if (animation.BeginTime.HasValue)
            {
                // We have an animation
                AnimationClock animationClock;
                animationClock = animation.CreateClock();  // note that CreateClock also calls InternalBeginIn

                ApplyAnimationClocks(d, dp, new AnimationClock[] { animationClock }, handoffBehavior);

                // ApplyAnimationClocks has fixed up the storage and called
                // WritePostscript already so we can just return.
                return;
            }
            else if (storage == null)
            {
                //  The user gave us an animation with a BeginTime of null which
                // means snapshot the current value and throw away all animations
                // for SnapshotAndReplace and means nothing for Compose.
                //  But since we don't have any animations the current we don't
                // have to do anything for either of these cases.

                return;
            }
            else if (handoffBehavior == HandoffBehavior.SnapshotAndReplace)
            {
                // This block handles the case where the user has called
                // BeginAnimation with an animation that has a null begin time.
                // We handle this by taking a snapshot value and throwing
                // out the animation, which is the same as keeping it because
                // we know it will never start.
                //
                // If the handoffBehavior is Compose, we ignore the user's call
                // because it wouldn't mean anything unless they were planning
                // on changing the BeginTime of their animation later, which we
                // don't support.

                // If _hasStickySnapshotValue is set, unset it and remove our
                // event handler from the clock. The current snapshot value
                // will still be used.
                if (storage._hasStickySnapshotValue)
                {
                    Debug.Assert(storage._animationClocks != null && storage._animationClocks.Count > 0,
                        "If _hasStickySnapshotValue is set we should have at least one animation clock stored in the AnimationStorage.");

                    storage._hasStickySnapshotValue = false;
                    storage._animationClocks[0].CurrentStateInvalidated -= new EventHandler(storage.OnCurrentStateInvalidated);
                }
                // Otherwise take a new snapshot value.
                else
                {
                    storage._snapshotValue = d.GetValue(dp);
                }

                storage.ClearAnimations();
            }

            // If storage were null we would have returned already.
            storage.WritePostscript();
        }
Exemplo n.º 42
0
    /// <summary>
    ///     For complex property paths, we need to dig our way down to the
    /// property and attach the animation clock there.  We will not be able to
    /// actually attach the clocks if the targetProperty points to a frozen
    /// Freezable.  More extensive handling will be required for that case.
    /// </summary>
    private void ProcessComplexPath( HybridDictionary clockMappings, DependencyObject targetObject,
        PropertyPath path, AnimationClock animationClock, HandoffBehavior handoffBehavior, Int64 layer )
    {
        Debug.Assert(path.Length > 1, "This method shouldn't even be called for a simple property path.");

        // For complex paths, the target object/property differs from the actual
        //  animated object/property.
        //
        // Example:
        //  TargetName="Rect1" TargetProperty="(Rectangle.LayoutTransform).(RotateTransform.Angle)"
        //
        // The target object is a Rectangle.
        // The target property is LayoutTransform.
        // The animated object is a RotateTransform
        // The animated property is Angle.

        // Currently unsolved problem: If the LayoutTransform is not a RotateTransform,
        //  we have no way of knowing.  We'll merrily set up to animate the Angle
        //  property as an attached property, not knowing that the value will be
        //  completely ignored.

        DependencyProperty targetProperty   = path.GetAccessor(0) as DependencyProperty;

        // Two different ways to deal with property paths.  If the target is
        //  on a frozen Freezable, we'll have to make a clone of the value and
        //  attach the animation on the clone instead.
        // For all other objects, we attach the animation clock directly on the
        //  specified animating object and property.
        object targetPropertyValue = targetObject.GetValue(targetProperty);

        DependencyObject   animatedObject   = path.LastItem as DependencyObject;
        DependencyProperty animatedProperty = path.LastAccessor as DependencyProperty;

        if( animatedObject == null ||
            animatedProperty == null ||
            targetProperty == null )
        {
            throw new InvalidOperationException(SR.Get(SRID.Storyboard_PropertyPathUnresolved, path.Path));
        }

        VerifyAnimationIsValid(animatedProperty, animationClock);

        if( PropertyCloningRequired( targetPropertyValue ) )
        {
            // Verify that property paths are supported for the specified
            //  object and property.  If the property value query (usually in
            //  GetValueCore) doesn't call into Storyboard code, then none of this
            //  will have any effect.  (Silently do nothing.)
            // Throwing here is for user's sake to alert that nothing will happen.
            VerifyComplexPathSupport( targetObject );

            // We need to clone the value of the target, and from here onwards
            //  try to pretend that it is the actual value.
            Debug.Assert(targetPropertyValue is Freezable, "We shouldn't be trying to clone a type we don't understand.  PropertyCloningRequired() has improperly flagged the current value as 'need to clone'.");

            // To enable animations on frozen Freezable objects, complex
            //  path processing is done on a clone of the value.
            Freezable clone = ((Freezable)targetPropertyValue).Clone();
            SetComplexPathClone( targetObject, targetProperty, targetPropertyValue, clone );

            // Promote the clone to the EffectiveValues cache
            targetObject.InvalidateProperty(targetProperty);

            // We're supposed to have the animatable clone in place by now.  But if
            //  things went sour for whatever reason, halt the app instead of corrupting
            //  the frozen object.
            if( targetObject.GetValue(targetProperty) != clone )
            {
                throw new InvalidOperationException(SR.Get(SRID.Storyboard_ImmutableTargetNotSupported, path.Path));
            }

            // Now that we have a clone, update the animatedObject and animatedProperty
            //  with references to those on the clone.
            using(path.SetContext(targetObject))
            {
                animatedObject = path.LastItem as DependencyObject;
                animatedProperty = path.LastAccessor as DependencyProperty;
            }

            // And set up to listen to changes on this clone.
            ChangeListener.ListenToChangesOnFreezable(
                targetObject, clone, targetProperty, (Freezable)targetPropertyValue );
        }

        // Apply animation clock on the animated object/animated property.
        ObjectPropertyPair directApplyTarget = new ObjectPropertyPair( animatedObject, animatedProperty );
        UpdateMappings( clockMappings, directApplyTarget, animationClock );
    }
Exemplo n.º 43
0
 /// <summary>
 ///     Begins the given Storyboard as a non-controllable Storyboard but
 /// with the given handoff policy. 
 /// </summary>
 public void BeginStoryboard(Storyboard storyboard, HandoffBehavior handoffBehavior) 
 { 
     BeginStoryboard(storyboard, handoffBehavior, false);
 } 
Exemplo n.º 44
0
        public static void ApplyAnimationClock(this IAnimatable animatable, DependencyProperty dependencyProperty, AnimationTimelineClock animationClock, HandoffBehavior handoffBehavior = HandoffBehavior.SnapshotAndReplace, object layerOwner = null)
        {
            IEnumerable <AnimationTimelineClock> animationClocks = animationClock != null ? new[] { animationClock } : new AnimationTimelineClock[0];

            animatable.ApplyAnimationClocks(dependencyProperty, animationClocks, handoffBehavior, layerOwner);
        }
        [FriendAccessAllowed] // Built into Core, also used by Framework.
        internal static void ApplyAnimationClocks(
            DependencyObject d,
            DependencyProperty dp,
            IList<AnimationClock> animationClocks,
            HandoffBehavior handoffBehavior)
        {
            Debug.Assert(animationClocks != null,
                "The animationClocks parameter should not be passed in as null.");
            Debug.Assert(animationClocks.Count > 0,
                "The animationClocks parameter should contain at least one clock.");
            Debug.Assert(!animationClocks.Contains(null),
                "The animationClocks parameter should not contain a null entry.");
            Debug.Assert(HandoffBehaviorEnum.IsDefined(handoffBehavior),
                "Public API caller of this internal method is responsible for validating that the HandoffBehavior value is valid." );

            AnimationStorage storage = GetStorage(d, dp);

            // handoffBehavior is SnapshotAndReplace or the situation is such
            // that it is the equivalent because we have nothing to compose
            // with.
            if (   handoffBehavior == HandoffBehavior.SnapshotAndReplace
                || storage == null
                || storage._animationClocks == null)
            {
                if (storage != null)
                {
                    EventHandler handler = new EventHandler(storage.OnCurrentStateInvalidated);

                    // If we have a sticky snapshot value, the clock that would have
                    // unstuck it is being replaced, so we need to remove our event
                    // handler from that clock.
                    if (storage._hasStickySnapshotValue)
                    {
                        storage._animationClocks[0].CurrentStateInvalidated -= handler;
                    }
                    // Calculate a snapshot value if we don't already have one
                    // since the last tick.
                    else
                    {
                        storage._snapshotValue = d.GetValue(dp);
                    }

                    // If we have a new clock in a stopped state, then the snapshot
                    // value will be sticky.
                    if (animationClocks[0].CurrentState == ClockState.Stopped)
                    {
                        storage._hasStickySnapshotValue = true;
                        animationClocks[0].CurrentStateInvalidated += new EventHandler(storage.OnCurrentStateInvalidated);
                    }
                    // Otherwise it won't be sticky.
                    else
                    {
                        storage._hasStickySnapshotValue = false;
                    }

                    storage.ClearAnimations();
                }
                else
                {
                    storage = CreateStorage(d, dp);
                }

                // Add and attach new animation.
                storage._animationClocks = new FrugalObjectList<AnimationClock>(animationClocks.Count);

                for (int i = 0; i < animationClocks.Count; i++)
                {
                    Debug.Assert(animationClocks[i] != null);

                    storage._animationClocks.Add(animationClocks[i]);
                    storage.AttachAnimationClock(animationClocks[i], storage._removeRequestedHandler);
                }
            }
            else
            {
                Debug.Assert(handoffBehavior == HandoffBehavior.Compose);
                Debug.Assert(storage != null);
                Debug.Assert(storage._animationClocks != null);

                FrugalObjectList<AnimationClock> newClockCollection = new FrugalObjectList<AnimationClock>(storage._animationClocks.Count + animationClocks.Count);

                for (int i = 0; i < storage._animationClocks.Count; i++)
                {
                    newClockCollection.Add(storage._animationClocks[i]);
                }

                storage._animationClocks = newClockCollection;

                for (int i = 0; i < animationClocks.Count; i++)
                {
                    newClockCollection.Add(animationClocks[i]);
                    storage.AttachAnimationClock(animationClocks[i], storage._removeRequestedHandler);
                }
            }

            storage.WritePostscript();
        }
Exemplo n.º 46
0
 public static void ApplyAnimationClocks(this IAnimatable animatable, DependencyProperty dependencyProperty, IEnumerable <AnimationTimelineClock> animationClocks, HandoffBehavior handoffBehavior = HandoffBehavior.SnapshotAndReplace, object layerOwner = null)
 {
     if (handoffBehavior == HandoffBehavior.SnapshotAndReplace)
     {
         animatable.SetAnimationClocks(dependencyProperty, animationClocks, layerOwner);
     }
     else
     {
         animatable.AddAnimationClocks(dependencyProperty, animationClocks, layerOwner);
     }
 }
Exemplo n.º 47
0
        public static void BeginAnimation(this IAnimatable animatable, DependencyProperty dependencyProperty, AnimationTimeline animation, HandoffBehavior handoffBehavior = HandoffBehavior.SnapshotAndReplace, object layerOwner = null)
        {
            AnimationTimelineClock animationClock = (AnimationTimelineClock)animation.CreateClock();

            animatable.ApplyAnimationClock(dependencyProperty, animationClock, handoffBehavior, layerOwner);
            animationClock.Begin(animatable.RootClock);
        }
Exemplo n.º 48
0
 public void Begin(FrameworkElement containingObject,
                   HandoffBehavior handoffBehavior)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 49
0
 public void BeginStoryboard(Storyboard storyboard, HandoffBehavior handoffBehavior, bool isControllable)
 {
     if (storyboard == null)
     throw new ArgumentNullException("storyboard");
       storyboard.Begin(this, handoffBehavior, isControllable);
 }
Exemplo n.º 50
0
 public void Begin(System.Windows.FrameworkContentElement containingObject, HandoffBehavior handoffBehavior)
 {
 }
 public void BeginAnimation(System.Windows.DependencyProperty dp, AnimationTimeline animation, HandoffBehavior handoffBehavior)
 {
 }
Exemplo n.º 52
0
 public void Begin(System.Windows.FrameworkElement containingObject, HandoffBehavior handoffBehavior, bool isControllable)
 {
 }
Exemplo n.º 53
0
 /// <summary>
 ///     Begins all animations underneath this storyboard, clock tree starts at the given containing object.
 /// </summary>
 public void Begin( FrameworkContentElement containingObject, HandoffBehavior handoffBehavior )
 {
     Begin( containingObject, handoffBehavior, false );
 }
 public void BeginAnimation(DependencyProperty dp, AnimationTimeline animation, HandoffBehavior handoffBehavior);
Exemplo n.º 55
0
 /// <summary>
 /// Handles the handoff between conflicting animations.
 /// This method will, depending on the specified <paramref name="handoffBehavior"/>, stop conflicting
 /// animations (in case see cref="HandoffBehavior.SnapshotAndReplace"/>)
 /// or add them to the wait set for the given <paramref name="animationContext"/>
 /// (in case <see cref="HandoffBehavior.Compose"/>).
 /// The handoff behavior <see cref="HandoffBehavior.TemporaryReplace"/> will stop the conflicting
 /// animations, let the new animation run, and re-schedule the conflicting animations after the new animation.
 /// </summary>
 protected void ExecuteHandoff(AnimationContext animationContext, ICollection<AnimationContext> conflictingAnimations,
     HandoffBehavior handoffBehavior)
 {
   // Do the handoff depending on HandoffBehavior
   switch (handoffBehavior)
   {
     case HandoffBehavior.Compose:
       foreach (AnimationContext ac in conflictingAnimations)
         animationContext.WaitingFor.Add(ac);
       break;
     case HandoffBehavior.TemporaryReplace:
       foreach (AnimationContext ac in conflictingAnimations)
         ac.WaitingFor.Add(animationContext);
       break;
     case HandoffBehavior.SnapshotAndReplace:
       // Reset values of conflicting animations
       foreach (AnimationContext ac in conflictingAnimations)
         ResetAllValues(ac);
       // And remove those values which are handled by the new animation -
       // avoids flickering
       IDictionary<IDataDescriptor, object> animProperties = new Dictionary<IDataDescriptor, object>();
       animationContext.Timeline.AddAllAnimatedProperties(animationContext.TimelineContext, animProperties);
       foreach (IDataDescriptor dd in animProperties.Keys)
         _valuesToSet.Remove(dd);
       break;
     default:
       throw new NotImplementedException("Animator.HandleConflicts: HandoffBehavior '" + handoffBehavior + "' is not implemented");
   }
 }
Exemplo n.º 56
0
 /// <summary>
 ///     Begins all animations underneath this storyboard, clock tree starts at the given containing object.
 /// </summary>
 public void Begin( FrameworkContentElement containingObject, HandoffBehavior handoffBehavior, bool isControllable )
 {
     BeginCommon(containingObject, null, handoffBehavior, isControllable, Storyboard.Layers.Code );
 }
Exemplo n.º 57
0
        internal void ApplyAnimationClocks(
            IList <AnimationClock> newAnimationClocks,
            HandoffBehavior handoffBehavior,
            object defaultDestinationValue)
        {
            Debug.Assert(
                newAnimationClocks == null ||
                (newAnimationClocks.Count > 0 &&
                 !newAnimationClocks.Contains(null)));

            if (handoffBehavior == HandoffBehavior.SnapshotAndReplace)
            {
                Debug.Assert(defaultDestinationValue != DependencyProperty.UnsetValue,
                             "We need a valid default destination value when peforming a snapshot and replace.");

                EventHandler handler = new EventHandler(OnCurrentStateInvalidated);

                // If we have a sticky snapshot value, the clock that would have
                // unstuck it is being replaced, so we need to remove our event
                // handler from that clock.
                if (_hasStickySnapshotValue)
                {
                    _animationClocks[0].CurrentStateInvalidated -= handler;

                    DetachAnimationClocks();
                }
                // Otherwise if we have at least one clock take a new snapshot
                // value.
                else if (_animationClocks != null)
                {
                    _snapshotValue = GetCurrentValue(defaultDestinationValue);

                    DetachAnimationClocks();
                }
                // Otherwise we can use the defaultDestinationValue as the
                // new snapshot value.
                else
                {
                    _snapshotValue = defaultDestinationValue;
                }

                // If we have a new clock in a stopped state, then the snapshot
                // value will be sticky.
                if (newAnimationClocks != null &&
                    newAnimationClocks[0].CurrentState == ClockState.Stopped)
                {
                    _hasStickySnapshotValue = true;
                    newAnimationClocks[0].CurrentStateInvalidated += handler;
                }
                // Otherwise it won't be sticky.
                else
                {
                    _hasStickySnapshotValue = false;
                }

                SetAnimationClocks(newAnimationClocks);
            }
            else
            {
                Debug.Assert(handoffBehavior == HandoffBehavior.Compose,
                             "Unhandled handoffBehavior value.");
                Debug.Assert(defaultDestinationValue == DependencyProperty.UnsetValue,
                             "We shouldn't take the time to calculate a default destination value when it isn't needed.");

                if (newAnimationClocks == null)
                {
                    return;
                }
                else if (_animationClocks == null)
                {
                    SetAnimationClocks(newAnimationClocks);
                }
                else
                {
                    AppendAnimationClocks(newAnimationClocks);
                }
            }
        }
Exemplo n.º 58
0
    /// <summary>
    ///     Begins all animations underneath this storyboard, clock tree starts at the given containing object.
    /// </summary>
    internal void BeginCommon( DependencyObject containingObject, INameScope nameScope,
        HandoffBehavior handoffBehavior, bool isControllable, Int64 layer)
    {

        if (containingObject == null)
        {
            throw new ArgumentNullException("containingObject");
        }

        if (!HandoffBehaviorEnum.IsDefined(handoffBehavior))
        {
            throw new ArgumentException(SR.Get(SRID.Storyboard_UnrecognizedHandoffBehavior));
        }

        if (BeginTime == null)
        {
            // a null BeginTime means to not allocate or start the clock
            return;
        }

        // It's not possible to begin when there is no TimeManager.  This condition
        //  is known to occur during app shutdown.  Since an app being shut down
        //  won't care about its Storyboards, we silently exit.
        // If we don't exit here, we'll need to catch and handle the "no time
        //  manager" exception implemented for bug #1247862
        if( MediaContext.CurrentMediaContext.TimeManager == null )
        {
            return;
        }


        if( TraceAnimation.IsEnabled )
        {
            TraceAnimation.TraceActivityItem(
                TraceAnimation.StoryboardBegin,
                this,
                Name,
                containingObject,
                nameScope );
        }


        // This table maps an [object,property] key pair to one or more clocks.
        // If we have knowledge of whether this Storyboard was changed between multiple
        //  Begin(), we can cache this.  But we don't know, so we don't cache.
        HybridDictionary simplePathClockMappings = new HybridDictionary();

        // Create (and Begin) a clock tree corresponding to this Storyboard timeline tree
        Clock storyboardClockTree = CreateClock(isControllable);

        // We now have one or more clocks that are created from this storyboard.
        //  However, the individual clocks are not necessarily intended for
        //  the containing object so we need to do a tree walk and sort out
        //  which clocks go on which objects and their properties.
        ClockTreeWalkRecursive(
            storyboardClockTree,
            containingObject,
            nameScope,
            null, /* target object */
            null, /* target object name */
            null, /* target property path */
            handoffBehavior,
            simplePathClockMappings,
            layer);

        // Apply the storyboard's animation clocks we found in the tree walk
        ApplyAnimationClocks( simplePathClockMappings, handoffBehavior, layer );

        if (isControllable)
        {
            // Save a reference to this clock tree on the containingObject.  We
            //  need it there in order to control this clock tree later.
            SetStoryboardClock(containingObject, storyboardClockTree);
        }

        return;
    }
Exemplo n.º 59
0
        /// <inheritdoc/>
        internal override void AddToCompositionChains(AnimationManager animationManager, HandoffBehavior handoffBehavior, AnimationInstance previousInstance)
        {
            var property = Property;

            if (property == null)
            {
                return;
            }

            // Get (or create) the animation composition chain.
            var compositionChain = animationManager.GetCompositionChain(property, Animation.Traits, true);

            if (handoffBehavior == HandoffBehavior.SnapshotAndReplace)
            {
                // Make a snapshot of the current animation value.
                compositionChain.TakeSnapshot();
            }

            if (handoffBehavior == HandoffBehavior.Replace || handoffBehavior == HandoffBehavior.SnapshotAndReplace)
            {
                // Remove all previous animations.
                if (compositionChain.Count > 0)
                {
                    var rootInstance = this.GetRoot();
                    for (int i = compositionChain.Count - 1; i >= 0; i--)
                    {
                        var animationInstance = compositionChain[i];

                        // Do not remove animation instances of the same animation tree!
                        if (animationInstance.GetRoot() != rootInstance)
                        {
                            compositionChain.RemoveAt(i);
                        }
                    }
                }
            }

            AnimationInstance <T> referenceInstance = null;

            if (previousInstance != null)
            {
                // previousInstance is either a single animation instance or an animation tree that
                // should be replaced. Find the instance that is assigned to the current property.
                referenceInstance = previousInstance.GetAssignedInstance(Property) as AnimationInstance <T>;
            }

            if (referenceInstance == null)
            {
                // Add at the end of the animation composition chain.
                compositionChain.Add(this);
            }
            else
            {
                // Insert in animation composition chain at a certain index.
                int index = compositionChain.IndexOf(referenceInstance);
                if (index == -1)
                {
                    // The referenceInstance has not been applied to the current property.
                    compositionChain.Add(this);
                }
                else
                {
                    // Insert after referenceInstance.
                    index++;

                    // Other animation instances of the same animation tree might have already been
                    // inserted after referenceInstance. To maintain the correct order we need to add
                    // this instance after the other instances of the same tree.
                    var rootInstance      = this.GetRoot();
                    var numberOfInstances = compositionChain.Count;
                    while (index < numberOfInstances && compositionChain[index].GetRoot() == rootInstance)
                    {
                        index++;
                    }

                    compositionChain.Insert(index, this);
                }
            }
        }
Exemplo n.º 60
0
    /// <summary>
    ///     Recursively walks the clock tree and determine the target object
    /// and property for each clock in the tree.
    /// </summary>
    /// <remarks>
    ///     The currently active object and property path are passed in as parameters,
    /// they will be used unless a target/property specification exists on
    /// the Timeline object corresponding to the current clock.  (So that the
    /// leaf-most reference wins.)
    ///
    ///     The active object and property parameters may be null if they have
    /// never been specified.  If we reach a leaf node clock and a needed attribute
    /// is still null, it is an error condition.  Otherwise we keep hoping they'll be found.
    /// </remarks>
    private void ClockTreeWalkRecursive(
        Clock currentClock,                /* No two calls will have the same currentClock     */
        DependencyObject containingObject, /* Remains the same through all the recursive calls */
        INameScope nameScope,              /* Remains the same through all the recursive calls */
        DependencyObject parentObject,
        string parentObjectName,
        PropertyPath parentPropertyPath,
        HandoffBehavior handoffBehavior,   /* Remains the same through all the recursive calls */
        HybridDictionary clockMappings,
        Int64 layer                        /* Remains the same through all the recursive calls */)
    {
        Timeline currentTimeline = currentClock.Timeline;

        DependencyObject targetObject = parentObject;
        string currentObjectName = parentObjectName;
        PropertyPath currentPropertyPath = parentPropertyPath;

        // If we have target object/property information, use it instead of the
        //  parent's information.
        string nameString = (string)currentTimeline.GetValue(TargetNameProperty);
        if( nameString != null )
        {
            if( nameScope is Style )
            {
                // We are inside a Style - we don't let people target anything.
                //  They're only allowed to modify the Styled object, which is
                //  already the implicit target.
                throw new InvalidOperationException(SR.Get(SRID.Storyboard_TargetNameNotAllowedInStyle, nameString));
            }
            currentObjectName = nameString;
        }

        // The TargetProperty trumps the TargetName property.
        DependencyObject localTargetObject = (DependencyObject) currentTimeline.GetValue(TargetProperty);
        if( localTargetObject != null )
        {
            targetObject = localTargetObject;
            currentObjectName = null;
        }

        PropertyPath propertyPath = (PropertyPath)currentTimeline.GetValue(TargetPropertyProperty);
        if( propertyPath != null )
        {
            currentPropertyPath = propertyPath;
        }

        // Now see if the current clock is an animation clock
        if( currentClock is AnimationClock )
        {
            DependencyProperty targetProperty = null;
            AnimationClock animationClock = (AnimationClock)currentClock;

            if( targetObject == null )
            {
                // Resolve the target object name.  If no name specified, use the
                //  containing object.
                if( currentObjectName != null )
                {
                    DependencyObject mentor = Helper.FindMentor(containingObject);

                    targetObject = ResolveTargetName(currentObjectName, nameScope, mentor);
                }
                else
                {
                    // The containing object must be either an FE or FCE.
                    // (Not a Storyboard, as used for "shared clocks" mode.)
                    targetObject = containingObject as FrameworkElement;
                    if(targetObject == null)
                    {
                        targetObject = containingObject as FrameworkContentElement;
                    }

                    if( targetObject == null )
                    {
                        // The containing object is not an FE or FCE.
                        throw new InvalidOperationException(SR.Get(SRID.Storyboard_NoTarget, currentTimeline.GetType().ToString() ));
                    }
                }
            }

            // See if we have a property name to use.
            if( currentPropertyPath == null )
            {
                throw new InvalidOperationException(SR.Get(SRID.Storyboard_TargetPropertyRequired, currentTimeline.GetType().ToString() ));
            }

            // A property name can be a straightforward property name (like "Angle")
            // but may be a more complex multi-step property path.  The two cases
            // are handled differently.
            using(currentPropertyPath.SetContext(targetObject))
            {
                if( currentPropertyPath.Length < 1 )
                {
                    throw new InvalidOperationException(SR.Get(SRID.Storyboard_PropertyPathEmpty));
                }

                VerifyPathIsAnimatable(currentPropertyPath);

                if( currentPropertyPath.Length == 1 )
                {
                    // We have a simple single-step property.
                    targetProperty = currentPropertyPath.GetAccessor(0) as DependencyProperty;

                    if( targetProperty == null )
                    {
                        // Unfortunately it's not a DependencyProperty.
                        throw new InvalidOperationException(SR.Get(SRID.Storyboard_PropertyPathMustPointToDependencyProperty, currentPropertyPath.Path ));
                    }

                    VerifyAnimationIsValid(targetProperty, animationClock);

                    ObjectPropertyPair animatedTarget = new ObjectPropertyPair(targetObject, targetProperty);
                    UpdateMappings(clockMappings, animatedTarget, animationClock);
                }
                else // path.Length > 1
                {
                    // This is a multi-step property path that requires more extensive
                    //  setup.
                    ProcessComplexPath(clockMappings, targetObject, currentPropertyPath, animationClock, handoffBehavior, layer);
                }
            }
        }
        else if ( currentClock is MediaClock ) // Not an animation clock - maybe a media clock?
        {
            // Yes it's a media clock.  Try to find the corresponding object and
            //  apply the clock to that object.
            ApplyMediaClock(nameScope, containingObject, targetObject, currentObjectName, (MediaClock) currentClock);
        }
        else
        {
            // None of the types we recognize as leaf node clock types -
            //  recursively process child clocks.
            ClockGroup currentClockGroup = currentClock as ClockGroup;

            if (currentClockGroup != null)
            {
                ClockCollection childrenClocks = currentClockGroup.Children;

                for( int i = 0; i < childrenClocks.Count; i++ )
                {
                    ClockTreeWalkRecursive(
                        childrenClocks[i],
                        containingObject,
                        nameScope,
                        targetObject,
                        currentObjectName,
                        currentPropertyPath,
                        handoffBehavior,
                        clockMappings,
                        layer);
                }
            }
        }
    }