diff --git a/src/SamplesApp/UITests.Shared/Microsoft_UI_Xaml_Controls/AnimatedVisualPlayer/Checkmark.cs b/src/SamplesApp/UITests.Shared/Microsoft_UI_Xaml_Controls/AnimatedVisualPlayer/Checkmark.cs new file mode 100644 index 000000000000..babd4beae2db --- /dev/null +++ b/src/SamplesApp/UITests.Shared/Microsoft_UI_Xaml_Controls/AnimatedVisualPlayer/Checkmark.cs @@ -0,0 +1,1324 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// LottieGen version: +// 8.1.240821.1+077322fa26 +// +// Command: +// LottieGen -Language CSharp -Public -WinUIVersion 3.0 -InputFile Checkmark.lottie +// +// Input file: +// Checkmark.lottie (2345 bytes created 13:06+01:00 Jan 23 2025) +// +// LottieGen source: +// http://aka.ms/Lottie +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ +// ____________________________________ +// | Object stats | Count | +// |__________________________|_______| +// | All CompositionObjects | 202 | +// |--------------------------+-------| +// | Expression animators | 17 | +// | KeyFrame animators | 33 | +// | Reference parameters | 17 | +// | Expression operations | 0 | +// |--------------------------+-------| +// | Animated brushes | 1 | +// | Animated gradient stops | - | +// | ExpressionAnimations | 17 | +// | PathKeyFrameAnimations | - | +// |--------------------------+-------| +// | ContainerVisuals | 12 | +// | ShapeVisuals | 12 | +// |--------------------------+-------| +// | ContainerShapes | - | +// | CompositionSpriteShapes | 13 | +// |--------------------------+-------| +// | Brushes | 3 | +// | Gradient stops | - | +// | CompositionVisualSurface | - | +// ------------------------------------ +using Microsoft.Graphics; +using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.UI.Composition; +using Microsoft.UI.Xaml.Controls; +using System; +using System.Collections.Generic; +using System.Numerics; +using Windows.Foundation; +using Windows.UI; + +namespace AnimatedVisuals +{ + // Name: Comp 1 + // Frame rate: 29.9700012207031 fps + // Frame count: 45.0000018328876 + // Duration: 1501.5 mS + sealed class Checkmark + : Microsoft.UI.Xaml.Controls.IAnimatedVisualSource + , Microsoft.UI.Xaml.Controls.IAnimatedVisualSource2 + { + // Animation duration: 1.502 seconds. + internal const long c_durationTicks = 15015015; + + public Microsoft.UI.Xaml.Controls.IAnimatedVisual TryCreateAnimatedVisual(Compositor compositor) + { + object ignored = null; + return TryCreateAnimatedVisual(compositor, out ignored); + } + + public Microsoft.UI.Xaml.Controls.IAnimatedVisual TryCreateAnimatedVisual(Compositor compositor, out object diagnostics) + { + diagnostics = null; + + var res = + new Checkmark_AnimatedVisual( + compositor + ); + res.CreateAnimations(); + return res; + } + + /// + /// Gets the number of frames in the animation. + /// + public double FrameCount => 45.0000018328876; + + /// + /// Gets the frame rate of the animation. + /// + public double Framerate => 29.9700012207031; + + /// + /// Gets the duration of the animation. + /// + public TimeSpan Duration => TimeSpan.FromTicks(15015015); + + /// + /// Converts a zero-based frame number to the corresponding progress value denoting the + /// start of the frame. + /// + public double FrameToProgress(double frameNumber) + { + return frameNumber / 45.0000018328876; + } + + /// + /// Returns a map from marker names to corresponding progress values. + /// + public IReadOnlyDictionary Markers => + new Dictionary + { + }; + + /// + /// Sets the color property with the given name, or does nothing if no such property + /// exists. + /// + public void SetColorProperty(string propertyName, Color value) + { + } + + /// + /// Sets the scalar property with the given name, or does nothing if no such property + /// exists. + /// + public void SetScalarProperty(string propertyName, double value) + { + } + + public void Update(AnimatedVisualPlayer player) => throw new NotImplementedException(); + public void Load() => throw new NotImplementedException(); + public void Unload() => throw new NotImplementedException(); + public void Play(double fromProgress, double toProgress, bool looped) => throw new NotImplementedException(); + public void Stop() => throw new NotImplementedException(); + public void Pause() => throw new NotImplementedException(); + public void Resume() => throw new NotImplementedException(); + public void SetProgress(double progress) => throw new NotImplementedException(); + public Size Measure(Size availableSize) => throw new NotImplementedException(); + + sealed class Checkmark_AnimatedVisual + : Microsoft.UI.Xaml.Controls.IAnimatedVisual + , Microsoft.UI.Xaml.Controls.IAnimatedVisual2 + { + const long c_durationTicks = 15015015; + readonly Compositor _c; + readonly ExpressionAnimation _reusableExpressionAnimation; + AnimationController _animationController_0; + CompositionColorBrush _animatedColorBrush_TransparentWhite_to_TransparentWhite; + CompositionColorBrush _colorBrush_AlmostDodgerBlue_FF149BD6; + CompositionEllipseGeometry _ellipse_0_0; + CompositionEllipseGeometry _ellipse_0_1; + CompositionEllipseGeometry _ellipse_0_2; + CompositionEllipseGeometry _ellipse_0_3; + CompositionPath _path; + CompositionPathGeometry _pathGeometry_0; + CompositionPathGeometry _pathGeometry_1; + CompositionPathGeometry _pathGeometry_2; + CompositionPathGeometry _pathGeometry_3; + CompositionPathGeometry _pathGeometry_4; + CompositionPathGeometry _pathGeometry_5; + CompositionPathGeometry _pathGeometry_6; + CompositionPathGeometry _pathGeometry_7; + CompositionPathGeometry _pathGeometry_8; + CompositionSpriteShape _spriteShape_06; + CompositionSpriteShape _spriteShape_07; + CompositionSpriteShape _spriteShape_08; + ContainerVisual _root; + CubicBezierEasingFunction _cubicBezierEasingFunction_0; + CubicBezierEasingFunction _cubicBezierEasingFunction_1; + CubicBezierEasingFunction _cubicBezierEasingFunction_2; + CubicBezierEasingFunction _cubicBezierEasingFunction_3; + CubicBezierEasingFunction _cubicBezierEasingFunction_4; + CubicBezierEasingFunction _cubicBezierEasingFunction_5; + InsetClip _insetClip_0; + ScalarKeyFrameAnimation _opacityScalarAnimation_1_to_0p3_0; + ScalarKeyFrameAnimation _opacityScalarAnimation_1_to_0p3_1; + ScalarKeyFrameAnimation _tEndScalarAnimation_0_to_1_0; + ScalarKeyFrameAnimation _tEndScalarAnimation_0_to_1_1; + ScalarKeyFrameAnimation _tStartScalarAnimation_0_to_1_0; + ScalarKeyFrameAnimation _tStartScalarAnimation_0_to_1_1; + ShapeVisual _shapeVisual_01; + ShapeVisual _shapeVisual_02; + ShapeVisual _shapeVisual_03; + ShapeVisual _shapeVisual_04; + ShapeVisual _shapeVisual_08; + ShapeVisual _shapeVisual_09; + ShapeVisual _shapeVisual_10; + ShapeVisual _shapeVisual_11; + StepEasingFunction _holdThenStepEasingFunction; + StepEasingFunction _stepThenHoldEasingFunction; + Vector2KeyFrameAnimation _offsetVector2Animation; + Vector2KeyFrameAnimation _radiusVector2Animation_1; + + void BindProperty( + CompositionObject target, + string animatedPropertyName, + string expression, + string referenceParameterName, + CompositionObject referencedObject) + { + _reusableExpressionAnimation.ClearAllParameters(); + _reusableExpressionAnimation.Expression = expression; + _reusableExpressionAnimation.SetReferenceParameter(referenceParameterName, referencedObject); + target.StartAnimation(animatedPropertyName, _reusableExpressionAnimation); + } + + ColorKeyFrameAnimation CreateColorKeyFrameAnimation(float initialProgress, Color initialValue, CompositionEasingFunction initialEasingFunction) + { + var result = _c.CreateColorKeyFrameAnimation(); + result.Duration = TimeSpan.FromTicks(c_durationTicks); + result.InterpolationColorSpace = CompositionColorSpace.Rgb; + result.InsertKeyFrame(initialProgress, initialValue, initialEasingFunction); + return result; + } + + ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation(float initialProgress, float initialValue, CompositionEasingFunction initialEasingFunction) + { + var result = _c.CreateScalarKeyFrameAnimation(); + result.Duration = TimeSpan.FromTicks(c_durationTicks); + result.InsertKeyFrame(initialProgress, initialValue, initialEasingFunction); + return result; + } + + Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation(float initialProgress, Vector2 initialValue, CompositionEasingFunction initialEasingFunction) + { + var result = _c.CreateVector2KeyFrameAnimation(); + result.Duration = TimeSpan.FromTicks(c_durationTicks); + result.InsertKeyFrame(initialProgress, initialValue, initialEasingFunction); + return result; + } + + CompositionSpriteShape CreateSpriteShape(CompositionGeometry geometry, Matrix3x2 transformMatrix) + { + var result = _c.CreateSpriteShape(geometry); + result.TransformMatrix = transformMatrix; + return result; + } + + CompositionSpriteShape CreateSpriteShape(CompositionGeometry geometry, Matrix3x2 transformMatrix, CompositionBrush fillBrush) + { + var result = _c.CreateSpriteShape(geometry); + result.TransformMatrix = transformMatrix; + result.FillBrush = fillBrush; + return result; + } + + AnimationController AnimationController_0() + { + if (_animationController_0 != null) { return _animationController_0; } + var result = _animationController_0 = _c.CreateAnimationController(); + result.Pause(); + BindProperty(_animationController_0, "Progress", "_.Progress", "_", _root); + return result; + } + + // - - - Layer aggregator + // - - Scale:0.6959,0.6959, Offset:<236.888, 240.258> + CanvasGeometry Geometry_0() + { + CanvasGeometry result; + using (var builder = new CanvasPathBuilder(null)) + { + builder.BeginFigure(new Vector2(-76.4260025F, 37.9990005F)); + builder.AddLine(new Vector2(12.0559998F, 114.073997F)); + builder.AddLine(new Vector2(169.990997F, -68.6350021F)); + builder.EndFigure(CanvasFigureLoop.Open); + result = CanvasGeometry.CreatePath(builder); + } + return result; + } + + CanvasGeometry Geometry_1() + { + CanvasGeometry result; + using (var builder = new CanvasPathBuilder(null)) + { + builder.BeginFigure(new Vector2(-230F, 4F)); + builder.AddLine(new Vector2(214F, 4F)); + builder.EndFigure(CanvasFigureLoop.Open); + result = CanvasGeometry.CreatePath(builder); + } + return result; + } + + // Color + ColorKeyFrameAnimation ColorAnimation_TransparentWhite_to_TransparentWhite() + { + // Frame 0. + var result = CreateColorKeyFrameAnimation(0F, Color.FromArgb(0x00, 0xFF, 0xFF, 0xFF), StepThenHoldEasingFunction()); + // Frame 24. + // TransparentWhite + result.InsertKeyFrame(0.533333302F, Color.FromArgb(0x00, 0xFF, 0xFF, 0xFF), HoldThenStepEasingFunction()); + // Frame 25. + // White + result.InsertKeyFrame(0.555555522F, Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), CubicBezierEasingFunction_5()); + // Frame 29. + // White + result.InsertKeyFrame(0.644444406F, Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), CubicBezierEasingFunction_5()); + // Frame 38. + // TransparentWhite + result.InsertKeyFrame(0.844444454F, Color.FromArgb(0x00, 0xFF, 0xFF, 0xFF), CubicBezierEasingFunction_5()); + return result; + } + + CompositionColorBrush AnimatedColorBrush_TransparentWhite_to_TransparentWhite() + { + if (_animatedColorBrush_TransparentWhite_to_TransparentWhite != null) { return _animatedColorBrush_TransparentWhite_to_TransparentWhite; } + var result = _animatedColorBrush_TransparentWhite_to_TransparentWhite = _c.CreateColorBrush(); + return result; + } + + CompositionColorBrush ColorBrush_AlmostDodgerBlue_FF149BD6() + { + return (_colorBrush_AlmostDodgerBlue_FF149BD6 == null) + ? _colorBrush_AlmostDodgerBlue_FF149BD6 = _c.CreateColorBrush(Color.FromArgb(0xFF, 0x14, 0x9B, 0xD6)) + : _colorBrush_AlmostDodgerBlue_FF149BD6; + } + + // - Layer aggregator + // Scale:0.6959,0.6959, Offset:<236.888, 240.258> + CompositionColorBrush ColorBrush_White() + { + return _c.CreateColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF)); + } + + // - Layer aggregator + // Scale:0.8,0.8, Offset:<256, 256> + // Ellipse Path 1.EllipseGeometry + CompositionEllipseGeometry Ellipse_0_0() + { + if (_ellipse_0_0 != null) { return _ellipse_0_0; } + var result = _ellipse_0_0 = _c.CreateEllipseGeometry(); + result.Radius = new Vector2(0F, 0F); + return result; + } + + // - - PreComp layer: firefly + // - Shape tree root for layer: Shape Layer 1 + // Offset:<256, 256> + // Ellipse Path 1.EllipseGeometry + CompositionEllipseGeometry Ellipse_0_1() + { + if (_ellipse_0_1 != null) { return _ellipse_0_1; } + var result = _ellipse_0_1 = _c.CreateEllipseGeometry(); + result.Radius = new Vector2(0F, 0F); + return result; + } + + // - - PreComp layer: firefly + // - Shape tree root for layer: Shape Layer 1 + // Offset:<256, 256> + // Ellipse Path 1.EllipseGeometry + CompositionEllipseGeometry Ellipse_0_2() + { + if (_ellipse_0_2 != null) { return _ellipse_0_2; } + var result = _ellipse_0_2 = _c.CreateEllipseGeometry(); + result.Radius = new Vector2(0F, 0F); + return result; + } + + // - - PreComp layer: firefly + // - Shape tree root for layer: Shape Layer 1 + // Offset:<256, 256> + // Ellipse Path 1.EllipseGeometry + CompositionEllipseGeometry Ellipse_0_3() + { + if (_ellipse_0_3 != null) { return _ellipse_0_3; } + var result = _ellipse_0_3 = _c.CreateEllipseGeometry(); + result.Radius = new Vector2(0F, 0F); + return result; + } + + CompositionPath Path() + { + if (_path != null) { return _path; } + var result = _path = new CompositionPath(Geometry_1()); + return result; + } + + // - Layer aggregator + // Scale:0.6959,0.6959, Offset:<236.888, 240.258> + CompositionPathGeometry PathGeometry_0() + { + if (_pathGeometry_0 != null) { return _pathGeometry_0; } + var result = _pathGeometry_0 = _c.CreatePathGeometry(new CompositionPath(Geometry_0())); + return result; + } + + CompositionPathGeometry PathGeometry_1() + { + if (_pathGeometry_1 != null) { return _pathGeometry_1; } + var result = _pathGeometry_1 = _c.CreatePathGeometry(Path()); + var propertySet = result.Properties; + propertySet.InsertScalar("TEnd", 0F); + propertySet.InsertScalar("TStart", 0F); + BindProperty(_pathGeometry_1, "TrimStart", "Min(my.TStart,my.TEnd)", "my", _pathGeometry_1); + BindProperty(_pathGeometry_1, "TrimEnd", "Max(my.TStart,my.TEnd)", "my", _pathGeometry_1); + return result; + } + + CompositionPathGeometry PathGeometry_2() + { + if (_pathGeometry_2 != null) { return _pathGeometry_2; } + var result = _pathGeometry_2 = _c.CreatePathGeometry(Path()); + var propertySet = result.Properties; + propertySet.InsertScalar("TEnd", 0F); + propertySet.InsertScalar("TStart", 0F); + BindProperty(_pathGeometry_2, "TrimStart", "Min(my.TStart,my.TEnd)", "my", _pathGeometry_2); + BindProperty(_pathGeometry_2, "TrimEnd", "Max(my.TStart,my.TEnd)", "my", _pathGeometry_2); + return result; + } + + CompositionPathGeometry PathGeometry_3() + { + if (_pathGeometry_3 != null) { return _pathGeometry_3; } + var result = _pathGeometry_3 = _c.CreatePathGeometry(Path()); + var propertySet = result.Properties; + propertySet.InsertScalar("TEnd", 0F); + propertySet.InsertScalar("TStart", 0F); + BindProperty(_pathGeometry_3, "TrimStart", "Min(my.TStart,my.TEnd)", "my", _pathGeometry_3); + BindProperty(_pathGeometry_3, "TrimEnd", "Max(my.TStart,my.TEnd)", "my", _pathGeometry_3); + return result; + } + + CompositionPathGeometry PathGeometry_4() + { + if (_pathGeometry_4 != null) { return _pathGeometry_4; } + var result = _pathGeometry_4 = _c.CreatePathGeometry(Path()); + var propertySet = result.Properties; + propertySet.InsertScalar("TEnd", 0F); + propertySet.InsertScalar("TStart", 0F); + BindProperty(_pathGeometry_4, "TrimStart", "Min(my.TStart,my.TEnd)", "my", _pathGeometry_4); + BindProperty(_pathGeometry_4, "TrimEnd", "Max(my.TStart,my.TEnd)", "my", _pathGeometry_4); + return result; + } + + CompositionPathGeometry PathGeometry_5() + { + if (_pathGeometry_5 != null) { return _pathGeometry_5; } + var result = _pathGeometry_5 = _c.CreatePathGeometry(Path()); + var propertySet = result.Properties; + propertySet.InsertScalar("TEnd", 0F); + propertySet.InsertScalar("TStart", 0F); + BindProperty(_pathGeometry_5, "TrimStart", "Min(my.TStart,my.TEnd)", "my", _pathGeometry_5); + BindProperty(_pathGeometry_5, "TrimEnd", "Max(my.TStart,my.TEnd)", "my", _pathGeometry_5); + return result; + } + + CompositionPathGeometry PathGeometry_6() + { + if (_pathGeometry_6 != null) { return _pathGeometry_6; } + var result = _pathGeometry_6 = _c.CreatePathGeometry(Path()); + var propertySet = result.Properties; + propertySet.InsertScalar("TEnd", 0F); + propertySet.InsertScalar("TStart", 0F); + BindProperty(_pathGeometry_6, "TrimStart", "Min(my.TStart,my.TEnd)", "my", _pathGeometry_6); + BindProperty(_pathGeometry_6, "TrimEnd", "Max(my.TStart,my.TEnd)", "my", _pathGeometry_6); + return result; + } + + CompositionPathGeometry PathGeometry_7() + { + if (_pathGeometry_7 != null) { return _pathGeometry_7; } + var result = _pathGeometry_7 = _c.CreatePathGeometry(Path()); + var propertySet = result.Properties; + propertySet.InsertScalar("TEnd", 0F); + propertySet.InsertScalar("TStart", 0F); + BindProperty(_pathGeometry_7, "TrimStart", "Min(my.TStart,my.TEnd)", "my", _pathGeometry_7); + BindProperty(_pathGeometry_7, "TrimEnd", "Max(my.TStart,my.TEnd)", "my", _pathGeometry_7); + return result; + } + + CompositionPathGeometry PathGeometry_8() + { + if (_pathGeometry_8 != null) { return _pathGeometry_8; } + var result = _pathGeometry_8 = _c.CreatePathGeometry(Path()); + var propertySet = result.Properties; + propertySet.InsertScalar("TEnd", 0F); + propertySet.InsertScalar("TStart", 0F); + BindProperty(_pathGeometry_8, "TrimStart", "Min(my.TStart,my.TEnd)", "my", _pathGeometry_8); + BindProperty(_pathGeometry_8, "TrimEnd", "Max(my.TStart,my.TEnd)", "my", _pathGeometry_8); + return result; + } + + // Layer aggregator + // Ellipse Path 1 + CompositionSpriteShape SpriteShape_00() + { + // Offset:<260.7936, 258.792>, Rotation:-0.011598425070025746 degrees, + // Scale:<0.8, 0.8> + var geometry = Ellipse_0_0(); + var result = CreateSpriteShape(geometry, new Matrix3x2(0.800000012F, 0F, 0F, 0.800000012F, 260.79361F, 258.791992F), ColorBrush_AlmostDodgerBlue_FF149BD6());; + return result; + } + + // Layer aggregator + // Path 1 + CompositionSpriteShape SpriteShape_01() + { + // Offset:<232.0167, 247.9129>, Scale:<0.6959, 0.6959> + var result = CreateSpriteShape(PathGeometry_0(), new Matrix3x2(0.695900023F, 0F, 0F, 0.695900023F, 232.016693F, 247.912903F));; + result.StrokeBrush = ColorBrush_White(); + result.StrokeDashCap = CompositionStrokeCap.Round; + result.StrokeStartCap = CompositionStrokeCap.Round; + result.StrokeEndCap = CompositionStrokeCap.Round; + result.StrokeMiterLimit = 2F; + result.StrokeThickness = 35F; + return result; + } + + // - PreComp layer: trait 2 + // Opacity for layer: Shape Layer 1 + // Path 1 + CompositionSpriteShape SpriteShape_02() + { + // Offset:<256, 256> + var result = CreateSpriteShape(PathGeometry_1(), new Matrix3x2(1F, 0F, 0F, 1F, 256F, 256F));; + result.StrokeBrush = ColorBrush_AlmostDodgerBlue_FF149BD6(); + result.StrokeDashCap = CompositionStrokeCap.Round; + result.StrokeStartCap = CompositionStrokeCap.Round; + result.StrokeEndCap = CompositionStrokeCap.Round; + result.StrokeMiterLimit = 2F; + result.StrokeThickness = 70F; + return result; + } + + // - PreComp layer: trait 2 + // Opacity for layer: Shape Layer 1 + // Path 1 + CompositionSpriteShape SpriteShape_03() + { + // Offset:<256, 256> + var result = CreateSpriteShape(PathGeometry_2(), new Matrix3x2(1F, 0F, 0F, 1F, 256F, 256F));; + result.StrokeBrush = ColorBrush_AlmostDodgerBlue_FF149BD6(); + result.StrokeDashCap = CompositionStrokeCap.Round; + result.StrokeStartCap = CompositionStrokeCap.Round; + result.StrokeEndCap = CompositionStrokeCap.Round; + result.StrokeMiterLimit = 2F; + result.StrokeThickness = 70F; + return result; + } + + // - PreComp layer: trait 2 + // Opacity for layer: Shape Layer 1 + // Path 1 + CompositionSpriteShape SpriteShape_04() + { + // Offset:<256, 256> + var result = CreateSpriteShape(PathGeometry_3(), new Matrix3x2(1F, 0F, 0F, 1F, 256F, 256F));; + result.StrokeBrush = ColorBrush_AlmostDodgerBlue_FF149BD6(); + result.StrokeDashCap = CompositionStrokeCap.Round; + result.StrokeStartCap = CompositionStrokeCap.Round; + result.StrokeEndCap = CompositionStrokeCap.Round; + result.StrokeMiterLimit = 2F; + result.StrokeThickness = 70F; + return result; + } + + // - PreComp layer: trait 2 + // Opacity for layer: Shape Layer 1 + // Path 1 + CompositionSpriteShape SpriteShape_05() + { + // Offset:<256, 256> + var result = CreateSpriteShape(PathGeometry_4(), new Matrix3x2(1F, 0F, 0F, 1F, 256F, 256F));; + result.StrokeBrush = ColorBrush_AlmostDodgerBlue_FF149BD6(); + result.StrokeDashCap = CompositionStrokeCap.Round; + result.StrokeStartCap = CompositionStrokeCap.Round; + result.StrokeEndCap = CompositionStrokeCap.Round; + result.StrokeMiterLimit = 2F; + result.StrokeThickness = 70F; + return result; + } + + // - PreComp layer: firefly + // Shape tree root for layer: Shape Layer 1 + // Ellipse Path 1 + CompositionSpriteShape SpriteShape_06() + { + // Offset:<256, 256> + var geometry = Ellipse_0_1(); + if (_spriteShape_06 != null) { return _spriteShape_06; } + var result = _spriteShape_06 = CreateSpriteShape(geometry, new Matrix3x2(1F, 0F, 0F, 1F, 256F, 256F), AnimatedColorBrush_TransparentWhite_to_TransparentWhite());; + return result; + } + + // - PreComp layer: firefly + // Shape tree root for layer: Shape Layer 1 + // Ellipse Path 1 + CompositionSpriteShape SpriteShape_07() + { + // Offset:<256, 256> + var geometry = Ellipse_0_2(); + if (_spriteShape_07 != null) { return _spriteShape_07; } + var result = _spriteShape_07 = CreateSpriteShape(geometry, new Matrix3x2(1F, 0F, 0F, 1F, 256F, 256F), AnimatedColorBrush_TransparentWhite_to_TransparentWhite());; + return result; + } + + // - PreComp layer: firefly + // Shape tree root for layer: Shape Layer 1 + // Ellipse Path 1 + CompositionSpriteShape SpriteShape_08() + { + // Offset:<256, 256> + var geometry = Ellipse_0_3(); + if (_spriteShape_08 != null) { return _spriteShape_08; } + var result = _spriteShape_08 = CreateSpriteShape(geometry, new Matrix3x2(1F, 0F, 0F, 1F, 256F, 256F), AnimatedColorBrush_TransparentWhite_to_TransparentWhite());; + return result; + } + + // - PreComp layer: trait + // Opacity for layer: Shape Layer 1 + // Path 1 + CompositionSpriteShape SpriteShape_09() + { + // Offset:<256, 256> + var result = CreateSpriteShape(PathGeometry_5(), new Matrix3x2(1F, 0F, 0F, 1F, 256F, 256F));; + result.StrokeBrush = ColorBrush_AlmostDodgerBlue_FF149BD6(); + result.StrokeDashCap = CompositionStrokeCap.Round; + result.StrokeStartCap = CompositionStrokeCap.Round; + result.StrokeEndCap = CompositionStrokeCap.Round; + result.StrokeMiterLimit = 2F; + result.StrokeThickness = 70F; + return result; + } + + // - PreComp layer: trait + // Opacity for layer: Shape Layer 1 + // Path 1 + CompositionSpriteShape SpriteShape_10() + { + // Offset:<256, 256> + var result = CreateSpriteShape(PathGeometry_6(), new Matrix3x2(1F, 0F, 0F, 1F, 256F, 256F));; + result.StrokeBrush = ColorBrush_AlmostDodgerBlue_FF149BD6(); + result.StrokeDashCap = CompositionStrokeCap.Round; + result.StrokeStartCap = CompositionStrokeCap.Round; + result.StrokeEndCap = CompositionStrokeCap.Round; + result.StrokeMiterLimit = 2F; + result.StrokeThickness = 70F; + return result; + } + + // - PreComp layer: trait + // Opacity for layer: Shape Layer 1 + // Path 1 + CompositionSpriteShape SpriteShape_11() + { + // Offset:<256, 256> + var result = CreateSpriteShape(PathGeometry_7(), new Matrix3x2(1F, 0F, 0F, 1F, 256F, 256F));; + result.StrokeBrush = ColorBrush_AlmostDodgerBlue_FF149BD6(); + result.StrokeDashCap = CompositionStrokeCap.Round; + result.StrokeStartCap = CompositionStrokeCap.Round; + result.StrokeEndCap = CompositionStrokeCap.Round; + result.StrokeMiterLimit = 2F; + result.StrokeThickness = 70F; + return result; + } + + // - PreComp layer: trait + // Opacity for layer: Shape Layer 1 + // Path 1 + CompositionSpriteShape SpriteShape_12() + { + // Offset:<256, 256> + var result = CreateSpriteShape(PathGeometry_8(), new Matrix3x2(1F, 0F, 0F, 1F, 256F, 256F));; + result.StrokeBrush = ColorBrush_AlmostDodgerBlue_FF149BD6(); + result.StrokeDashCap = CompositionStrokeCap.Round; + result.StrokeStartCap = CompositionStrokeCap.Round; + result.StrokeEndCap = CompositionStrokeCap.Round; + result.StrokeMiterLimit = 2F; + result.StrokeThickness = 70F; + return result; + } + + // Transforms for trait 2 Scale(0.19512,0.19512,0), + // RotationDegrees(-45.60599899291992), Offset(160.72198,-142.794,0) + ContainerVisual ContainerVisual_00() + { + var result = _c.CreateContainerVisual(); + result.Clip = InsetClip_0(); + result.Size = new Vector2(512F, 512F); + // Offset:<346.08496, 113.953125>, Rotation:{X:0 Y:-0 Z:-0.38756385 W:0.9218429}, + // Scale:<0.19512, 0.19512> + result.TransformMatrix = new Matrix4x4(0.136503726F, -0.139422208F, 0F, 0F, 0.139422208F, 0.136503726F, 0F, 0F, 0F, 0F, 0F, 0F, 346.084961F, 113.953125F, 0F, 1F); + // Opacity for layer: Shape Layer 1 + result.Children.InsertAtTop(ShapeVisual_01()); + return result; + } + + // Transforms for trait 2 Scale(0.19512,0.19512,0), + // RotationDegrees(-135.2050018310547), Offset(-151.136,-144.29001,0) + ContainerVisual ContainerVisual_01() + { + var result = _c.CreateContainerVisual(); + result.Clip = InsetClip_0(); + result.Size = new Vector2(512F, 512F); + // Offset:<105.116745, 182.3505>, Rotation:{X:0 Y:0 Z:0.92456263 W:-0.38103005}, + // Scale:<0.19511999, 0.19511999> + result.TransformMatrix = new Matrix4x4(-0.138463438F, -0.137476146F, 0F, 0F, 0.137476146F, -0.138463438F, 0F, 0F, 0F, 0F, 0F, 0F, 105.116745F, 182.350494F, 0F, 1F); + // Opacity for layer: Shape Layer 1 + result.Children.InsertAtTop(ShapeVisual_02()); + return result; + } + + // Transforms for trait 2 Scale(-0.19512,0.19512,0), + // RotationDegrees(-45.60599899291992), Offset(-150.465,146.59799,0) + ContainerVisual ContainerVisual_02() + { + var result = _c.CreateContainerVisual(); + result.Clip = InsetClip_0(); + result.Size = new Vector2(512F, 512F); + // Offset:<104.78787, 331.96097>, Rotation:{X:0.38756385 Y:0.9218429 Z:0 W:0}, + // Scale:<0.19512, 0.19512> + result.TransformMatrix = new Matrix4x4(-0.136503726F, 0.139422208F, 0F, 0F, 0.139422208F, 0.136503726F, 0F, 0F, 0F, 0F, 0F, 0F, 104.787872F, 331.960968F, 0F, 1F); + // Opacity for layer: Shape Layer 1 + result.Children.InsertAtTop(ShapeVisual_03()); + return result; + } + + // Transforms for trait 2 Scale(-0.19512,0.19512,0), + // RotationDegrees(-135.2050018310547), Offset(154.86499,150.53,0) + ContainerVisual ContainerVisual_03() + { + var result = _c.CreateContainerVisual(); + result.Clip = InsetClip_0(); + result.Size = new Vector2(512F, 512F); + // Offset:<340.22446, 406.7827>, Rotation:{X:0.92456263 Y:0.38103005 Z:0 W:0}, + // Scale:<0.19511999, 0.19511999> + result.TransformMatrix = new Matrix4x4(0.138463438F, 0.137476146F, 0F, 0F, 0.137476146F, -0.138463438F, 0F, 0F, 0F, 0F, 0F, 0F, 340.224457F, 406.782715F, 0F, 1F); + // Opacity for layer: Shape Layer 1 + result.Children.InsertAtTop(ShapeVisual_04()); + return result; + } + + // Transforms for firefly Scale(0.3,0.3,0), RotationDegrees(-45.707000732421875), + // Offset(140.89401,-105.039,0) + ContainerVisual ContainerVisual_04() + { + var result = _c.CreateContainerVisual(); + result.Clip = InsetClip_0(); + result.Size = new Vector2(512F, 512F); + // Offset:<288.29068, 152.30118>, Rotation:{X:0 Y:-0 Z:-0.3883762 W:0.92150086}, + // Scale:<0.3, 0.3> + result.TransformMatrix = new Matrix4x4(0.209498361F, -0.214733422F, 0F, 0F, 0.214733422F, 0.209498361F, 0F, 0F, 0F, 0F, 0F, 0F, 288.29068F, 152.301178F, 0F, 1F); + // Shape tree root for layer: Shape Layer 1 + result.Children.InsertAtTop(ShapeVisual_05()); + return result; + } + + // Transforms for firefly Scale(0.2,0.2,0), RotationDegrees(-72.47100067138672), + // Offset(103.412994,-105.088,0) + ContainerVisual ContainerVisual_05() + { + var result = _c.CreateContainerVisual(); + result.Clip = InsetClip_0(); + result.Size = new Vector2(512F, 512F); + // Offset:<295.16965, 184.31367>, Rotation:{X:0 Y:-0 Z:-0.5911056 W:0.8065942}, + // Scale:<0.2, 0.2> + result.TransformMatrix = new Matrix4x4(0.060237702F, -0.190712929F, 0F, 0F, 0.190712929F, 0.060237702F, 0F, 0F, 0F, 0F, 0F, 0F, 295.169647F, 184.313675F, 0F, 1F); + // Shape tree root for layer: Shape Layer 1 + result.Children.InsertAtTop(ShapeVisual_06()); + return result; + } + + // Transforms for firefly Scale(0.2,0.2,0), RotationDegrees(-18.097000122070312), + // Offset(144.63501,-66.29201,0) + ContainerVisual ContainerVisual_06() + { + var result = _c.CreateContainerVisual(); + result.Clip = InsetClip_0(); + result.Size = new Vector2(512F, 512F); + // Offset:<336.0637, 156.94484>, Rotation:{X:0 Y:-0 Z:-0.15727048 W:0.98755556}, + // Scale:<0.2, 0.2> + result.TransformMatrix = new Matrix4x4(0.190106407F, -0.0621253327F, 0F, 0F, 0.0621253327F, 0.190106407F, 0F, 0F, 0F, 0F, 0F, 0F, 336.06369F, 156.944839F, 0F, 1F); + // Shape tree root for layer: Shape Layer 1 + result.Children.InsertAtTop(ShapeVisual_07()); + return result; + } + + // Transforms for trait Scale(0.15,0.15,0), Offset(213.91,2.7919922,0) + ContainerVisual ContainerVisual_07() + { + var result = _c.CreateContainerVisual(); + result.Clip = InsetClip_0(); + result.Size = new Vector2(512F, 512F); + // Offset:<431.51, 220.392>, Scale:<0.15, 0.15> + result.TransformMatrix = new Matrix4x4(0.150000006F, 0F, 0F, 0F, 0F, 0.150000006F, 0F, 0F, 0F, 0F, 0F, 0F, 431.51001F, 220.391998F, 0F, 1F); + // Opacity for layer: Shape Layer 1 + result.Children.InsertAtTop(ShapeVisual_08()); + return result; + } + + // Transforms for trait Scale(0.15,0.15,0), RotationDegrees(-90), + // Offset(10.321991,-211.685,0) + ContainerVisual ContainerVisual_08() + { + var result = _c.CreateContainerVisual(); + result.Clip = InsetClip_0(); + result.Size = new Vector2(512F, 512F); + // Offset:<227.92198, 82.714966>, Rotation:{X:0 Y:0 Z:-0.70710677 W:0.70710677}, + // Scale:<0.15, 0.15> + result.TransformMatrix = new Matrix4x4(-6.55670851E-09F, -0.150000006F, 0F, 0F, 0.150000006F, -6.55670851E-09F, 0F, 0F, 0F, 0F, 0F, 0F, 227.921982F, 82.7149658F, 0F, 1F); + // Opacity for layer: Shape Layer 1 + result.Children.InsertAtTop(ShapeVisual_09()); + return result; + } + + // Transforms for trait Scale(0.15,0.15,0), RotationDegrees(-180), + // Offset(-204.35901,-2.725006,0) + ContainerVisual ContainerVisual_09() + { + var result = _c.CreateContainerVisual(); + result.Clip = InsetClip_0(); + result.Size = new Vector2(512F, 512F); + // Offset:<90.040955, 291.67496>, Rotation:{X:0 Y:0 Z:1 W:4.371139E-08}, + // Scale:<0.15, 0.15> + result.TransformMatrix = new Matrix4x4(-0.150000006F, 1.3113417E-08F, 0F, 0F, -1.3113417E-08F, -0.150000006F, 0F, 0F, 0F, 0F, 0F, 0F, 90.0409546F, 291.674957F, 0F, 1F); + // Opacity for layer: Shape Layer 1 + result.Children.InsertAtTop(ShapeVisual_10()); + return result; + } + + // Transforms for trait Scale(0.15,0.15,0), RotationDegrees(90), + // Offset(7.334015,215.10901,0) + ContainerVisual ContainerVisual_10() + { + var result = _c.CreateContainerVisual(); + result.Clip = InsetClip_0(); + result.Size = new Vector2(512F, 512F); + // Offset:<301.73398, 432.70898>, Rotation:{X:0 Y:0 Z:0.70710677 W:0.70710677}, + // Scale:<0.15, 0.15> + result.TransformMatrix = new Matrix4x4(-6.55670851E-09F, 0.150000006F, 0F, 0F, -0.150000006F, -6.55670851E-09F, 0F, 0F, 0F, 0F, 0F, 0F, 301.733978F, 432.708984F, 0F, 1F); + // Opacity for layer: Shape Layer 1 + result.Children.InsertAtTop(ShapeVisual_11()); + return result; + } + + // The root of the composition. + ContainerVisual Root() + { + if (_root != null) { return _root; } + var result = _root = _c.CreateContainerVisual(); + var propertySet = result.Properties; + propertySet.InsertScalar("Progress", 0F); + var children = result.Children; + // Layer aggregator + children.InsertAtTop(ShapeVisual_00()); + // PreComp layer: trait 2 + children.InsertAtTop(ContainerVisual_00()); + // PreComp layer: trait 2 + children.InsertAtTop(ContainerVisual_01()); + // PreComp layer: trait 2 + children.InsertAtTop(ContainerVisual_02()); + // PreComp layer: trait 2 + children.InsertAtTop(ContainerVisual_03()); + // PreComp layer: firefly + children.InsertAtTop(ContainerVisual_04()); + // PreComp layer: firefly + children.InsertAtTop(ContainerVisual_05()); + // PreComp layer: firefly + children.InsertAtTop(ContainerVisual_06()); + // PreComp layer: trait + children.InsertAtTop(ContainerVisual_07()); + // PreComp layer: trait + children.InsertAtTop(ContainerVisual_08()); + // PreComp layer: trait + children.InsertAtTop(ContainerVisual_09()); + // PreComp layer: trait + children.InsertAtTop(ContainerVisual_10()); + return result; + } + + CubicBezierEasingFunction CubicBezierEasingFunction_0() + { + return (_cubicBezierEasingFunction_0 == null) + ? _cubicBezierEasingFunction_0 = _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.588F, 0F)) + : _cubicBezierEasingFunction_0; + } + + CubicBezierEasingFunction CubicBezierEasingFunction_1() + { + return (_cubicBezierEasingFunction_1 == null) + ? _cubicBezierEasingFunction_1 = _c.CreateCubicBezierEasingFunction(new Vector2(0.509000003F, 0.00300000003F), new Vector2(0.69599998F, 0.999000013F)) + : _cubicBezierEasingFunction_1; + } + + CubicBezierEasingFunction CubicBezierEasingFunction_2() + { + return (_cubicBezierEasingFunction_2 == null) + ? _cubicBezierEasingFunction_2 = _c.CreateCubicBezierEasingFunction(new Vector2(0.456999987F, 0.063000001F), new Vector2(0.565999985F, 0.999000013F)) + : _cubicBezierEasingFunction_2; + } + + CubicBezierEasingFunction CubicBezierEasingFunction_3() + { + return (_cubicBezierEasingFunction_3 == null) + ? _cubicBezierEasingFunction_3 = _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.572000027F, 0.555999994F)) + : _cubicBezierEasingFunction_3; + } + + CubicBezierEasingFunction CubicBezierEasingFunction_4() + { + return (_cubicBezierEasingFunction_4 == null) + ? _cubicBezierEasingFunction_4 = _c.CreateCubicBezierEasingFunction(new Vector2(0.640999973F, 0.0560000017F), new Vector2(0.833000004F, 0.833000004F)) + : _cubicBezierEasingFunction_4; + } + + CubicBezierEasingFunction CubicBezierEasingFunction_5() + { + return (_cubicBezierEasingFunction_5 == null) + ? _cubicBezierEasingFunction_5 = _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.833000004F)) + : _cubicBezierEasingFunction_5; + } + + InsetClip InsetClip_0() + { + if (_insetClip_0 != null) { return _insetClip_0; } + var result = _insetClip_0 = _c.CreateInsetClip(); + return result; + } + + // Layer opacity animation + ScalarKeyFrameAnimation OpacityScalarAnimation_1_to_0p3_0() + { + // Frame 0. + if (_opacityScalarAnimation_1_to_0p3_0 != null) { return _opacityScalarAnimation_1_to_0p3_0; } + var result = _opacityScalarAnimation_1_to_0p3_0 = CreateScalarKeyFrameAnimation(0F, 1F, StepThenHoldEasingFunction()); + // Frame 10. + result.InsertKeyFrame(0.222222209F, 1F, HoldThenStepEasingFunction()); + // Frame 16. + result.InsertKeyFrame(0.355555534F, 0.921540022F, CubicBezierEasingFunction_3()); + // Frame 20. + result.InsertKeyFrame(0.444444448F, 0.300000012F, CubicBezierEasingFunction_4()); + return result; + } + + // Layer opacity animation + ScalarKeyFrameAnimation OpacityScalarAnimation_1_to_0p3_1() + { + // Frame 0. + if (_opacityScalarAnimation_1_to_0p3_1 != null) { return _opacityScalarAnimation_1_to_0p3_1; } + var result = _opacityScalarAnimation_1_to_0p3_1 = CreateScalarKeyFrameAnimation(0F, 1F, StepThenHoldEasingFunction()); + // Frame 7. + result.InsertKeyFrame(0.155555546F, 1F, HoldThenStepEasingFunction()); + // Frame 13. + result.InsertKeyFrame(0.288888872F, 0.921540022F, CubicBezierEasingFunction_3()); + // Frame 17. + result.InsertKeyFrame(0.377777785F, 0.300000012F, CubicBezierEasingFunction_4()); + return result; + } + + // TEnd + ScalarKeyFrameAnimation TEndScalarAnimation_0_to_1_0() + { + // Frame 0. + if (_tEndScalarAnimation_0_to_1_0 != null) { return _tEndScalarAnimation_0_to_1_0; } + var result = _tEndScalarAnimation_0_to_1_0 = CreateScalarKeyFrameAnimation(0F, 0F, StepThenHoldEasingFunction()); + // Frame 10. + result.InsertKeyFrame(0.222222209F, 0F, HoldThenStepEasingFunction()); + // Frame 19. + result.InsertKeyFrame(0.422222227F, 1F, CubicBezierEasingFunction_2()); + return result; + } + + // TEnd + ScalarKeyFrameAnimation TEndScalarAnimation_0_to_1_1() + { + // Frame 0. + if (_tEndScalarAnimation_0_to_1_1 != null) { return _tEndScalarAnimation_0_to_1_1; } + var result = _tEndScalarAnimation_0_to_1_1 = CreateScalarKeyFrameAnimation(0F, 0F, StepThenHoldEasingFunction()); + // Frame 7. + result.InsertKeyFrame(0.155555546F, 0F, HoldThenStepEasingFunction()); + // Frame 16. + result.InsertKeyFrame(0.355555564F, 1F, CubicBezierEasingFunction_2()); + return result; + } + + // - - Layer aggregator + // - Scale:0.6959,0.6959, Offset:<236.888, 240.258> + // TrimEnd + ScalarKeyFrameAnimation TrimEndScalarAnimation_0_to_1() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 0F, HoldThenStepEasingFunction()); + // Frame 14.79. + result.InsertKeyFrame(0.32868889F, 0F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19.79. + result.InsertKeyFrame(0.439799994F, 0.319999993F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0419999994F), new Vector2(0F, 0.97299999F))); + // Frame 24.79. + result.InsertKeyFrame(0.550916672F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.828000009F, 0.0109999999F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // TStart + ScalarKeyFrameAnimation TStartScalarAnimation_0_to_1_0() + { + // Frame 0. + if (_tStartScalarAnimation_0_to_1_0 != null) { return _tStartScalarAnimation_0_to_1_0; } + var result = _tStartScalarAnimation_0_to_1_0 = CreateScalarKeyFrameAnimation(0F, 0F, StepThenHoldEasingFunction()); + // Frame 10. + result.InsertKeyFrame(0.222222209F, 0F, HoldThenStepEasingFunction()); + // Frame 13. + result.InsertKeyFrame(0.288888872F, 0F, CubicBezierEasingFunction_0()); + // Frame 19. + result.InsertKeyFrame(0.422222227F, 1F, CubicBezierEasingFunction_1()); + return result; + } + + // TStart + ScalarKeyFrameAnimation TStartScalarAnimation_0_to_1_1() + { + // Frame 0. + if (_tStartScalarAnimation_0_to_1_1 != null) { return _tStartScalarAnimation_0_to_1_1; } + var result = _tStartScalarAnimation_0_to_1_1 = CreateScalarKeyFrameAnimation(0F, 0F, StepThenHoldEasingFunction()); + // Frame 7. + result.InsertKeyFrame(0.155555546F, 0F, HoldThenStepEasingFunction()); + // Frame 10. + result.InsertKeyFrame(0.222222209F, 0F, CubicBezierEasingFunction_0()); + // Frame 16. + result.InsertKeyFrame(0.355555564F, 1F, CubicBezierEasingFunction_1()); + return result; + } + + // Layer aggregator + ShapeVisual ShapeVisual_00() + { + var result = _c.CreateShapeVisual(); + result.Size = new Vector2(512F, 512F); + var shapes = result.Shapes; + // Scale:0.8,0.8, Offset:<256, 256> + shapes.Add(SpriteShape_00()); + // Scale:0.6959,0.6959, Offset:<236.888, 240.258> + shapes.Add(SpriteShape_01()); + return result; + } + + // PreComp layer: trait 2 + // Shape tree root for layer: Shape Layer 1 + ShapeVisual ShapeVisual_01() + { + if (_shapeVisual_01 != null) { return _shapeVisual_01; } + var result = _shapeVisual_01 = _c.CreateShapeVisual(); + result.Size = new Vector2(512F, 512F); + // Offset:<256, 256> + result.Shapes.Add(SpriteShape_02()); + return result; + } + + // PreComp layer: trait 2 + // Shape tree root for layer: Shape Layer 1 + ShapeVisual ShapeVisual_02() + { + if (_shapeVisual_02 != null) { return _shapeVisual_02; } + var result = _shapeVisual_02 = _c.CreateShapeVisual(); + result.Size = new Vector2(512F, 512F); + // Offset:<256, 256> + result.Shapes.Add(SpriteShape_03()); + return result; + } + + // PreComp layer: trait 2 + // Shape tree root for layer: Shape Layer 1 + ShapeVisual ShapeVisual_03() + { + if (_shapeVisual_03 != null) { return _shapeVisual_03; } + var result = _shapeVisual_03 = _c.CreateShapeVisual(); + result.Size = new Vector2(512F, 512F); + // Offset:<256, 256> + result.Shapes.Add(SpriteShape_04()); + return result; + } + + // PreComp layer: trait 2 + // Shape tree root for layer: Shape Layer 1 + ShapeVisual ShapeVisual_04() + { + if (_shapeVisual_04 != null) { return _shapeVisual_04; } + var result = _shapeVisual_04 = _c.CreateShapeVisual(); + result.Size = new Vector2(512F, 512F); + // Offset:<256, 256> + result.Shapes.Add(SpriteShape_05()); + return result; + } + + // PreComp layer: firefly + // Shape tree root for layer: Shape Layer 1 + ShapeVisual ShapeVisual_05() + { + var result = _c.CreateShapeVisual(); + result.Size = new Vector2(512F, 512F); + // Offset:<256, 256> + result.Shapes.Add(SpriteShape_06()); + return result; + } + + // PreComp layer: firefly + // Shape tree root for layer: Shape Layer 1 + ShapeVisual ShapeVisual_06() + { + var result = _c.CreateShapeVisual(); + result.Size = new Vector2(512F, 512F); + // Offset:<256, 256> + result.Shapes.Add(SpriteShape_07()); + return result; + } + + // PreComp layer: firefly + // Shape tree root for layer: Shape Layer 1 + ShapeVisual ShapeVisual_07() + { + var result = _c.CreateShapeVisual(); + result.Size = new Vector2(512F, 512F); + // Offset:<256, 256> + result.Shapes.Add(SpriteShape_08()); + return result; + } + + // PreComp layer: trait + // Shape tree root for layer: Shape Layer 1 + ShapeVisual ShapeVisual_08() + { + if (_shapeVisual_08 != null) { return _shapeVisual_08; } + var result = _shapeVisual_08 = _c.CreateShapeVisual(); + result.Size = new Vector2(512F, 512F); + // Offset:<256, 256> + result.Shapes.Add(SpriteShape_09()); + return result; + } + + // PreComp layer: trait + // Shape tree root for layer: Shape Layer 1 + ShapeVisual ShapeVisual_09() + { + if (_shapeVisual_09 != null) { return _shapeVisual_09; } + var result = _shapeVisual_09 = _c.CreateShapeVisual(); + result.Size = new Vector2(512F, 512F); + // Offset:<256, 256> + result.Shapes.Add(SpriteShape_10()); + return result; + } + + // PreComp layer: trait + // Shape tree root for layer: Shape Layer 1 + ShapeVisual ShapeVisual_10() + { + if (_shapeVisual_10 != null) { return _shapeVisual_10; } + var result = _shapeVisual_10 = _c.CreateShapeVisual(); + result.Size = new Vector2(512F, 512F); + // Offset:<256, 256> + result.Shapes.Add(SpriteShape_11()); + return result; + } + + // PreComp layer: trait + // Shape tree root for layer: Shape Layer 1 + ShapeVisual ShapeVisual_11() + { + if (_shapeVisual_11 != null) { return _shapeVisual_11; } + var result = _shapeVisual_11 = _c.CreateShapeVisual(); + result.Size = new Vector2(512F, 512F); + // Offset:<256, 256> + result.Shapes.Add(SpriteShape_12()); + return result; + } + + StepEasingFunction HoldThenStepEasingFunction() + { + if (_holdThenStepEasingFunction != null) { return _holdThenStepEasingFunction; } + var result = _holdThenStepEasingFunction = _c.CreateStepEasingFunction(); + result.IsFinalStepSingleFrame = true; + return result; + } + + StepEasingFunction StepThenHoldEasingFunction() + { + if (_stepThenHoldEasingFunction != null) { return _stepThenHoldEasingFunction; } + var result = _stepThenHoldEasingFunction = _c.CreateStepEasingFunction(); + result.IsInitialStepSingleFrame = true; + return result; + } + + // Offset + Vector2KeyFrameAnimation OffsetVector2Animation() + { + // Frame 0. + if (_offsetVector2Animation != null) { return _offsetVector2Animation; } + var result = _offsetVector2Animation = CreateVector2KeyFrameAnimation(0F, new Vector2(-181.074005F, -5.41400003F), StepThenHoldEasingFunction()); + // Frame 24. + result.InsertKeyFrame(0.533333302F, new Vector2(-181.074005F, -5.41400003F), HoldThenStepEasingFunction()); + // Frame 38. + result.InsertKeyFrame(0.844444454F, new Vector2(200F, -5.41400003F), _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.666999996F, 1F))); + return result; + } + + // - - Layer aggregator + // - Scale:0.8,0.8, Offset:<256, 256> + // Ellipse Path 1.EllipseGeometry + // Radius + Vector2KeyFrameAnimation RadiusVector2Animation_0() + { + // Frame 0. + var result = CreateVector2KeyFrameAnimation(0F, new Vector2(0F, 0F), HoldThenStepEasingFunction()); + // Frame 7. + result.InsertKeyFrame(0.155555546F, new Vector2(200.512497F, 200.512497F), _c.CreateCubicBezierEasingFunction(new Vector2(0.653999984F, 0.00700000022F), new Vector2(0.976000011F, 0.967999995F))); + // Frame 12. + result.InsertKeyFrame(0.266666651F, new Vector2(186.350006F, 186.350006F), _c.CreateCubicBezierEasingFunction(new Vector2(0.345999986F, 0F), new Vector2(0.467999995F, 1F))); + // Frame 16. + result.InsertKeyFrame(0.355555534F, new Vector2(200.512497F, 200.512497F), _c.CreateCubicBezierEasingFunction(new Vector2(0.363999993F, 0.0309999995F), new Vector2(0.375F, 1F))); + // Frame 20. + result.InsertKeyFrame(0.444444448F, new Vector2(200.512497F, 200.512497F), _c.CreateCubicBezierEasingFunction(new Vector2(0.326999992F, 0F), new Vector2(0.833000004F, 1F))); + return result; + } + + // Radius + Vector2KeyFrameAnimation RadiusVector2Animation_1() + { + // Frame 0. + if (_radiusVector2Animation_1 != null) { return _radiusVector2Animation_1; } + var result = _radiusVector2Animation_1 = CreateVector2KeyFrameAnimation(0F, new Vector2(20F, 20F), StepThenHoldEasingFunction()); + // Frame 24. + result.InsertKeyFrame(0.533333302F, new Vector2(20F, 20F), HoldThenStepEasingFunction()); + // Frame 27. + result.InsertKeyFrame(0.599999964F, new Vector2(45F, 45F), _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0F, 0.996999979F))); + // Frame 38. + result.InsertKeyFrame(0.844444454F, new Vector2(9.19699955F, 9.19699955F), _c.CreateCubicBezierEasingFunction(new Vector2(0.574000001F, 0F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + internal Checkmark_AnimatedVisual( + Compositor compositor + ) + { + _c = compositor; + _reusableExpressionAnimation = compositor.CreateExpressionAnimation(); + Root(); + } + + public Visual RootVisual => _root; + public TimeSpan Duration => TimeSpan.FromTicks(c_durationTicks); + public Vector2 Size => new Vector2(512F, 512F); + void IDisposable.Dispose() => _root?.Dispose(); + + public void CreateAnimations() + { + _animatedColorBrush_TransparentWhite_to_TransparentWhite.StartAnimation("Color", ColorAnimation_TransparentWhite_to_TransparentWhite(), AnimationController_0()); + _ellipse_0_0.StartAnimation("Radius", RadiusVector2Animation_0(), AnimationController_0()); + _ellipse_0_1.StartAnimation("Radius", RadiusVector2Animation_1(), AnimationController_0()); + _ellipse_0_2.StartAnimation("Radius", RadiusVector2Animation_1(), AnimationController_0()); + _ellipse_0_3.StartAnimation("Radius", RadiusVector2Animation_1(), AnimationController_0()); + _pathGeometry_0.StartAnimation("TrimEnd", TrimEndScalarAnimation_0_to_1(), AnimationController_0()); + _pathGeometry_1.StartAnimation("TStart", TStartScalarAnimation_0_to_1_0(), AnimationController_0()); + _pathGeometry_1.StartAnimation("TEnd", TEndScalarAnimation_0_to_1_0(), AnimationController_0()); + _pathGeometry_2.StartAnimation("TStart", TStartScalarAnimation_0_to_1_0(), AnimationController_0()); + _pathGeometry_2.StartAnimation("TEnd", TEndScalarAnimation_0_to_1_0(), AnimationController_0()); + _pathGeometry_3.StartAnimation("TStart", TStartScalarAnimation_0_to_1_0(), AnimationController_0()); + _pathGeometry_3.StartAnimation("TEnd", TEndScalarAnimation_0_to_1_0(), AnimationController_0()); + _pathGeometry_4.StartAnimation("TStart", TStartScalarAnimation_0_to_1_0(), AnimationController_0()); + _pathGeometry_4.StartAnimation("TEnd", TEndScalarAnimation_0_to_1_0(), AnimationController_0()); + _pathGeometry_5.StartAnimation("TStart", TStartScalarAnimation_0_to_1_1(), AnimationController_0()); + _pathGeometry_5.StartAnimation("TEnd", TEndScalarAnimation_0_to_1_1(), AnimationController_0()); + _pathGeometry_6.StartAnimation("TStart", TStartScalarAnimation_0_to_1_1(), AnimationController_0()); + _pathGeometry_6.StartAnimation("TEnd", TEndScalarAnimation_0_to_1_1(), AnimationController_0()); + _pathGeometry_7.StartAnimation("TStart", TStartScalarAnimation_0_to_1_1(), AnimationController_0()); + _pathGeometry_7.StartAnimation("TEnd", TEndScalarAnimation_0_to_1_1(), AnimationController_0()); + _pathGeometry_8.StartAnimation("TStart", TStartScalarAnimation_0_to_1_1(), AnimationController_0()); + _pathGeometry_8.StartAnimation("TEnd", TEndScalarAnimation_0_to_1_1(), AnimationController_0()); + _spriteShape_06.StartAnimation("Offset", OffsetVector2Animation(), AnimationController_0()); + _spriteShape_07.StartAnimation("Offset", OffsetVector2Animation(), AnimationController_0()); + _spriteShape_08.StartAnimation("Offset", OffsetVector2Animation(), AnimationController_0()); + _shapeVisual_01.StartAnimation("Opacity", OpacityScalarAnimation_1_to_0p3_0(), AnimationController_0()); + _shapeVisual_02.StartAnimation("Opacity", OpacityScalarAnimation_1_to_0p3_0(), AnimationController_0()); + _shapeVisual_03.StartAnimation("Opacity", OpacityScalarAnimation_1_to_0p3_0(), AnimationController_0()); + _shapeVisual_04.StartAnimation("Opacity", OpacityScalarAnimation_1_to_0p3_0(), AnimationController_0()); + _shapeVisual_08.StartAnimation("Opacity", OpacityScalarAnimation_1_to_0p3_1(), AnimationController_0()); + _shapeVisual_09.StartAnimation("Opacity", OpacityScalarAnimation_1_to_0p3_1(), AnimationController_0()); + _shapeVisual_10.StartAnimation("Opacity", OpacityScalarAnimation_1_to_0p3_1(), AnimationController_0()); + _shapeVisual_11.StartAnimation("Opacity", OpacityScalarAnimation_1_to_0p3_1(), AnimationController_0()); + } + + public void DestroyAnimations() + { + _animatedColorBrush_TransparentWhite_to_TransparentWhite.StopAnimation("Color"); + _ellipse_0_0.StopAnimation("Radius"); + _ellipse_0_1.StopAnimation("Radius"); + _ellipse_0_2.StopAnimation("Radius"); + _ellipse_0_3.StopAnimation("Radius"); + _pathGeometry_0.StopAnimation("TrimEnd"); + _pathGeometry_1.StopAnimation("TStart"); + _pathGeometry_1.StopAnimation("TEnd"); + _pathGeometry_2.StopAnimation("TStart"); + _pathGeometry_2.StopAnimation("TEnd"); + _pathGeometry_3.StopAnimation("TStart"); + _pathGeometry_3.StopAnimation("TEnd"); + _pathGeometry_4.StopAnimation("TStart"); + _pathGeometry_4.StopAnimation("TEnd"); + _pathGeometry_5.StopAnimation("TStart"); + _pathGeometry_5.StopAnimation("TEnd"); + _pathGeometry_6.StopAnimation("TStart"); + _pathGeometry_6.StopAnimation("TEnd"); + _pathGeometry_7.StopAnimation("TStart"); + _pathGeometry_7.StopAnimation("TEnd"); + _pathGeometry_8.StopAnimation("TStart"); + _pathGeometry_8.StopAnimation("TEnd"); + _spriteShape_06.StopAnimation("Offset"); + _spriteShape_07.StopAnimation("Offset"); + _spriteShape_08.StopAnimation("Offset"); + _shapeVisual_01.StopAnimation("Opacity"); + _shapeVisual_02.StopAnimation("Opacity"); + _shapeVisual_03.StopAnimation("Opacity"); + _shapeVisual_04.StopAnimation("Opacity"); + _shapeVisual_08.StopAnimation("Opacity"); + _shapeVisual_09.StopAnimation("Opacity"); + _shapeVisual_10.StopAnimation("Opacity"); + _shapeVisual_11.StopAnimation("Opacity"); + } + + } + } +} diff --git a/src/SamplesApp/UITests.Shared/UITests.Shared.projitems b/src/SamplesApp/UITests.Shared/UITests.Shared.projitems index 35fc576c69e2..6dfad9978920 100644 --- a/src/SamplesApp/UITests.Shared/UITests.Shared.projitems +++ b/src/SamplesApp/UITests.Shared/UITests.Shared.projitems @@ -5553,6 +5553,7 @@ AnimatedIconPage.xaml + BreadcrumbBarPage.xaml diff --git a/src/Uno.UI.Composition/Composition/Compositor.cs b/src/Uno.UI.Composition/Composition/Compositor.cs index cfeefd2cc726..64138daab4fe 100644 --- a/src/Uno.UI.Composition/Composition/Compositor.cs +++ b/src/Uno.UI.Composition/Composition/Compositor.cs @@ -28,25 +28,41 @@ public Compositor() // See https://github.com/dotnet/runtime/blob/c52fd37cc835a13bcfa9a64fdfe7520809a75345/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.cs#L157 public long TimestampInTicks => unchecked((long)(Stopwatch.GetTimestamp() * s_tickFrequency)); + /// + /// Creates an instance of AnimationController. + /// + /// The created AnimationController object. + public AnimationController CreateAnimationController() => new(this); + + /// + /// Creates an instance of CompositionColorBrush. + /// + /// Returns the created CompositionColorBrush object. + public CompositionColorBrush CreateColorBrush() => new(this); + + /// + /// Creates an instance of CompositionColorBrush using the specified color. + /// + /// The color for the brush to use. + /// Returns the created CompositionColorBrush object. + public CompositionColorBrush CreateColorBrush(Color color) => new(this) + { + Color = color + }; + internal static Compositor GetSharedCompositor() => _sharedCompositorLazy.Value; [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static CompositionEasingFunction GetDefaultEasingFunction() => _defaultEasingFunction.Value; - public ContainerVisual CreateContainerVisual() - => new ContainerVisual(this); + + public ContainerVisual CreateContainerVisual() => new(this); public SpriteVisual CreateSpriteVisual() => new SpriteVisual(this); - public CompositionColorBrush CreateColorBrush() - => new CompositionColorBrush(this); - public CompositionColorBrush CreateColorBrush(Color color) - => new CompositionColorBrush(this) - { - Color = color - }; + public ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation() => new ScalarKeyFrameAnimation(this); diff --git a/src/Uno.UI.Composition/Generated/3.0.0.0/Microsoft.UI.Composition/Compositor.cs b/src/Uno.UI.Composition/Generated/3.0.0.0/Microsoft.UI.Composition/Compositor.cs index 8afa2035912b..eba2e36ab688 100644 --- a/src/Uno.UI.Composition/Generated/3.0.0.0/Microsoft.UI.Composition/Compositor.cs +++ b/src/Uno.UI.Composition/Generated/3.0.0.0/Microsoft.UI.Composition/Compositor.cs @@ -173,7 +173,7 @@ public static float MinGlobalPlaybackRate #endif // Skipping already declared method Microsoft.UI.Composition.Compositor.CreateRadialGradientBrush() // Skipping already declared method Microsoft.UI.Composition.Compositor.CreateVisualSurface() -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false [global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")] public global::Microsoft.UI.Composition.AnimationController CreateAnimationController() { diff --git a/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Automation.Peers/AnimatedVisualPlayerAutomationPeer.cs b/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Automation.Peers/AnimatedVisualPlayerAutomationPeer.cs index 85585e0f9e75..c6556afa7da3 100644 --- a/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Automation.Peers/AnimatedVisualPlayerAutomationPeer.cs +++ b/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Automation.Peers/AnimatedVisualPlayerAutomationPeer.cs @@ -3,12 +3,12 @@ #pragma warning disable 114 // new keyword hiding namespace Microsoft.UI.Xaml.Automation.Peers { -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false [global::Uno.NotImplemented] #endif public partial class AnimatedVisualPlayerAutomationPeer : global::Microsoft.UI.Xaml.Automation.Peers.FrameworkElementAutomationPeer { -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false [global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")] public AnimatedVisualPlayerAutomationPeer(global::Microsoft.UI.Xaml.Controls.AnimatedVisualPlayer owner) : base(owner) { diff --git a/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/AnimatedVisualPlayer.cs b/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/AnimatedVisualPlayer.cs index f039a6b3ff28..5aedee6cd138 100644 --- a/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/AnimatedVisualPlayer.cs +++ b/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/AnimatedVisualPlayer.cs @@ -13,7 +13,7 @@ public partial class AnimatedVisualPlayer : global::Microsoft.UI.Xaml.FrameworkE // Skipping already declared property PlaybackRate // Skipping already declared property FallbackContent // Skipping already declared property AutoPlay -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false [global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")] public object Diagnostics { @@ -26,7 +26,7 @@ public object Diagnostics // Skipping already declared property Duration // Skipping already declared property IsAnimatedVisualLoaded // Skipping already declared property IsPlaying -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false [global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")] public global::Microsoft.UI.Composition.CompositionObject ProgressObject { @@ -36,7 +36,7 @@ public object Diagnostics } } #endif -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false [global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")] public global::Microsoft.UI.Xaml.Controls.PlayerAnimationOptimization AnimationOptimization { @@ -51,7 +51,7 @@ public object Diagnostics } #endif // Skipping already declared property AutoPlayProperty -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false [global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")] public static global::Microsoft.UI.Xaml.DependencyProperty DiagnosticsProperty { get; } = Microsoft.UI.Xaml.DependencyProperty.Register( @@ -66,7 +66,7 @@ public object Diagnostics // Skipping already declared property PlaybackRateProperty // Skipping already declared property SourceProperty // Skipping already declared property StretchProperty -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false [global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")] public static global::Microsoft.UI.Xaml.DependencyProperty AnimationOptimizationProperty { get; } = Microsoft.UI.Xaml.DependencyProperty.Register( diff --git a/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/IAnimatedVisual2.cs b/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/IAnimatedVisual2.cs index 20bd9d66a240..4239f050fae1 100644 --- a/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/IAnimatedVisual2.cs +++ b/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/IAnimatedVisual2.cs @@ -3,15 +3,15 @@ #pragma warning disable 114 // new keyword hiding namespace Microsoft.UI.Xaml.Controls { -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false [global::Uno.NotImplemented] #endif public partial interface IAnimatedVisual2 : global::Microsoft.UI.Xaml.Controls.IAnimatedVisual, global::System.IDisposable { -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false void CreateAnimations(); #endif -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false void DestroyAnimations(); #endif } diff --git a/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/IAnimatedVisualSource.cs b/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/IAnimatedVisualSource.cs index f4ed6e4e8950..569bc1167611 100644 --- a/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/IAnimatedVisualSource.cs +++ b/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/IAnimatedVisualSource.cs @@ -8,7 +8,7 @@ namespace Microsoft.UI.Xaml.Controls #endif public partial interface IAnimatedVisualSource { -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false global::Microsoft.UI.Xaml.Controls.IAnimatedVisual TryCreateAnimatedVisual(global::Microsoft.UI.Composition.Compositor compositor, out object diagnostics); #endif } diff --git a/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/IAnimatedVisualSource3.cs b/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/IAnimatedVisualSource3.cs index 70fe8e842a29..37b022fe537c 100644 --- a/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/IAnimatedVisualSource3.cs +++ b/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/IAnimatedVisualSource3.cs @@ -3,12 +3,12 @@ #pragma warning disable 114 // new keyword hiding namespace Microsoft.UI.Xaml.Controls { -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false [global::Uno.NotImplemented] #endif public partial interface IAnimatedVisualSource3 { -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false global::Microsoft.UI.Xaml.Controls.IAnimatedVisual2 TryCreateAnimatedVisual(global::Microsoft.UI.Composition.Compositor compositor, out object diagnostics, bool createAnimations); #endif } diff --git a/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/PlayerAnimationOptimization.cs b/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/PlayerAnimationOptimization.cs index 01f972ddd670..85209bb2a1de 100644 --- a/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/PlayerAnimationOptimization.cs +++ b/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml.Controls/PlayerAnimationOptimization.cs @@ -3,13 +3,13 @@ #pragma warning disable 114 // new keyword hiding namespace Microsoft.UI.Xaml.Controls { -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false public enum PlayerAnimationOptimization { -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false Latency = 0, #endif -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if false Resources = 1, #endif } diff --git a/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.Properties.cs b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.Properties.cs new file mode 100644 index 000000000000..abfd06358c33 --- /dev/null +++ b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.Properties.cs @@ -0,0 +1,205 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. +// MUX Reference src\controls\dev\Generated\AnimatedVisualPlayer.properties.cpp, tag winui3/release/1.6.3, commit 66d24dfff + +using System; +using Microsoft.UI.Xaml.Media; + +namespace Microsoft/* UWP don't rename */.UI.Xaml.Controls; + +partial class AnimatedVisualPlayer +{ + /// + /// Gets or sets a value that specifies how animations are cached when the AnimatedVisualPlayer is idle (when PlayAsync is not active). + /// + public PlayerAnimationOptimization AnimationOptimization + { + get => (PlayerAnimationOptimization)GetValue(AnimationOptimizationProperty); + set => SetValue(AnimationOptimizationProperty, value); + } + + /// + /// Identifies the AnimationOptimization dependency property. + /// + public static DependencyProperty AnimationOptimizationProperty { get; } = + DependencyProperty.Register( + nameof(AnimationOptimization), + typeof(PlayerAnimationOptimization), + typeof(AnimatedVisualPlayer), + new FrameworkPropertyMetadata( + PlayerAnimationOptimization.Latency, + (sender, args) => ((AnimatedVisualPlayer)sender).OnAnimationOptimizationPropertyChanged(args)); + + /// + /// Gets or sets a value that indicates whether an animated visual plays immediately when it is loaded. + /// + public bool AutoPlay + { + get => (bool)GetValue(AutoPlayProperty); + set => SetValue(AutoPlayProperty, value); + } + + /// + /// Identifies the AutoPlay dependency property. + /// + public static DependencyProperty AutoPlayProperty { get; } = + DependencyProperty.Register( + nameof(AutoPlay), + typeof(bool), + typeof(AnimatedVisualPlayer), + new FrameworkPropertyMetadata( + true, + (sender, args) => ((AnimatedVisualPlayer)sender).OnAutoPlayPropertyChanged(args))); + + /// + /// Gets optional diagnostics information about the last attempt to load an animated visual. + /// + public object Diagnostics + { + get => GetValue(DiagnosticsProperty); + private set => SetValue(DiagnosticsProperty, value); + } + + /// + /// Identifies the Diagnostics dependency property. + /// + public static DependencyProperty DiagnosticsProperty { get; } = + DependencyProperty.Register( + nameof(Diagnostics), + typeof(object), + typeof(AnimatedVisualPlayer), + new FrameworkPropertyMetadata(null)); + + /// + /// Gets the duration of the the currently loaded animated visual, or TimeSpan.Zero if no animated visual is loaded. + /// + public TimeSpan Duration + { + get => (TimeSpan)GetValue(DurationProperty); + private set => SetValue(DurationProperty, value); + } + + /// + /// Identifies the Duration dependency property. + /// + public static DependencyProperty DurationProperty { get; } = + DependencyProperty.Register( + nameof(Duration), + typeof(TimeSpan), + typeof(AnimatedVisualPlayer), + new FrameworkPropertyMetadata(default(TimeSpan))); + + /// + /// Gets or sets content to display if an animated visual fails to load. + /// + public DataTemplate FallbackContent + { + get => (DataTemplate)GetValue(FallbackContentProperty); + set => SetValue(FallbackContentProperty, value); + } + + /// + /// Identifies the FallbackContent dependency property. + /// + public static DependencyProperty FallbackContentProperty { get; } = + DependencyProperty.Register( + nameof(FallbackContent), + typeof(DataTemplate), + typeof(AnimatedVisualPlayer), + new FrameworkPropertyMetadata( + null, + (sender, args) => ((AnimatedVisualPlayer)sender).OnFallbackContentPropertyChanged(args))); + + /// + /// Gets a value that indicates whether an animated visual is loaded. + /// + public bool IsAnimatedVisualLoaded + { + get => (bool)GetValue(IsAnimatedVisualLoadedProperty); + private set => SetValue(IsAnimatedVisualLoadedProperty, value); + } + + /// + /// Identifies the IsAnimatedVisualLoaded dependency property. + /// + public static DependencyProperty IsAnimatedVisualLoadedProperty { get; } = + DependencyProperty.Register(nameof(IsAnimatedVisualLoaded), typeof(bool), typeof(AnimatedVisualPlayer), new FrameworkPropertyMetadata(false)); + + /// + /// Gets a value that indicates whether an animated visual is loaded and a play is underway. + /// + public bool IsPlaying => (bool)GetValue(IsPlayingProperty); + + /// + /// Identifies the IsPlaying dependency property. + /// + public static DependencyProperty IsPlayingProperty { get; } = + DependencyProperty.Register( + nameof(IsPlaying), + typeof(bool), + typeof(AnimatedVisualPlayer), + new FrameworkPropertyMetadata(false)); + + /// + /// Gets or sets the rate at which the animation plays. + /// + public double PlaybackRate + { + get => (double)GetValue(PlaybackRateProperty); + set => SetValue(PlaybackRateProperty, value); + } + + /// + /// Identifies the PlaybackRate dependency property. + /// + public static DependencyProperty PlaybackRateProperty { get; } = + DependencyProperty.Register( + nameof(PlaybackRate), + typeof(double), + typeof(AnimatedVisualPlayer), + new FrameworkPropertyMetadata( + 1.0, + (sender, args) => ((AnimatedVisualPlayer)sender).OnPlaybackRatePropertyChanged(args))); + + /// + /// Gets or sets the provider of the animated visual for the player. + /// + public IAnimatedVisualSource Source + { + get => (IAnimatedVisualSource)GetValue(SourceProperty); + set => SetValue(SourceProperty, value); + } + + /// + /// Identifies the Source dependency property. + /// + public static DependencyProperty SourceProperty { get; } = + DependencyProperty.Register( + nameof(Source), + typeof(IAnimatedVisualSource), + typeof(AnimatedVisualPlayer), + new FrameworkPropertyMetadata( + null, + (sender, args) => ((AnimatedVisualPlayer)sender).OnSourcePropertyChanged(args))); + + /// + /// Gets or sets a value that describes how an animated visual should be stretched to fill the destination rectangle. + /// + public Stretch Stretch + { + get => (Stretch)GetValue(StretchProperty); + set => SetValue(StretchProperty, value); + } + + /// + /// Identifies the Stretch dependency property. + /// + public static DependencyProperty StretchProperty { get; } = + DependencyProperty.Register( + nameof(Stretch), + typeof(Stretch), + typeof(AnimatedVisualPlayer), + new FrameworkPropertyMetadata( + Stretch.Uniform, + (sender, args) => ((AnimatedVisualPlayer)sender).OnStretchPropertyChanged(args))); +} diff --git a/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.cs b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.cs new file mode 100644 index 000000000000..cc36d59149c0 --- /dev/null +++ b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Microsoft/* UWP don't rename */.UI.Xaml.Controls; + +/// +/// An element that displays and controls an IAnimatedVisual. +/// +public partial class AnimatedVisualPlayer : FrameworkElement +{ +} diff --git a/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.h.mux.cs b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.h.mux.cs new file mode 100644 index 000000000000..0215f3cdfe4f --- /dev/null +++ b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.h.mux.cs @@ -0,0 +1,68 @@ +using System; +using System.Numerics; +using System.Threading.Tasks; +using Microsoft.UI.Composition; +using Uno.Disposables; + +namespace Microsoft/* UWP don't rename */.UI.Xaml.Controls; + +partial class AnimatedVisualPlayer +{ + internal partial class AnimationPlay : TaskCompletionSource + { + private AnimatedVisualPlayer m_owner; + private readonly float m_fromProgress; + private readonly float m_toProgress; + private readonly bool m_looped; + private TimeSpan m_playDuration; + + private AnimationController m_controller; + private bool m_isPaused; + private bool m_isPausedBecauseHidden; + private long m_batchCompletedToken; + CompositionScopedBatch m_batch; + } + + // + // Initialized by the constructor. + // + // A Visual used for clipping and for parenting of m_animatedVisualRoot. + private SpriteVisual m_rootVisual; + // The property set that contains the Progress property that will be used to + // set the progress of the animated visual. + private CompositionPropertySet m_progressPropertySet; + // Revokers for events that we are subscribed to. + private SerialDisposable m_suspendingRevoker = new(); + private SerialDisposable m_resumingRevoker = new(); + private SerialDisposable m_xamlRootChangedRevoker = new(); + private SerialDisposable m_loadedRevoker = new(); + private SerialDisposable m_unloadedRevoker = new(); + + // + // Player mutable state state. + // + private IAnimatedVisual m_animatedVisual; + // The native size of the current animated visual. Only valid if m_animatedVisual is not nullptr. + private Vector2 m_animatedVisualSize; + private Visual m_animatedVisualRoot; + private int m_playAsyncVersion; + private double m_currentPlayFromProgress; + // The play that will be stopped when Stop() is called. + private AnimationPlay m_nowPlaying; + private SerialDisposable m_dynamicAnimatedVisualInvalidatedRevoker; + + // Set true if an animated visual has failed to load and set false the next time an animated + // visual loads with non-null content. When this is true the fallback content (if any) will + // be displayed. + private bool m_isFallenBack; + + // Set true when FrameworkElement::Unloaded is fired, then set false when FrameworkElement::Loaded is fired. + // This is used to differentiate the first Loaded event (when the element has never been + // unloaded) from later Loaded events. + private bool m_isUnloaded; + + private bool m_isAnimationsCreated; + private uint m_createAnimationsCounter = 0; + + private bool m_isHostVisible; +} diff --git a/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.mux.cs b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.mux.cs new file mode 100644 index 000000000000..4522ba73876e --- /dev/null +++ b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.mux.cs @@ -0,0 +1,1154 @@ +using System; +using System.Numerics; +using Microsoft.UI.Composition; +using Microsoft.UI.Xaml.Automation.Peers; +using Microsoft.UI.Xaml.Hosting; +using Microsoft.UI.Xaml.Media; +using Uno.Disposables; +using Uno.UI.DataBinding; +using Windows.Foundation; +using static Microsoft/* UWP don't rename */.UI.Xaml.Controls._Tracing; + +namespace Microsoft/* UWP don't rename */.UI.Xaml.Controls; + +partial class AnimatedVisualPlayer +{ + partial class AnimationPlay + { + private AnimationPlay( + AnimatedVisualPlayer owner, + float fromProgress, + float toProgress, + bool looped) + { + // Save the play duration as time. + m_owner = owner; + m_fromProgress = fromProgress; + + m_toProgress = toProgress; + + m_looped = looped; + // Save the play duration as time. + // If toProgress is less than fromProgress the animation will wrap around, + // so the time is calculated as fromProgress..end + start..toProgress. + var durationAsProgress = fromProgress > toProgress ? ((1 - fromProgress) + toProgress) : (toProgress - fromProgress); + // NOTE: this relies on the Duration() being set on the owner. + m_playDuration = std.chrono.duration_cast(m_owner.Duration() * durationAsProgress); + } + + internal internalfloat FromProgress() + { + return m_fromProgress; + } + + // REENTRANCE SIDE EFFECT: IsPlaying DP. + internal void Start() + { + //// m_owner should be alive since we are calling Start() from owner only + //MUX_ASSERT(m_owner); + //MUX_ASSERT(IsCurrentPlay()); + //MUX_ASSERT(!m_controller); + + //// If the duration is really short (< 20ms) don't bother trying to animate. + //if (m_playDuration < TimeSpan{ 20ms }) + // { + // // Nothing to play. Jump to the from position. + // // This will have the side effect of completing this play immediately. + // m_owner.SetProgress(m_fromProgress); + // // Do not do anything after calling SetProgress()... the AnimationPlay is destructed already. + // return; + //} + + // else + //{ + // // Create an animation to drive the Progress property. + // var compositor = m_owner.m_progressPropertySet.Compositor(); + // var animation = compositor.CreateScalarKeyFrameAnimation(); + // animation.Duration(m_playDuration); + // var linearEasing = compositor.CreateLinearEasingFunction(); + + // // Play from fromProgress. + // animation.InsertKeyFrame(0, m_fromProgress); + + // // from > to is treated as playing from fromProgress to the end, then playing from + // // the beginning to toProgress. Insert extra keyframes to do that. + // if (m_fromProgress > m_toProgress) + // { + // // Play to the end. + // var timeToEnd = (1 - m_fromProgress) / ((1 - m_fromProgress) + m_toProgress); + // animation.InsertKeyFrame(timeToEnd, 1, linearEasing); + // // Jump to the beginning. + // animation.InsertKeyFrame(.nextafterf(timeToEnd, 1), 0, linearEasing); + // } + + // // Play to toProgress + // animation.InsertKeyFrame(1, m_toProgress, linearEasing); + + // if (m_looped) + // { + // animation.IterationBehavior(AnimationIterationBehavior.Forever); + // } + // else + // { + // animation.IterationBehavior(AnimationIterationBehavior.Count); + // animation.IterationCount(1); + // } + + // // Create a batch so that we can know when the animation finishes. This only + // // works for non-looping animations (the batch completes immediately + // // for looping animations). + // m_batch = m_looped + // ? null + // : compositor.CreateScopedBatch(CompositionBatchTypes.Animation); + + // // Start the animation and get the controller. + // m_owner.m_progressPropertySet.StartAnimation("Progress", animation); + + // m_controller = m_owner.m_progressPropertySet.TryGetAnimationController("Progress"); + + // if (m_isPaused || m_isPausedBecauseHidden) + // { + // // The play was paused before it was started. + // m_controller.Pause(); + // } + + // // Set the playback rate. + // var playbackRate = (float)(m_owner.PlaybackRate()); + // m_controller.PlaybackRate(playbackRate); + + // if (playbackRate < 0) + // { + // // Play from end to beginning if playing in reverse. + // m_controller.Progress(1); + // } + + // if (m_batch) + // { + // std.weak_ptr me_weak = m_owner.m_nowPlaying; + // // Subscribe to the batch completed event. + // m_batchCompletedToken = m_batch.Completed([me_weak](object &, CompositionBatchCompletedEventArgs &) + + // { + // var me = me_weak.lock () ; + + // if (!me) + // { + // return; + // } + + // if (me.m_owner) + // { + // // If optimization is set to Resources - destroy animations immediately after player stops. + // if (me.m_owner.AnimationOptimization() == PlayerAnimationOptimization.Resources) + // { + // me.m_owner.DestroyAnimations(); + // } + // } + + // // Complete the play when the batch completes. + // // + // // The "this" pointer is guaranteed to be valid because: + // // 1) The AnimationPlay (this) is kept alive by a reference from m_owner.m_nowPlaying that + // // is only reset by a call to the AnimationPlay.Complete() method. + // // 2) Before m_owner.m_nowPlaying is reset in AnimationPlay.Complete(), + // // the m_batch.Completed event is unsubscribed, guaranteeing that this lambda + // // will not run after AnimationPlay.Complete() has been called. + // // 3) To handle AnimatedVisualPlayer shutdown, AnimationPlay.Complete() is called when + // // the AnimatedVisualPlayer is unloaded, so that the AnimationPlay cannot outlive + // // the AnimatedVisualPlayer. + // // + // // Do not do anything after calling Complete()... the object is destructed already. + // me.Complete(); + // }); + // // Indicate that nothing else is going into the batch. + // m_batch.End(); + // } + + // // WARNING - this may cause reentrance. + // m_owner.IsPlaying(true); + //} + } + + internal bool IsCurrentPlay() + { + return m_owner is not null && m_owner.m_nowPlaying == this; + } + + internal void SetPlaybackRate(float value) + { + if (m_controller is not null) + { + m_controller.PlaybackRate = value; + } + } + + // Called when the animation is becoming hidden. + internal void OnHiding() + { + if (!m_isPausedBecauseHidden) + { + m_isPausedBecauseHidden = true; + + // Pause the animation if it's not already paused. + // This is necessary to ensure that the animation doesn't + // keep running and causing DWM to wake up when the animation + // cannot be seen. + if (m_controller is not null) + { + if (!m_isPaused) + { + m_controller.Pause(); + } + } + } + } + + // Called when the animation was hidden but is now becoming visible. + internal void OnUnhiding() + { + if (m_isPausedBecauseHidden) + { + m_isPausedBecauseHidden = false; + + // Resume the animation that was paused due to the app being suspended. + if (m_controller is not null) + { + if (!m_isPaused) + { + m_controller.Resume(); + } + } + } + } + + internal void Pause() + { + m_isPaused = true; + + if (m_controller is not null) + { + if (!m_isPausedBecauseHidden) + { + m_controller.Pause(); + } + } + } + + internal void Resume() + { + m_isPaused = false; + + if (m_controller is not null) + { + if (!m_isPausedBecauseHidden) + { + m_controller.Resume(); + } + } + } + + // Completes the play, and unregisters it from the player. + // Called on the UI thread from: + // * SetProgress + // - when any property is set that invalidates the current play, such as starting a new play or setting progress. + // * CompositionScopedBatch.BatchCompleted event + // - when a non-looping animation gets to it final keyframe. + // * ~AnimatedVisualPlayer - in owner's destructor + // Do not do anything with this object after calling here... the object is destructed already. + // REENTRANCE SIDE EFFECT: IsPlaying DP. + internal void Complete() + { + // + // NOTEs about lifetime (i.e. why we can trust that m_owner is still valid) + // The AnimatedVisualPlayer will be alive as the time when Complete() is called. This + // is because: + // 1. There is only ever one un-completed AnimationPlay. When a new play + // is started the current play is completed. + // 2. An uncompleted AnimationPlay will be completed when the AnimatedVisualPlayer + // is unloaded or the AnimatedVisualPlayer destructor is run. + // 3. If the call to here is from SetProgress + // then the AnimatedVisualPlayer is obviously still alive. + // 4. If the batch completion event fires the AnimatedVisualPlayer must still be + // alive because if it had been unloaded or destroyedComplete() would have been + // called during the unload or from the destructor which would have unsubscribed + // from the batch completion event. + // + + // Grab a copy of the pointer so the object stays alive until the method returns. + // We need to copy pointer only in case if owner is alive, + // because we are resetting only owner's pointer in this method + std.AnimationPlay me; + if (m_owner) + { + me = m_owner.m_nowPlaying; + } + + // Unsubscribe from batch.Completed. + if (m_batch) + { + m_batch.Completed(m_batchCompletedToken); + m_batchCompletedToken = { 0 }; + } + + // If this play is the one that is currently associated with the player, + // disassociate it from the player and update the player's IsPlaying property. + if (m_owner && IsCurrentPlay()) + { + // Disconnect this AnimationPlay from the player. + m_owner.m_nowPlaying.reset(); + + // Update the IsPlaying state. Note that this is done + // after being disconnected so that this AnimationPlay won't be + // reentered, however the AnimatedVisualPlayer may be reentered. + // WARNING - this may cause reentrance. + m_owner.IsPlaying(false); + } + + // Allow anything waiting on this awaitable to complete. + // This will not cause reentrance because this signals an event and does not call out. + CompleteAwaits(); + } + + // This is called in AnimatedVisualPlayer destructor to prevent + // AnimationPlay accessing owner in case if it lives longer + internal void ResetOwner() + { + m_owner = null; + } + } + + + public AnimatedVisualPlayer() + { + //__RP_Marker_ClassById(RuntimeProfiler.ProfId_AnimatedVisualPlayer); + + // EnsureProperties(); + + var compositor = ElementCompositionPreview.GetElementVisual(this).Compositor; + m_rootVisual = compositor.CreateSpriteVisual(); + m_progressPropertySet = m_rootVisual.Properties; + + // Set an initial value for the Progress property. + m_progressPropertySet.InsertScalar("Progress", 0); + + // Ensure the content can't render outside the bounds of the element. + m_rootVisual.Clip = compositor.CreateInsetClip(); + + // Subscribe to suspending, resuming, and visibility events so we can pause the animation if it's + // definitely not visible. + m_suspendingRevoker = Application.Current.Suspending(auto_revoke, [weakThis{ get_weak() }]( + var /*sender*/, + var /*e*/) + + { + if (var strongThis = weakThis) + { + strongThis.OnHiding(); + } + }); + + m_resumingRevoker = Application.Current.Resuming(auto_revoke, [weakThis{ get_weak() }]( + var /*sender*/, + var /*e*/) + + { + if (var strongThis = weakThis) + { + if (CoreWindow.GetForCurrentThread().Visible()) + { + strongThis.OnUnhiding(); + } + } + }); + + // Subscribe to the Loaded/Unloaded events to ensure we unload the animated visual then reload + // when it is next loaded. + Loaded += OnLoaded; + m_loadedRevoker.Disposable = Disposable.Create(() => Loaded -= OnLoaded); + Unloaded += OnUnloaded; + m_unloadedRevoker.Disposable = Disposable.Create(() => Unloaded -= OnUnloaded); + } + + ~AnimatedVisualPlayer() + { + // TODO:MZ: Move to unloaded + // Ensure any outstanding play is stopped. + if (m_nowPlaying) + { + // To stop and destroy m_nowPlaying we need to call Complete() + // But we need to detach us (m_owner) from m_nowPlaying first so that AnimationPlay + // will not try to call us (m_owner), since we are already in the destructor + m_nowPlaying.ResetOwner(); + m_nowPlaying.Complete(); + } + } + + private void OnLoaded(object sender, RoutedEventArgs args) + { + // + // Do initialization here rather than in the ructor because when the + // ructor is called the outer object is not fully initialized. + // + // Any initialization that can call back into the outer object MUST be + // done here rather than the ructor. + // + // Other initialization can be done here too, so rather than having to + // guess whether an initialization call calls back into the outer, just + // put most of the initialization here. + // + + // Calls back into the outer - must be done OnLoaded rather than in the ructor. + ElementCompositionPreview.SetElementChildVisual(this, m_rootVisual); + + // Set the background for AnimatedVisualPlayer to ensure it will be visible to + // hit-testing. XAML does not hit test anything that has a null background. + // Set here rather than in the ructor so we don't have to worry about it + // calling back into the outer. + Background = new SolidColorBrush(Colors.Transparent); + + if (m_isUnloaded) + { + // Reload the content. + // Only do this if the element had been previously unloaded so that the + // first Loaded event doesn't overwrite any state that was set before + // the event was fired. + UpdateContent(); + m_isUnloaded = false; + } + + // TODO:MZ: Avoid leaking (XamlRoot.Changed should be a weak event!) + var weakThis = WeakReferencePool.RentSelfWeakReference(this); + void OnXamlRootChanged(object sender, object args) + { + if (weakThis.IsAlive && weakThis.Target is AnimatedVisualPlayer strongThis) + { + var xamlRoot = strongThis.XamlRoot; + bool hostVisibility = xamlRoot.IsHostVisible; + if (hostVisibility != strongThis.m_isHostVisible) + { + strongThis.m_isHostVisible = hostVisibility; + if (hostVisibility) + { + // Transition from invisible to visible. + strongThis.OnUnhiding(); + } + else + { + // Transition from visible to invisible. + strongThis.OnHiding(); + } + + } + } + } + + XamlRoot.Changed += OnXamlRootChanged; + m_xamlRootChangedRevoker.Disposable = Disposable.Create(() => XamlRoot.Changed -= OnXamlRootChanged); + } + + private void OnUnloaded(object sender, RoutedEventArgs args) + { + // There is an anomaly in the Loading/Loaded/Unloaded events that can cause an Unloaded event to + // fire when the element is in the tree. When this happens, we end up unlaoding our content + // and not displaying it. Unfortunately, we can't fix this until at least version 2.0 so for + // for now we will work around it (as we have suggested to customers to do), by checking to see + // if we are actually unloaded before removing our content. + if (!IsLoaded) + { + m_isUnloaded = true; + // Remove any content. If we get reloaded the content will get reloaded. + UnloadContent(); + } + } + + private void OnHiding() + { + if (m_nowPlaying) + { + m_nowPlaying.OnHiding(); + } + } + + private void OnUnhiding() + { + if (m_nowPlaying) + { + m_nowPlaying.OnUnhiding(); + } + } + + // Public API. + protected override AutomationPeer OnCreateAutomationPeer() => new AnimatedVisualPlayerAutomationPeer(this); + + // Public API. + // Overrides FrameworkElement.MeasureOverride. Returns the size that is needed to display the + // animated visual within the available size and respecting the Stretch property. + protected override Size MeasureOverride(Size availableSize) + { + if (m_isFallenBack && Children.Size > 0) + { + // We are showing the fallback content due to a failure to load an animated visual. + // Tell the content to measure itself. + Children[0].Measure(availableSize); + // Our size is whatever the fallback content desires. + return Children[0].DesiredSize; + } + + if ((!m_animatedVisualRoot) || (m_animatedVisualSize == float2.zero())) + { + return { 0, 0 }; + } + + switch (Stretch) + { + case Stretch.None: + // No scaling will be done. Measured size is the smallest of each dimension. + return { std.min(m_animatedVisualSize.x, availableSize.Width), std.min(m_animatedVisualSize.y, availableSize.Height) }; + case Stretch.Fill: + // Both height and width will be scaled to fill the available space. + if (availableSize.Width != std.numeric_limits.infinity() && availableSize.Height != std.numeric_limits.infinity()) + { + // We will scale both dimensions to fill all available space. + return availableSize; + } + // One of the dimensions is infinite and we can't fill infinite dimensions, so + // fall back to Uniform so at least the non-infinite dimension will be filled. + break; + case Stretch.UniformToFill: + // Height and width will be scaled by the same amount such that there is no space + // around the edges. + if (availableSize.Width != std.numeric_limits.infinity() && availableSize.Height != std.numeric_limits.infinity()) + { + // Scale so there is no space around the edge. + var widthScale = availableSize.Width / m_animatedVisualSize.x; + var heightScale = availableSize.Height / m_animatedVisualSize.y; + var measuredSize = (heightScale < widthScale) + ? Size{ availableSize.Width, m_animatedVisualSize.y* widthScale } + : Size{ m_animatedVisualSize.x* heightScale, availableSize.Height }; + + // Clip the size to the available size. + measuredSize = Size{ + std.min(measuredSize.Width, availableSize.Width), + std.min(measuredSize.Height, availableSize.Height) + + }; + + return measuredSize; + } + // One of the dimensions is infinite and we can't fill infinite dimensions, so + // fall back to Uniform so at least the non-infinite dimension will be filled. + break; + } // end switch + + // Uniform scaling. + // Scale so that one dimension fits exactly and no dimension exceeds the boundary. + var widthScale = ((availableSize.Width == std.numeric_limits.infinity()) ? FLT_MAX : availableSize.Width) / m_animatedVisualSize.x; + var heightScale = ((availableSize.Height == std.numeric_limits.infinity()) ? FLT_MAX : availableSize.Height) / m_animatedVisualSize.y; + return (heightScale > widthScale) + ? Size{ availableSize.Width, m_animatedVisualSize.y* widthScale } + : Size{ m_animatedVisualSize.x* heightScale, availableSize.Height }; + } + + // Public API. + // Overrides FrameworkElement.ArrangeOverride. Scales to fit the animated visual into finalSize + // respecting the current Stretch and returns the size actually used. + protected override Size ArrangeOverride(Size finalSize) + { + // if (m_isFallenBack && Children.Size > 0) + // { + // // We are showing the fallback content due to a failure to load an animated visual. + // // Tell the content to arrange itself. + // Children[0].Arrange(Rect{ Point{ 0,0}, finalSize }); + // return finalSize; + // } + + // float2 scale; + // float2 arrangedSize; + + // if (!m_animatedVisualRoot) + // { + // // No content. 0 size. + // scale = { 1, 1 }; + // arrangedSize = { 0,0 }; + // } + // else + // { + // var stretch = Stretch; + // if (stretch == Stretch.None) + // { + // // Do not scale, do not center. + // scale = { 1, 1 }; + // arrangedSize = { + // std.min(finalSize.Width, m_animatedVisualSize.x), + // std.min(finalSize.Height, m_animatedVisualSize.y) + + // }; + // } + // else + // { + // scale = (float2)(finalSize) / m_animatedVisualSize; + + // switch (stretch) + // { + // case Stretch.Uniform: + // // Scale both dimensions by the same amount. + // if (scale.x < scale.y) + // { + // scale.y = scale.x; + // } + // else + // { + // scale.x = scale.y; + // } + // break; + // case Stretch.UniformToFill: + // // Scale both dimensions by the same amount and leave no gaps around the edges. + // if (scale.x > scale.y) + // { + // scale.y = scale.x; + // } + // else + // { + // scale.x = scale.y; + // } + // break; + // } + + // // A size needs to be set because there's an InsetClip applied, and without a + // // size the clip will prevent anything from being visible. + // arrangedSize = { + // std.min(finalSize.Width / scale.x, m_animatedVisualSize.x), + // std.min(finalSize.Height / scale.y, m_animatedVisualSize.y) + + // }; + + // // Center the animation within the available space. + // var offset = (finalSize - (m_animatedVisualSize * scale)) / 2; + // var z = 0.0F; + // m_rootVisual.Offset({ offset, z }); + + // // Adjust the position of the clip. + // m_rootVisual.Clip().Offset( + // (stretch == Stretch.UniformToFill) + // ? -(offset / scale) + // : float2.zero() + // ); + // } + // } + + // m_rootVisual.Size(arrangedSize); + // var z = 1.0F; + // m_rootVisual.Scale({ scale, z }); + + // return finalSize; + } + + // Public API. + // Accessor for ProgressObject property. + // NOTE: This is not a dependency property because it never changes and is not useful for binding. + /// + /// Gets a CompositionObject that is animated along with the progress of the AnimatedVisualPlayer. + /// + public CompositionObject ProgressObject => m_progressPropertySet; + + // Public API. + /// + /// Pauses the currently playing animated visual, or does nothing if no play is underway. + /// + public void Pause() + { + if (m_nowPlaying) + { + m_nowPlaying.Pause(); + } + } + + // Public API. + + /// + /// Starts playing the loaded animated visual, or does nothing if no animated visual is loaded. + /// + /// The point from which to start the animation, as a value from 0 to 1. + /// The point at which to finish the animation, as a value from 0 to 1. + /// If true, the animation loops continuously between fromProgress and toProgress. If false, the animation plays once then stops. + /// An async action that is completed when the play is stopped or, if looped is not set, when the play reaches toProgress. + public IAsyncAction PlayAsync(double fromProgress, double toProgress, bool looped) + { + // Make sure that animations are created. + CreateAnimations(); + + // Used to detect reentrance. + var version = ++m_playAsyncVersion; + + // Complete m_nowPlaying if it is still running. + // Identical to Stop() call but without destroying the animations. + // WARNING - this call may cause reentrance via the IsPlaying DP. + if (m_nowPlaying) + { + m_progressPropertySet.InsertScalar("Progress", (float)(m_currentPlayFromProgress)); + m_nowPlaying.Complete(); + } + + if (version != m_playAsyncVersion) + { + // The call was overtaken by another call due to reentrance. + co_return; + } + + MUX_ASSERT(!m_nowPlaying); + + // Adjust for the case where there is a segment that + // goes from [fromProgress..0] where m_fromProgress > 0. + // This is equivalent to [fromProgress..1], and by setting + // toProgress to 1 it saves us from generating extra key frames. + if (toProgress == 0 && fromProgress > 0) + { + toProgress = 1; + } + + // Adjust for the case where there is a segment that + // goes from [1..toProgress] where toProgress > 0. + // This is equivalent to [0..toProgress], and by setting + // fromProgress to 0 it saves us from generating extra key frames. + if (toProgress > 0 && fromProgress == 1) + { + fromProgress = 0; + } + + // Create an AnimationPlay to hold the play information. + // Keep a copy of the pointer because reentrance may cause the m_nowPlaying + // value to change. + var thisPlay = m_nowPlaying = std.new AnimationPlay( + this, + std.clamp((float)(fromProgress), 0.0F, 1.0F), + std.clamp((float)(toProgress), 0.0F, 1.0F), + looped); + + if (IsAnimatedVisualLoaded()) + { + // There is an animated visual loaded, so start it playing. + // WARNING - this may cause reentrance via IsPlaying DP. + thisPlay.Start(); + } + + // Capture the context so we can finish in the calling thread. + apartment_context calling_thread; + + // Await the current play. The await will complete when the animation completes + // or Stop() is called. It can complete on any thread. + co_await thisPlay; + + // Get back to the calling thread. + // This is necessary to destruct the AnimationPlay, and because callers + // from the dispatcher thread will expect to continue on the dispatcher thread. + co_await calling_thread; + } + + // Public API. + /// + /// Resumes the currently paused animated visual, or does nothing if there is no animated visual loaded or the animated visual is not paused. + /// + public void Resume() + { + if (m_nowPlaying) + { + m_nowPlaying.Resume(); + } + } + + // Public API. + // REENTRANCE SIDE EFFECT: IsPlaying DP via m_nowPlaying.Complete() or InsertScalar iff m_nowPlaying. + /// + /// Moves the progress of the animated visual to the given value, or does nothing if no animated visual is loaded. + /// + /// A value from 0 to 1 that represents the progress of the animated visual. + public void SetProgress(double progress) + { + // Make sure that animations are created. + CreateAnimations(); + + var clampedProgress = Math.Clamp((float)(progress), 0.0F, 1.0F); + + // WARNING: Reentrance via IsPlaying DP may occur from this point down to the end of the method + // iff m_nowPlaying. + + // Setting the Progress value will stop the current play. + m_progressPropertySet.InsertScalar("Progress", (float)(clampedProgress)); + + // Ensure the current PlayAsync task is completed. + // Note that this explicit call is necessary, even though InsertScalar + // will stop the current animation, because the BatchCompleted event for + // the animation only gets hooked up if the animation is not looped. + // If there was a BatchCompleted event and it already fired from setting the Progress + // value then Complete() is a no-op. + if (m_nowPlaying) + { + m_nowPlaying.Complete(); + } + + // If optimization is set to Resources - destroy annimations immediately. + if (AnimationOptimization == PlayerAnimationOptimization.Resources) + { + DestroyAnimations(); + } + } + + // Public API. + // REENTRANCE SIDE EFFECT: IsPlaying DP via SetProgress or InsertScalar iff m_nowPlaying. + /// + /// Stops the current play, or does nothing if no play is underway. + /// + public void Stop() + { + if (m_nowPlaying) + { + // Stop the animation by setting the Progress value to the fromProgress of the + // most recent play. + // This may cause reentrance via the IsPlaying DP. + SetProgress(m_currentPlayFromProgress); + } + } + + private void OnAutoPlayPropertyChanged(DependencyPropertyChangedEventArgs args) + { + var newValue = (bool)args.NewValue; + + if (newValue && IsAnimatedVisualLoaded && !m_nowPlaying) + { + // Start playing immediately. + var from = 0; + var to = 1; + var looped = true; + var ignore = PlayAsync(from, to, looped); + } + } + + private void OnAnimationOptimizationPropertyChanged(DependencyPropertyChangedEventArgs args) + { + var optimization = (PlayerAnimationOptimization)args.NewValue; + + if (m_nowPlaying) + { + // If there is something in play right now we should not create/destroy animations. + return; + } + + if (optimization == PlayerAnimationOptimization.Resources) + { + DestroyAnimations(); + } + else if (optimization == PlayerAnimationOptimization.Latency) + { + CreateAnimations(); + } + } + + private void CreateAnimations() + { + m_createAnimationsCounter++; + + if (m_isAnimationsCreated || m_animatedVisual == null) + { + return; + } + + // Check if current animated visual supports creating animations and create them. + if (m_animatedVisual is { } animatedVisual) + { + if (animatedVisual is IAnimatedVisual2 animatedVisual2) + { + animatedVisual2.CreateAnimations(); + m_isAnimationsCreated = true; + } + } + } + + private void DestroyAnimations() + { + if (!m_isAnimationsCreated || m_animatedVisual == null) + { + return; + } + + // Call RequestCommit to make sure that previous compositor calls complete before destroying animations. + // RequestCommitAsync is available only for RS4+ + m_rootVisual.Compositor.RequestCommitAsync().Completed( + [me_weak = get_weak(), createAnimationsCounter = m_createAnimationsCounter](auto, auto) { + var me = me_weak; + + if (!me) + { + return; + } + + // Check if there was any CreateAnimations call after DestroyAnimations. + // We should not destroy animations in this case, + // they will be destroyed by the following DestroyAnimations call. + if (createAnimationsCounter != me.m_createAnimationsCounter) + { + return; + } + + // Check if current animated visual supports destroyig animations. + if (var animatedVisual = me.m_animatedVisual) + { + if (var animatedVisual2 = animatedVisual as IAnimatedVisual2()) + { + animatedVisual2.DestroyAnimations(); + me.m_isAnimationsCreated = false; + } + } + } + ); + } + + private void OnFallbackContentPropertyChanged(DependencyPropertyChangedEventArgs args) + { + if (m_isFallenBack) + { + LoadFallbackContent(); + } + } + + private void OnSourcePropertyChanged(DependencyPropertyChangedEventArgs args) + { + var newSource = args.NewValue as IAnimatedVisualSource; + + // WARNING - this may cause reentrance via the IsPlaying DP iff m_nowPlaying. + Stop(); + + // Disconnect from the update notifications of the old source. + m_dynamicAnimatedVisualInvalidatedRevoker.revoke(); + + if (newSource is IDynamicAnimatedVisualSource newDynamicSource) + { + // Connect to the update notifications of the new source. + m_dynamicAnimatedVisualInvalidatedRevoker + = newDynamicSource.AnimatedVisualInvalidated(auto_revoke, [weakThis{ get_weak() }]( + var /*sender*/, + var /*e*/) + + { + if (var strongThis = weakThis) + { + strongThis.UpdateContent(); + } + }); + } + + UpdateContent(); + } + + // Unload the current animated visual (if any). + private void UnloadContent() + { + if (m_animatedVisualRoot is not null) + { + // This will complete any current play. + // WARNING - this may cause reentrance via IsPlaying DP iff m_nowPlaying. + Stop(); + + // Remove the old animated visual (if any). + var animatedVisual = m_animatedVisual; + if (animatedVisual is not null) + { + m_rootVisual.Children.RemoveAll(); + m_animatedVisualRoot = null; + // Notify the animated visual that it will no longer be used. + (animatedVisual as IDisposable)?.Dispose(); + m_animatedVisual = null; + } + + // Size has changed. Tell XAML to re-measure. + InvalidateMeasure(); + + // WARNING - these may cause reentrance. + Duration = TimeSpan.Zero; + Diagnostics = null; + // Set IsAnimatedVisualLoaded last as it is the property that is most likely + // to have user code react to its state change. + IsAnimatedVisualLoaded = false; + } + } + + private void UpdateContent() + { + // Unload the existing content, if any. + UnloadContent(); + + // Try to create a new animated visual. + var source = Source; + if (source is null) + { + // No source set. Nothing to do. + return; + } + + object diagnostics; + IAnimatedVisual animatedVisual; + + bool createAnimations = AnimationOptimization == PlayerAnimationOptimization.Latency; + + if (source is IAnimatedVisualSource3 source3) + { + animatedVisual = source3.TryCreateAnimatedVisual(m_rootVisual.Compositor, out diagnostics, createAnimations); + m_isAnimationsCreated = createAnimations; + m_animatedVisual = animatedVisual; + } + + else + { + animatedVisual = source.TryCreateAnimatedVisual(m_rootVisual.Compositor, out diagnostics); + m_isAnimationsCreated = true; + + // m_animatedVisual should be updated before DestroyAnimations call + m_animatedVisual = animatedVisual; + + // Destroy animations if we don't need them. + // Old IAnimatedVisualSource interface always creates them. + if (!createAnimations) + { + DestroyAnimations(); + } + } + + if (animatedVisual is null) + { + // Create failed. + + if (!m_isFallenBack) + { + // Show the fallback content, if any. + m_isFallenBack = true; + LoadFallbackContent(); + } + + // Complete any play that was started during loading. + // WARNING - this may cause reentrance via IsPlaying DP iff m_nowPlaying. + Stop(); + + // WARNING - this may cause reentrance. + Diagnostics = diagnostics; + + return; + } + + // If the content is empty, do nothing. If we are in fallback from a previous + // failure to load, stay fallen back. + // Empty content means the source has nothing to show yet. + if (animatedVisual?.RootVisual is null || animatedVisual.Size == default(Vector2)) + { + // WARNING - this may cause reentrance. + Diagnostics = diagnostics; + + return; + } + + // We have non-empty content to show. + // If we were in fallback, clear that fallback content. + if (m_isFallenBack) + { + // Get out of the fallback state. + m_isFallenBack = false; + UnloadFallbackContent(); + } + + // Hook up the new animated visual. + m_animatedVisualRoot = animatedVisual.RootVisual; + m_animatedVisualSize = animatedVisual.Size; + m_rootVisual.Children.InsertAtTop(m_animatedVisualRoot); + + // Size has changed. Tell XAML to re-measure. + InvalidateMeasure(); + + // Ensure the animated visual has a Progress property. This guarantees that a composition without + // a Progress property won't blow up when we create an expression that references it below. + // Normally the animated visual would have a Progress property that all its expressions reference, + // but just in case, insert it here. + m_animatedVisualRoot.Properties.InsertScalar("Progress", 0.0F); + + // Tie the animated visual's Progress property to the player Progress with an ExpressionAnimation. + var compositor = m_rootVisual.Compositor; + var progressAnimation = compositor.CreateExpressionAnimation("_.Progress"); + progressAnimation.SetReferenceParameter("_", m_progressPropertySet); + m_animatedVisualRoot.Properties.StartAnimation("Progress", progressAnimation); + + // WARNING - these may cause reentrance. + // Set these properties before the if (AutoPlay()) branch calls PlayAsync + // so that the properties are updated before playing starts. + Duration = animatedVisual.Duration; + Diagnostics = diagnostics; + // Set IsAnimatedVisualLoaded last as it is the property that is most likely + // to have user code react to its state change. + IsAnimatedVisualLoaded = true; + + // Check whether playing has been started already via reentrance from a DP handler. + if (m_nowPlaying) + { + m_nowPlaying.Start(); + } + else if (AutoPlay) + { + // Start playing immediately. + var from = 0; + var to = 1; + var looped = true; + // NOTE: If !IsAnimatedVisualLoaded() then this is a no-op. + var ignore = PlayAsync(from, to, looped); + } + } + + private void LoadFallbackContent() + { + MUX_ASSERT(m_isFallenBack); + + UIElement fallbackContentElement = null; + var fallbackContentTemplate = FallbackContent; + if (fallbackContentTemplate is not null) + { + // Load the content from the DataTemplate. It should be a UIElement tree root. + DependencyObject fallbackContentObject = fallbackContentTemplate.LoadContent(); + // Get the content. + fallbackContentElement = fallbackContentObject as UIElement; + } + + // Set the (possibly null) content. We allow null content so as to handle the + // case where the fallback content got removed - in which case we want to + // clear out the existing content if any. + SetFallbackContent(fallbackContentElement); + } + + private void UnloadFallbackContent() + { + MUX_ASSERT(!m_isFallenBack); + SetFallbackContent(null); + } + + private void SetFallbackContent(UIElement uiElement) + { + // Clear out the existing content. + ClearChildren(); + + // Place the content in the tree. + if (uiElement is not null) + { + AddChild(uiElement); + } + + // Size has probably changed. Tell XAML to re-measure. + InvalidateMeasure(); + } + + private void OnPlaybackRatePropertyChanged(DependencyPropertyChangedEventArgs args) + { + if (m_nowPlaying is not null) + { + m_nowPlaying.SetPlaybackRate((float)(double)args.NewValue); + } + } + + private void OnStretchPropertyChanged(DependencyPropertyChangedEventArgs args) + { + InvalidateMeasure(); + } +} diff --git a/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayerAutomationPeer.mux.cs b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayerAutomationPeer.mux.cs new file mode 100644 index 000000000000..42efe756e2a1 --- /dev/null +++ b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayerAutomationPeer.mux.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. +// MUX Reference src\controls\dev\AnimatedVisualPlayer\AnimatedVisualPlayerAutomationPeer.cpp, tag winui3/release/1.6.3, commit 66d24dfff + +using System.Text; +using System.Threading.Tasks; +using Microsoft.UI.Xaml.Controls; + +namespace Microsoft/* UWP don't rename */.UI.Xaml.Automation.Peers; + +/// +/// Exposes AnimatedVisualPlayer types to Microsoft UI Automation. +/// +public partial class AnimatedVisualPlayerAutomationPeer : FrameworkElementAutomationPeer +{ + /// + /// Initializes a new instance of the AnimatedVisualPlayerAutomationPeer class. + /// + /// + public AnimatedVisualPlayerAutomationPeer(AnimatedVisualPlayer owner) : base(owner) + { + } + + protected override string GetClassNameCore() => nameof(AnimatedVisualPlayer); + + protected override AutomationControlType GetAutomationControlTypeCore() => AutomationControlType.Image; +} diff --git a/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisual.cs b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisual.cs index 13a44ad4d47d..223c09b732bf 100644 --- a/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisual.cs +++ b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisual.cs @@ -6,26 +6,25 @@ using System.Numerics; using Microsoft.UI.Composition; -namespace Microsoft/* UWP don't rename */.UI.Xaml.Controls +namespace Microsoft/* UWP don't rename */.UI.Xaml.Controls; + +/// +/// An animated Composition.Visual that can be used by other objects, such as an AnimatedVisualPlayer or AnimatedIcon. +/// +public partial interface IAnimatedVisual : IDisposable { /// - /// An animated Composition.Visual that can be used by other objects, such as an AnimatedVisualPlayer or AnimatedIcon. + /// Gets the root Visual of the animated visual. /// - public partial interface IAnimatedVisual : IDisposable - { - /// - /// Gets the root Visual of the animated visual. - /// - Visual RootVisual { get; } + Visual RootVisual { get; } - /// - /// Gets the size of the animated visual. - /// - Vector2 Size { get; } + /// + /// Gets the size of the animated visual. + /// + Vector2 Size { get; } - /// - /// Gets the duration of the animated visual. - /// - TimeSpan Duration { get; } - } + /// + /// Gets the duration of the animated visual. + /// + TimeSpan Duration { get; } } diff --git a/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisual2.cs b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisual2.cs new file mode 100644 index 000000000000..18c4a2d0781e --- /dev/null +++ b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisual2.cs @@ -0,0 +1,14 @@ +using System; + +namespace Microsoft/* UWP don't rename */.UI.Xaml.Controls; + +/// +/// An animated Composition.Visual that can be used by other objects, such as an AnimatedVisualPlayer or AnimatedIcon. +/// Extends IAnimatedVisual with methods to create and destroy animations. +/// +public partial interface IAnimatedVisual2 : IAnimatedVisual, IDisposable +{ + void CreateAnimations(); + + void DestroyAnimations(); +} diff --git a/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisualSource.cs b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisualSource.cs new file mode 100644 index 000000000000..3308b37a4f12 --- /dev/null +++ b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisualSource.cs @@ -0,0 +1,17 @@ +using Microsoft.UI.Composition; + +namespace Microsoft/* UWP don't rename */.UI.Xaml.Controls; + +/// +/// An animated Visual that can be used by other objects, such as an AnimatedVisualPlayer. +/// +public partial interface IAnimatedVisualSource +{ + /// + /// Attempts to create an animated visual. + /// + /// The compositor for the animated visual. + /// The diagnostics information about the attempt to create an animated visual. + /// An animated visual that can be used by other objects. + IAnimatedVisual TryCreateAnimatedVisual(Compositor compositor, out object diagnostics); +} diff --git a/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisualSource2.cs b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisualSource2.cs new file mode 100644 index 000000000000..f4acc857fb2c --- /dev/null +++ b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisualSource2.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using Windows.UI; + +namespace Microsoft/* UWP don't rename */.UI.Xaml.Controls; + +/// +/// An animated Visual that can be used by other objects, such as an AnimatedIcon. Extends IAnimatedVisualSource. +/// +public partial interface IAnimatedVisualSource2 : IAnimatedVisualSource +{ + /// + /// Gets a collection that provides a mapping of marker names to playback positions in the animation. + /// + public IReadOnlyDictionary Markers { get; } + + /// + /// Sets a color for the animated visual. + /// + /// The property name of the color as defined in the JSON file for the animated icon. + /// The color value for the propertyName. + void SetColorProperty(string propertyName, Color value); +} diff --git a/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisualSource3.cs b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisualSource3.cs new file mode 100644 index 000000000000..1916dd56231a --- /dev/null +++ b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisualSource3.cs @@ -0,0 +1,18 @@ +using Microsoft.UI.Composition; + +namespace Microsoft/* UWP don't rename */.UI.Xaml.Controls; + +/// +/// An animated Composition.Visual that can be used by other objects, such as an AnimatedVisualPlayer or AnimatedIcon. +/// +public partial interface IAnimatedVisualSource3 +{ + /// + /// Attempts to create an animated visual. + /// + /// The compositor for the animated visual. + /// The diagnostics information about the attempt to create an animated visual. + /// True to create the animations; otherwise, false. + /// An animated visual that can be used by other objects. + IAnimatedVisual2 TryCreateAnimatedVisual(Compositor compositor, out object diagnostics, bool createAnimations); +} diff --git a/src/Uno.UI/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.cs b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/Legacy/AnimatedVisualPlayer.legacy.cs similarity index 99% rename from src/Uno.UI/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.cs rename to src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/Legacy/AnimatedVisualPlayer.legacy.cs index 0f9e303b41dc..9d35908137c2 100644 --- a/src/Uno.UI/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.cs +++ b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/Legacy/AnimatedVisualPlayer.legacy.cs @@ -1,4 +1,5 @@ -using System; +#if false +using System; using System.Threading.Tasks; using Uno; using Windows.Foundation; @@ -139,3 +140,4 @@ protected override Size MeasureOverride(Size availableSize) protected override Size ArrangeOverride(Size finalSize) => ArrangeFirstChild(finalSize); } } +#endif diff --git a/src/Uno.UI/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisualSource.cs b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/Legacy/IAnimatedVisualSource.legacy.cs similarity index 94% rename from src/Uno.UI/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisualSource.cs rename to src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/Legacy/IAnimatedVisualSource.legacy.cs index e321eb286427..c4b85de1fead 100644 --- a/src/Uno.UI/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisualSource.cs +++ b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/Legacy/IAnimatedVisualSource.legacy.cs @@ -1,4 +1,5 @@ -using System; +#if false +using System; using Microsoft/* UWP don't rename */.UI.Xaml.Controls; using Windows.Foundation; @@ -24,3 +25,4 @@ internal partial interface IAnimatedVisualSourceWithUri Uri UriSource { get; set; } } } +#endif diff --git a/src/Uno.UI/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisualSource2.cs b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/Legacy/IAnimatedVisualSource2.legacy.cs similarity index 85% rename from src/Uno.UI/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisualSource2.cs rename to src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/Legacy/IAnimatedVisualSource2.legacy.cs index c839ad5ca75c..3b07ac0e98ec 100644 --- a/src/Uno.UI/UI/Xaml/Controls/AnimatedVisualPlayer/IAnimatedVisualSource2.cs +++ b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/Legacy/IAnimatedVisualSource2.legacy.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +#if false +using System.Collections.Generic; using Windows.UI; using Microsoft.UI.Xaml.Controls; @@ -11,3 +12,4 @@ public partial interface IAnimatedVisualSource2 : IAnimatedVisualSource void SetColorProperty(string propertyName, Color value); } } +#endif diff --git a/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/ILottieVisualSourceProvider.cs b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/Legacy/ILottieVisualSourceProvider.cs similarity index 100% rename from src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/ILottieVisualSourceProvider.cs rename to src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/Legacy/ILottieVisualSourceProvider.cs diff --git a/src/Uno.UI/UI/Xaml/Controls/AnimatedVisualPlayer/IThemableAnimatedVisualSource.cs b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/Legacy/IThemableAnimatedVisualSource.cs similarity index 100% rename from src/Uno.UI/UI/Xaml/Controls/AnimatedVisualPlayer/IThemableAnimatedVisualSource.cs rename to src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/Legacy/IThemableAnimatedVisualSource.cs diff --git a/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/PlayerAnimationOptimization.cs b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/PlayerAnimationOptimization.cs new file mode 100644 index 000000000000..ce951290dcbd --- /dev/null +++ b/src/Uno.UI/Microsoft/UI/Xaml/Controls/AnimatedVisualPlayer/PlayerAnimationOptimization.cs @@ -0,0 +1,17 @@ +namespace Microsoft/* UWP don't rename */.UI.Xaml.Controls; + +/// +/// Defines constants that specify how an AnimatedVisualPlayer caches animations when the player is idle. +/// +public enum PlayerAnimationOptimization +{ + /// + /// The player optimizes animation caching for lower latency. + /// + Latency = 0, + + /// + /// The player optimizes animation caching for lower resource usage. + /// + Resources = 1, +}