internal void Begin(FrameworkElement target, bool useTransitions, string visualStateGroupName, bool isVisualStateChange) { #if MIGRATION Dispatcher #else CoreDispatcher #endif .INTERNAL_GetCurrentDispatcher().BeginInvoke(() => { Guid guid = Guid.NewGuid(); IterationParameters parameters = new IterationParameters() { Target = target, Guid = guid, UseTransitions = useTransitions, VisualStateGroupName = visualStateGroupName, IsVisualStateChange = isVisualStateChange }; InitializeIteration(); bool isThisSingleLoop = RepeatBehavior.Type == RepeatBehaviorType.Count && RepeatBehavior.Count == 1; StartFirstIteration(parameters, isThisSingleLoop, new TimeSpan()); //todo: use a parameter instead of just a new TimeSpan since we can have a Storyboard inside a Storyboard. }); }
internal void Initialize(IterationParameters parameters) { GetTargetInformation(parameters); InitializeCore(); ComputeDuration(); _isInitialized = true; }
internal override void Apply(IterationParameters parameters, bool isLastLoop) { if (To != null) { OnAnimationCompleted(parameters, isLastLoop, To.Value, _propertyContainer, _targetProperty); } }
internal void OnIterationCompleted(IterationParameters parameters) { if (_isAnimationDurationReached) //the default duration is Automatic, which currently has a TimeSpan of 0 ms (which is considered here to be no timespan). { --remainingIterations; if (remainingIterations <= 0) { if (this is Storyboard) { ((Storyboard)this).Stop(parameters.Target); } else { Stop(parameters.Target, revertToFormerValue: false); } INTERNAL_RaiseCompletedEvent(); } else { if (this is Storyboard) { ((Storyboard)this).Stop(parameters.Target); } else { Stop(parameters.Target, revertToFormerValue: true); } IterateOnce(parameters, isLastLoop: remainingIterations == 1); } } }
internal void Begin(FrameworkElement target, bool useTransitions, string visualStateGroupName, bool isVisualStateChange) { this.isUnApplied = false; // Note: we set this variable because the animation start is done inside a Dispatcher, so if the user synchronously Starts then Stops then Starts an animation, we want it to be in the started state. #if MIGRATION Dispatcher #else CoreDispatcher #endif // Note: we use a Dispatcher in order to ensure that the page is fully loaded when starting the animation. .INTERNAL_GetCurrentDispatcher().BeginInvoke(() => { if (!this.isUnApplied) // Note: we use this variable because the animation start is done inside a Dispatcher, so if the user Starts then Stops the animation immediately (in the same thread), we want to cancel the start of the animation. { Guid guid = Guid.NewGuid(); IterationParameters parameters = new IterationParameters() { Target = target, Guid = guid, UseTransitions = useTransitions, VisualStateGroupName = visualStateGroupName, IsVisualStateChange = isVisualStateChange }; InitializeIteration(); bool isThisSingleLoop = RepeatBehavior.Type == RepeatBehaviorType.Count && RepeatBehavior.Count == 1; StartFirstIteration(parameters, isThisSingleLoop, new TimeSpan()); //todo: use a parameter instead of just a new TimeSpan since we can have a Storyboard inside a Storyboard. } }); }
internal override void Apply(IterationParameters parameters, bool isLastLoop) { DependencyObject target; PropertyPath propertyPath; if (parameters.Target != null) { GetTargetElementAndPropertyInfo(parameters.Target, out target, out propertyPath, parameters.IsTargetParentTheTarget); //todo: find out why we put the test on target and put it back? (I removed it because id kept ScaleTransform from working properly) if (To != null)//&& target is FrameworkElement) { //if (Duration == TimeSpan.Zero) //{ // AnimationHelpers.ApplyInstantAnimationWorkAround() // OnAnimationCompleted(parameters, isLastLoop, target, propertyPath); //} //else //{ // - Get the propertyMetadata from the property DependencyProperty dp = GetProperty(target, propertyPath); PropertyMetadata propertyMetadata = dp.GetTypeMetaData(target.GetType()); //we make a specific name for this animation: string specificGroupName = parameters.VisualStateGroupName + animationInstanceSpecificName.ToString(); bool cssEquivalentExists = false; if (propertyMetadata.GetCSSEquivalent != null) { CSSEquivalent cssEquivalent = propertyMetadata.GetCSSEquivalent(target); if (cssEquivalent != null) { cssEquivalentExists = true; StartAnimation(target, cssEquivalent, From, To, Duration, EasingFunction, specificGroupName, OnAnimationCompleted(parameters, isLastLoop, target, propertyPath)); } } //todo: use GetCSSEquivalent instead (?) if (propertyMetadata.GetCSSEquivalents != null) { List <CSSEquivalent> cssEquivalents = propertyMetadata.GetCSSEquivalents(target); foreach (CSSEquivalent equivalent in cssEquivalents) { cssEquivalentExists = true; StartAnimation(target, equivalent, From, To, Duration, EasingFunction, specificGroupName, OnAnimationCompleted(parameters, isLastLoop, target, propertyPath)); } } if (!cssEquivalentExists) { OnAnimationCompleted(parameters, isLastLoop, target, propertyPath); } //} } } }
private List <Cell> CreateWallCellsListForTargetCell(Cell targetCell, out IterationParameters iterationP) { var wallCellsCoveredByRouter = new List <Cell>(); var targetCellRowPosition = targetCell.Row; var targetCellColumnPosition = targetCell.Column; // find restrictions, if any, for further calculations var startRowRestriction = targetCellRowPosition - routerRadius; if (startRowRestriction < 0) { startRowRestriction = 0; } var endRowRestriction = targetCellRowPosition + routerRadius; if (endRowRestriction >= building.cells.GetLength(0)) { endRowRestriction = building.cells.GetLength(0) - 1; } var startColumnRestriction = targetCellColumnPosition - routerRadius; if (startColumnRestriction < 0) { startColumnRestriction = 0; } var endColumnRestriction = targetCellColumnPosition + routerRadius; if (endColumnRestriction >= building.cells.GetLength(1)) { endColumnRestriction = building.cells.GetLength(1) - 1; } iterationP = new IterationParameters { StartRowRestriction = startRowRestriction, EndRowRestriction = endRowRestriction, StartColumnRestriction = startColumnRestriction, EndColumnRestriction = endColumnRestriction }; // Considering restrictions calculated above, iterating over all cells that router would cover if was // connected to a backbone in given coordinates for (int i = startRowRestriction; i <= endRowRestriction; i++) { for (int j = startColumnRestriction; j <= endColumnRestriction; j++) { if (building.cells[i, j].Type == "wall") { wallCellsCoveredByRouter.Add(building.cells[i, j]); } } } return(wallCellsCoveredByRouter); }
private Dictionary <Guid, IterationParameters> _guidToIterationParametersDict = new Dictionary <Guid, IterationParameters>(); //the purpose of this Dictionary is to be able to retreive the parameters at the next iteration of the Storyboard. internal override void IterateOnce(IterationParameters parameters, bool isLastLoop) { base.IterateOnce(parameters, isLastLoop); //we (re)set the children's remaining iterations: foreach (Timeline timeline in Children) { timeline.InitializeIteration(); } GetPropertiesChanged(); //we make sure INTERNAL_propertiesChanged is filled. _expectedAmountOfTimelineEnds = _children.Count; if (!_expectedAmountOfTimelineEndsDict.ContainsKey(parameters.Guid)) { _expectedAmountOfTimelineEndsDict.Add(parameters.Guid, _children.Count); _guidToIterationParametersDict.Add(parameters.Guid, parameters); } else { //I'm not sure this is useful but we never know. _expectedAmountOfTimelineEndsDict[parameters.Guid] = _children.Count; _guidToIterationParametersDict[parameters.Guid] = parameters; } if (parameters.Target != null) { foreach (Timeline timeLine in _children) { IterationParameters currentParameters = parameters.Clone(); //note: we make a clone for each timeline because the value of IsTargetParentTheTarget can change from one timeline to another. timeLine.Completed -= timeLine_Completed; timeLine.Completed += timeLine_Completed; currentParameters.IsTargetParentTheTarget = true; if (currentParameters.IsVisualStateChange && Storyboard.GetTargetName(timeLine) != null) { currentParameters.IsTargetParentTheTarget = false; } bool isTimelineSingleLoop = timeLine.RepeatBehavior.Type == RepeatBehaviorType.Count && timeLine.RepeatBehavior.Count == 1; timeLine.StartFirstIteration(currentParameters, isTimelineSingleLoop, BeginTime); } } else { foreach (Timeline timeLine in _children) { DependencyObject target = Storyboard.GetTarget(timeLine); if (target is FrameworkElement) { parameters.Target = (FrameworkElement)target; timeLine.Completed -= timeLine_Completed; timeLine.Completed += timeLine_Completed; parameters.VisualStateGroupName = "visualStateGroupName"; parameters.IsTargetParentTheTarget = false; bool isTimelineSingleLoop = timeLine.RepeatBehavior.Type == RepeatBehaviorType.Count && timeLine.RepeatBehavior.Count == 1; timeLine.StartFirstIteration(parameters, isTimelineSingleLoop, BeginTime); } } } }
internal override void IterateOnce(IterationParameters parameters, bool isLastLoop) { this.Completed -= ApplyLastKeyFrame; this.Completed += ApplyLastKeyFrame; BeforeApply(parameters, isLastLoop); InitializeKeyFramesSet(); base.IterateOnce(parameters, isLastLoop); Apply(parameters, isLastLoop); }
private Action OnAnimationCompleted(IterationParameters parameters, bool isLastLoop, object value, DependencyObject target, PropertyPath propertyPath, Guid callBackGuid) { return(() => { if (isLastLoop && _animationID == callBackGuid) { AnimationHelpers.ApplyValue(target, propertyPath, value, parameters.IsVisualStateChange); } OnIterationCompleted(parameters); }); }
private Action OnAnimationCompleted(IterationParameters parameters, bool isLastLoop, DependencyObject target, PropertyPath propertyPath) { return(() => { if (isLastLoop) { AnimationHelpers.ApplyInstantAnimation(target, propertyPath, To.Value, parameters.IsVisualStateChange); } OnIterationCompleted(parameters); }); }
internal virtual void IterateOnce(IterationParameters parameters, bool isLastLoop) { if (Duration.HasTimeSpan && Duration.TimeSpan.TotalMilliseconds > 0) { _parameters = parameters; _animationTimer.Interval = Duration.TimeSpan; _animationTimer.Tick -= _animationTimer_Tick; _animationTimer.Tick += _animationTimer_Tick; _isAnimationDurationReached = false; _animationTimer.Start(); } }
private void OnAnimationCompleted(IterationParameters parameters, bool isLastLoop, object value, DependencyObject target, PropertyPath propertyPath) { if (!this._isUnapplied) { if (isLastLoop) { AnimationHelpers.ApplyValue(target, propertyPath, value, parameters.IsVisualStateChange); } OnIterationCompleted(parameters); } }
internal override void GetTargetInformation(IterationParameters parameters) { _parameters = parameters; DependencyObject target; PropertyPath propertyPath; GetTargetElementAndPropertyInfo(parameters.Target, out target, out propertyPath, parameters.IsTargetParentTheTarget); _propertyContainer = target; _targetProperty = propertyPath; _propDp = GetProperty(_propertyContainer, _targetProperty); _target = Storyboard.GetTarget(this); _targetName = Storyboard.GetTargetName(this); }
internal override void GetTargetInformation(IterationParameters parameters) { _parameters = parameters; DependencyObject target; PropertyPath propertyPath; DependencyObject targetBeforePath; GetPropertyPathAndTargetBeforePath(parameters.Target, out targetBeforePath, out propertyPath, parameters.IsTargetParentTheTarget); DependencyObject parentElement = targetBeforePath; //this will be the parent of the clonable element (if any). foreach (Tuple <DependencyObject, DependencyProperty, int?> element in GoThroughElementsToAccessProperty(propertyPath, targetBeforePath)) { DependencyObject depObject = element.Item1; DependencyProperty depProp = element.Item2; int?index = element.Item3; if (depObject is ICloneOnAnimation) { if (!((ICloneOnAnimation)depObject).IsAlreadyAClone()) { object clone = ((ICloneOnAnimation)depObject).Clone(); if (index != null) { #if BRIDGE parentElement.GetType().GetProperty("Item").SetValue(parentElement, clone, new object[] { index }); #else //JSIL does not support SetValue(object, object, object[]) #endif } else { parentElement.SetValue(depProp, clone); } } break; } else { parentElement = depObject; } } GetTargetElementAndPropertyInfo(parameters.Target, out target, out propertyPath, parameters.IsTargetParentTheTarget); _propertyContainer = target; _targetProperty = propertyPath; _propDp = GetProperty(_propertyContainer, _targetProperty); _target = Storyboard.GetTarget(this); _targetName = Storyboard.GetTargetName(this); }
private Action OnKeyFrameCompleted(IterationParameters parameters, bool isLastLoop, object value, DependencyObject target, PropertyPath propertyPath, Guid callBackGuid) { return(() => { if (_animationID == callBackGuid) { AnimationHelpers.ApplyValue(target, propertyPath, value, parameters.IsVisualStateChange); _appliedKeyFramesCount++; if (!CheckTimeLineEndAndRaiseCompletedEvent(_parameters)) { ApplyKeyFrame(GetNextKeyFrame(), isLastLoop); } } }); }
internal override void IterateOnce(IterationParameters parameters, bool isLastLoop) { if (!_isInitialized) { Initialize(parameters); } else { RestoreDefault(); } // This is a workaround to tell the property the effective value should be the animated value. SetInitialAnimationValue(parameters.IsVisualStateChange); base.IterateOnce(parameters, isLastLoop); Apply(parameters, isLastLoop); }
private bool CheckTimeLineEndAndRaiseCompletedEvent(IterationParameters parameters) { bool raiseEvent = false; lock (thisLock) { if (_appliedKeyFramesCount >= KeyFrames.Count) { raiseEvent = true; } } if (raiseEvent || _cancelledAnimation) { OnIterationCompleted(parameters); } return(raiseEvent || _cancelledAnimation); }
internal void CheckTimeLineEndAndRaiseCompletedEvent(IterationParameters parameters) { bool raiseEvent = false; lock (thisLock) { --_expectedAmountOfKeyFrameEnds; if (_expectedAmountOfKeyFrameEnds <= 0) { raiseEvent = true; } } if (raiseEvent) { OnIterationCompleted(parameters); } }
internal override void Apply(IterationParameters parameters, bool isLastLoop) { if (To != null) { // - Get the propertyMetadata from the property PropertyMetadata propertyMetadata = _propDp.GetTypeMetaData(_propertyContainer.GetType()); //we make a specific name for this animation: string specificGroupName = parameters.VisualStateGroupName + animationInstanceSpecificName.ToString(); _animationID = Guid.NewGuid(); bool cssEquivalentExists = false; if (propertyMetadata.GetCSSEquivalent != null) { CSSEquivalent cssEquivalent = propertyMetadata.GetCSSEquivalent(_propertyContainer); if (cssEquivalent != null) { cssEquivalentExists = true; StartAnimation(_propertyContainer, cssEquivalent, From, To, Duration, (EasingFunctionBase)EasingFunction, specificGroupName, OnAnimationCompleted(parameters, isLastLoop, To.Value, _propertyContainer, _targetProperty, _animationID)); } } //todo: use GetCSSEquivalent instead (?) if (propertyMetadata.GetCSSEquivalents != null) { List <CSSEquivalent> cssEquivalents = propertyMetadata.GetCSSEquivalents(_propertyContainer); foreach (CSSEquivalent equivalent in cssEquivalents) { cssEquivalentExists = true; StartAnimation(_propertyContainer, equivalent, From, To, Duration, (EasingFunctionBase)EasingFunction, specificGroupName, OnAnimationCompleted(parameters, isLastLoop, To.Value, _propertyContainer, _targetProperty, _animationID)); } } if (!cssEquivalentExists) { OnAnimationCompleted(parameters, isLastLoop, To.Value, _propertyContainer, _targetProperty, _animationID)(); } } }
internal virtual void IterateOnce(IterationParameters parameters, bool isLastLoop) { ComputeDuration(); if (Duration.HasTimeSpan) { if (Duration.TimeSpan.TotalMilliseconds > 0) { _parameters = parameters; _animationTimer.Interval = Duration.TimeSpan; _animationTimer.Tick -= _animationTimer_Tick; _animationTimer.Tick += _animationTimer_Tick; _isAnimationDurationReached = false; _animationTimer.Start(); } else { _isAnimationDurationReached = true; //OnIterationCompleted(parameters); } } }
internal void OnIterationCompleted(IterationParameters parameters) { if (!Duration.HasTimeSpan || Duration.TimeSpan.TotalMilliseconds == 0 || _isAnimationDurationReached) //the default duration is Automatic, which currently has a TimeSpan of 0 ms (which is considered here to be no timespan). { --remainingIterations; if (remainingIterations <= 0) { if (this is Storyboard) { ((Storyboard)this).Stop(parameters.Target); } else { Stop(parameters.Target, revertToFormerValue: false); } INTERNAL_RaiseCompletedEvent(); _isAnimationDurationReached = false; //for the next time. } else { if (this is Storyboard) { ((Storyboard)this).Stop(parameters.Target); } else { Stop(parameters.Target, revertToFormerValue: true); } if (Duration.HasTimeSpan && Duration.TimeSpan.TotalMilliseconds > 0) { _isAnimationDurationReached = false; _animationTimer.Start(); } IterateOnce(parameters, isLastLoop: remainingIterations == 1); } } }
private void ApplyKeyFrame(DependencyObject target, IterationParameters parameters, PropertyPath propertyPath, Type propertyType, ObjectKeyFrame keyFrame, DispatcherTimer timer) { if (timer != null) { timer.Stop(); } _keyFramesToObjectTimers.Remove(keyFrame); object value = keyFrame.Value; if (value is string && propertyType != typeof(string)) { if (propertyType.IsEnum) { value = Enum.Parse(propertyType, (string)value); } else { //we convert the value from the given string: value = DotNetForHtml5.Core.TypeFromStringConverters.ConvertFromInvariantString(propertyType, (string)value); } } var castedValue = DynamicCast(value, propertyType); //Note: we put this line here because the Xaml could use a Color gotten from a StaticResource (which was therefore not converted to a SolidColorbrush by the compiler in the .g.cs file) and led to a wrong type set in a property (Color value in a property of type Brush). if (parameters.IsVisualStateChange) { propertyPath.INTERNAL_PropertySetVisualState(target, castedValue); } else { propertyPath.INTERNAL_PropertySetLocalValue(target, castedValue); } CheckTimeLineEndAndRaiseCompletedEvent(parameters); //---------------------------------------- //todo:clone required ? //---------------------------------------- }
/// <summary> /// Starts the first iteration of this timeline, while managing the BeginTime property. /// </summary> /// <param name="parameters">the parameters required for the iteration</param> /// <param name="isLastLoop">A boolean that says if it is the last loop</param> /// <param name="parentDelay">The Delay due to the BeginTime of the parent Timeline</param> internal void StartFirstIteration(IterationParameters parameters, bool isLastLoop, TimeSpan?parentDelay) { if (BeginTime != null) { if (BeginTime.Value.TotalMilliseconds > 0) { _beginTimeTimer = new DispatcherTimer(); //this line is to avoid having more than one callback on the tick (we cannot use "_beginTimeTimer.Tick -= XXX" since we use a anonymous method). _beginTimeTimer.Interval = BeginTime.Value; //Note: anonymous method since it allows us to use simply parameters and isLastLoop. _beginTimeTimer.Tick += (sender, args) => { _beginTimeTimer.Stop(); IterateOnce(parameters, isLastLoop); }; _beginTimeTimer.Start(); } else { IterateOnce(parameters, isLastLoop); } } }
private int CountNumberOfTargetCellsCovered(IterationParameters iterationP, Cell routerCell, List <Cell> wallCells) { var count = 0; for (int i = iterationP.StartRowRestriction; i <= iterationP.EndRowRestriction; i++) { for (int j = iterationP.StartColumnRestriction; j <= iterationP.EndColumnRestriction; j++) { if (building.cells[i, j].Type == "target") { if (IsTargetCellCovered(building.cells[i, j], routerCell, wallCells)) { // if target cell is already covered it shouldn't be taken into account anymore if (building.cells[i, j].IsCovered) { continue; } count++; } } } } return(count); }
internal override void Apply(IterationParameters parameters, bool isLastLoop) { _animationID = Guid.NewGuid(); ApplyKeyFrame(GetNextKeyFrame(), isLastLoop); }
internal virtual void Apply(IterationParameters parameters, bool isLastLoop) //Note: stateContainerGroupName is useful for allowing us to stop the animations made using velocity: we can stop all the animations from a queue of animations that has a given name { //this needs to be overriden }
internal virtual void GetTargetInformation(IterationParameters parameters) { }
//Note: stateContainerGroupName is useful for allowing us to stop the animations made using velocity: // we can stop all the animations from a queue of animations that has a given name internal virtual void Apply(IterationParameters parameters, bool isLastLoop) { // Needs to be overriden }
internal override void Apply(IterationParameters parameters, bool isLastLoop) { if (To != null) { var castedValue = DynamicCast(To, _propDp.PropertyType); //Note: we put this line here because the Xaml could use a Color gotten from a StaticResource (which was therefore not converted to a SolidColorbrush by the compiler in the .g.cs file) and led to a wrong type set in a property (Color value in a property of type Brush). // - Get the propertyMetadata from the property PropertyMetadata propertyMetadata = _propDp.GetTypeMetaData(_propertyContainer.GetType()); // - Get the cssPropertyName from the PropertyMetadata //we make a specific name for this animation: string specificGroupName = parameters.VisualStateGroupName + animationInstanceSpecificName.ToString(); bool cssEquivalentExists = false; if (propertyMetadata.GetCSSEquivalent != null) { CSSEquivalent cssEquivalent = propertyMetadata.GetCSSEquivalent(_propertyContainer); if (cssEquivalent != null) { cssEquivalentExists = true; TryStartAnimation(_propertyContainer, cssEquivalent, From, To, Duration, EasingFunction, specificGroupName, OnAnimationCompleted(parameters, isLastLoop, castedValue, _propertyContainer, _targetProperty, _animationID)); } } if (propertyMetadata.GetCSSEquivalents != null) { List <CSSEquivalent> cssEquivalents = propertyMetadata.GetCSSEquivalents(_propertyContainer); bool isFirst = true; foreach (CSSEquivalent equivalent in cssEquivalents) { cssEquivalentExists = true; if (equivalent.CallbackMethod == null) { if (isFirst) { bool updateIsFirst = TryStartAnimation(_propertyContainer, equivalent, From, To, Duration, EasingFunction, specificGroupName, OnAnimationCompleted(parameters, isLastLoop, castedValue, _propertyContainer, _targetProperty, _animationID)); if (updateIsFirst) { isFirst = false; } } else { TryStartAnimation(_propertyContainer, equivalent, From, To, Duration, EasingFunction, specificGroupName, OnAnimationCompleted(parameters, isLastLoop, castedValue, _propertyContainer, _targetProperty, _animationID)); } } else { OnAnimationCompleted(parameters, isLastLoop, castedValue, _propertyContainer, _targetProperty, _animationID)(); } } } if (!cssEquivalentExists) { OnAnimationCompleted(parameters, isLastLoop, castedValue, _propertyContainer, _targetProperty, _animationID)(); } } else { OnAnimationCompleted(parameters, isLastLoop, To, _propertyContainer, _targetProperty, _animationID)(); } }