internal override void StopAnimation(string groupName) { if (_isInitialized) { //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) //todo: "To" can never be "null", fix this. { // - Get the propertyMetadata from the property PropertyMetadata propertyMetadata = _propDp.GetTypeMetaData(_propertyContainer.GetType()); //we make a specific name for this animation: string specificGroupName = groupName + animationInstanceSpecificName.ToString(); // - Get the cssPropertyName from the PropertyMetadata if (propertyMetadata.GetCSSEquivalent != null) { CSSEquivalent cssEquivalent = propertyMetadata.GetCSSEquivalent(_propertyContainer); if (cssEquivalent != null) { UIElement uiElement = cssEquivalent.UIElement ?? (_propertyContainer as UIElement); // If no UIElement is specified, we assume that the property is intended to be applied to the instance on which the PropertyChanged has occurred. bool hasTemplate = (uiElement is Control) && ((Control)uiElement).HasTemplate; if (!hasTemplate || cssEquivalent.ApplyAlsoWhenThereIsAControlTemplate) { if (cssEquivalent.DomElement == null && uiElement != null) { cssEquivalent.DomElement = uiElement.INTERNAL_OuterDomElement; // Default value } if (cssEquivalent.DomElement != null) { CSHTML5.Interop.ExecuteJavaScriptAsync(@"Velocity($0, ""stop"", $1);", cssEquivalent.DomElement, specificGroupName); } } } } if (propertyMetadata.GetCSSEquivalents != null) { List <CSSEquivalent> cssEquivalents = propertyMetadata.GetCSSEquivalents(_propertyContainer); foreach (CSSEquivalent equivalent in cssEquivalents) { if (equivalent.DomElement != null) { CSHTML5.Interop.ExecuteJavaScriptAsync(@"Velocity($0, ""stop"", $1);", equivalent.DomElement, specificGroupName); } } } } } }
private void ApplyCSSChanges(RotateTransform rotateTransform, double angle) { CSSEquivalent anglecssEquivalent = AngleProperty.GetTypeMetaData(typeof(RotateTransform)).GetCSSEquivalent(rotateTransform); if (anglecssEquivalent != null) { object domElement = anglecssEquivalent.DomElement; if (angle != _appliedCssAngle || (_domElementToWhichTheCssWasApplied != null && domElement != _domElementToWhichTheCssWasApplied)) // Optimization to avoid setting the transform if the value is 0 or if it is the same as the last time. { INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(anglecssEquivalent.DomElement, anglecssEquivalent.Name, anglecssEquivalent.Value(rotateTransform, angle)); _appliedCssAngle = angle; _domElementToWhichTheCssWasApplied = domElement; } } }
static void StartAnimation(DependencyObject target, CSSEquivalent cssEquivalent, double?from, object to, Duration Duration, EasingFunctionBase easingFunction, string visualStateGroupName, DependencyProperty dependencyProperty, Action callbackForWhenfinished = null) { if (cssEquivalent.Name != null && cssEquivalent.Name.Count != 0) { UIElement uiElement = cssEquivalent.UIElement ?? (target as UIElement); // If no UIElement is specified, we assume that the property is intended to be applied to the instance on which the PropertyChanged has occurred. bool hasTemplate = (uiElement is Control) && ((Control)uiElement).HasTemplate; if (!hasTemplate || cssEquivalent.ApplyAlsoWhenThereIsAControlTemplate) { if (cssEquivalent.DomElement == null && uiElement != null) { cssEquivalent.DomElement = uiElement.INTERNAL_OuterDomElement; // Default value } if (cssEquivalent.DomElement != null) { if (cssEquivalent.Value == null) { cssEquivalent.Value = (finalInstance, value) => { return(value ?? ""); }; // Default value } object cssValue = cssEquivalent.Value(target, to); object newObj = CSHTML5.Interop.ExecuteJavaScriptAsync(@"new Object()"); if (AnimationHelpers.IsValueNull(from)) //todo: when using Bridge, I guess we would want to directly use "from == null" since it worked in the first place (I think). { foreach (string csspropertyName in cssEquivalent.Name) { CSHTML5.Interop.ExecuteJavaScriptAsync(@"$0[$1] = $2;", newObj, csspropertyName, cssValue); } } else { foreach (string csspropertyName in cssEquivalent.Name) { CSHTML5.Interop.ExecuteJavaScriptAsync(@"$0[$1] = [$2, $3];", newObj, csspropertyName, cssValue, from); } } AnimationHelpers.CallVelocity(cssEquivalent.DomElement, Duration, easingFunction, visualStateGroupName, callbackForWhenfinished, newObj); target.DirtyVisualValue(dependencyProperty); } } } else { throw new InvalidOperationException("Please set the Name property of the CSSEquivalent class."); } }
internal void GetCSSEquivalents(FrameworkElement frameworkElement, out CSSEquivalent cssEquivalent, out List <CSSEquivalent> cssEquivalents) { DependencyObject target; PropertyPath propertyPath; cssEquivalent = null; cssEquivalents = null; Control frameworkElementAsControl = frameworkElement as Control; //todo: check if the following comment is true and relevant or maybe remove the test if (frameworkElementAsControl != null) //if frameworkElement is not a control, there can't be a Storyboard? { GetTargetElementAndPropertyInfo(frameworkElement, out target, out propertyPath); //DependencyObject lastElementBeforeProperty = propertyPath.INTERNAL_AccessPropertyContainer(target); Type lastElementType = target.GetType(); PropertyInfo propertyInfo = lastElementType.GetProperty(propertyPath.INTERNAL_DependencyPropertyName); Type dependencyPropertyContainerType = propertyInfo.DeclaringType; FieldInfo dependencyPropertyField = dependencyPropertyContainerType.GetField(propertyPath.INTERNAL_DependencyPropertyName + "Property"); // - Get the DependencyProperty #if MIGRATION DependencyProperty dp = (global::System.Windows.DependencyProperty)dependencyPropertyField.GetValue(null); #else DependencyProperty dp = (global::Windows.UI.Xaml.DependencyProperty)dependencyPropertyField.GetValue(null); #endif // - Get the propertyMetadata from the property PropertyMetadata propertyMetadata = dp.GetTypeMetaData(target.GetType()); // - Get the cssPropertyName from the PropertyMetadata if (propertyMetadata.GetCSSEquivalent != null) { cssEquivalent = propertyMetadata.GetCSSEquivalent(target); } //todo: use GetCSSEquivalent instead (?) if (propertyMetadata.GetCSSEquivalents != null) { cssEquivalents = propertyMetadata.GetCSSEquivalents(target); } } }
internal override void StopAnimation(string groupName) { if (_isInitialized) { string specificGroupName = groupName + animationInstanceSpecificName.ToString(); if (_propertyMetadata.GetCSSEquivalent != null) { CSSEquivalent cssEquivalent = _propertyMetadata.GetCSSEquivalent(_propertyContainer); if (cssEquivalent != null) { UIElement uiElement = cssEquivalent.UIElement ?? (_propertyContainer as UIElement); // If no UIElement is specified, we assume that the property is intended to be applied to the instance on which the PropertyChanged has occurred. bool hasTemplate = (uiElement is Control) && ((Control)uiElement).HasTemplate; if (!hasTemplate || cssEquivalent.ApplyAlsoWhenThereIsAControlTemplate) { if (cssEquivalent.DomElement == null && uiElement != null) { cssEquivalent.DomElement = uiElement.INTERNAL_OuterDomElement; // Default value } if (cssEquivalent.DomElement != null) { CSHTML5.Interop.ExecuteJavaScriptAsync(@"Velocity($0, ""stop"", $1);", cssEquivalent.DomElement, specificGroupName); } } } } if (_propertyMetadata.GetCSSEquivalents != null) { List <CSSEquivalent> cssEquivalents = _propertyMetadata.GetCSSEquivalents(_propertyContainer); foreach (CSSEquivalent equivalent in cssEquivalents) { if (equivalent.DomElement != null) { CSHTML5.Interop.ExecuteJavaScriptAsync(@"Velocity($0, ""stop"", $1);", equivalent.DomElement, specificGroupName); } } } } }
private void ApplyCSSChanges(CompositeTransform compositeTransform, double scaleX, double scaleY, double skewX, double skewY, double rotation, double translateX, double translateY) { //------------- // In XAML, order is always: // 1. Scale // 2. Skew // 3. Rotate // 4. Translate // // Below we do in reverse order because in CSS the right-most operation is done first. //------------- //TranslateX: CSSEquivalent translateXcssEquivalent = TranslateXProperty.GetTypeMetaData(typeof(CompositeTransform)).GetCSSEquivalent(compositeTransform); INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(translateXcssEquivalent.DomElement, translateXcssEquivalent.Name, translateXcssEquivalent.Value(compositeTransform, translateX)); //TranslateY: CSSEquivalent translateYcssEquivalent = TranslateYProperty.GetTypeMetaData(typeof(CompositeTransform)).GetCSSEquivalent(compositeTransform); INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(translateYcssEquivalent.DomElement, translateYcssEquivalent.Name, translateYcssEquivalent.Value(compositeTransform, translateY)); //Rotation: CSSEquivalent rotationcssEquivalent = RotationProperty.GetTypeMetaData(typeof(CompositeTransform)).GetCSSEquivalent(compositeTransform); INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(rotationcssEquivalent.DomElement, rotationcssEquivalent.Name, rotationcssEquivalent.Value(compositeTransform, rotation)); //SkewX: CSSEquivalent skewXcssEquivalent = SkewXProperty.GetTypeMetaData(typeof(CompositeTransform)).GetCSSEquivalent(compositeTransform); INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(skewXcssEquivalent.DomElement, skewXcssEquivalent.Name, skewXcssEquivalent.Value(compositeTransform, skewX)); //SkewY: CSSEquivalent skewYcssEquivalent = SkewYProperty.GetTypeMetaData(typeof(CompositeTransform)).GetCSSEquivalent(compositeTransform); INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(skewYcssEquivalent.DomElement, skewYcssEquivalent.Name, skewYcssEquivalent.Value(compositeTransform, skewY)); //ScaleX: CSSEquivalent scaleXcssEquivalent = ScaleXProperty.GetTypeMetaData(typeof(CompositeTransform)).GetCSSEquivalent(compositeTransform); INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(scaleXcssEquivalent.DomElement, scaleXcssEquivalent.Name, scaleXcssEquivalent.Value(compositeTransform, scaleX)); //ScaleY: CSSEquivalent scaleYcssEquivalent = ScaleYProperty.GetTypeMetaData(typeof(CompositeTransform)).GetCSSEquivalent(compositeTransform); INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(scaleYcssEquivalent.DomElement, scaleYcssEquivalent.Name, scaleYcssEquivalent.Value(compositeTransform, scaleY)); }
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)(); } } }
void ApplyRotateTransform(double angle) { if (this.INTERNAL_parent != null && INTERNAL_VisualTreeManager.IsElementInVisualTree(this.INTERNAL_parent)) { object parentDom = this.INTERNAL_parent.INTERNAL_OuterDomElement; CSSEquivalent anglecssEquivalent = AngleProperty.GetTypeMetaData(typeof(TranslateTransform)).GetCSSEquivalent(this); INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(anglecssEquivalent.DomElement, anglecssEquivalent.Name, anglecssEquivalent.Value(this, angle)); //dynamic domStyle = INTERNAL_HtmlDomManager.GetFrameworkElementOuterStyleForModification(this.INTERNAL_parent); //string value = "rotate(" + angle + "deg)"; //todo: make sure that the conversion from double to string is culture-invariant so that it uses dots instead of commas for the decimal separator. //try //{ // domStyle.transform = value; //} //catch //{ // //do nothing //} //try //{ // domStyle.msTransform = value; //} //catch //{ // //do nothing //} //try // Prevents crash in the simulator that uses IE. //{ // domStyle.WebkitTransform = value; //} //catch //{ // //do nothing //} } }
private void ApplyCSSChanges(SkewTransform skewTransform, double angleX, double angleY) { CSSEquivalent angleXcssEquivalent = AngleXProperty.GetTypeMetaData(typeof(SkewTransform)).GetCSSEquivalent(skewTransform); object domElementX = angleXcssEquivalent.DomElement; if (angleX != _appliedCssAngleX || (_domElementToWhichTheCssAngleXWasApplied != null && domElementX != _domElementToWhichTheCssAngleXWasApplied)) // Optimization to avoid setting the transform if the value is (0,0) or if it is the same as the last time. { INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(angleXcssEquivalent.DomElement, angleXcssEquivalent.Name, angleXcssEquivalent.Value(skewTransform, angleX)); _appliedCssAngleX = angleX; _domElementToWhichTheCssAngleXWasApplied = domElementX; } CSSEquivalent angleYcssEquivalent = AngleYProperty.GetTypeMetaData(typeof(SkewTransform)).GetCSSEquivalent(skewTransform); object domElementY = angleYcssEquivalent.DomElement; if (angleY != _appliedCssAngleY || (_domElementToWhichTheCssAngleYWasApplied != null && domElementY != _domElementToWhichTheCssAngleYWasApplied)) // Optimization to avoid setting the transform if the value is (0,0) or if it is the same as the last time. { INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(angleYcssEquivalent.DomElement, angleYcssEquivalent.Name, angleYcssEquivalent.Value(skewTransform, angleY)); _appliedCssAngleY = angleY; _domElementToWhichTheCssAngleYWasApplied = domElementY; } }
//private static void Y_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) //{ // var translateTransform = (TranslateTransform)d; // double newY = (double)e.NewValue; // translateTransform.ApplyTranslateTransform(translateTransform.X, newY); //} private void ApplyCSSChanges(TranslateTransform translateTransform, double x, double y) { CSSEquivalent translateXcssEquivalent = XProperty.GetTypeMetaData(typeof(TranslateTransform)).GetCSSEquivalent(translateTransform); object domElementX = translateXcssEquivalent.DomElement; if (x != _appliedCssX || (_domElementToWhichTheCssXWasApplied != null && domElementX != _domElementToWhichTheCssXWasApplied)) // Optimization to avoid setting the transform if the value is (0,0) or if it is the same as the last time. { INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(domElementX, translateXcssEquivalent.Name, translateXcssEquivalent.Value(translateTransform, x)); _appliedCssX = x; _domElementToWhichTheCssXWasApplied = domElementX; } CSSEquivalent translateYcssEquivalent = YProperty.GetTypeMetaData(typeof(TranslateTransform)).GetCSSEquivalent(translateTransform); object domElementY = translateYcssEquivalent.DomElement; if (y != _appliedCssY || (_domElementToWhichTheCssYWasApplied != null && domElementY != _domElementToWhichTheCssYWasApplied)) // Optimization to avoid setting the transform if the value is (0,0) or if it is the same as the last time. { INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(translateYcssEquivalent.DomElement, translateYcssEquivalent.Name, translateYcssEquivalent.Value(translateTransform, y)); _appliedCssY = x; _domElementToWhichTheCssYWasApplied = domElementX; } }
internal override void INTERNAL_UnapplyTransform() { if (this.INTERNAL_parent != null && INTERNAL_VisualTreeManager.IsElementInVisualTree(this.INTERNAL_parent)) { object parentDom = this.INTERNAL_parent.INTERNAL_OuterDomElement; //------------- // In XAML, order is always: // 1. Scale // 2. Skew // 3. Rotate // 4. Translate // // Below we do in reverse order because in CSS the right-most operation is done first. //------------- //TranslateX: CSSEquivalent translateXcssEquivalent = TranslateXProperty.GetTypeMetaData(typeof(CompositeTransform)).GetCSSEquivalent(this); INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(translateXcssEquivalent.DomElement, translateXcssEquivalent.Name, translateXcssEquivalent.Value(this, 0)); //TranslateY: CSSEquivalent translateYcssEquivalent = TranslateYProperty.GetTypeMetaData(typeof(CompositeTransform)).GetCSSEquivalent(this); INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(translateYcssEquivalent.DomElement, translateYcssEquivalent.Name, translateYcssEquivalent.Value(this, 0)); //Rotation: CSSEquivalent rotationcssEquivalent = RotationProperty.GetTypeMetaData(typeof(CompositeTransform)).GetCSSEquivalent(this); INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(rotationcssEquivalent.DomElement, rotationcssEquivalent.Name, rotationcssEquivalent.Value(this, 0)); //SkewX: CSSEquivalent skewXcssEquivalent = SkewXProperty.GetTypeMetaData(typeof(CompositeTransform)).GetCSSEquivalent(this); INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(skewXcssEquivalent.DomElement, skewXcssEquivalent.Name, skewXcssEquivalent.Value(this, 0)); //SkewY: CSSEquivalent skewYcssEquivalent = SkewYProperty.GetTypeMetaData(typeof(CompositeTransform)).GetCSSEquivalent(this); INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(skewYcssEquivalent.DomElement, skewYcssEquivalent.Name, skewYcssEquivalent.Value(this, 0)); //ScaleX: CSSEquivalent scaleXcssEquivalent = ScaleXProperty.GetTypeMetaData(typeof(CompositeTransform)).GetCSSEquivalent(this); INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(scaleXcssEquivalent.DomElement, scaleXcssEquivalent.Name, scaleXcssEquivalent.Value(this, 1)); //ScaleY: CSSEquivalent scaleYcssEquivalent = ScaleYProperty.GetTypeMetaData(typeof(CompositeTransform)).GetCSSEquivalent(this); INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(scaleYcssEquivalent.DomElement, scaleYcssEquivalent.Name, scaleYcssEquivalent.Value(this, 1)); } }
internal static void ApplyCssChanges(object oldValue, object newValue, PropertyMetadata typeMetadata, DependencyObject sender) { if (typeMetadata.GetCSSEquivalent != null) { CSSEquivalent cssEquivalent = typeMetadata.GetCSSEquivalent(sender); if (cssEquivalent != null) { ApplyPropertyChanged(sender, cssEquivalent, oldValue, newValue); } } if (typeMetadata.GetCSSEquivalents != null) { List <CSSEquivalent> cssEquivalents = typeMetadata.GetCSSEquivalents(sender); if (cssEquivalents != null) { foreach (CSSEquivalent cssEquivalent in cssEquivalents) { ApplyPropertyChanged(sender, cssEquivalent, oldValue, newValue); } } } }
private void ApplyKeyFrame(DoubleKeyFrame keyFrame, bool isLastLoop) { if (keyFrame != null) { //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; StartAnimation(_propertyContainer, cssEquivalent, null, keyFrame.Value, GetKeyFrameDuration(keyFrame), keyFrame.INTERNAL_GetEasingFunction(), specificGroupName, OnKeyFrameCompleted(_parameters, isLastLoop, keyFrame.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, null, keyFrame.Value, Duration, keyFrame.INTERNAL_GetEasingFunction(), specificGroupName, OnKeyFrameCompleted(_parameters, isLastLoop, keyFrame.Value, _propertyContainer, _targetProperty, _animationID)); } } if (!cssEquivalentExists) { OnKeyFrameCompleted(_parameters, isLastLoop, keyFrame.Value, _propertyContainer, _targetProperty, _animationID)(); } } }
private void ApplyCSSChanges(double scaleX, double scaleY) { CSSEquivalent scaleXcssEquivalent = ScaleXProperty.GetTypeMetaData(typeof(ScaleTransform)).GetCSSEquivalent(this); if (scaleXcssEquivalent != null) { object domElementX = scaleXcssEquivalent.DomElement; if (scaleX != _appliedCssScaleX || (_domElementToWhichTheCssScaleXWasApplied != null && domElementX != _domElementToWhichTheCssScaleXWasApplied)) // Optimization to avoid setting the transform if the value is (0,0) or if it is the same as the last time. { INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity( scaleXcssEquivalent.DomElement, scaleXcssEquivalent.Name, scaleXcssEquivalent.Value(this, scaleX)); _appliedCssScaleX = scaleX; _domElementToWhichTheCssScaleXWasApplied = domElementX; } } CSSEquivalent scaleYcssEquivalent = ScaleYProperty.GetTypeMetaData(typeof(ScaleTransform)).GetCSSEquivalent(this); if (scaleYcssEquivalent != null) { object domElementY = scaleYcssEquivalent.DomElement; if ((scaleY != _appliedCssScaleY) || (_domElementToWhichTheCssScaleYWasApplied != null && domElementY != _domElementToWhichTheCssScaleYWasApplied)) // Optimization to avoid setting the transform if the value is (0,0) or if it is the same as the last time. { INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity( scaleYcssEquivalent.DomElement, scaleYcssEquivalent.Name, scaleYcssEquivalent.Value(this, scaleY)); _appliedCssScaleY = scaleY; _domElementToWhichTheCssScaleYWasApplied = domElementY; } } }
internal override void Stop(FrameworkElement frameworkElement, string groupName, bool revertToFormerValue = false) { base.Stop(frameworkElement, groupName, revertToFormerValue); DependencyObject target; PropertyPath propertyPath; GetTargetElementAndPropertyInfo(frameworkElement, out target, out propertyPath); //DependencyObject lastElementBeforeProperty = propertyPath.INTERNAL_AccessPropertyContainer(target); Type lastElementType = target.GetType(); PropertyInfo propertyInfo = lastElementType.GetProperty(propertyPath.INTERNAL_DependencyPropertyName); Color?valuetoSet = To; if (revertToFormerValue) { valuetoSet = (Color?)propertyInfo.GetValue(target); //propertyInfo.SetValue(target, formerValue); } //todo: find out why we put the test on target and put it back? (I removed it because it kept ScaleTransform from working properly) if (valuetoSet != null)// && target is FrameworkElement) { Type propertyType = propertyInfo.PropertyType; var castedValue = DynamicCast(valuetoSet, 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). Type dependencyPropertyContainerType = propertyInfo.DeclaringType; FieldInfo dependencyPropertyField = dependencyPropertyContainerType.GetField(propertyPath.INTERNAL_DependencyPropertyName + "Property"); // - Get the DependencyProperty #if MIGRATION DependencyProperty dp = (global::System.Windows.DependencyProperty)dependencyPropertyField.GetValue(null); #else DependencyProperty dp = (global::Windows.UI.Xaml.DependencyProperty)dependencyPropertyField.GetValue(null); #endif // - Get the propertyMetadata from the property PropertyMetadata propertyMetadata = dp.GetTypeMetaData(target.GetType()); // - Get the cssPropertyName from the PropertyMetadata //we make a specific name for this animation: string specificGroupName = groupName + animationInstanceSpecificName.ToString(); bool cssEquivalentExists = false; if (propertyMetadata.GetCSSEquivalent != null) { CSSEquivalent cssEquivalent = propertyMetadata.GetCSSEquivalent(target); UIElement uiElement = cssEquivalent.UIElement ?? (target as UIElement); // If no UIElement is specified, we assume that the property is intended to be applied to the instance on which the PropertyChanged has occurred. bool hasTemplate = (uiElement is Control) && ((Control)uiElement).HasTemplate; if (!hasTemplate || cssEquivalent.ApplyAlsoWhenThereIsAControlTemplate) { if (cssEquivalent.DomElement == null && uiElement != null) { cssEquivalent.DomElement = uiElement.INTERNAL_OuterDomElement; // Default value } if (cssEquivalent.DomElement != null) { cssEquivalentExists = true; CSHTML5.Interop.ExecuteJavaScriptAsync(@" Velocity($0, ""stop"", $1);", cssEquivalent.DomElement, specificGroupName); } } } //todo: use GetCSSEquivalent instead (?) if (propertyMetadata.GetCSSEquivalents != null) { List <CSSEquivalent> cssEquivalents = propertyMetadata.GetCSSEquivalents(target); foreach (CSSEquivalent equivalent in cssEquivalents) { if (equivalent.DomElement != null && equivalent.CallbackMethod == null) { cssEquivalentExists = true; CSHTML5.Interop.ExecuteJavaScriptAsync(@" Velocity($0, ""stop"", $1);", equivalent.DomElement, specificGroupName); if (revertToFormerValue) { propertyPath.INTERNAL_PropertySetVisualState(target, castedValue); } } } } if (!cssEquivalentExists) { propertyPath.INTERNAL_PropertySetVisualState(target, castedValue); } } else { propertyPath.INTERNAL_PropertySetVisualState(target, valuetoSet); } }
private static void ApplyPropertyChanged(DependencyObject sender, CSSEquivalent cssEquivalent, object oldValue, object newValue) { //if (cssEquivalent.ApplyWhenControlHasTemplate) //Note: this is to handle the case of a Control with a ControlTemplate (some properties must not be applied on the control itself) if (cssEquivalent.Name != null && cssEquivalent.Name.Count > 0 || cssEquivalent.CallbackMethod != null) { UIElement uiElement = cssEquivalent.UIElement ?? (sender as UIElement); // If no UIElement is specified, we assume that the property is intended to be applied to the instance on which the PropertyChanged has occurred. bool hasTemplate = (uiElement is Control) && ((Control)uiElement).HasTemplate; if (!hasTemplate || cssEquivalent.ApplyAlsoWhenThereIsAControlTemplate) { if (cssEquivalent.CallbackMethod != null)// && cssEquivalent.UIElement != null) //Note: I don't see when the commented part of this test could be false so I'm commenting it and we'll put it back if needed. { //PropertyInfo propertyInfo = uiElement.GetType().GetProperty(cssEquivalent.DependencyProperty.Name); //Type propertyType = propertyInfo.PropertyType; //var castedValue = DynamicCast(newValue, 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). //uiElement.SetVisualStateValue(cssEquivalent.DependencyProperty, castedValue); cssEquivalent.CallbackMethod(cssEquivalent.UIElement, new DependencyPropertyChangedEventArgs(oldValue, newValue, cssEquivalent.DependencyProperty)); } else { if (cssEquivalent.DomElement == null && uiElement != null) { cssEquivalent.DomElement = uiElement.INTERNAL_OuterDomElement; // Default value } if (cssEquivalent.DomElement != null) { if (newValue is ICanConvertToCSSValue) { cssEquivalent.Value = (finalInstance, value) => { return(((ICanConvertToCSSValue)value).ConvertToCSSValue()); }; } if (newValue is ICanConvertToCSSValues) { cssEquivalent.Values = (finalInstance, value) => { return(((ICanConvertToCSSValues)value).ConvertToCSSValues(sender)); }; } if (cssEquivalent.Value == null) { cssEquivalent.Value = (finalInstance, value) => { return(value ?? ""); }; // Default value } if (cssEquivalent.Values != null) { List <object> cssValues = cssEquivalent.Values(sender, newValue); if (cssEquivalent.OnlyUseVelocity) { foreach (object cssValue in cssValues) { INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(cssEquivalent.DomElement, cssEquivalent.Name, cssValue); } } else { foreach (object cssValue in cssValues) { INTERNAL_HtmlDomManager.SetDomElementStyleProperty(cssEquivalent.DomElement, cssEquivalent.Name, cssValue); } } } else if (cssEquivalent.Value != null) //I guess we cannot have both defined { object cssValue = cssEquivalent.Value(sender, newValue); if (!(cssValue is Dictionary <string, object>)) { if (cssEquivalent.OnlyUseVelocity) { INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(cssEquivalent.DomElement, cssEquivalent.Name, cssValue); } else { INTERNAL_HtmlDomManager.SetDomElementStyleProperty(cssEquivalent.DomElement, cssEquivalent.Name, cssValue); } } else { //Note: currently, only Color needs to set multiple values when using Velocity (which is why cssValue is a Dictionary), which is why it has a special treatment. //todo: if more types arrive here, find a way to have a more generic way of handling it ? if (newValue is Color) { Color newColor = (Color)newValue; if (cssEquivalent.OnlyUseVelocity) { INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(cssEquivalent.DomElement, cssEquivalent.Name, newColor.INTERNAL_ToHtmlStringForVelocity()); } else { INTERNAL_HtmlDomManager.SetDomElementStyleProperty(cssEquivalent.DomElement, cssEquivalent.Name, newColor.INTERNAL_ToHtmlString(1d)); } } } } } } } } else { throw new InvalidOperationException("Please set the Name property of the CSSEquivalent class."); } }
internal override void StopAnimation(string groupName) { if (_isInitialized) { Type lastElementType = _propertyContainer.GetType(); PropertyInfo propertyInfo = lastElementType.GetProperty(_targetProperty.INTERNAL_DependencyPropertyName); //todo: find out why we put the test on target and put it back? (I removed it because it kept ScaleTransform from working properly) if (To != null)// && target is FrameworkElement) { Type dependencyPropertyContainerType = propertyInfo.DeclaringType; FieldInfo dependencyPropertyField = dependencyPropertyContainerType.GetField(_targetProperty.INTERNAL_DependencyPropertyName + "Property"); // - Get the DependencyProperty #if MIGRATION DependencyProperty dp = (global::System.Windows.DependencyProperty)dependencyPropertyField.GetValue(null); #else DependencyProperty dp = (global::Windows.UI.Xaml.DependencyProperty)dependencyPropertyField.GetValue(null); #endif // - Get the propertyMetadata from the property PropertyMetadata propertyMetadata = dp.GetTypeMetaData(_propertyContainer.GetType()); // - Get the cssPropertyName from the PropertyMetadata //we make a specific name for this animation: string specificGroupName = groupName + animationInstanceSpecificName.ToString(); bool cssEquivalentExists = false; if (propertyMetadata.GetCSSEquivalent != null) { CSSEquivalent cssEquivalent = propertyMetadata.GetCSSEquivalent(_propertyContainer); UIElement uiElement = cssEquivalent.UIElement ?? (_propertyContainer as UIElement); // If no UIElement is specified, we assume that the property is intended to be applied to the instance on which the PropertyChanged has occurred. bool hasTemplate = (uiElement is Control) && ((Control)uiElement).HasTemplate; if (!hasTemplate || cssEquivalent.ApplyAlsoWhenThereIsAControlTemplate) { if (cssEquivalent.DomElement == null && uiElement != null) { cssEquivalent.DomElement = uiElement.INTERNAL_OuterDomElement; // Default value } if (cssEquivalent.DomElement != null) { cssEquivalentExists = true; CSHTML5.Interop.ExecuteJavaScriptAsync(@"Velocity($0, ""stop"", $1);", cssEquivalent.DomElement, specificGroupName); } } } //todo: use GetCSSEquivalent instead (?) if (propertyMetadata.GetCSSEquivalents != null) { List <CSSEquivalent> cssEquivalents = propertyMetadata.GetCSSEquivalents(_propertyContainer); foreach (CSSEquivalent equivalent in cssEquivalents) { if (equivalent.DomElement != null && equivalent.CallbackMethod == null) { cssEquivalentExists = true; CSHTML5.Interop.ExecuteJavaScriptAsync(@"Velocity($0, ""stop"", $1);", equivalent.DomElement, specificGroupName); } } } } } }
static bool TryStartAnimation(DependencyObject target, CSSEquivalent cssEquivalent, Color?from, object to, Duration Duration, EasingFunctionBase easingFunction, string visualStateGroupName, Action callbackForWhenfinished = null) { if (cssEquivalent.Name != null && cssEquivalent.Name.Count != 0) { UIElement uiElement = cssEquivalent.UIElement ?? (target as UIElement); // If no UIElement is specified, we assume that the property is intended to be applied to the instance on which the PropertyChanged has occurred. bool hasTemplate = (uiElement is Control) && ((Control)uiElement).HasTemplate; if (!hasTemplate || cssEquivalent.ApplyAlsoWhenThereIsAControlTemplate) { if (cssEquivalent.DomElement == null && uiElement != null) { cssEquivalent.DomElement = uiElement.INTERNAL_OuterDomElement; // Default value } if (cssEquivalent.DomElement != null) { if (cssEquivalent.Value == null) { cssEquivalent.Value = (finalInstance, value) => { if (value == null) { return(""); } else { Dictionary <string, object> valuesDict = new Dictionary <string, object>(); foreach (string name in cssEquivalent.Name) { if (!name.EndsWith("Alpha")) { valuesDict.Add(name, ((Color)value).INTERNAL_ToHtmlStringForVelocity()); } else { valuesDict.Add(name, ((double)((Color)value).A) / 255); } } return(valuesDict); } //return value ?? ""; }; // Default value } object cssValue = cssEquivalent.Value(target, to); //INTERNAL_HtmlDomManager.SetDomElementStyleProperty(cssEquivalent.DomElement, cssEquivalent.Name, cssValue); object newObj = CSHTML5.Interop.ExecuteJavaScriptAsync(@"new Object()"); if (AnimationHelpers.IsValueNull(from)) //todo: when using Bridge, I guess we would want to directly use "from == null" since it worked in the first place (I think). { if (!(cssValue is Dictionary <string, object>)) { foreach (string csspropertyName in cssEquivalent.Name) { //todo: check the note below once the clone will work properly (a value set through velocity is not set in c#, which makes the clone take the former value). //Note: the test below is to avoid setting Background because Velocity cannot handle it, // which makes the element go transparent (no color) before then changing color with backgroundColor. // Therefore, we no longer go in the animation from the previous color to the new one but from no color to the new one if (csspropertyName != "background") //todo: when we will be able to use velocity for linearGradientBrush, we will need another solution here. { CSHTML5.Interop.ExecuteJavaScriptAsync(@"$0[$1] = $2;", newObj, csspropertyName, cssValue); } } } else { Dictionary <string, object> cssValueAsDictionary = (Dictionary <string, object>)cssValue; foreach (string csspropertyName in cssEquivalent.Name) { //todo: check the note below once the clone will work properly (a value set through velocity is not set in c#, which makes the clone take the former value). //Note: the test below is to avoid setting Background because Velocity cannot handle it, // which makes the element go transparent (no color) before then changing color with backgroundColor. // Therefore, we no longer go in the animation from the previous color to the new one but from no color to the new one if (csspropertyName != "background") //todo: when we will be able to use velocity for linearGradientBrush, we will need another solution here. { CSHTML5.Interop.ExecuteJavaScriptAsync(@"$0[$1] = $2;", newObj, csspropertyName, cssValueAsDictionary[csspropertyName]); } } } } else { object fromCssValue = cssEquivalent.Value(target, from); foreach (string csspropertyName in cssEquivalent.Name) { //todo: check the note below once the clone will work properly (a value set through velocity is not set in c#, which makes the clone take the former value). //Note: the test below is to avoid setting Background because Velocity cannot handle it, // which makes the element go transparent (no color) before then changing color with backgroundColor. // Therefore, we no longer go in the animation from the previous color to the new one but from no color to the new one if (csspropertyName != "background") //todo: when we will be able to use velocity for linearGradientBrush, we will need another solution here. { object currentCssValue = cssValue; if (cssValue is Dictionary <string, object> ) { currentCssValue = ((Dictionary <string, object>)cssValue)[csspropertyName]; } object currentFromCssValue = fromCssValue; if (fromCssValue is Dictionary <string, object> ) { currentFromCssValue = ((Dictionary <string, object>)fromCssValue)[csspropertyName]; } CSHTML5.Interop.ExecuteJavaScriptAsync(@"$0[$1] = [$2, $3];", newObj, csspropertyName, currentCssValue, currentFromCssValue); } } } AnimationHelpers.CallVelocity(cssEquivalent.DomElement, Duration, easingFunction, visualStateGroupName, callbackForWhenfinished, newObj); return(true); } } return(false); } else { throw new InvalidOperationException("Please set the Name property of the CSSEquivalent class."); } }
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)(); } }
private void ApplyCSSChanges(RotateTransform rotateTransform, double angle) { CSSEquivalent anglecssEquivalent = AngleProperty.GetTypeMetaData(typeof(TranslateTransform)).GetCSSEquivalent(rotateTransform); INTERNAL_HtmlDomManager.SetDomElementStylePropertyUsingVelocity(anglecssEquivalent.DomElement, anglecssEquivalent.Name, anglecssEquivalent.Value(rotateTransform, angle)); }
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); DependencyProperty dp = GetProperty(target, propertyPath); //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) { // - Get the propertyMetadata from the property 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, () => { if (isLastLoop) { if (parameters.IsVisualStateChange) //if we change the visual state, we set the VisualStateValue in the storage { propertyPath.INTERNAL_PropertySetVisualState(target, To); } else //otherwise (if we used Storyboard.Begin()), we set the Local value in the storage { propertyPath.INTERNAL_PropertySetLocalValue(target, To); } } OnIterationCompleted(parameters); //INTERNAL_RaiseCompletedEvent(applyCallGuid); }); } } //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, () => { if (isLastLoop) { if (parameters.IsVisualStateChange) //if we change the visual state, we set the VisualStateValue in the storage { propertyPath.INTERNAL_PropertySetVisualState(target, To); } else //otherwise (if we used Storyboard.Begin()), we set the Local value in the storage { propertyPath.INTERNAL_PropertySetLocalValue(target, To); } } OnIterationCompleted(parameters); //INTERNAL_RaiseCompletedEvent(applyCallGuid); }); } } if (!cssEquivalentExists) { if (isLastLoop) { if (parameters.IsVisualStateChange) { propertyPath.INTERNAL_PropertySetVisualState(target, To); } else { propertyPath.INTERNAL_PropertySetLocalValue(target, To); } } OnIterationCompleted(parameters); //INTERNAL_RaiseCompletedEvent(applyCallGuid); } } //else //{ // if (isLastLoop) // { // if (parameters.IsVisualStateChange) // { // propertyPath.INTERNAL_PropertySetVisualState(target, To); // } // else // { // propertyPath.INTERNAL_PropertySetLocalValue(target, To); // } // } // OnIterationCompleted(parameters); // //INTERNAL_RaiseCompletedEvent(applyCallGuid); //} } }
internal override void Apply(IterationParameters parameters, bool isLastLoop) { 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). //we clone what needs to be cloned (ICloneOnAnimation: contient Clone() ) --> // foreach sur le résultat de la méthode autogénérée avec les yield return et on clone le 1er ICloneOnAnimation 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.HasValue) { if (Interop.IsRunningInTheSimulator) { parentElement.GetType().GetProperty("Item").SetValue(parentElement, clone, new object[] { index.Value }); } else { #if BRIDGE parentElement.GetType().GetProperty("Item").SetValue(parentElement, clone, new object[] { index.Value }); #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); //we do the following normally Type lastElementType = target.GetType(); PropertyInfo propertyInfo = lastElementType.GetProperty(propertyPath.INTERNAL_DependencyPropertyName); //todo: find out why we put the test on target and put it back? (I removed it because it kept ScaleTransform from working properly) if (To != null)// && target is FrameworkElement) { Type propertyType = propertyInfo.PropertyType; var castedValue = DynamicCast(To, 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). Type dependencyPropertyContainerType = propertyInfo.DeclaringType; FieldInfo dependencyPropertyField = dependencyPropertyContainerType.GetField(propertyPath.INTERNAL_DependencyPropertyName + "Property"); // - Get the DependencyProperty #if MIGRATION DependencyProperty dp = (global::System.Windows.DependencyProperty)dependencyPropertyField.GetValue(null); #else DependencyProperty dp = (global::Windows.UI.Xaml.DependencyProperty)dependencyPropertyField.GetValue(null); #endif // - Get the propertyMetadata from the property PropertyMetadata propertyMetadata = dp.GetTypeMetaData(target.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(target); if (cssEquivalent != null) { cssEquivalentExists = true; TryStartAnimation(target, cssEquivalent, From, To, Duration, EasingFunction, specificGroupName, () => { if (isLastLoop) { if (parameters.IsVisualStateChange) //if we change the visual state, we set the VisualStateValue in the storage { propertyPath.INTERNAL_PropertySetVisualState(target, castedValue); } else //otherwise (if we used Storyboard.Begin()), we set the Local value in the storage { propertyPath.INTERNAL_PropertySetLocalValue(target, castedValue); } } OnIterationCompleted(parameters); }); } } if (propertyMetadata.GetCSSEquivalents != null) { List <CSSEquivalent> cssEquivalents = propertyMetadata.GetCSSEquivalents(target); bool isFirst = true; foreach (CSSEquivalent equivalent in cssEquivalents) { cssEquivalentExists = true; if (equivalent.CallbackMethod == null) { if (isFirst) { bool updateIsFirst = TryStartAnimation(target, equivalent, From, To, Duration, EasingFunction, specificGroupName, () => { if (isLastLoop) { if (parameters.IsVisualStateChange) //if we change the visual state, we set the VisualStateValue in the storage { propertyPath.INTERNAL_PropertySetVisualState(target, castedValue); } else //otherwise (if we used Storyboard.Begin()), we set the Local value in the storage { propertyPath.INTERNAL_PropertySetLocalValue(target, castedValue); } } OnIterationCompleted(parameters); }); if (updateIsFirst) { isFirst = false; } } else { TryStartAnimation(target, equivalent, From, To, Duration, EasingFunction, specificGroupName, () => { if (isLastLoop) { if (parameters.IsVisualStateChange) //if we change the visual state, we set the VisualStateValue in the storage { propertyPath.INTERNAL_PropertySetVisualState(target, castedValue); } else //otherwise (if we used Storyboard.Begin()), we set the Local value in the storage { propertyPath.INTERNAL_PropertySetLocalValue(target, castedValue); } } }); } } else { if (isLastLoop) { if (parameters.IsVisualStateChange) { propertyPath.INTERNAL_PropertySetVisualState(target, castedValue); } else { propertyPath.INTERNAL_PropertySetLocalValue(target, castedValue); } } OnIterationCompleted(parameters); } } } if (!cssEquivalentExists) { if (parameters.IsVisualStateChange) { propertyPath.INTERNAL_PropertySetVisualState(target, castedValue); } else { propertyPath.INTERNAL_PropertySetLocalValue(target, castedValue); } OnIterationCompleted(parameters); } } else { if (parameters.IsVisualStateChange) { propertyPath.INTERNAL_PropertySetVisualState(target, To); } else { propertyPath.INTERNAL_PropertySetLocalValue(target, To); } OnIterationCompleted(parameters); } }
internal override void Stop(FrameworkElement frameworkElement, string groupName, bool revertToFormerValue = false) { base.Stop(frameworkElement, groupName, revertToFormerValue); DependencyObject target; PropertyPath propertyPath; GetTargetElementAndPropertyInfo(frameworkElement, out target, out propertyPath); Type lastElementType = target.GetType(); PropertyInfo propertyInfo = lastElementType.GetProperty(propertyPath.INTERNAL_DependencyPropertyName); //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) //todo: "To" can never be "null", fix this. { Type dependencyPropertyContainerType = propertyInfo.DeclaringType; FieldInfo dependencyPropertyField = dependencyPropertyContainerType.GetField(propertyPath.INTERNAL_DependencyPropertyName + "Property"); // - Get the DependencyProperty #if MIGRATION DependencyProperty dp = (global::System.Windows.DependencyProperty)dependencyPropertyField.GetValue(null); #else DependencyProperty dp = (global::Windows.UI.Xaml.DependencyProperty)dependencyPropertyField.GetValue(null); #endif // - Get the propertyMetadata from the property PropertyMetadata propertyMetadata = dp.GetTypeMetaData(target.GetType()); // - Get the cssPropertyName from the PropertyMetadata //we make a specific name for this animation: string specificGroupName = groupName + animationInstanceSpecificName.ToString(); if (propertyMetadata.GetCSSEquivalent != null) { CSSEquivalent cssEquivalent = propertyMetadata.GetCSSEquivalent(target); UIElement uiElement = cssEquivalent.UIElement ?? (target as UIElement); // If no UIElement is specified, we assume that the property is intended to be applied to the instance on which the PropertyChanged has occurred. bool hasTemplate = (uiElement is Control) && ((Control)uiElement).HasTemplate; if (!hasTemplate || cssEquivalent.ApplyAlsoWhenThereIsAControlTemplate) { if (cssEquivalent.DomElement == null && uiElement != null) { cssEquivalent.DomElement = uiElement.INTERNAL_OuterDomElement; // Default value } if (cssEquivalent.DomElement != null) { CSHTML5.Interop.ExecuteJavaScriptAsync(@" Velocity($0, ""stop"", $1);", cssEquivalent.DomElement, specificGroupName); } } } if (propertyMetadata.GetCSSEquivalents != null) { List <CSSEquivalent> cssEquivalents = propertyMetadata.GetCSSEquivalents(target); foreach (CSSEquivalent equivalent in cssEquivalents) { if (equivalent.DomElement != null) { CSHTML5.Interop.ExecuteJavaScriptAsync(@" Velocity($0, ""stop"", $1);", equivalent.DomElement, specificGroupName); } } } } //else //{ // propertyPath.INTERNAL_PropertySetVisualState(target, To); //To = null here --> Is it really what we want to do? //} if (revertToFormerValue) //todo: check if this is sufficient or if we need to put stuff into the GetCSSEquivalents thing like for ColorAnimation: { object formerValue = propertyInfo.GetValue(target); propertyInfo.SetValue(target, formerValue); } }
internal static List <CSSEquivalent> MergeCSSEquivalentsOfTheParentsProperties(Brush brush, Func <CSSEquivalent, ValueToHtmlConverter> parentPropertyToValueToHtmlConverter) // note: "CSSEquivalent" here stands for the CSSEquicalent of the parent property. { List <CSSEquivalent> result = new List <CSSEquivalent>(); //We copy brush.PropertiesWhereUsed in a local variable because we need to modify it in the foreach: HashSet2 <KeyValuePair <DependencyObject, DependencyProperty> > propertiesWhereUsed = new HashSet2 <KeyValuePair <DependencyObject, DependencyProperty> >(); foreach (KeyValuePair <DependencyObject, DependencyProperty> tuple in brush.PropertiesWhereUsed) { propertiesWhereUsed.Add(tuple); } foreach (KeyValuePair <DependencyObject, DependencyProperty> tuple in propertiesWhereUsed) { UIElement uiElement = tuple.Key as UIElement; DependencyProperty dependencyProperty = tuple.Value; if (uiElement != null) { if (!INTERNAL_VisualTreeManager.IsElementInVisualTree(uiElement)) { brush.PropertiesWhereUsed.Remove(tuple); } else { PropertyMetadata propertyMetadata = dependencyProperty.GetTypeMetaData(uiElement.GetType()); if (propertyMetadata.GetCSSEquivalent != null) // If the parent has a CSSEquivalent, we use it, otherwise we use the parent PropertyChanged method. { var parentPropertyCSSEquivalent = propertyMetadata.GetCSSEquivalent(uiElement); CSSEquivalent newCSSEquivalent = new CSSEquivalent() { Name = parentPropertyCSSEquivalent.Name, ApplyAlsoWhenThereIsAControlTemplate = parentPropertyCSSEquivalent.ApplyAlsoWhenThereIsAControlTemplate, Value = parentPropertyToValueToHtmlConverter(parentPropertyCSSEquivalent), DomElement = parentPropertyCSSEquivalent.DomElement, UIElement = uiElement }; if (newCSSEquivalent.DomElement == null) { newCSSEquivalent.DomElement = uiElement.INTERNAL_OuterDomElement; } result.Add(newCSSEquivalent); } else { //we want to create a CSSEquivalent that will just make the UIElement call the property callback if any: if (propertyMetadata.PropertyChangedCallback != null) { result.Add(new CSSEquivalent() { UIElement = uiElement, CallbackMethod = propertyMetadata.PropertyChangedCallback, DependencyProperty = dependencyProperty }); } } } } else { //Commented because it could be a Setter in a Style //throw new NotSupportedException("A solidColorBrush cannot currently be set inside a class that desn't inherit from UIElement."); } } return(result); }