Inheritance: DependencyObject
Example #1
0
 public TimeTracker()
 {
     _timeline = new ParallelTimeline(null, Duration.Forever);
     _timeClock = _timeline.CreateClock();
     _timeClock.Controller.Begin();
     _lastTime = TimeSpan.FromSeconds(0);
 } 
Example #2
0
      /// <summary>Defines timeline properties common to all atomic effects and returns the resulting total duration</summary>
      protected TimeSpan DefineTimelineCore(Timeline timeline, TimeSpan parentOffset) {
         var totalDuration = (Duration.HasValue ? Duration.Value : TimeSpan.Zero);
         timeline.Duration = totalDuration;

         if (RepeatCount.HasValue) {
            var repeatCount = RepeatCount.Value;
            if (!repeatCount.IsOne()) {
               if (Double.IsPositiveInfinity(repeatCount)) {
                  timeline.RepeatBehavior = RepeatBehavior.Forever;
               } else {
                  timeline.RepeatBehavior = new RepeatBehavior(repeatCount);
                  totalDuration = TimeSpan.FromTicks((long)(totalDuration.Ticks * repeatCount));
               }
            }
         }
         if (AutoReverse) {
            timeline.AutoReverse = true;
            totalDuration += totalDuration;
         }
         var offset = parentOffset + BeginTime;
         if (offset != TimeSpan.Zero) {
            timeline.BeginTime = offset;
            totalDuration += offset;
         }

         Assumption.IsFalse(totalDuration < TimeSpan.Zero, "An effect cannot have a negative duration");
         return totalDuration;
      }
Example #3
0
 protected internal Clock(Timeline timeline)
 {
   _timeline = timeline;
   _timeline.CurrentGlobalSpeedInvalidated += new EventHandler(TimelineCurrentGlobalSpeedInvalidated);
   _timeline.CurrentStateInvalidated += new EventHandler(TimelineCurrentStateInvalidated);
   _timeline.CurrentTimeInvalidated += new EventHandler(TimelineCurrentTimeInvalidated);
 }
 public static void BeginAnimation(this DependencyObject obj, DependencyProperty property, Timeline animation)
 {
     Storyboard.SetTargetProperty(animation, new PropertyPath(property));
     Storyboard.SetTarget(animation, obj);
     var storyboard = new Storyboard();
     storyboard.Children.Add(animation);
     storyboard.Begin();
 }
    public void Insert(int index, Timeline timeline)
    {
      if (timeline == null)
      {
        throw new ArgumentNullException("timeline");
      }

      List.Insert(index, timeline);
    }
    public int IndexOf(Timeline timeline)
    {
      if (timeline == null)
      {
        throw new ArgumentNullException("timeline");
      }

      return List.IndexOf(timeline);
    }
    public void CopyTo(Timeline[] array, int arrayIndex)
    {
      if (array == null)
      {
        throw new ArgumentNullException("array");
      }

      List.CopyTo(array, arrayIndex);
    }
    public bool Contains(Timeline timeline)
    {
      if (timeline == null)
      {
        throw new ArgumentNullException("timeline");
      }

      return List.Contains(timeline);
    }
    public void Add(Timeline timeline)
    {
      if (timeline == null)
      {
        throw new ArgumentNullException("timeline");
      }

      List.Add(timeline);
    }
        /// <summary>
        /// Extension method to quickly animate a DependencyObject.  Simply provide the propertyPath and a timeline.
        /// </summary>
        /// <param name="element">The element to animate.</param>
        /// <param name="propertyPath">The property to animate.</param>
        /// <param name="timeline">The animation to apply to the element.</param>
        /// <param name="completed">The event handler to fire once the animation completes.</param>
        public static void Animate(this DependencyObject element, string propertyPath, Timeline timeline, EventHandler completed)
        {
            Storyboard sb = new Storyboard();
            if (completed != null)
                sb.Completed += completed;

            sb.Children.Add(timeline);
            Storyboard.SetTarget(sb, element);
            Storyboard.SetTargetProperty(sb, new PropertyPath(propertyPath));
            sb.Begin();
        }
Example #11
0
 public static void BeginAnimation(Timeline animation, FrameworkElement element, DependencyProperty property,
                                   Action completed = null)
 {
     Storyboard.SetTarget(animation, element);
     Storyboard.SetTargetProperty(animation, new PropertyPath(property));
     var sb = new Storyboard();
     sb.Children.Add(animation);
     if (completed != null)
         sb.Completed += (s, e) => {
             completed.Invoke();
         };
     sb.Begin(element);
 }
Example #12
0
File: Clock.cs Project: koush/Xaml
 protected internal Clock(Timeline timeline)
 {
     myAutoReverse = timeline.AutoReverse;
     myTimeline = timeline;
     myNaturalDuration = myTimeline.Duration;
     if (timeline.RepeatBehavior == RepeatBehavior.Forever)
         myTotalTime = float.MaxValue;
     else
     {
         if (timeline.RepeatBehavior.HasCount)
             myTotalTime = (float)(myTimeline.Duration.TimeSpan.TotalMilliseconds * myTimeline.RepeatBehavior.Count);
         else
             myTotalTime = (float)myTimeline.RepeatBehavior.Duration.TimeSpan.TotalMilliseconds;
     }
     mySystem.AddClock(this);
 }
    public bool Remove(Timeline timeline)
    {
      if (timeline == null)
      {
        throw new ArgumentNullException("timeline");
      }

      if (List.Contains(timeline) == false)
      {
        return false;
      }

      List.Remove(timeline);

      return true;
    }
 private static TimeSpan GetTimeToFinished(Timeline timeline)
 {
     if (timeline.Duration.HasTimeSpan)
     {
         var beginTime = timeline.BeginTime ?? TimeSpan.Zero;
         return beginTime + timeline.Duration.TimeSpan;
     }
     var storyboard = timeline as Storyboard;
     if (storyboard != null)
     {
         if (storyboard.Children.Count == 0)
         {
             return TimeSpan.Zero;
         }
         return storyboard.Children.Max(x => GetTimeToFinished(x));
     }
     throw new NotImplementedException(string.Format("GetTimeToFinished not implemented for: {0}", timeline.GetType().FullName));
 }
Example #15
0
        /// <summary>
        /// Creates an enumerator that iterates over a subtree of timelines
        /// in prefix order.
        /// </summary>
        /// <param name="root">
        /// The timeline that is the root of the subtree to enumerate.
        /// </param>
        /// <param name="processRoot">
        /// True to include the root in the enumeration, false otherwise.
        /// </param>
        internal TimelineTreeEnumerator(Timeline root, bool processRoot)
        {
            _rootTimeline = root;
            _flags = processRoot ? (SubtreeFlag.Reset | SubtreeFlag.ProcessRoot) : SubtreeFlag.Reset;

            // Start with stacks of capacity 10. That's relatively small, yet
            // it covers very large trees without reallocation of stack data.
            // Note that given the way we use the stacks we need one less entry
            // for indices than for timelines, as we don't care what the index
            // of the root timeline is.
            _indexStack = new Stack(9);
            _timelineStack = new Stack<Timeline>(10);
        }
Example #16
0
        internal static Clock BuildClockTreeFromTimeline(
            Timeline rootTimeline,
            bool hasControllableRoot)
        {
            Clock rootClock = AllocateClock(rootTimeline, hasControllableRoot);

            // Set this flag so that the subsequent method can rely on it.
            rootClock.IsRoot = true;
            rootClock._rootData = new RootData();  // Create a RootData to hold root specific information.

            // The root clock was given a reference to a frozen copy of the 
            // timing tree.  We pass this copy down BuildClockSubTreeFromTimeline
            // so that each child clock will use that tree rather
            // than create a new one.
            rootClock.BuildClockSubTreeFromTimeline(rootClock.Timeline, hasControllableRoot);
            
            rootClock.AddToTimeManager();

            return rootClock;
        }
Example #17
0
        internal virtual void BuildClockSubTreeFromTimeline(
            Timeline timeline,
            bool hasControllableRoot)
        {
            SetFlag(ClockFlags.CanSlip, GetCanSlip());  // Set the CanSlip flag

            // Here we preview the clock's own slip-ability, hence ClockGroups should return false
            // at this stage, because their children are not yet added by the time of this call.
            if (CanSlip && (IsRoot || _timeline.BeginTime.HasValue))
            {
                ResolveDuration();

                // A [....] clock with duration of zero or no begin time has no effect, so do skip it
                if (!_resolvedDuration.HasTimeSpan || _resolvedDuration.TimeSpan > TimeSpan.Zero)
                {
                    // Verify that we only use SlipBehavior in supported scenarios
                    if ((_timeline.AutoReverse == true) ||
                        (_timeline.AccelerationRatio > 0) ||
                        (_timeline.DecelerationRatio > 0))
                    {
                        throw new NotSupportedException(SR.Get(SRID.Timing_CanSlipOnlyOnSimpleTimelines));
                    }

                    _syncData = new SyncData(this);  // CanSlip clocks keep themselves synced
                    HasDescendantsWithUnresolvedDuration = !HasResolvedDuration;  // Keep track of when our duration is resolved

                    Clock current = _parent;  // Traverse up the parent chain and verify that no unsupported behavior is specified
                    while (current != null)
                    {
                        Debug.Assert(!current.IsTimeManager);  // We should not yet be connected to the TimeManager
                        if (current._timeline.AutoReverse || current._timeline.AccelerationRatio > 0
                                                          || current._timeline.DecelerationRatio > 0)
                        {
                            throw new System.InvalidOperationException(SR.Get(SRID.Timing_SlipBehavior_SyncOnlyWithSimpleParents));
                        }

                        current.SetFlag(ClockFlags.CanGrow, true);  // Propagate the slippage tracking up the tree
                        if (!HasResolvedDuration)  // Let the parents know that we have not yet unresolved duration
                        {
                            current.HasDescendantsWithUnresolvedDuration = true;
                        }
                        current._currentIterationBeginTime = current._beginTime;

                        current = current._parent;
                    }
                }
            }
        }
Example #18
0
        internal static Clock AllocateClock(
            Timeline timeline,
            bool hasControllableRoot)
        {
            Clock clock = timeline.AllocateClock();

            // Assert that we weren't given an existing clock
            Debug.Assert(!clock.IsTimeManager);

            ClockGroup clockGroup = clock as ClockGroup;

            if (   clock._parent != null
                || (   clockGroup != null
                    && clockGroup.InternalChildren != null ))
            {
                // The derived class is trying to fool us -- we require a new,
                // fresh, unassociated clock here
                throw new InvalidOperationException(
                    SR.Get(
                        SRID.Timing_CreateClockMustReturnNewClock,
                        timeline.GetType().Name));
            }

            clock.SetFlag(ClockFlags.HasControllableRoot, hasControllableRoot);

            return clock;
        }
Example #19
0
        //
        // Constructors
        // 

        #region Constructors

        /// <summary>
        /// Creates a Clock object.
        /// </summary>
        /// <param name="timeline">
        /// The Timeline to use as a template.
        /// </param>
        /// <remarks>
        /// The returned Clock doesn't have any children.
        /// </remarks>
        protected internal Clock(Timeline timeline)
        {
#if DEBUG
            lock (_debugLockObject)
            {
                _debugIdentity = ++_nextIdentity;
                WeakReference weakRef = new WeakReference(this);
                _objectTable[_debugIdentity] = weakRef;
            }
#endif // DEBUG

            Debug.Assert(timeline != null);

            // 
            // Store a frozen copy of the timeline
            //

            _timeline = (Timeline)timeline.GetCurrentValueAsFrozen();

            // GetCurrentValueAsFrozen will make a clone of the Timeline if it's 
            // not frozen and will return the Timeline if it is frozen.
            // The clone will never have event handlers, while the
            // frozen original may.  This means we need to copy
            // the event handlers from the original timeline onto the clock
            // to be consistent.

            //
            // Copy the event handlers from the original timeline into the clock
            //
            _eventHandlersStore = timeline.InternalEventHandlersStore;

            //                                                                      
            // FXCop fix. Do not call overridables in constructors
            // UpdateNeedsTicksWhenActive();
            // Set the NeedsTicksWhenActive only if we have someone listening
            // to an event.

            SetFlag(ClockFlags.NeedsTicksWhenActive, _eventHandlersStore != null);  
                                                                                                
            //
            // Cache values that won't change as the clock ticks
            //

            // Non-root clocks have an unchanging begin time specified by their timelines.
            // A root clock will update _beginTime as necessary.
            _beginTime = _timeline.BeginTime;

            // Cache duration, getting Timeline.Duration and recalculating duration 
            // each Tick was eating perf, resolve the duration if possible.
            _resolvedDuration = _timeline.Duration;

            if (_resolvedDuration == Duration.Automatic)
            {
                // Forever is the default for an automatic duration. We can't
                // try to resolve the duration yet because the tree
                // may not be fully built, in which case ClockGroups won't 
                // have their children yet.
                _resolvedDuration = Duration.Forever;
            }
            else
            {
                HasResolvedDuration = true;
            }

            _currentDuration = _resolvedDuration;

            // Cache speed ratio, for roots this value may be updated if the interactive
            // speed ratio changes, but for non-roots this value will remain constant
            // throughout the lifetime of the clock.
            _appliedSpeedRatio = _timeline.SpeedRatio;

            //
            // Initialize current state
            //
   
            _currentClockState = ClockState.Stopped;

            if (_beginTime.HasValue)
            {
                // We need a tick to bring our state up to date
                _nextTickNeededTime = TimeSpan.Zero;
            }

            // All other data members initialized to zero by default
        }
Example #20
0
 /// <summary>
 /// Helper for the UpdateDropIndicatorAnimationHeight method.
 /// </summary>
 private void UpdateDropIndicatorAnimationHeight(double height, Timeline animation)
 {
     DoubleAnimation da = animation as DoubleAnimation;
     if (da != null)
     {
         string targetName = Storyboard.GetTargetName(da);
         PropertyPath targetPath = Storyboard.GetTargetProperty(da);
         if ((targetName == ReorderListBoxItem.DropBeforeSpacePart ||
              targetName == ReorderListBoxItem.DropAfterSpacePart) &&
             targetPath != null && targetPath.Path == "Height")
         {
             if (da.From > 0 && da.From != height)
             {
                 da.From = height;
             }
             if (da.To > 0 && da.To != height)
             {
                 da.To = height;
             }
         }
     }
 }
Example #21
0
		// Hack for VSM.
		internal static DependencyProperty GetTargetDependencyProperty (Timeline element)
		{
			if (element == null)
				throw new ArgumentNullException ("element");
			IntPtr ptr = NativeMethods.storyboard_get_target_dependency_property (element.native);
			return ptr == IntPtr.Zero ? null : DependencyProperty.Lookup (ptr);
		}
Example #22
0
		public static string GetTargetName (Timeline element)
		{
			return (string) element.GetValue (TargetNameProperty);
		}
Example #23
0
		public static void SetTargetName (Timeline element, string name)
		{
			// NOTE: this throws a NRE if element is null, while name == null is a valid value

			// FIXME Exception if setting on running
			element.SetValue (TargetNameProperty, name);
		}
Example #24
0
		public static void SetTarget (Timeline timeline, DependencyObject target)
		{
			if (timeline == null)
				throw new ArgumentNullException ("timeline");
			if (target == null)
				throw new ArgumentNullException ("target");
			// FIXME Exception if setting on running
			timeline.ManualTarget = target;
		}
 //
 // Summary:
 //     Causes the specified System.Windows.Media.Animation.Timeline to target the
 //     specified object.
 //
 // Parameters:
 //   timeline:
 //     The timeline that targets the specified dependency object.
 //
 //   target:
 //     The actual instance of the object to target.
 //
 // Exceptions:
 //   System.ArgumentNullException:
 //     One or more of the parameters is null.
 extern public static void SetTarget(Timeline timeline, DependencyObject target);
Example #26
0
		public static void SetTargetProperty (Timeline element, PropertyPath path)
		{
			if (element == null)
				throw new ArgumentNullException ("element");
			if (path == null)
				throw new ArgumentNullException ("path");
			// FIXME Exception if setting on running
			element.SetValue (TargetPropertyProperty, path);
		}
 //
 // Summary:
 //     Causes the specified System.Windows.Media.Animation.Timeline to target the
 //     object with the specified name.
 //
 // Parameters:
 //   element:
 //     The timeline that targets the specified dependency object.
 //
 //   name:
 //     The name of the object to target.
 extern public static void SetTargetName(Timeline element, string name);
Example #28
0
		public static PropertyPath GetTargetProperty (Timeline element)
		{
			if (element == null)
				throw new ArgumentNullException ("element");

			return (PropertyPath) element.GetValue (TargetPropertyProperty);
		}
Example #29
0
 public TimelineClock(IClock baseClock, Timeline timeline)
 {
     this.clock        = CreateClock(baseClock, timeline);
     this.Timeline     = timeline;
     this.CurrentState = ClockState.Empty;
 }
 //
 // Summary:
 //     Causes the specified System.Windows.Media.Animation.Timeline to target the
 //     specified dependency property.
 //
 // Parameters:
 //   element:
 //     The timeline with which to associate the specified dependency property.
 //
 //   path:
 //     A path that describe the dependency property to be animated.
 //
 // Exceptions:
 //   System.ArgumentNullException:
 //     One or more of the parameters is null.
 extern public static void SetTargetProperty(Timeline element, PropertyPath path);
Example #31
0
        /// <summary>
        /// Moves the clock forward to the current time and updates the state of
        /// all timing objects based on the time change.
        /// </summary>
        /// <remarks>
        /// The associated reference clock is used to determine the current time.
        /// The new position of the clock will be equal to the difference between the
        /// starting system time and the current system time. The time manager requires
        /// the system time to move forward.
        /// </remarks>
        public void Tick()
        {
            try
            {
#if DEBUG
                // On a regular interval, clean up our tables of known
                // timelines and clocks
                if (++_frameCount >= 1000) // Should be about once every 10s
                {
                    Timeline.CleanKnownTimelinesTable();
                    System.Windows.Media.Animation.Clock.CleanKnownClocksTable();
                    _frameCount = 0;
                }
#endif // DEBUG
                // Don't need to worry about needing a tick sooner
                _nextTickTimeQueried = false;

                // Mark the tree as clean immediately. If any changes occur during
                // processing of the tick, the tree will be marked as dirty again.
                _isDirty = false;

                // No effect unless we are in the running state
                if (_timeState == TimeState.Running)
                {
                    // Figure out the current time
                    _globalTime = GetCurrentGlobalTime();

                    // Start the tick
                    _isInTick = true;
                }

                // Trace the start of the tick and pass along the absolute time to which
                // we are ticking.
                EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnimation | EventTrace.Keyword.KeywordPerf, EventTrace.Event.WClientTimeManagerTickBegin, (_startTime + _globalTime).Ticks / TimeSpan.TicksPerMillisecond);

                // Run new property querying logic on the timing tree
                if (_lastTimeState == TimeState.Stopped && _timeState == TimeState.Stopped)  // We were stopped the whole time
                {
                    _currentTickInterval = TimeIntervalCollection.CreateNullPoint();
                }
                else  // We were not stopped at some time, so process the tick interval
                {
                    _currentTickInterval = TimeIntervalCollection.CreateOpenClosedInterval(_lastTickTime, _globalTime);

                    // If at either tick we were stopped, add the null point to represent that
                    if (_lastTimeState == TimeState.Stopped || _timeState == TimeState.Stopped)
                    {
                        _currentTickInterval.AddNullPoint();
                    }
                }

                // Compute the tree state, using _currentTickInterval to compute the events that occured
                _timeManagerClock.ComputeTreeState();

                // Cache TimeManager state at this time
                _lastTimeState = _timeState;

                // When the tick is done, we raise timing events
                RaiseEnqueuedEvents();
            }
            finally
            {
                _isInTick = false;

                // Cache the tick time
                _lastTickTime = _globalTime;

                //trace the end of the tick
                EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnimation | EventTrace.Keyword.KeywordPerf, EventTrace.Event.WClientTimeManagerTickEnd);
            }

            // At the end of every tick clean up GC'ed clocks, if necessary
            CleanupClocks();
        }
 protected internal Clock(Timeline timeline)
 {
 }
        internal override void BuildClockSubTreeFromTimeline(
            Timeline timeline,
            bool hasControllableRoot)
        {
            // This is not currently necessary
            //base.BuildClockSubTreeFromTimeline(timeline);

            // Only TimelineGroup has children
            TimelineGroup timelineGroup = timeline as TimelineGroup;

            // Only a TimelineGroup should have allocated a ClockGroup.
            Debug.Assert(timelineGroup != null);

            // Create a clock for each of the children of the timeline
            TimelineCollection timelineChildren = timelineGroup.Children;

            if (timelineChildren != null && timelineChildren.Count > 0)
            {
                Clock childClock;

                // Create a collection for the children of the clock
                _children = new List <Clock>();

                // Create clocks for the children
                for (int index = 0; index < timelineChildren.Count; index++)
                {
                    childClock         = AllocateClock(timelineChildren[index], hasControllableRoot);
                    childClock._parent = this;  // We connect the child to the subtree before calling BuildClockSubtreeFromTimeline
                    childClock.BuildClockSubTreeFromTimeline(timelineChildren[index], hasControllableRoot);
                    _children.Add(childClock);
                    childClock._childIndex = index;
                }

                // If we have SlipBehavior, check if we have any childen with which to slip.
                if (_timeline is ParallelTimeline &&
                    ((ParallelTimeline)_timeline).SlipBehavior == SlipBehavior.Slip)
                {
                    // Verify that we only use SlipBehavior in supported scenarios
                    if (!IsRoot ||
                        (_timeline.RepeatBehavior.HasDuration) ||
                        (_timeline.AutoReverse == true) ||
                        (_timeline.AccelerationRatio > 0) ||
                        (_timeline.DecelerationRatio > 0))
                    {
                        throw new NotSupportedException(SR.Get(SRID.Timing_SlipBehavior_SlipOnlyOnSimpleTimelines));
                    }

                    for (int index = 0; index < _children.Count; index++)
                    {
                        Clock child = _children[index];
                        if (child.CanSlip)
                        {
                            Duration duration = child.ResolvedDuration;

                            // A [....] clock with duration of zero or no begin time has no effect, so do skip it
                            if ((!duration.HasTimeSpan || duration.TimeSpan > TimeSpan.Zero) &&
                                child._timeline.BeginTime.HasValue)
                            {
                                _syncData       = new SyncData(child);
                                child._syncData = null;  // The child will no longer self-[....]
                            }

                            break;  // We only want the first child with CanSlip
                        }
                    }
                }
            }
        }