From 33628908248430882ed7ce22f8a49a09f64b01db Mon Sep 17 00:00:00 2001 From: michael-hawker <24302614+michael-hawker@users.noreply.github.com> Date: Wed, 16 Dec 2020 17:29:51 -0800 Subject: [PATCH 001/171] Creating Microsoft.Toolkit.Uwp.UI.Behaviors Removes ScrollHeader from the Controls Package Updates Sample pages to use Behaviors instead from new Behaviors package TODO/Broken: - Animation Behaviors Currently don't have a home (still in folder structure of Animations, most likely removed for new approach using Behaviors directly w/ new Animation System) - General Animation extensions removed (to be replaced with a new coordinated system) - Blur/Saturation Effect extensions don't have a home (to move to Media package?) - Sample App - Graph Control Samples (needs to be rebuilt with new Behaviors package) - ViewportBehavior Example (was using Blur Extension) - Re-apply Blur effect to the backgrounds in Shell.xaml as was using Behavior --- .../Microsoft.Toolkit.Uwp.SampleApp.csproj | 77 +------ .../Models/Sample.cs | 22 +- .../FadeHeader/FadeHeaderBehaviorPage.xaml | 10 +- .../FadeHeader/FadeHeaderBehaviorXaml.bind | 4 +- .../IconExtensions/IconExtensionsPage.xaml.cs | 4 - .../ImplicitAnimationsCode.bind | 16 +- .../LoginButton/LoginButtonPage.xaml | 12 +- .../SamplePages/OnDevice/OnDevicePage.xaml.cs | 4 - .../PeoplePicker/PeoplePickerPage.xaml | 8 +- .../PersonView/PersonViewPage.xaml | 4 +- .../ScrollHeader/ScrollHeaderCode.bind | 45 +++-- .../ScrollHeader/ScrollHeaderPage.xaml | 18 +- .../ScrollViewerExtensionsPage.xaml | 131 ++++++------ .../ScrollViewerExtensionsXaml.bind | 47 +++-- .../ViewportBehaviorPage.xaml.cs | 6 +- Microsoft.Toolkit.Uwp.SampleApp/Shell.xaml | 157 +++++++++------ .../Custom/PivotHeaderItemUnderlineStyle.xaml | 173 ++++++++++------ ...Microsoft.Toolkit.Uwp.UI.Animations.csproj | 20 +- .../SurfaceLoader.cs | 190 ------------------ .../ApiInformationHelper.cs | 14 ++ .../BehaviorBase.cs | 0 .../Focus}/AutoFocusBehavior.cs | 0 .../Focus}/FocusBehavior.cs | 0 .../Headers}/FadeHeaderBehavior.cs | 4 +- .../Headers}/QuickReturnHeaderBehavior.cs | 3 +- .../Headers}/StickyHeaderBehavior.cs | 3 +- .../Microsoft.Toolkit.Uwp.UI.Behaviors.csproj | 31 +++ .../Microsoft.Toolkit.Uwp.UI.Behaviors.rd.xml | 5 + .../Viewport}/ViewportBehavior.cs | 0 .../Microsoft.Toolkit.Uwp.UI.Controls.csproj | 1 + .../ScrollHeader/ScrollHeader.cs | 96 --------- .../ScrollHeader/ScrollHeader.xaml | 16 -- .../ScrollHeader/ScrollHeaderMode.cs | 32 --- .../Themes/Generic.xaml | 1 - .../Microsoft.Toolkit.Uwp.UI.csproj | 10 +- Windows Community Toolkit.sln | 23 +++ 36 files changed, 466 insertions(+), 721 deletions(-) delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/SurfaceLoader.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Behaviors/ApiInformationHelper.cs rename {Microsoft.Toolkit.Uwp.UI/Behaviors => Microsoft.Toolkit.Uwp.UI.Behaviors}/BehaviorBase.cs (100%) rename {Microsoft.Toolkit.Uwp.UI/Behaviors => Microsoft.Toolkit.Uwp.UI.Behaviors/Focus}/AutoFocusBehavior.cs (100%) rename {Microsoft.Toolkit.Uwp.UI/Behaviors => Microsoft.Toolkit.Uwp.UI.Behaviors/Focus}/FocusBehavior.cs (100%) rename {Microsoft.Toolkit.Uwp.UI.Animations/Behaviors => Microsoft.Toolkit.Uwp.UI.Behaviors/Headers}/FadeHeaderBehavior.cs (98%) rename {Microsoft.Toolkit.Uwp.UI.Animations/Behaviors => Microsoft.Toolkit.Uwp.UI.Behaviors/Headers}/QuickReturnHeaderBehavior.cs (99%) rename {Microsoft.Toolkit.Uwp.UI.Animations/Behaviors => Microsoft.Toolkit.Uwp.UI.Behaviors/Headers}/StickyHeaderBehavior.cs (98%) create mode 100644 Microsoft.Toolkit.Uwp.UI.Behaviors/Microsoft.Toolkit.Uwp.UI.Behaviors.csproj create mode 100644 Microsoft.Toolkit.Uwp.UI.Behaviors/Properties/Microsoft.Toolkit.Uwp.UI.Behaviors.rd.xml rename {Microsoft.Toolkit.Uwp.UI/Behaviors => Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport}/ViewportBehavior.cs (100%) delete mode 100644 Microsoft.Toolkit.Uwp.UI.Controls/ScrollHeader/ScrollHeader.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Controls/ScrollHeader/ScrollHeader.xaml delete mode 100644 Microsoft.Toolkit.Uwp.UI.Controls/ScrollHeader/ScrollHeaderMode.cs diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index c163498a562..8c9bb57abca 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -112,9 +112,6 @@ 10.1901.28001 - - 6.1.0-build.6 - 2.4.2 @@ -294,7 +291,6 @@ - @@ -303,7 +299,6 @@ - @@ -325,7 +320,6 @@ - @@ -336,7 +330,6 @@ - @@ -344,10 +337,7 @@ - - - @@ -380,11 +370,7 @@ - - - - @@ -396,13 +382,7 @@ - - - - - - @@ -422,8 +402,6 @@ - - Designer @@ -440,8 +418,6 @@ - - Designer @@ -832,9 +808,6 @@ BladePage.xaml - - BlurBehaviorPage.xaml - AlignmentGridPage.xaml @@ -844,9 +817,6 @@ MicrosoftTranslatorPage.xaml - - SaturationBehaviorPage.xaml - TileControlPage.xaml @@ -867,9 +837,6 @@ - - LightBehaviorPage.xaml - LinkedInPage.xaml @@ -915,12 +882,6 @@ TwitterPage.xaml - - OffsetBehaviorPage.xaml - - - FadeBehaviorPage.xaml - ImageExPage.xaml @@ -934,12 +895,6 @@ WeatherLiveTileAndToastPage.xaml - - RotateBehaviorPage.xaml - - - ScaleBehaviorPage.xaml - RadialGaugePage.xaml @@ -1305,10 +1260,6 @@ Designer MSBuild:Compile - - MSBuild:Compile - Designer - MSBuild:Compile Designer @@ -1325,10 +1276,6 @@ MSBuild:Compile Designer - - Designer - MSBuild:Compile - MSBuild:Compile Designer @@ -1357,10 +1304,6 @@ MSBuild:Compile Designer - - Designer - MSBuild:Compile - Designer MSBuild:Compile @@ -1393,14 +1336,6 @@ MSBuild:Compile Designer - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - Designer MSBuild:Compile @@ -1453,14 +1388,6 @@ MSBuild:Compile Designer - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - Designer MSBuild:Compile @@ -1531,6 +1458,10 @@ {1ae2cb5c-58a0-4f12-8e6f-2cd4aaadb34c} Microsoft.Toolkit.Uwp.Samples.BackgroundTasks + + {d4ff799d-0df2-495a-adc9-3bbc4aef8971} + Microsoft.Toolkit.Uwp.UI.Behaviors + {daeb9cec-c817-33b2-74b2-bc379380db72} Microsoft.Toolkit.Uwp.UI.Controls.DataGrid diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs b/Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs index 805261aa7ec..6bc44c71e22 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs @@ -16,8 +16,6 @@ using System.Text.Json.Serialization; using System.Text.RegularExpressions; using System.Threading.Tasks; -using Microsoft.Toolkit.Graph.Converters; -using Microsoft.Toolkit.Graph.Providers; using Microsoft.Toolkit.Uwp.Helpers; using Microsoft.Toolkit.Uwp.Input.GazeInteraction; using Microsoft.Toolkit.Uwp.SampleApp.Models; @@ -658,16 +656,16 @@ private static Type LookForTypeByName(string typeName) } // Search in Microsoft.Toolkit.Graph.Controls - var graphControlsProxyType = typeof(UserToPersonConverter); - assembly = graphControlsProxyType.GetTypeInfo().Assembly; - - foreach (var typeInfo in assembly.ExportedTypes) - { - if (typeInfo.Name == typeName) - { - return typeInfo; - } - } + //var graphControlsProxyType = typeof(UserToPersonConverter); + //assembly = graphControlsProxyType.GetTypeInfo().Assembly; + + //foreach (var typeInfo in assembly.ExportedTypes) + //{ + // if (typeInfo.Name == typeName) + // { + // return typeInfo; + // } + //} // Search in Microsoft.Toolkit.Uwp.UI.Animations var animationsProxyType = EasingType.Default; diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/FadeHeader/FadeHeaderBehaviorPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/FadeHeader/FadeHeaderBehaviorPage.xaml index a2ae6567063..ce25561b9d0 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/FadeHeader/FadeHeaderBehaviorPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/FadeHeader/FadeHeaderBehaviorPage.xaml @@ -7,12 +7,6 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> - - - - - - - - + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/FadeHeader/FadeHeaderBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/FadeHeader/FadeHeaderBehaviorXaml.bind index 851181f5164..60ffa5965b2 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/FadeHeader/FadeHeaderBehaviorXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/FadeHeader/FadeHeaderBehaviorXaml.bind @@ -3,7 +3,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:interactivity="using:Microsoft.Xaml.Interactivity" - xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Animations.Behaviors" + xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors" mc:Ignorable="d"> @@ -24,7 +24,7 @@ Margin="12" /> diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/IconExtensions/IconExtensionsPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/IconExtensions/IconExtensionsPage.xaml.cs index 0311ad04acf..35971fb6a53 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/IconExtensions/IconExtensionsPage.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/IconExtensions/IconExtensionsPage.xaml.cs @@ -2,10 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Linq; -using Microsoft.Toolkit.Uwp.UI.Animations.Behaviors; -using Microsoft.Toolkit.Uwp.UI.Extensions; -using Microsoft.Xaml.Interactivity; using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Implicit Animations/ImplicitAnimationsCode.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Implicit Animations/ImplicitAnimationsCode.bind index 71ab3ffa96e..ca217f3cd13 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Implicit Animations/ImplicitAnimationsCode.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Implicit Animations/ImplicitAnimationsCode.bind @@ -19,24 +19,24 @@ extensions:VisualExtensions.CenterPoint="50,50,0"> - - + + - + - - + + - + - + - + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/LoginButton/LoginButtonPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/LoginButton/LoginButtonPage.xaml index cd37f20d156..ca429d0df3f 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/LoginButton/LoginButtonPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/LoginButton/LoginButtonPage.xaml @@ -1,19 +1,19 @@  - + - - + + - + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/OnDevice/OnDevicePage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/OnDevice/OnDevicePage.xaml.cs index 9943ccb283d..274c96025f0 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/OnDevice/OnDevicePage.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/OnDevice/OnDevicePage.xaml.cs @@ -2,10 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Linq; -using Microsoft.Toolkit.Uwp.UI.Animations.Behaviors; -using Microsoft.Toolkit.Uwp.UI.Extensions; -using Microsoft.Xaml.Interactivity; using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PeoplePicker/PeoplePickerPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PeoplePicker/PeoplePickerPage.xaml index 829819c6c95..c4da0eaa5ae 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PeoplePicker/PeoplePickerPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PeoplePicker/PeoplePickerPage.xaml @@ -7,10 +7,12 @@ xmlns:wgt="using:Microsoft.Toolkit.Graph.Controls" mc:Ignorable="d"> - + - + - + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PersonView/PersonViewPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PersonView/PersonViewPage.xaml index 702efbf97d2..fc19d88e848 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PersonView/PersonViewPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PersonView/PersonViewPage.xaml @@ -5,8 +5,8 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:wgt="using:Microsoft.Toolkit.Graph.Controls" mc:Ignorable="d"> - + - + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollHeader/ScrollHeaderCode.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollHeader/ScrollHeaderCode.bind index 8303522e746..9edcd2542b6 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollHeader/ScrollHeaderCode.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollHeader/ScrollHeaderCode.bind @@ -2,34 +2,37 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls" xmlns:models="using:Microsoft.Toolkit.Uwp.SampleApp.Models" + xmlns:interactivity="using:Microsoft.Xaml.Interactivity" + xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> + + + - - - - - - - - + + + + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollHeader/ScrollHeaderPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollHeader/ScrollHeaderPage.xaml index d95346f0b88..44a877fd63d 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollHeader/ScrollHeaderPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollHeader/ScrollHeaderPage.xaml @@ -1,19 +1,15 @@  - - - - - - - - - - + + + + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsPage.xaml index 08bf65c2e7c..d4da6b9a6da 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsPage.xaml @@ -1,10 +1,12 @@ - @@ -14,47 +16,49 @@ + extensions:ScrollViewerExtensions.VerticalScrollBarMargin="{Binding MinHeight, ElementName=MyHeaderGrid, Converter={StaticResource DoubleTopThicknessConverter}}"> + + + - - - - - - - - + + + + + + - + + Grid.Column="0" + Width="100" + Height="100" + Margin="0,0,24,0" + Source="ms-appx:///Assets/ToolkitLogo.png" /> + VerticalAlignment="Center" + Text="{Binding Title}" + TextTrimming="CharacterEllipsis" /> @@ -66,45 +70,44 @@ - - + - - + HorizontalAlignment="Center" + VerticalAlignment="Center" + Orientation="Horizontal" + Spacing="4"> + + - - - - + + + + - + Fill="Crimson" + Points="0,0 0,60 60,60 60,0" + Stroke="DarkRed" /> \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsXaml.bind index 555377bdebe..6b28c95e185 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ScrollViewerExtensions/ScrollViewerExtensionsXaml.bind @@ -5,6 +5,8 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:extensions="using:Microsoft.Toolkit.Uwp.UI.Extensions" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:interactivity="using:Microsoft.Xaml.Interactivity" + xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors" mc:Ignorable="d"> @@ -15,29 +17,30 @@ + + + - - - - - - - - + + + + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorPage.xaml.cs index eb09f531121..17a683842cb 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorPage.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ViewportBehavior/ViewportBehaviorPage.xaml.cs @@ -39,7 +39,7 @@ public void OnXamlRendered(FrameworkElement control) if (control.FindChildByName("EffectElement") is Image effectElement) { _effectElement = effectElement; - _effectElement.Blur(value: 10, duration: 0).Start(); + ////TODO: _effectElement.Blur(value: 10, duration: 0).Start(); } if (control.FindChildByName("EffectElementHost") is FrameworkElement effectElementHost) @@ -72,7 +72,7 @@ private async void EffectElementHost_EnteredViewport(object sender, EventArgs e) { AddLog("Entered viewport"); - await _effectElement.Blur(value: 0, duration: 1500).StartAsync(); + ////TODO: await _effectElement.Blur(value: 0, duration: 1500).StartAsync(); } private void EffectElementHost_EnteringViewport(object sender, EventArgs e) @@ -87,7 +87,7 @@ private async void EffectElementHost_ExitedViewport(object sender, EventArgs e) AddLog("Exited viewport"); _effectElement.Source = null; - await _effectElement.Blur(value: 8, duration: 0).StartAsync(); + ////TODO: await _effectElement.Blur(value: 8, duration: 0).StartAsync(); } private void EffectElementHost_ExitingViewport(object sender, EventArgs e) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Shell.xaml b/Microsoft.Toolkit.Uwp.SampleApp/Shell.xaml index 7aa45fcdc86..fc16ce0693f 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Shell.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/Shell.xaml @@ -1,15 +1,15 @@  + Style="{StaticResource ToolkitNavViewStyle}"> + QueryIcon="Find" + QuerySubmitted="SearchBox_QuerySubmitted" + TextChanged="SearchBox_TextChanged" /> - + - + Duration="0" />--> - + - + - + + ShadowOpacity="0.7" + Color="Black"> @@ -89,35 +93,47 @@ - + - + - - + + - - + + @@ -125,30 +141,30 @@ + Visibility="Collapsed"> - + ShadowOpacity="0.6" + Color="Black"> - + @@ -160,58 +176,81 @@ - - + Text="{Binding About}" + TextWrapping="Wrap" /> - + - - + + - - + + - - + + - - + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Styles/Custom/PivotHeaderItemUnderlineStyle.xaml b/Microsoft.Toolkit.Uwp.SampleApp/Styles/Custom/PivotHeaderItemUnderlineStyle.xaml index 73231c861a7..7d7ad535788 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Styles/Custom/PivotHeaderItemUnderlineStyle.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/Styles/Custom/PivotHeaderItemUnderlineStyle.xaml @@ -1,14 +1,17 @@ - - - + + + + + + - - + + - - + + - - + + @@ -43,71 +79,97 @@ + Storyboard.TargetProperty="X" + To="{ThemeResource PivotHeaderItemLockedTranslation}" + Duration="0" /> + Storyboard.TargetProperty="(UIElement.Opacity)" + To="0" + Duration="0" /> - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + @@ -121,25 +183,6 @@ - - - - - - diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj b/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj index df6558d9426..f31624a8267 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj @@ -7,22 +7,34 @@ This library provides helpers and extensions on top of Windows Composition and XAML storyboards. It is part of the Windows Community Toolkit. Namespace: - - Behaviors: Blur, CompositionBehaviorBase, CompositionBehaviorBase, Fade, FadeHeaderBehavior, Light, Offset, QuickReturnHeaderBehavior, Rotate, Saturation, Scale, StickyHeaderBehavior. - CompositionAnimations: - Animations: AnimationBase, OffsetAnimation, OpacityAnimation, RotationAnimation, RotationInDegreesAnimation, ScalarAnimation, ScaleAnimation, TranslationAnimation, TypedAnimationBase, Vector2Animation, Vector3Animation, Vector4Animation - CompositionAnimations: ExpressionKeyFrame, KeyFrame, KeyFrameCollection, ScalarKeyFrame, TypedKeyFrame, Vector2KeyFrame, Vector3KeyFrame, Vector4KeyFrame - ConnectedAnimations: Connected, ConnectedAnimationHelper, ConnectedAnimationListProperty, ConnectedAnimationProperties - - Effects: AnimationEffect, Blur, Saturation - Expressions: ExpressionNodes, ExpressionValues, ReferenceNodes, CompositionExtensions, ExpressionFunctions, OperationType - AnimationExtensions: Blur, Fade, Light, Offset, Rotate, Saturation, Scale UWP Toolkit Windows Animations Composition Connected Implicit XAML + + + + + + + + + + + + + + + + - - diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/SurfaceLoader.cs b/Microsoft.Toolkit.Uwp.UI.Animations/SurfaceLoader.cs deleted file mode 100644 index 8610c13fb83..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/SurfaceLoader.cs +++ /dev/null @@ -1,190 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Threading.Tasks; -using Microsoft.Graphics.Canvas; -using Microsoft.Graphics.Canvas.Text; -using Microsoft.Graphics.Canvas.UI.Composition; -using Windows.Foundation; -using Windows.Foundation.Metadata; -using Windows.Graphics.DirectX; -using Windows.UI; -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// A delegate for load time effects. - /// - /// The bitmap. - /// The device. - /// The size target. - /// A CompositeDrawingSurface - public delegate CompositionDrawingSurface LoadTimeEffectHandler(CanvasBitmap bitmap, CompositionGraphicsDevice device, Size sizeTarget); - - /// - /// The SurfaceLoader is responsible to loading images into Composition Objects. - /// - [Deprecated("This class is deprecated, please use the SurfaceLoader class from the Microsoft.Toolkit.Uwp.UI.Media package.", DeprecationType.Deprecate, 6)] - public class SurfaceLoader - { - /// - /// A flag to store the initialized state. - /// - private static bool _intialized; - - /// - /// The compositor - /// - private static Compositor _compositor; - - /// - /// The canvas device - /// - private static CanvasDevice _canvasDevice; - - /// - /// The composition graphic device to determine which GPU is handling the request. - /// - private static CompositionGraphicsDevice _compositionDevice; - - /// - /// Initializes the specified compositor. - /// - /// The compositor. - public static void Initialize(Compositor compositor) - { - if (!_intialized) - { - _compositor = compositor; - _canvasDevice = new CanvasDevice(); - _compositionDevice = CanvasComposition.CreateCompositionGraphicsDevice(_compositor, _canvasDevice); - - _intialized = true; - } - } - - /// - /// Uninitializes this instance. - /// - public static void Uninitialize() - { - _compositor = null; - - if (_compositionDevice != null) - { - _compositionDevice.Dispose(); - _compositionDevice = null; - } - - if (_canvasDevice != null) - { - _canvasDevice.Dispose(); - _canvasDevice = null; - } - - _intialized = false; - } - - /// - /// Gets a value indicating whether this instance is initialized. - /// - /// - /// true if this instance is initialized; otherwise, false. - /// - public static bool IsInitialized - { - get - { - return _intialized; - } - } - - /// - /// Loads an image from the URI. - /// - /// The URI. - /// - public static async Task LoadFromUri(Uri uri) - { - return await LoadFromUri(uri, Size.Empty); - } - - /// - /// Loads an image from URI with a specified size. - /// - /// The URI. - /// The size target. - /// - public static async Task LoadFromUri(Uri uri, Size sizeTarget) - { - CanvasBitmap bitmap = await CanvasBitmap.LoadAsync(_canvasDevice, uri); - Size sizeSource = bitmap.Size; - - if (sizeTarget.IsEmpty) - { - sizeTarget = sizeSource; - } - - CompositionDrawingSurface surface = _compositionDevice.CreateDrawingSurface( - sizeTarget, - DirectXPixelFormat.B8G8R8A8UIntNormalized, - DirectXAlphaMode.Premultiplied); - - using (var ds = CanvasComposition.CreateDrawingSession(surface)) - { - ds.Clear(Color.FromArgb(0, 0, 0, 0)); - ds.DrawImage(bitmap, new Rect(0, 0, sizeTarget.Width, sizeTarget.Height), new Rect(0, 0, sizeSource.Width, sizeSource.Height)); - } - - return surface; - } - - /// - /// Loads the text on to a . - /// - /// The text. - /// The size target. - /// The text format. - /// Color of the text. - /// Color of the bg. - /// - public static CompositionDrawingSurface LoadText(string text, Size sizeTarget, CanvasTextFormat textFormat, Color textColor, Color bgColor) - { - CompositionDrawingSurface surface = _compositionDevice.CreateDrawingSurface( - sizeTarget, - DirectXPixelFormat.B8G8R8A8UIntNormalized, - DirectXAlphaMode.Premultiplied); - - using (var ds = CanvasComposition.CreateDrawingSession(surface)) - { - ds.Clear(bgColor); - ds.DrawText(text, new Rect(0, 0, sizeTarget.Width, sizeTarget.Height), textColor, textFormat); - } - - return surface; - } - - /// - /// Loads an image from URI, with a specified size. - /// - /// The URI. - /// The size target. - /// The load effect handler callback. - /// - public static async Task LoadFromUri(Uri uri, Size sizeTarget, LoadTimeEffectHandler loadEffectHandler) - { - if (loadEffectHandler != null) - { - var bitmap = await CanvasBitmap.LoadAsync(_canvasDevice, uri); - return loadEffectHandler(bitmap, _compositionDevice, sizeTarget); - } - else - { - return await LoadFromUri(uri, sizeTarget); - } - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/ApiInformationHelper.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/ApiInformationHelper.cs new file mode 100644 index 00000000000..a7875948b3b --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/ApiInformationHelper.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.Foundation.Metadata; + +namespace Microsoft.Toolkit.Uwp.UI.Behaviors +{ + internal class ApiInformationHelper + { + // 1903 - 18362 + public static bool IsXamlRootAvailable { get; } = ApiInformation.IsPropertyPresent("Windows.UI.Xaml.UIElement", "XamlRoot"); + } +} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI/Behaviors/BehaviorBase.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/BehaviorBase.cs similarity index 100% rename from Microsoft.Toolkit.Uwp.UI/Behaviors/BehaviorBase.cs rename to Microsoft.Toolkit.Uwp.UI.Behaviors/BehaviorBase.cs diff --git a/Microsoft.Toolkit.Uwp.UI/Behaviors/AutoFocusBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Focus/AutoFocusBehavior.cs similarity index 100% rename from Microsoft.Toolkit.Uwp.UI/Behaviors/AutoFocusBehavior.cs rename to Microsoft.Toolkit.Uwp.UI.Behaviors/Focus/AutoFocusBehavior.cs diff --git a/Microsoft.Toolkit.Uwp.UI/Behaviors/FocusBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Focus/FocusBehavior.cs similarity index 100% rename from Microsoft.Toolkit.Uwp.UI/Behaviors/FocusBehavior.cs rename to Microsoft.Toolkit.Uwp.UI.Behaviors/Focus/FocusBehavior.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/FadeHeaderBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Headers/FadeHeaderBehavior.cs similarity index 98% rename from Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/FadeHeaderBehavior.cs rename to Microsoft.Toolkit.Uwp.UI.Behaviors/Headers/FadeHeaderBehavior.cs index c965f783473..231a354515f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/FadeHeaderBehavior.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Headers/FadeHeaderBehavior.cs @@ -3,13 +3,13 @@ // See the LICENSE file in the project root for more information. using Microsoft.Toolkit.Uwp.UI.Animations.Expressions; -using Microsoft.Toolkit.Uwp.UI.Behaviors; using Microsoft.Toolkit.Uwp.UI.Extensions; +using Windows.UI.Composition; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Hosting; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Behaviors +namespace Microsoft.Toolkit.Uwp.UI.Behaviors { /// /// Performs an fade animation on a ListView or GridView Header using composition. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/QuickReturnHeaderBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Headers/QuickReturnHeaderBehavior.cs similarity index 99% rename from Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/QuickReturnHeaderBehavior.cs rename to Microsoft.Toolkit.Uwp.UI.Behaviors/Headers/QuickReturnHeaderBehavior.cs index fe86fd75bbb..ffe9e518cd5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/QuickReturnHeaderBehavior.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Headers/QuickReturnHeaderBehavior.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using Microsoft.Toolkit.Uwp.UI.Animations.Expressions; -using Microsoft.Toolkit.Uwp.UI.Behaviors; using Microsoft.Toolkit.Uwp.UI.Extensions; using Windows.Foundation; using Windows.UI.Composition; @@ -12,7 +11,7 @@ using Windows.UI.Xaml.Hosting; using Windows.UI.Xaml.Input; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Behaviors +namespace Microsoft.Toolkit.Uwp.UI.Behaviors { /// /// Performs an animation on a ListView or GridView Header to make it quick return using composition. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/StickyHeaderBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Headers/StickyHeaderBehavior.cs similarity index 98% rename from Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/StickyHeaderBehavior.cs rename to Microsoft.Toolkit.Uwp.UI.Behaviors/Headers/StickyHeaderBehavior.cs index ec322bf6eb3..5ca0fbf764e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/StickyHeaderBehavior.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Headers/StickyHeaderBehavior.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using Microsoft.Toolkit.Uwp.UI.Animations.Expressions; -using Microsoft.Toolkit.Uwp.UI.Behaviors; using Microsoft.Toolkit.Uwp.UI.Extensions; using Windows.Foundation; using Windows.UI.Composition; @@ -13,7 +12,7 @@ using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Behaviors +namespace Microsoft.Toolkit.Uwp.UI.Behaviors { /// /// Performs an animation on a ListView or GridView Header to make it sticky using composition. diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Microsoft.Toolkit.Uwp.UI.Behaviors.csproj b/Microsoft.Toolkit.Uwp.UI.Behaviors/Microsoft.Toolkit.Uwp.UI.Behaviors.csproj new file mode 100644 index 00000000000..045cbbc0cec --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Microsoft.Toolkit.Uwp.UI.Behaviors.csproj @@ -0,0 +1,31 @@ + + + + uap10.0.17763 + 8.0 + Windows Community Toolkit UI Behaviors + + This library provides UI behaviors built on the XAML behaviors SDK. It is part of the Windows Community Toolkit. + + Behaviors: + - BehaviorBase: Helper for building Behaviors + - AutoFocusBehevior: Sets focus to the associated control. + - FocusBehavior: Sets focus to a specified control. + - ViewportBehavior: Listening for element to enter or exit the ScrollViewer viewport + - FadeHeaderBehavior, QuickReturnHeaderBehavior, StickyHeaderBehavior: Helpers for ListViewBase Header Behavior + + UWP Toolkit Windows UI Behaviors XAML + + true + + + + + + + + + + + + diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Properties/Microsoft.Toolkit.Uwp.UI.Behaviors.rd.xml b/Microsoft.Toolkit.Uwp.UI.Behaviors/Properties/Microsoft.Toolkit.Uwp.UI.Behaviors.rd.xml new file mode 100644 index 00000000000..2a652962f91 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Properties/Microsoft.Toolkit.Uwp.UI.Behaviors.rd.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/Microsoft.Toolkit.Uwp.UI/Behaviors/ViewportBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.cs similarity index 100% rename from Microsoft.Toolkit.Uwp.UI/Behaviors/ViewportBehavior.cs rename to Microsoft.Toolkit.Uwp.UI.Behaviors/Viewport/ViewportBehavior.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/Microsoft.Toolkit.Uwp.UI.Controls.csproj b/Microsoft.Toolkit.Uwp.UI.Controls/Microsoft.Toolkit.Uwp.UI.Controls.csproj index bf18c15c898..26ff92e907a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/Microsoft.Toolkit.Uwp.UI.Controls.csproj +++ b/Microsoft.Toolkit.Uwp.UI.Controls/Microsoft.Toolkit.Uwp.UI.Controls.csproj @@ -47,6 +47,7 @@ + diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/ScrollHeader/ScrollHeader.cs b/Microsoft.Toolkit.Uwp.UI.Controls/ScrollHeader/ScrollHeader.cs deleted file mode 100644 index 21c44fcf9b0..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Controls/ScrollHeader/ScrollHeader.cs +++ /dev/null @@ -1,96 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using Microsoft.Toolkit.Uwp.UI.Animations.Behaviors; -using Microsoft.Toolkit.Uwp.UI.Extensions; -using Microsoft.Xaml.Interactivity; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; - -namespace Microsoft.Toolkit.Uwp.UI.Controls -{ - /// - /// Scroll header control to be used with ListViews or GridViews - /// - public class ScrollHeader : ContentControl - { - /// - /// Initializes a new instance of the class. - /// - public ScrollHeader() - { - DefaultStyleKey = typeof(ScrollHeader); - HorizontalContentAlignment = HorizontalAlignment.Stretch; - } - - /// - /// Identifies the property. - /// - public static readonly DependencyProperty ModeProperty = - DependencyProperty.Register(nameof(Mode), typeof(ScrollHeaderMode), typeof(ScrollHeader), new PropertyMetadata(ScrollHeaderMode.None, OnModeChanged)); - - /// - /// Gets or sets a value indicating whether the current mode. - /// Default is none. - /// - public ScrollHeaderMode Mode - { - get { return (ScrollHeaderMode)GetValue(ModeProperty); } - set { SetValue(ModeProperty, value); } - } - - /// - /// Invoked whenever application code or internal processes (such as a rebuilding layout pass) call . - /// - protected override void OnApplyTemplate() - { - UpdateScrollHeaderBehavior(); - } - - private static void OnModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - (d as ScrollHeader)?.UpdateScrollHeaderBehavior(); - } - - private static void OnTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - (d as ScrollHeader)?.OnApplyTemplate(); - } - - private void UpdateScrollHeaderBehavior() - { - var targetListViewBase = this.FindAscendant(); - - if (targetListViewBase == null) - { - return; - } - - // Remove previous behaviors - foreach (var behavior in Interaction.GetBehaviors(targetListViewBase)) - { - if (behavior is FadeHeaderBehavior || behavior is QuickReturnHeaderBehavior || behavior is StickyHeaderBehavior) - { - Interaction.GetBehaviors(targetListViewBase).Remove(behavior); - } - } - - switch (Mode) - { - case ScrollHeaderMode.None: - break; - case ScrollHeaderMode.QuickReturn: - Interaction.GetBehaviors(targetListViewBase).Add(new QuickReturnHeaderBehavior()); - break; - case ScrollHeaderMode.Sticky: - Interaction.GetBehaviors(targetListViewBase).Add(new StickyHeaderBehavior()); - break; - case ScrollHeaderMode.Fade: - Interaction.GetBehaviors(targetListViewBase).Add(new FadeHeaderBehavior()); - break; - } - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/ScrollHeader/ScrollHeader.xaml b/Microsoft.Toolkit.Uwp.UI.Controls/ScrollHeader/ScrollHeader.xaml deleted file mode 100644 index 2521843c6f5..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Controls/ScrollHeader/ScrollHeader.xaml +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/ScrollHeader/ScrollHeaderMode.cs b/Microsoft.Toolkit.Uwp.UI.Controls/ScrollHeader/ScrollHeaderMode.cs deleted file mode 100644 index 5774585a90d..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Controls/ScrollHeader/ScrollHeaderMode.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Uwp.UI.Controls -{ - /// - /// Define mode available for - /// - public enum ScrollHeaderMode - { - /// - /// No change. This is the default value. - /// - None, - - /// - /// Enable quick return mode. - /// - QuickReturn, - - /// - /// Enable sticky mode. - /// - Sticky, - - /// - /// Enable fade mode. - /// - Fade - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/Themes/Generic.xaml b/Microsoft.Toolkit.Uwp.UI.Controls/Themes/Generic.xaml index 6422f8690d2..a6c650d3a4b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/Themes/Generic.xaml +++ b/Microsoft.Toolkit.Uwp.UI.Controls/Themes/Generic.xaml @@ -27,7 +27,6 @@ - diff --git a/Microsoft.Toolkit.Uwp.UI/Microsoft.Toolkit.Uwp.UI.csproj b/Microsoft.Toolkit.Uwp.UI/Microsoft.Toolkit.Uwp.UI.csproj index 99767ff0f0c..a9387db46e3 100644 --- a/Microsoft.Toolkit.Uwp.UI/Microsoft.Toolkit.Uwp.UI.csproj +++ b/Microsoft.Toolkit.Uwp.UI/Microsoft.Toolkit.Uwp.UI.csproj @@ -9,10 +9,6 @@ AdvancedCollectionView: It's a collection view implementation that support filtering, sorting and incremental loading. It's meant to be used in a viewmodel. - Behaviors: - - BehaviorBase: Helper for building Behaviors - - ViewportBehavior: Listening for element to enter or exit the ScrollViewer viewport - CacheBase: Provides methods and tools to cache files in a folder. Converters: Commonly used converters that allow the data to be modified as it passes through the binding engine. @@ -47,11 +43,7 @@ true - - - - - + diff --git a/Windows Community Toolkit.sln b/Windows Community Toolkit.sln index 17df1370cd3..9f57b24e708 100644 --- a/Windows Community Toolkit.sln +++ b/Windows Community Toolkit.sln @@ -135,6 +135,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UITests.Tests.TAEF", "UITes EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "UITests.Tests.Shared", "UITests\UITests.Tests.Shared\UITests.Tests.Shared.shproj", "{1D8B0260-5C17-41DA-9C38-1E37441B3925}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Toolkit.Uwp.UI.Behaviors", "Microsoft.Toolkit.Uwp.UI.Behaviors\Microsoft.Toolkit.Uwp.UI.Behaviors.csproj", "{D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution UITests\UITests.Tests.Shared\UITests.Tests.Shared.projitems*{05c83067-fa46-45e2-bec4-edee84ad18d0}*SharedItemsImports = 4 @@ -956,6 +958,26 @@ Global {C8182EF0-77FB-4B43-A588-C71748A309C7}.Release|x64.Build.0 = Release|Any CPU {C8182EF0-77FB-4B43-A588-C71748A309C7}.Release|x86.ActiveCfg = Release|Any CPU {C8182EF0-77FB-4B43-A588-C71748A309C7}.Release|x86.Build.0 = Release|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Debug|ARM.ActiveCfg = Debug|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Debug|ARM.Build.0 = Debug|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Debug|ARM64.Build.0 = Debug|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Debug|x64.ActiveCfg = Debug|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Debug|x64.Build.0 = Debug|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Debug|x86.ActiveCfg = Debug|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Debug|x86.Build.0 = Debug|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Release|Any CPU.Build.0 = Release|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Release|ARM.ActiveCfg = Release|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Release|ARM.Build.0 = Release|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Release|ARM64.ActiveCfg = Release|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Release|ARM64.Build.0 = Release|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Release|x64.ActiveCfg = Release|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Release|x64.Build.0 = Release|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Release|x86.ActiveCfg = Release|Any CPU + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -997,6 +1019,7 @@ Global {5F720475-E263-4A5A-8C88-2B805B45B5BC} = {6FAA1CFE-3368-4FD2-9DBD-F4700F69174C} {C8182EF0-77FB-4B43-A588-C71748A309C7} = {6FAA1CFE-3368-4FD2-9DBD-F4700F69174C} {1D8B0260-5C17-41DA-9C38-1E37441B3925} = {6FAA1CFE-3368-4FD2-9DBD-F4700F69174C} + {D4FF799D-0DF2-495A-ADC9-3BBC4AEF8971} = {F1AFFFA7-28FE-4770-BA48-10D76F3E59BC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5403B0C4-F244-4F73-A35C-FE664D0F4345} From 9d874a8913ad7b690190918ff4f896370f677720 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 17 Dec 2020 22:07:26 +0100 Subject: [PATCH 002/171] Ported enum types --- .../Enums/Axis.cs | 28 +++++++++ .../Enums/Easing.cs | 62 +++++++++++++++++++ .../Enums/FrameworkLayer.cs | 22 +++++++ .../Enums/Side.cs | 32 ++++++++++ 4 files changed, 144 insertions(+) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Enums/Axis.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Enums/Easing.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Enums/FrameworkLayer.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Enums/Side.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Enums/Axis.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Enums/Axis.cs new file mode 100644 index 00000000000..1b4e69f00d7 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Enums/Axis.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// Indicates an axis in the 3D space. + /// + public enum Axis + { + /// + /// The X axis (horizontal). + /// + X, + + /// + /// The Y axis (vertical). + /// + Y, + + /// + /// The Z axis (depth). + /// + /// This axis might only be available in certain scenarios, such as when working with composition APIs. + Z + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Enums/Easing.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Enums/Easing.cs new file mode 100644 index 00000000000..20188082135 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Enums/Easing.cs @@ -0,0 +1,62 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// Indicates an easing function for an animation. + /// + public enum Easing + { + /// + /// The linear easing, with [0, 0] and [1, 1] as control points. + /// + Linear, + + /// + /// The sine in easing, with [0.4, 0] and [1, 1] as control points. + /// + SineEaseIn, + + /// + /// The sine out easing, with [0, 0] and [0.6, 1] as control points. + /// + SineEaseOut, + + /// + /// The sine in out easing, with [0.4, 0] and [0.6, 1] as control points. + /// + SineEaseInOut, + + /// + /// The quadratic in easing, with [0.8, 0] and [1, 1] as control points. + /// + QuadraticEaseIn, + + /// + /// The quadratic out easing, with [0, 0] and [0.2, 1] as control points. + /// + QuadraticEaseOut, + + /// + /// The quadratic in out easing, with [0.8, 0] and [0.2, 1] as control points. + /// + QuadraticEaseInOut, + + /// + /// The circle in easing, with [1, 0] and [1, 0.8] as control points. + /// + CircleEaseIn, + + /// + /// The circle out easing, with [0, 0.3] and [0, 1] as control points. + /// + CircleEaseOut, + + /// + /// The circle in out easing, with [0.9, 0] and [0.1, 1] as control points. + /// + CircleEaseInOut + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Enums/FrameworkLayer.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Enums/FrameworkLayer.cs new file mode 100644 index 00000000000..e43462fdd5d --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Enums/FrameworkLayer.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// An that indicates the framework layer to target in a specific animation. + /// + public enum FrameworkLayer + { + /// + /// Indicates the APIs. + /// + Composition, + + /// + /// Indicates the APIs. + /// + Xaml + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Enums/Side.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Enums/Side.cs new file mode 100644 index 00000000000..856909a8e93 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Enums/Side.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// Indicates a side to animate in the bounds of a given element. + /// + public enum Side + { + /// + /// Maps the top side of the target bounds. + /// + Top, + + /// + /// Maps the bottom side of the target bounds. + /// + Bottom, + + /// + /// Maps the left side of the target bounds. + /// + Left, + + /// + /// Maps the right side of the target bounds. + /// + Right + } +} From 1cd580269b4935b91c39939199088312854277bf Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 17 Dec 2020 22:18:38 +0100 Subject: [PATCH 003/171] Code refactoring, switched to previous EasingType --- .../EasingType.cs | 67 ----- .../Enums/Easing.cs | 62 ---- .../Enums/EasingType.cs | 67 +++++ .../Extensions/AnimationExtensions.Blur.cs | 76 ----- .../Extensions/AnimationExtensions.Fade.cs | 110 ------- .../Extensions/AnimationExtensions.Light.cs | 193 ------------ .../Extensions/AnimationExtensions.Offset.cs | 122 -------- .../Extensions/AnimationExtensions.Rotate.cs | 126 -------- .../AnimationExtensions.Saturation.cs | 72 ----- .../Extensions/AnimationExtensions.Scale.cs | 134 --------- .../Extensions/AnimationExtensions.cs | 282 ------------------ .../Extensions/AnimationTools.cs | 43 --- ...Microsoft.Toolkit.Uwp.UI.Animations.csproj | 4 - 13 files changed, 67 insertions(+), 1291 deletions(-) delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/EasingType.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Enums/Easing.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Enums/EasingType.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Blur.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Fade.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Light.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Offset.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Rotate.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Saturation.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Scale.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationTools.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/EasingType.cs b/Microsoft.Toolkit.Uwp.UI.Animations/EasingType.cs deleted file mode 100644 index b233d652652..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/EasingType.cs +++ /dev/null @@ -1,67 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// EasingType is used to describe how the animation interpolates between keyframes. - /// - public enum EasingType - { - /// - /// Creates an animation that accelerates with the default EasingType which is specified in AnimationExtensions.DefaultEasingType which is by default Cubic. - /// - Default, - - /// - /// Creates an animation that accelerates or decelerates linearly. - /// - Linear, - - /// - /// Creates an animation that accelerates or decelerates using the formula f(t) = t3. - /// - Cubic, - - /// - /// Retracts the motion of an animation slightly before it begins to animate in the path indicated. - /// - Back, - - /// - /// Creates a bouncing effect. - /// - Bounce, - - /// - /// Creates an animation that resembles a spring oscillating back and forth until it comes to rest. - /// - Elastic, - - /// - /// Creates an animation that accelerates or decelerates using a circular function. - /// - Circle, - - /// - /// Creates an animation that accelerates or decelerates using the formula f(t) = t2. - /// - Quadratic, - - /// - /// Creates an animation that accelerates or decelerates using the formula f(t) = t4. - /// - Quartic, - - /// - /// Create an animation that accelerates or decelerates using the formula f(t) = t5. - /// - Quintic, - - /// - /// Creates an animation that accelerates or decelerates using a sine formula. - /// - Sine - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Enums/Easing.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Enums/Easing.cs deleted file mode 100644 index 20188082135..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Enums/Easing.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Indicates an easing function for an animation. - /// - public enum Easing - { - /// - /// The linear easing, with [0, 0] and [1, 1] as control points. - /// - Linear, - - /// - /// The sine in easing, with [0.4, 0] and [1, 1] as control points. - /// - SineEaseIn, - - /// - /// The sine out easing, with [0, 0] and [0.6, 1] as control points. - /// - SineEaseOut, - - /// - /// The sine in out easing, with [0.4, 0] and [0.6, 1] as control points. - /// - SineEaseInOut, - - /// - /// The quadratic in easing, with [0.8, 0] and [1, 1] as control points. - /// - QuadraticEaseIn, - - /// - /// The quadratic out easing, with [0, 0] and [0.2, 1] as control points. - /// - QuadraticEaseOut, - - /// - /// The quadratic in out easing, with [0.8, 0] and [0.2, 1] as control points. - /// - QuadraticEaseInOut, - - /// - /// The circle in easing, with [1, 0] and [1, 0.8] as control points. - /// - CircleEaseIn, - - /// - /// The circle out easing, with [0, 0.3] and [0, 1] as control points. - /// - CircleEaseOut, - - /// - /// The circle in out easing, with [0.9, 0] and [0.1, 1] as control points. - /// - CircleEaseInOut - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Enums/EasingType.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Enums/EasingType.cs new file mode 100644 index 00000000000..1639ad76060 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Enums/EasingType.cs @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// Indicates how the animation interpolates between keyframes. + /// + public enum EasingType + { + /// + /// The default easing type, which is specified in AnimationExtensions.DefaultEasingType which is by default Cubic. + /// + Default, + + /// + /// A linear acceleration and deceleration. + /// + Linear, + + /// + /// An acceleration or deceleration using the formula f(t) = t3. + /// + Cubic, + + /// + /// An animation that rectracts its motion slightly before it begins to animate in the path indicated. + /// + Back, + + /// + /// A bouncing animation. + /// + Bounce, + + /// + /// An animation that resembles a spring oscillating back and forth until it comes to rest. + /// + Elastic, + + /// + /// An animation that accelerates or decelerates using a circular function. + /// + Circle, + + /// + /// An animation that accelerates or decelerates using the formula f(t) = t^2. + /// + Quadratic, + + /// + /// An animation that accelerates or decelerates using the formula f(t) = t^4. + /// + Quartic, + + /// + /// An animation that accelerates or decelerates using the formula f(t) = t^5. + /// + Quintic, + + /// + /// An animation that accelerates or decelerates using a sine formula. + /// + Sine + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Blur.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Blur.cs deleted file mode 100644 index 879e7a2819d..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Blur.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.Toolkit.Uwp.UI.Animations.Effects; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Media.Animation; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// These extension methods perform animation on UIElements - /// - public static partial class AnimationExtensions - { - /// - /// Gets the blur effect. - /// - /// - /// The blur effect. - /// - public static Blur BlurEffect { get; } = new Blur(); - - /// - /// Animates the Gaussian blur of the UIElement. - /// - /// The associated object. - /// The blur amount. - /// The duration in milliseconds. - /// The delay. (ignored if duration == 0) - /// The easing function - /// The easing mode - /// - /// An Animation Set. - /// - public static AnimationSet Blur( - this FrameworkElement associatedObject, - double value = 0d, - double duration = 500d, - double delay = 0d, - EasingType easingType = EasingType.Default, - EasingMode easingMode = EasingMode.EaseOut) - { - if (associatedObject == null) - { - return null; - } - - var animationSet = new AnimationSet(associatedObject); - return animationSet.Blur(value, duration, delay, easingType, easingMode); - } - - /// - /// Animates the Gaussian blur of the UIElement. - /// - /// The animation set. - /// The blur amount. - /// The duration in milliseconds. - /// The delay. (ignored if duration == 0) - /// The easing function - /// The easing mode - /// - /// An Animation Set. - /// - public static AnimationSet Blur( - this AnimationSet animationSet, - double value = 0d, - double duration = 500d, - double delay = 0d, - EasingType easingType = EasingType.Default, - EasingMode easingMode = EasingMode.EaseOut) - { - return BlurEffect.EffectAnimation(animationSet, value, duration, delay, easingType, easingMode); - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Fade.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Fade.cs deleted file mode 100644 index 24e7a65e631..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Fade.cs +++ /dev/null @@ -1,110 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Media.Animation; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// These extension methods perform animation on UIElements - /// - public static partial class AnimationExtensions - { - /// - /// Animates the opacity of the UIElement. - /// - /// The UI Element to change the opacity of. - /// The fade value, between 0 and 1. - /// The duration in milliseconds. - /// The delay. (ignored if duration == 0) - /// Used to describe how the animation interpolates between keyframes. - /// The easing mode to use to interpolate between keyframes. - /// - /// An AnimationSet. - /// - public static AnimationSet Fade( - this UIElement associatedObject, - float value = 0f, - double duration = 500d, - double delay = 0d, - EasingType easingType = EasingType.Default, - EasingMode easingMode = EasingMode.EaseOut) - { - if (associatedObject == null) - { - return null; - } - - var animationSet = new AnimationSet(associatedObject); - return animationSet.Fade(value, duration, delay, easingType, easingMode); - } - - /// - /// Animates the opacity of the UIElement. - /// - /// The animation set. - /// The fade value, between 0 and 1. - /// The duration in milliseconds. - /// The delay. (ignored if duration == 0) - /// Used to describe how the animation interpolates between keyframes. - /// The EasingMode to use to interpolate between keyframes. - /// - /// An AnimationSet. - /// - public static AnimationSet Fade( - this AnimationSet animationSet, - float value = 0f, - double duration = 500d, - double delay = 0d, - EasingType easingType = EasingType.Default, - EasingMode easingMode = EasingMode.EaseOut) - { - if (animationSet == null) - { - return null; - } - - if (!AnimationSet.UseComposition) - { - var animation = new DoubleAnimation - { - To = value, - Duration = TimeSpan.FromMilliseconds(duration), - BeginTime = TimeSpan.FromMilliseconds(delay), - EasingFunction = GetEasingFunction(easingType, easingMode) - }; - - animationSet.AddStoryboardAnimation("Opacity", animation); - } - else - { - if (duration <= 0) - { - animationSet.AddCompositionDirectPropertyChange("Opacity", value); - return animationSet; - } - - var visual = animationSet.Visual; - - var compositor = visual?.Compositor; - - if (compositor == null) - { - return null; - } - - var animation = compositor.CreateScalarKeyFrameAnimation(); - animation.Duration = TimeSpan.FromMilliseconds(duration); - animation.DelayTime = TimeSpan.FromMilliseconds(delay); - animation.InsertKeyFrame(1f, value, GetCompositionEasingFunction(easingType, compositor, easingMode)); - - animationSet.AddCompositionAnimation("Opacity", animation); - } - - return animationSet; - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Light.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Light.cs deleted file mode 100644 index c897d4cb206..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Light.cs +++ /dev/null @@ -1,193 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using Microsoft.Graphics.Canvas; -using Microsoft.Graphics.Canvas.Effects; -using Microsoft.Toolkit.Uwp.Extensions; -using Windows.UI; -using Windows.UI.Composition; -using Windows.UI.Composition.Effects; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Hosting; -using Windows.UI.Xaml.Media.Animation; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Provides an extension which allows lighting. - /// - public static partial class AnimationExtensions - { - /// - /// Stores all the point lights along with the visuals that they are applied to. - /// This is to stop multiplication of point lights on a single visual. - /// - private static Dictionary pointLights = new Dictionary(); - - /// - /// Animates a point light and it's distance. - /// - /// The associated object. - /// The value. - /// The duration. - /// The delay. - /// The color of the spotlight. - /// The easing function - /// The easing mode - /// An animation set. - [Obsolete("The Light effect will be removed in a future major release. Please use XamlLight instead")] - public static AnimationSet Light( - this FrameworkElement associatedObject, - double distance = 0d, - double duration = 500d, - double delay = 0d, - Color? color = null, - EasingType easingType = EasingType.Default, - EasingMode easingMode = EasingMode.EaseOut) - { - if (associatedObject == null) - { - return null; - } - - var animationSet = new AnimationSet(associatedObject); - return animationSet.Light(distance, duration, delay, color, easingType, easingMode); - } - - /// - /// Animates a point light and it's distance. - /// - /// The animation set. - /// The distance of the light. - /// The duration in milliseconds. - /// The delay. (ignored if duration == 0) - /// The color of the spotlight. - /// The easing function - /// The easing mode - /// - /// An Animation Set. - /// - [Obsolete("The Light effect will be removed in a future major release. Please use XamlLight instead")] - public static AnimationSet Light( - this AnimationSet animationSet, - double distance = 0d, - double duration = 500d, - double delay = 0d, - Color? color = null, - EasingType easingType = EasingType.Default, - EasingMode easingMode = EasingMode.EaseOut) - { - if (animationSet == null) - { - return null; - } - - var visual = animationSet.Visual; - var associatedObject = animationSet.Element as FrameworkElement; - - if (associatedObject == null) - { - return animationSet; - } - - var compositor = visual?.Compositor; - if (compositor == null) - { - return null; - } - - var task = new AnimationTask(); - task.AnimationSet = animationSet; - - task.Task = visual.DispatcherQueue.EnqueueAsync( - () => - { - const string sceneName = "PointLightScene"; - PointLight pointLight; - CompositionDrawingSurface normalMap = null; - - if (!pointLights.ContainsKey(visual)) - { - SurfaceLoader.Initialize(compositor); - normalMap = SurfaceLoader.LoadText(string.Empty, new Windows.Foundation.Size(512, 512), new Graphics.Canvas.Text.CanvasTextFormat(), Colors.Transparent, Colors.Transparent); - } - - if (pointLights.ContainsKey(visual)) - { - pointLight = pointLights[visual]; - } - else - { - pointLight = compositor.CreatePointLight(); - - var normalBrush = compositor.CreateSurfaceBrush(normalMap); - normalBrush.Stretch = CompositionStretch.Fill; - - // check to see if the visual already has a point light applied. - var spriteVisual = ElementCompositionPreview.GetElementChildVisual(associatedObject) as SpriteVisual; - var normalsBrush = spriteVisual?.Brush as CompositionEffectBrush; - - if (normalsBrush == null || normalsBrush.Comment != sceneName) - { - var lightEffect = new CompositeEffect() - { - Mode = CanvasComposite.Add, - Sources = - { - new CompositionEffectSourceParameter("ImageSource"), - new SceneLightingEffect() - { - Name = sceneName, - AmbientAmount = 0, - DiffuseAmount = 0.5f, - SpecularAmount = 0, - NormalMapSource = new CompositionEffectSourceParameter("NormalMap"), - } - } - }; - - var effectFactory = compositor.CreateEffectFactory(lightEffect); - var brush = effectFactory.CreateBrush(); - brush.SetSourceParameter("NormalMap", normalBrush); - - var sprite = compositor.CreateSpriteVisual(); - sprite.Size = visual.Size; - sprite.Brush = brush; - sprite.Comment = sceneName; - - ElementCompositionPreview.SetElementChildVisual(task.AnimationSet.Element, sprite); - - pointLight.CoordinateSpace = visual; - pointLight.Targets.Add(visual); - } - } - - pointLight.Color = color ?? Colors.White; - var delayTime = task.Delay != null ? task.Delay.Value : TimeSpan.FromMilliseconds(delay); - var durationTime = task.Duration != null ? task.Duration.Value : TimeSpan.FromMilliseconds(duration); - - if (durationTime.TotalMilliseconds <= 0) - { - task.AnimationSet.AddEffectDirectPropertyChange(pointLight, (float)distance, nameof(pointLight.Offset)); - } - else - { - var diffuseAnimation = compositor.CreateVector3KeyFrameAnimation(); - diffuseAnimation.InsertKeyFrame(1f, new System.Numerics.Vector3(visual.Size.X / 2, visual.Size.Y / 2, (float)distance), GetCompositionEasingFunction(easingType, compositor, easingMode)); - diffuseAnimation.Duration = durationTime; - diffuseAnimation.DelayTime = delayTime; - - task.AnimationSet.AddCompositionEffectAnimation(pointLight, diffuseAnimation, nameof(pointLight.Offset)); - } - - pointLights[visual] = pointLight; - }); - - animationSet.AddAnimationThroughTask(task); - return animationSet; - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Offset.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Offset.cs deleted file mode 100644 index a967fefbd7e..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Offset.cs +++ /dev/null @@ -1,122 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Numerics; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Media.Animation; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// These extension methods perform animation on UIElements - /// - public static partial class AnimationExtensions - { - /// - /// Animates the offset of the UIElement. - /// - /// The specified UI Element. - /// The offset on the x axis. - /// The offset on the y axis. - /// The duration in milliseconds. - /// The delay in milliseconds. (ignored if duration == 0) - /// Used to describe how the animation interpolates between keyframes. - /// The EasingMode to use to interpolate between keyframes. - /// - /// An AnimationSet. - /// - public static AnimationSet Offset( - this UIElement associatedObject, - float offsetX = 0f, - float offsetY = 0f, - double duration = 500d, - double delay = 0d, - EasingType easingType = EasingType.Default, - EasingMode easingMode = EasingMode.EaseOut) - { - if (associatedObject == null) - { - return null; - } - - var animationSet = new AnimationSet(associatedObject); - return animationSet.Offset(offsetX, offsetY, duration, delay, easingType, easingMode); - } - - /// - /// Animates the offset of the UIElement. - /// - /// The animation set. - /// The offset on the x axis. - /// The offset on the y axis. - /// The duration in milliseconds. - /// The delay in milliseconds. (ignored if duration == 0) - /// Used to describe how the animation interpolates between keyframes. - /// The EasingMode to use to interpolate between keyframes. - /// - /// An AnimationSet. - /// - public static AnimationSet Offset( - this AnimationSet animationSet, - float offsetX = 0f, - float offsetY = 0f, - double duration = 500d, - double delay = 0d, - EasingType easingType = EasingType.Default, - EasingMode easingMode = EasingMode.EaseOut) - { - if (animationSet == null) - { - return null; - } - - if (!AnimationSet.UseComposition) - { - var element = animationSet.Element; - var transform = GetAttachedCompositeTransform(element); - - var animationX = new DoubleAnimation(); - var animationY = new DoubleAnimation(); - - animationX.To = offsetX; - animationY.To = offsetY; - - animationX.Duration = animationY.Duration = TimeSpan.FromMilliseconds(duration); - animationX.BeginTime = animationY.BeginTime = TimeSpan.FromMilliseconds(delay); - animationX.EasingFunction = animationY.EasingFunction = GetEasingFunction(easingType, easingMode); - - animationSet.AddStoryboardAnimation(GetAnimationPath(transform, element, "TranslateX"), animationX); - animationSet.AddStoryboardAnimation(GetAnimationPath(transform, element, "TranslateY"), animationY); - } - else - { - var visual = animationSet.Visual; - var offsetVector = new Vector3(offsetX, offsetY, 0); - - if (duration <= 0) - { - animationSet.AddCompositionDirectPropertyChange("Offset", offsetVector); - return animationSet; - } - - var compositor = visual?.Compositor; - - if (compositor == null) - { - return null; - } - - var animation = compositor.CreateVector3KeyFrameAnimation(); - animation.Duration = TimeSpan.FromMilliseconds(duration); - animation.DelayTime = TimeSpan.FromMilliseconds(delay); - animation.InsertKeyFrame(1f, offsetVector, GetCompositionEasingFunction(easingType, compositor, easingMode)); - - animationSet.AddCompositionAnimation("Offset", animation); - } - - return animationSet; - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Rotate.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Rotate.cs deleted file mode 100644 index d288b07a453..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Rotate.cs +++ /dev/null @@ -1,126 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Numerics; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Media.Animation; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// These extension methods perform animation on UIElements - /// - public static partial class AnimationExtensions - { - /// - /// Animates the rotation in degrees of the UIElement. - /// - /// The UI Element to rotate. - /// The value in degrees to rotate. - /// The center x in pixels. - /// The center y in pixels. - /// The duration in milliseconds. - /// The delay in milliseconds. (ignored if duration == 0) - /// Used to describe how the animation interpolates between keyframes. - /// EasingMode used to interpolate between keyframes. - /// - /// An AnimationSet. - /// - public static AnimationSet Rotate( - this UIElement associatedObject, - float value = 0f, - float centerX = 0f, - float centerY = 0f, - double duration = 500d, - double delay = 0d, - EasingType easingType = EasingType.Default, - EasingMode easingMode = EasingMode.EaseOut) - { - if (associatedObject == null) - { - return null; - } - - var animationSet = new AnimationSet(associatedObject); - return animationSet.Rotate(value, centerX, centerY, duration, delay, easingType); - } - - /// - /// Animates the rotation in degrees of the UIElement. - /// - /// The animation set. - /// The value in degrees to rotate. - /// The center x in pixels. - /// The center y in pixels. - /// The duration in milliseconds. - /// The delay in milliseconds. (ignored if duration == 0) - /// Used to describe how the animation interpolates between keyframes. - /// The EasingMode to use to interpolate between keyframes. - /// - /// An AnimationSet. - /// - public static AnimationSet Rotate( - this AnimationSet animationSet, - float value = 0f, - float centerX = 0f, - float centerY = 0f, - double duration = 500d, - double delay = 0d, - EasingType easingType = EasingType.Default, - EasingMode easingMode = EasingMode.EaseOut) - { - if (animationSet == null) - { - return null; - } - - if (!AnimationSet.UseComposition) - { - var element = animationSet.Element; - var transform = GetAttachedCompositeTransform(element); - - transform.CenterX = centerX; - transform.CenterY = centerY; - - var animation = new DoubleAnimation - { - To = value, - Duration = TimeSpan.FromMilliseconds(duration), - BeginTime = TimeSpan.FromMilliseconds(delay), - EasingFunction = GetEasingFunction(easingType, easingMode) - }; - - animationSet.AddStoryboardAnimation(GetAnimationPath(transform, element, "Rotation"), animation); - } - else - { - var visual = animationSet.Visual; - visual.CenterPoint = new Vector3(centerX, centerY, 0); - - if (duration <= 0) - { - animationSet.AddCompositionDirectPropertyChange("RotationAngleInDegrees", value); - return animationSet; - } - - var compositor = visual.Compositor; - - if (compositor == null) - { - return null; - } - - var animation = compositor.CreateScalarKeyFrameAnimation(); - animation.Duration = TimeSpan.FromMilliseconds(duration); - animation.DelayTime = TimeSpan.FromMilliseconds(delay); - animation.InsertKeyFrame(1f, value, GetCompositionEasingFunction(easingType, compositor, easingMode)); - - animationSet.AddCompositionAnimation("RotationAngleInDegrees", animation); - } - - return animationSet; - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Saturation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Saturation.cs deleted file mode 100644 index 9a7169b3515..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Saturation.cs +++ /dev/null @@ -1,72 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.Toolkit.Uwp.UI.Animations.Effects; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Media.Animation; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// A partial for the AnimationExtension which includes saturation. - /// - public static partial class AnimationExtensions - { - /// - /// Gets the saturation effect. - /// - /// - /// The saturation effect. - /// - public static Saturation SaturationEffect { get; } = new Saturation(); - - /// - /// Saturates the FrameworkElement. - /// - /// The associated object. - /// The value, between 0 and 1. 0 is desaturated, 1 is saturated. - /// The duration in milliseconds. - /// The delay in milliseconds. - /// The - /// The - /// An animation set with saturation effects incorporated. - public static AnimationSet Saturation( - this FrameworkElement associatedObject, - double value = 0d, - double duration = 500d, - double delay = 0d, - EasingType easingType = EasingType.Default, - EasingMode easingMode = EasingMode.EaseOut) - { - if (associatedObject == null) - { - return null; - } - - var animationSet = new AnimationSet(associatedObject); - return animationSet.Saturation(value, duration, delay, easingType, easingMode); - } - - /// - /// Saturates the visual within the animation set. - /// - /// The animation set. - /// The value. 0 is desaturated, 1 is saturated. - /// The duration in milliseconds. - /// The delay in milliseconds. - /// The - /// The - /// An animation set with saturation effects incorporated. - public static AnimationSet Saturation( - this AnimationSet animationSet, - double value = 0d, - double duration = 500d, - double delay = 0d, - EasingType easingType = EasingType.Default, - EasingMode easingMode = EasingMode.EaseOut) - { - return SaturationEffect.EffectAnimation(animationSet, value, duration, delay, easingType, easingMode); - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Scale.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Scale.cs deleted file mode 100644 index 5ee0d22feb2..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.Scale.cs +++ /dev/null @@ -1,134 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Numerics; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Media.Animation; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// These extension methods perform animation on UIElements - /// - public static partial class AnimationExtensions - { - /// - /// Animates the scale of the specified UIElement. - /// - /// The associated UIElement. - /// The scale on the x axis. - /// The scale on the y axis. - /// The center x in pixels. - /// The center y in pixels. - /// The duration in millisecond. - /// The delay in milliseconds. (ignored if duration == 0) - /// Used to describe how the animation interpolates between keyframes. - /// The EasingMode to use to interpolate between keyframes. - /// - /// An AnimationSet. - /// - public static AnimationSet Scale( - this UIElement associatedObject, - float scaleX = 1f, - float scaleY = 1f, - float centerX = 0f, - float centerY = 0f, - double duration = 500d, - double delay = 0d, - EasingType easingType = EasingType.Default, - EasingMode easingMode = EasingMode.EaseOut) - { - if (associatedObject == null) - { - return null; - } - - var animationSet = new AnimationSet(associatedObject); - return animationSet.Scale(scaleX, scaleY, centerX, centerY, duration, delay, easingType, easingMode); - } - - /// - /// Animates the scale of the specified UIElement. - /// - /// The animationSet object. - /// The scale on the x axis. - /// The scale on the y axis. - /// The center x in pixels. - /// The center y in pixels. - /// The duration in milliseconds. - /// The delay in milliseconds. (ignored if duration == 0) - /// Used to describe how the animation interpolates between keyframes. - /// The EasingMode to use to interpolate between keyframes. - /// - /// An AnimationSet. - /// - public static AnimationSet Scale( - this AnimationSet animationSet, - float scaleX = 1f, - float scaleY = 1f, - float centerX = 0f, - float centerY = 0f, - double duration = 500d, - double delay = 0d, - EasingType easingType = EasingType.Default, - EasingMode easingMode = EasingMode.EaseOut) - { - if (animationSet == null) - { - return null; - } - - if (!AnimationSet.UseComposition) - { - var element = animationSet.Element; - var transform = GetAttachedCompositeTransform(element); - - transform.CenterX = centerX; - transform.CenterY = centerY; - - var animationX = new DoubleAnimation(); - var animationY = new DoubleAnimation(); - - animationX.To = scaleX; - animationY.To = scaleY; - - animationX.Duration = animationY.Duration = TimeSpan.FromMilliseconds(duration); - animationX.BeginTime = animationY.BeginTime = TimeSpan.FromMilliseconds(delay); - animationX.EasingFunction = animationY.EasingFunction = GetEasingFunction(easingType, easingMode); - - animationSet.AddStoryboardAnimation(GetAnimationPath(transform, element, "ScaleX"), animationX); - animationSet.AddStoryboardAnimation(GetAnimationPath(transform, element, "ScaleY"), animationY); - } - else - { - var visual = animationSet.Visual; - visual.CenterPoint = new Vector3(centerX, centerY, 0); - var scaleVector = new Vector3(scaleX, scaleY, 1.0f); - - if (duration <= 0) - { - animationSet.AddCompositionDirectPropertyChange("Scale", scaleVector); - return animationSet; - } - - var compositor = visual.Compositor; - - if (compositor == null) - { - return null; - } - - var animation = compositor.CreateVector3KeyFrameAnimation(); - animation.Duration = TimeSpan.FromMilliseconds(duration); - animation.DelayTime = TimeSpan.FromMilliseconds(delay); - animation.InsertKeyFrame(1f, scaleVector, GetCompositionEasingFunction(easingType, compositor, easingMode)); - - animationSet.AddCompositionAnimation("Scale", animation); - } - - return animationSet; - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs deleted file mode 100644 index 7692b9a3d0e..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs +++ /dev/null @@ -1,282 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Numerics; -using System.Threading.Tasks; -using Windows.UI.Composition; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Media; -using Windows.UI.Xaml.Media.Animation; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// These extension methods perform animation on UIElements - /// - public static partial class AnimationExtensions - { -#pragma warning disable SA1008 // Opening parenthesis must be spaced correctly -#pragma warning disable SA1009 // Closing parenthesis must be spaced correctly - /// - /// A cached dictionary mapping easings to b�zier control points - /// - private static readonly Dictionary<(string, EasingMode), (Vector2, Vector2)> _compositionEasingFunctions = new Dictionary<(string, EasingMode), (Vector2, Vector2)>(); -#pragma warning restore SA1009 // Closing parenthesis must be spaced correctly -#pragma warning restore SA1008 // Opening parenthesis must be spaced correctly - - /// - /// Gets or sets the default EasingType used for storyboard animations - /// - public static EasingType DefaultEasingType { get; set; } = EasingType.Cubic; - - /// - /// Begins a Storyboard animation and returns a task that completes when the - /// animation is complete - /// - /// The storyboard to be started - /// Task that completes when the animation is complete - public static Task BeginAsync(this Storyboard storyboard) - { - var taskSource = new TaskCompletionSource(); - EventHandler completed = null; - completed += (s, e) => - { - storyboard.Completed -= completed; - taskSource.SetResult(null); - }; - - storyboard.Completed += completed; - storyboard.Begin(); - - return taskSource.Task; - } - - /// - /// Gets the EasingFunction from an EasingType and optional EasingMode to be used with Storyboard animations - /// - /// The EasingType used to determine the EasingFunction - /// The EasingMode used to determine the EasingFunction. Defaults to - /// Return the appropriate EasingFuntion or null if the EasingType is Linear - public static EasingFunctionBase GetEasingFunction(EasingType easingType, EasingMode easingMode = EasingMode.EaseOut) - { - if (easingType == EasingType.Default) - { - easingType = DefaultEasingType; - } - - switch (easingType) - { - case EasingType.Linear: - return null; - case EasingType.Cubic: - return new CubicEase { EasingMode = easingMode }; - case EasingType.Back: - return new BackEase { EasingMode = easingMode }; - case EasingType.Bounce: - return new BounceEase { EasingMode = easingMode }; - case EasingType.Elastic: - return new ElasticEase { EasingMode = easingMode }; - case EasingType.Circle: - return new CircleEase { EasingMode = easingMode }; - case EasingType.Quadratic: - return new QuadraticEase { EasingMode = easingMode }; - case EasingType.Quartic: - return new QuarticEase { EasingMode = easingMode }; - case EasingType.Quintic: - return new QuinticEase { EasingMode = easingMode }; - case EasingType.Sine: - return new SineEase { EasingMode = easingMode }; - default: - throw new NotSupportedException($"{easingType.ToString()} EasingType is not currently supported"); - } - } - - /// - /// Generates an to be used with Composition animations - /// - /// The used to generate the CompositionEasingFunction - /// The - /// The used to generate the CompositionEasingFunction. Defaults to - /// - public static CompositionEasingFunction GetCompositionEasingFunction(EasingType easingType, Compositor compositor, EasingMode easingMode = EasingMode.EaseOut) - { - if (DesignTimeHelpers.IsRunningInLegacyDesignerMode) - { - return compositor.CreateLinearEasingFunction(); - } - - return GenerateCompositionEasingFunctionFromEasingType(easingType, compositor, easingMode); - } - - /// - /// Creates the cache of easing functions if the cache does not already exist. - /// - private static void EnsureEasingsCached() - { - if (_compositionEasingFunctions.Count > 0) - { - return; - } - - // We don't cache actual composition easing functions here as they can be disposed - // and we don't want to deal with caching a disposed easing function - void Add(EasingType type, EasingMode mode, Vector2 p1, Vector2 p2) - { - // In order to generate a usable hash code for our ValueTuple without collisions - // we can't use enum values for both type & mode, so we have to string one of them. -#pragma warning disable SA1008 // Opening parenthesis must be spaced correctly - _compositionEasingFunctions[(type.ToString(), mode)] = (p1, p2); -#pragma warning restore SA1008 // Opening parenthesis must be spaced correctly - } - - Add(EasingType.Cubic, EasingMode.EaseOut, new Vector2(0.215f, 0.61f), new Vector2(0.355f, 1f)); - Add(EasingType.Cubic, EasingMode.EaseIn, new Vector2(0.55f, 0.055f), new Vector2(0.675f, 0.19f)); - Add(EasingType.Cubic, EasingMode.EaseInOut, new Vector2(0.645f, 0.045f), new Vector2(0.355f, 1f)); - - Add(EasingType.Back, EasingMode.EaseOut, new Vector2(0.175f, 0.885f), new Vector2(0.32f, 1.275f)); - Add(EasingType.Back, EasingMode.EaseIn, new Vector2(0.6f, -0.28f), new Vector2(0.735f, 0.045f)); - Add(EasingType.Back, EasingMode.EaseInOut, new Vector2(0.68f, -0.55f), new Vector2(0.265f, 1.55f)); - - Add(EasingType.Bounce, EasingMode.EaseOut, new Vector2(0.58f, 1.93f), new Vector2(.08f, .36f)); - Add(EasingType.Bounce, EasingMode.EaseIn, new Vector2(0.93f, 0.7f), new Vector2(0.4f, -0.93f)); - Add(EasingType.Bounce, EasingMode.EaseInOut, new Vector2(0.65f, -0.85f), new Vector2(0.35f, 1.85f)); - - Add(EasingType.Elastic, EasingMode.EaseOut, new Vector2(0.37f, 2.68f), new Vector2(0f, 0.22f)); - Add(EasingType.Elastic, EasingMode.EaseIn, new Vector2(1, .78f), new Vector2(.63f, -1.68f)); - Add(EasingType.Elastic, EasingMode.EaseInOut, new Vector2(0.9f, -1.2f), new Vector2(0.1f, 2.2f)); - - Add(EasingType.Circle, EasingMode.EaseOut, new Vector2(0.075f, 0.82f), new Vector2(0.165f, 1f)); - Add(EasingType.Circle, EasingMode.EaseIn, new Vector2(0.6f, 0.04f), new Vector2(0.98f, 0.335f)); - Add(EasingType.Circle, EasingMode.EaseInOut, new Vector2(0.785f, 0.135f), new Vector2(0.15f, 0.86f)); - - Add(EasingType.Quadratic, EasingMode.EaseOut, new Vector2(0.25f, 0.46f), new Vector2(0.45f, 0.94f)); - Add(EasingType.Quadratic, EasingMode.EaseIn, new Vector2(0.55f, 0.085f), new Vector2(0.68f, 0.53f)); - Add(EasingType.Quadratic, EasingMode.EaseInOut, new Vector2(0.445f, 0.03f), new Vector2(0.515f, 0.955f)); - - Add(EasingType.Quartic, EasingMode.EaseOut, new Vector2(0.165f, 0.84f), new Vector2(0.44f, 1f)); - Add(EasingType.Quartic, EasingMode.EaseIn, new Vector2(0.895f, 0.03f), new Vector2(0.685f, 0.22f)); - Add(EasingType.Quartic, EasingMode.EaseInOut, new Vector2(0.77f, 0.0f), new Vector2(0.175f, 1.0f)); - - Add(EasingType.Quintic, EasingMode.EaseOut, new Vector2(0.23f, 1f), new Vector2(0.32f, 1f)); - Add(EasingType.Quintic, EasingMode.EaseIn, new Vector2(0.755f, 0.05f), new Vector2(0.855f, 0.06f)); - Add(EasingType.Quintic, EasingMode.EaseInOut, new Vector2(0.86f, 0.0f), new Vector2(0.07f, 1.0f)); - - Add(EasingType.Sine, EasingMode.EaseOut, new Vector2(0.39f, 0.575f), new Vector2(0.565f, 1f)); - Add(EasingType.Sine, EasingMode.EaseIn, new Vector2(0.47f, 0.0f), new Vector2(0.745f, 0.715f)); - Add(EasingType.Sine, EasingMode.EaseInOut, new Vector2(0.445f, 0.05f), new Vector2(0.55f, 0.95f)); - } - - private static CompositionEasingFunction GenerateCompositionEasingFunctionFromEasingType(EasingType easingType, Compositor compositor, EasingMode easingMode = EasingMode.EaseOut) - { - if (easingType == EasingType.Default) - { - easingType = DefaultEasingType; - } - - if (easingType == EasingType.Linear) - { - return compositor.CreateLinearEasingFunction(); - } - - // Pay-per-play caching of easing functions - EnsureEasingsCached(); - - if (_compositionEasingFunctions.TryGetValue((easingType.ToString(), easingMode), out (Vector2, Vector2) points)) - { - return compositor.CreateCubicBezierEasingFunction(points.Item1, points.Item2); - } - - throw new NotSupportedException($"{easingType.ToString()} EasingType and {easingMode.ToString()} EasingMode combination is not currently supported"); - } - - private static string GetAnimationPath(CompositeTransform transform, UIElement element, string property) - { - if (element.RenderTransform == transform) - { - return $"(UIElement.RenderTransform).(CompositeTransform.{property})"; - } - - var group = element.RenderTransform as TransformGroup; - - if (group == null) - { - return string.Empty; - } - - for (var index = 0; index < group.Children.Count; index++) - { - if (group.Children[index] == transform) - { - return $"(UIElement.RenderTransform).(TransformGroup.Children)[{index}].(CompositeTransform.{property})"; - } - } - - return string.Empty; - } - - private static CompositeTransform GetAttachedCompositeTransform(UIElement element) - { - // We need to use an index to keep track of our CompositeTransform as animation engine - // recreates new transform objects when animating properties - - // Already attached? - var compositeTransformIndex = AnimationTools.GetAnimationCompositeTransformIndex(element); - - if (compositeTransformIndex > -2) - { - if (compositeTransformIndex == -1 && element.RenderTransform is CompositeTransform) - { - return (CompositeTransform)element.RenderTransform; - } - - var group = element.RenderTransform as TransformGroup; - - if (group?.Children.Count > compositeTransformIndex && group.Children[compositeTransformIndex] is CompositeTransform) - { - return (CompositeTransform)group.Children[compositeTransformIndex]; - } - } - - // Let's create a new CompositeTransform - var result = new CompositeTransform(); - - var currentTransform = element.RenderTransform; - - if (currentTransform != null) - { - // We found a RenderTransform - - // Is it a TransformGroup? - var currentTransformGroup = currentTransform as TransformGroup; - - if (currentTransformGroup != null) - { - currentTransformGroup.Children.Add(result); - - AnimationTools.SetAnimationCompositeTransformIndex(element, currentTransformGroup.Children.Count - 1); - } - else - { - // Let's create our own TransformGroup - var group = new TransformGroup(); - group.Children.Add(currentTransform); - group.Children.Add(result); - element.RenderTransform = group; - - AnimationTools.SetAnimationCompositeTransformIndex(element, 1); - } - } - else - { - element.RenderTransform = result; - - AnimationTools.SetAnimationCompositeTransformIndex(element, -1); - } - - return result; - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationTools.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationTools.cs deleted file mode 100644 index 2d4deb838bd..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationTools.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Xaml; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Internal tool to link composite transforms to elements - /// - internal class AnimationTools : DependencyObject - { - /// - /// Attached property used to link composite transform with UIElement - /// - public static readonly DependencyProperty AnimationCompositeTransformIndexProperty = DependencyProperty.RegisterAttached( - "AnimationCompositeTransformIndex", - typeof(int), - typeof(AnimationTools), - new PropertyMetadata(-2)); - - /// - /// Attach a composite transform index to an UIElement. - /// - /// UIElement to use - /// Composite transform index - public static void SetAnimationCompositeTransformIndex(UIElement element, int value) - { - element.SetValue(AnimationCompositeTransformIndexProperty, value); - } - - /// - /// Get the composite transform index attached to an UIElement. - /// - /// UIElement to use - /// Composite transform index. - public static int GetAnimationCompositeTransformIndex(UIElement element) - { - return (int)element.GetValue(AnimationCompositeTransformIndexProperty); - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj b/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj index f31624a8267..1d85a6e296e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj @@ -21,16 +21,12 @@ - - - - From 9f77bb90aff09ee5924572f2720237d42b36809a Mon Sep 17 00:00:00 2001 From: michael-hawker <24302614+michael-hawker@users.noreply.github.com> Date: Thu, 17 Dec 2020 13:36:00 -0800 Subject: [PATCH 004/171] Removed ScrollHeader from project description --- .../Microsoft.Toolkit.Uwp.UI.Controls.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/Microsoft.Toolkit.Uwp.UI.Controls.csproj b/Microsoft.Toolkit.Uwp.UI.Controls/Microsoft.Toolkit.Uwp.UI.Controls.csproj index 26ff92e907a..692244e59f6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/Microsoft.Toolkit.Uwp.UI.Controls.csproj +++ b/Microsoft.Toolkit.Uwp.UI.Controls/Microsoft.Toolkit.Uwp.UI.Controls.csproj @@ -31,7 +31,6 @@ - RangeSelector: "Double slider" control for range values. - RemoteDevicePicker: Remote Device Picker Control for Project Rome. - RotatorTile: Rotates through a set of items one-by-one like a live-tile. - - ScrollHeader: A UI control that works as a ListView or GridView header control with quick return, sticky, and fade behavior. - StaggeredPanel: Layout of items in a column approach where an item will be added to whichever column has used the least amount of space. - TextToolbar: A Toolbar for Editing Text attached to a RichEditBox. It can format RTF, Markdown, or use a Custom Formatter. - TileControl: A ContentControl that show an image repeated many times. From 0c7085a39e4a1da150a0bfcdd11365e3352edcaa Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 17 Dec 2020 22:37:00 +0100 Subject: [PATCH 005/171] Reintroduced AnimationExtensions mapping --- .editorconfig | 3 +- .../Enums/EasingType.cs | 2 +- .../Extensions/AnimationExtensions.cs | 63 +++++++++++++++++++ ...Microsoft.Toolkit.Uwp.UI.Animations.csproj | 5 ++ 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs diff --git a/.editorconfig b/.editorconfig index 50eeccedc3f..e449ab4d46b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -324,4 +324,5 @@ dotnet_diagnostic.SA1652.severity = none dotnet_diagnostic.SA1629.severity = none # DocumentationTextMustEndWithAPeriod: Let's enable this rule back when we shift to WinUI3 (v8.x). If we do it now, it would mean more than 400 file changes. dotnet_diagnostic.SA1413.severity = none # UseTrailingCommasInMultiLineInitializers: This would also mean a lot of changes at the end of all multiline initializers. It's also debatable if we want this or not. -dotnet_diagnostic.SA1314.severity = none # TypeParameterNamesMustBeginWithT: We do have a few templates that don't start with T. We need to double check that changing this is not a breaking change. If not, we can re-enable this. \ No newline at end of file +dotnet_diagnostic.SA1314.severity = none # TypeParameterNamesMustBeginWithT: We do have a few templates that don't start with T. We need to double check that changing this is not a breaking change. If not, we can re-enable this. +dotnet_diagnostic.SA1000.severity = none # Hide warnings when using the new() expression from C# 9. \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Enums/EasingType.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Enums/EasingType.cs index 1639ad76060..b0c1b5a1f42 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Enums/EasingType.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Enums/EasingType.cs @@ -10,7 +10,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations public enum EasingType { /// - /// The default easing type, which is specified in AnimationExtensions.DefaultEasingType which is by default Cubic. + /// The default easing type, which is specified in which is by default . /// Default, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs new file mode 100644 index 00000000000..aeed4ea6e49 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs @@ -0,0 +1,63 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Numerics; +using Windows.UI.Xaml.Media.Animation; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Extensions +{ + /// + /// These extension methods perform animation on UIElements + /// + public static partial class AnimationExtensions + { + /// + /// The reusable mapping of control points for easing curves for combinations of and values. + /// + private static readonly Dictionary<(EasingType Type, EasingMode Mode), (Vector2 A, Vector2 B)> EasingMaps = new() + { + [(EasingType.Cubic, EasingMode.EaseOut)] = (new(0.215f, 0.61f), new(0.355f, 1f)), + [(EasingType.Cubic, EasingMode.EaseIn)] = (new(0.55f, 0.055f), new(0.675f, 0.19f)), + [(EasingType.Cubic, EasingMode.EaseInOut)] = (new(0.645f, 0.045f), new(0.355f, 1f)), + + [(EasingType.Back, EasingMode.EaseOut)] = (new(0.175f, 0.885f), new(0.32f, 1.275f)), + [(EasingType.Back, EasingMode.EaseIn)] = (new(0.6f, -0.28f), new(0.735f, 0.045f)), + [(EasingType.Back, EasingMode.EaseInOut)] = (new(0.68f, -0.55f), new(0.265f, 1.55f)), + + [(EasingType.Bounce, EasingMode.EaseOut)] = (new(0.58f, 1.93f), new(.08f, .36f)), + [(EasingType.Bounce, EasingMode.EaseIn)] = (new(0.93f, 0.7f), new(0.4f, -0.93f)), + [(EasingType.Bounce, EasingMode.EaseInOut)] = (new(0.65f, -0.85f), new(0.35f, 1.85f)), + + [(EasingType.Elastic, EasingMode.EaseOut)] = (new(0.37f, 2.68f), new(0f, 0.22f)), + [(EasingType.Elastic, EasingMode.EaseIn)] = (new(1, .78f), new(.63f, -1.68f)), + [(EasingType.Elastic, EasingMode.EaseInOut)] = (new(0.9f, -1.2f), new(0.1f, 2.2f)), + + [(EasingType.Circle, EasingMode.EaseOut)] = (new(0.075f, 0.82f), new(0.165f, 1f)), + [(EasingType.Circle, EasingMode.EaseIn)] = (new(0.6f, 0.04f), new(0.98f, 0.335f)), + [(EasingType.Circle, EasingMode.EaseInOut)] = (new(0.785f, 0.135f), new(0.15f, 0.86f)), + + [(EasingType.Quadratic, EasingMode.EaseOut)] = (new(0.25f, 0.46f), new(0.45f, 0.94f)), + [(EasingType.Quadratic, EasingMode.EaseIn)] = (new(0.55f, 0.085f), new(0.68f, 0.53f)), + [(EasingType.Quadratic, EasingMode.EaseInOut)] = (new(0.445f, 0.03f), new(0.515f, 0.955f)), + + [(EasingType.Quartic, EasingMode.EaseOut)] = (new(0.165f, 0.84f), new(0.44f, 1f)), + [(EasingType.Quartic, EasingMode.EaseIn)] = (new(0.895f, 0.03f), new(0.685f, 0.22f)), + [(EasingType.Quartic, EasingMode.EaseInOut)] = (new(0.77f, 0.0f), new(0.175f, 1.0f)), + + [(EasingType.Quintic, EasingMode.EaseOut)] = (new(0.23f, 1f), new(0.32f, 1f)), + [(EasingType.Quintic, EasingMode.EaseIn)] = (new(0.755f, 0.05f), new(0.855f, 0.06f)), + [(EasingType.Quintic, EasingMode.EaseInOut)] = (new(0.86f, 0.0f), new(0.07f, 1.0f)), + + [(EasingType.Sine, EasingMode.EaseOut)] = (new(0.39f, 0.575f), new(0.565f, 1f)), + [(EasingType.Sine, EasingMode.EaseIn)] = (new(0.47f, 0.0f), new(0.745f, 0.715f)), + [(EasingType.Sine, EasingMode.EaseInOut)] = (new(0.445f, 0.05f), new(0.55f, 0.95f)) + }; + + /// + /// Gets the default value used for storyboard animations. + /// + public static EasingType DefaultEasingType => EasingType.Cubic; + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj b/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj index 1d85a6e296e..e49f7af1cd7 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj @@ -15,18 +15,23 @@ - AnimationExtensions: Blur, Fade, Light, Offset, Rotate, Saturation, Scale UWP Toolkit Windows Animations Composition Connected Implicit XAML + 9.0 + + + + From d8efc040b036efa95553ae421e8145dec0a94841 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 17 Dec 2020 22:53:30 +0100 Subject: [PATCH 006/171] Ported Compositor and CompositionObject extensions --- .../Extensions/AnimationExtensions.cs | 2 +- .../Extensions/CompositionObjectExtensions.cs | 82 +++++++++ .../Extensions/CompositorExtensions.cs | 162 ++++++++++++++++++ ...Microsoft.Toolkit.Uwp.UI.Animations.csproj | 1 + 4 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs index aeed4ea6e49..ddc3fe7c2d0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs @@ -16,7 +16,7 @@ public static partial class AnimationExtensions /// /// The reusable mapping of control points for easing curves for combinations of and values. /// - private static readonly Dictionary<(EasingType Type, EasingMode Mode), (Vector2 A, Vector2 B)> EasingMaps = new() + internal static readonly Dictionary<(EasingType Type, EasingMode Mode), (Vector2 A, Vector2 B)> EasingMaps = new() { [(EasingType.Cubic, EasingMode.EaseOut)] = (new(0.215f, 0.61f), new(0.355f, 1f)), [(EasingType.Cubic, EasingMode.EaseIn)] = (new(0.55f, 0.055f), new(0.675f, 0.19f)), diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs new file mode 100644 index 00000000000..566bb9ded76 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs @@ -0,0 +1,82 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Numerics; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Extensions +{ + /// + /// An extension for the type. + /// + public static class CompositionObjectExtensions + { + /// + /// Creates and starts a scalar animation on the current . + /// + /// The target to animate. + /// The path that identifies the property to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The animation duration. + /// The optional initial delay for the animation. + /// The optional easing function for the animation. + public static void StartScalarAnimation( + this CompositionObject target, + string propertyPath, + float? from, + float to, + TimeSpan duration, + TimeSpan? delay, + CompositionEasingFunction? ease = null) + { + target.StartAnimation(propertyPath, target.Compositor.CreateScalarKeyFrameAnimation(from, to, duration, delay, ease)); + } + + /// + /// Creates and starts a animation on the current . + /// + /// The target to animate. + /// The path that identifies the property to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The animation duration. + /// The optional initial delay for the animation. + /// The optional easing function for the animation. + public static void StartVector2Animation( + this CompositionObject target, + string propertyPath, + Vector2? from, + Vector2 to, + TimeSpan duration, + TimeSpan? delay, + CompositionEasingFunction? ease = null) + { + target.StartAnimation(propertyPath, target.Compositor.CreateVector2KeyFrameAnimation(from, to, duration, delay, ease)); + } + + /// + /// Creates and starts a animation on the current . + /// + /// The target to animate. + /// The path that identifies the property to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The animation duration. + /// The optional initial delay for the animation. + /// The optional easing function for the animation. + public static void StartVector3Animation( + this CompositionObject target, + string propertyPath, + Vector3? from, + Vector3 to, + TimeSpan duration, + TimeSpan? delay, + CompositionEasingFunction? ease = null) + { + target.StartAnimation(propertyPath, target.Compositor.CreateVector3KeyFrameAnimation(from, to, duration, delay, ease)); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs new file mode 100644 index 00000000000..b80d82efa9d --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs @@ -0,0 +1,162 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Diagnostics.Contracts; +using System.Numerics; +using Windows.UI.Composition; +using Windows.UI.Xaml.Media.Animation; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Extensions +{ + /// + /// An extension for the type. + /// + public static class CompositorExtensions + { + /// + /// Creates a from the input control points. + /// + /// The source used to create the easing function. + /// The X coordinate of the first control point. + /// The Y coordinate of the first control point. + /// The X coordinate of the second control point. + /// The Y coordinate of the second control point. + /// A instance with the given control points. + [Pure] + public static CubicBezierEasingFunction CreateCubicBezierEasingFunction(this Compositor compositor, float x1, float y1, float x2, float y2) + { + return compositor.CreateCubicBezierEasingFunction(new(x1, y1), new(x2, y2)); + } + + /// + /// Creates the appropriate from the given easing type and mode. + /// + /// The source used to create the easing function. + /// The target easing function to use. + /// The target easing mode to use. + /// A instance with the specified easing. + [Pure] + public static CubicBezierEasingFunction CreateCubicBezierEasingFunction(this Compositor compositor, EasingType easingType, EasingMode easingMode) + { + var (a, b) = AnimationExtensions.EasingMaps[(easingType, easingMode)]; + + return compositor.CreateCubicBezierEasingFunction(a, b); + } + + /// + /// Creates a instance with the given parameters to on a target element. + /// + /// The current instance used to create the animation. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The animation duration. + /// The optional initial delay for the animation. + /// The optional easing function for the animation. + /// A instance with the specified parameters. + [Pure] + public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation( + this Compositor compositor, + float? from, + float to, + TimeSpan duration, + TimeSpan? delay, + CompositionEasingFunction? ease = null) + { + ScalarKeyFrameAnimation animation = compositor.CreateScalarKeyFrameAnimation(); + + animation.Duration = duration; + + if (delay.HasValue) + { + animation.DelayTime = delay.Value; + } + + animation.InsertKeyFrame(1, to, ease ?? compositor.CreateLinearEasingFunction()); + + if (from.HasValue) + { + animation.InsertKeyFrame(0, from.Value); + } + + return animation; + } + + /// + /// Creates a instance with the given parameters to on a target element. + /// + /// The current instance used to create the animation. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The animation duration. + /// The optional initial delay for the animation. + /// The optional easing function for the animation. + /// A instance with the specified parameters. + [Pure] + public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation( + this Compositor compositor, + Vector2? from, + Vector2 to, + TimeSpan duration, + TimeSpan? delay, + CompositionEasingFunction? ease = null) + { + Vector2KeyFrameAnimation animation = compositor.CreateVector2KeyFrameAnimation(); + + animation.Duration = duration; + + if (delay.HasValue) + { + animation.DelayTime = delay.Value; + } + + animation.InsertKeyFrame(1, to, ease ?? compositor.CreateLinearEasingFunction()); + + if (from.HasValue) + { + animation.InsertKeyFrame(0, from.Value); + } + + return animation; + } + + /// + /// Creates a instance with the given parameters to on a target element. + /// + /// The current instance used to create the animation. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The animation duration. + /// The optional initial delay for the animation. + /// The optional easing function for the animation. + /// A instance with the specified parameters. + [Pure] + public static Vector3KeyFrameAnimation CreateVector3KeyFrameAnimation( + this Compositor compositor, + Vector3? from, + Vector3 to, + TimeSpan duration, + TimeSpan? delay, + CompositionEasingFunction? ease = null) + { + Vector3KeyFrameAnimation animation = compositor.CreateVector3KeyFrameAnimation(); + + animation.Duration = duration; + + if (delay.HasValue) + { + animation.DelayTime = delay.Value; + } + + animation.InsertKeyFrame(1, to, ease ?? compositor.CreateLinearEasingFunction()); + + if (from.HasValue) + { + animation.InsertKeyFrame(0, from.Value); + } + + return animation; + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj b/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj index e49f7af1cd7..57f66ccdcb9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj @@ -16,6 +16,7 @@ UWP Toolkit Windows Animations Composition Connected Implicit XAML 9.0 + enable From 7c8df90cd161581b8e86b22556f37b565b84afa6 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 17 Dec 2020 23:02:11 +0100 Subject: [PATCH 007/171] Ported DependencyObject and Storyboard extensions --- .../Extensions/DependencyObjectExtensions.cs | 53 +++++++++++++++++++ .../Extensions/StoryboardAnimations.cs | 31 +++++++++++ 2 files changed, 84 insertions(+) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/StoryboardAnimations.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs new file mode 100644 index 00000000000..bd90bf9b815 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Diagnostics.Contracts; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Media.Animation; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Extensions +{ + /// + /// An extension for the type. + /// + public static class DependencyObjectExtensions + { + /// + /// Prepares a with the given info. + /// + /// The target to animate. + /// The property to animate inside the target . + /// The optional initial property value. + /// The final property value. + /// The duration of the . + /// The easing function to use inside the . + /// Indicates whether or not to apply this animation to elements that need the visual tree to be rearranged. + /// A instance with the specified parameters. + [Pure] + public static DoubleAnimation CreateDoubleAnimation( + this DependencyObject target, + string property, + double? from, + double to, + TimeSpan duration, + EasingFunctionBase? easing = null, + bool enableDependecyAnimations = false) + { + DoubleAnimation animation = new() + { + From = from, + To = to, + Duration = duration, + EasingFunction = easing, + EnableDependentAnimation = enableDependecyAnimations, + }; + + Storyboard.SetTarget(animation, target); + Storyboard.SetTargetProperty(animation, property); + + return animation; + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/StoryboardAnimations.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/StoryboardAnimations.cs new file mode 100644 index 00000000000..771fbc376d7 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/StoryboardAnimations.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Threading.Tasks; +using Windows.UI.Xaml.Media.Animation; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Extensions +{ + /// + /// An extension for the type. + /// + public static class StoryboardAnimations + { + /// + /// Starts an animation and returns a that reports when it completes. + /// + /// The target storyboard to start. + /// A that completes when completes. + public static Task BeginAsync(this Storyboard storyboard) + { + TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); + + storyboard.Completed += (_, _) => taskCompletionSource.SetResult(null); + + storyboard.Begin(); + + return taskCompletionSource.Task; + } + } +} From e13dcbad0db9ef0225eb22fdc7d57609e097eec6 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 17 Dec 2020 23:17:29 +0100 Subject: [PATCH 008/171] Ported EasingTypeExtensions type --- .../Extensions/AnimationExtensions.cs | 17 ++++--- .../Extensions/EasingTypeExtensions.cs | 46 +++++++++++++++++++ 2 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/EasingTypeExtensions.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs index ddc3fe7c2d0..6ce859556d2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs @@ -9,10 +9,20 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Extensions { /// - /// These extension methods perform animation on UIElements + /// Common properties related to extensions. /// public static partial class AnimationExtensions { + /// + /// The default value used for animations. + /// + public const EasingType DefaultEasingType = EasingType.Cubic; + + /// + /// The default value used for animations. + /// + public const EasingMode DefaultEasingMode = EasingMode.EaseOut; + /// /// The reusable mapping of control points for easing curves for combinations of and values. /// @@ -54,10 +64,5 @@ public static partial class AnimationExtensions [(EasingType.Sine, EasingMode.EaseIn)] = (new(0.47f, 0.0f), new(0.745f, 0.715f)), [(EasingType.Sine, EasingMode.EaseInOut)] = (new(0.445f, 0.05f), new(0.55f, 0.95f)) }; - - /// - /// Gets the default value used for storyboard animations. - /// - public static EasingType DefaultEasingType => EasingType.Cubic; } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/EasingTypeExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/EasingTypeExtensions.cs new file mode 100644 index 00000000000..5dff3dfe6a2 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/EasingTypeExtensions.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.Contracts; +using Microsoft.Toolkit.Diagnostics; +using Windows.UI.Xaml.Media.Animation; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Extensions +{ + /// + /// An extension for the type. + /// + public static class EasingTypeExtensions + { + /// + /// Gets an instance corresponding to a given value. + /// + /// The desired easing function type. + /// The desired easing mode. + /// An instance corresponding to the input parameters. + [Pure] + public static EasingFunctionBase? ToEasingFunction(this EasingType easingType, EasingMode easingMode) + { + if (easingType == EasingType.Default) + { + easingType = AnimationExtensions.DefaultEasingType; + } + + return easingType switch + { + EasingType.Linear => null, + EasingType.Cubic => new CubicEase { EasingMode = easingMode }, + EasingType.Back => new BackEase { EasingMode = easingMode }, + EasingType.Bounce => new BounceEase { EasingMode = easingMode }, + EasingType.Elastic => new ElasticEase { EasingMode = easingMode }, + EasingType.Circle => new CircleEase { EasingMode = easingMode }, + EasingType.Quadratic => new QuadraticEase { EasingMode = easingMode }, + EasingType.Quartic => new QuarticEase { EasingMode = easingMode }, + EasingType.Quintic => new QuinticEase { EasingMode = easingMode }, + EasingType.Sine => new SineEase { EasingMode = easingMode }, + _ => ThrowHelper.ThrowArgumentException("Invalid easing type") + }; + } + } +} From 8c5af50463cdf099b02207be0775879d415b6a49 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 17 Dec 2020 23:52:16 +0100 Subject: [PATCH 009/171] Initial porting of AnimationBuilder --- .editorconfig | 4 +- .../AnimationBuilder.Models.cs | 136 +++++++++++++++ .../AnimationBuilder.Setup.cs | 137 +++++++++++++++ .../AnimationBuilder.cs | 159 ++++++++++++++++++ .../Extensions/DependencyObjectExtensions.cs | 3 + .../Extensions/UIElementExtensions.cs | 46 +++++ .../Properties/IsExternalInit.cs | 17 ++ 7 files changed, 501 insertions(+), 1 deletion(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/UIElementExtensions.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Properties/IsExternalInit.cs diff --git a/.editorconfig b/.editorconfig index e449ab4d46b..36629f6b744 100644 --- a/.editorconfig +++ b/.editorconfig @@ -325,4 +325,6 @@ dotnet_diagnostic.SA1652.severity = none dotnet_diagnostic.SA1629.severity = none # DocumentationTextMustEndWithAPeriod: Let's enable this rule back when we shift to WinUI3 (v8.x). If we do it now, it would mean more than 400 file changes. dotnet_diagnostic.SA1413.severity = none # UseTrailingCommasInMultiLineInitializers: This would also mean a lot of changes at the end of all multiline initializers. It's also debatable if we want this or not. dotnet_diagnostic.SA1314.severity = none # TypeParameterNamesMustBeginWithT: We do have a few templates that don't start with T. We need to double check that changing this is not a breaking change. If not, we can re-enable this. -dotnet_diagnostic.SA1000.severity = none # Hide warnings when using the new() expression from C# 9. \ No newline at end of file +dotnet_diagnostic.SA1000.severity = none # Hide warnings when using the new() expression from C# 9. +dotnet_diagnostic.SA1313.severity = none # Hide warnings for record parameters. +dotnet_diagnostic.SA1101.severity = none # Hide warnings when accessing properties without "this". \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs new file mode 100644 index 00000000000..46b36d5ac86 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs @@ -0,0 +1,136 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Media.Animation; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + public sealed partial class AnimationBuilder + { + /// + /// A model representing a specified composition scalar animation. + /// + private sealed record CompositionScalarAnimation( + string Property, + float? From, + float To, + TimeSpan? Delay, + TimeSpan Duration, + EasingType EasingType, + EasingMode EasingMode) + : ICompositionAnimation + { + /// + public void StartAnimation(Visual visual) + { + visual.StopAnimation(Property); + + CompositionEasingFunction easingFunction = visual.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); + ScalarKeyFrameAnimation animation = visual.Compositor.CreateScalarKeyFrameAnimation(From, To, Duration, Delay, easingFunction); + + visual.StartAnimation(Property, animation); + } + } + + /// + /// A model representing a specified composition animation. + /// + private sealed record CompositionVector3Animation( + string Property, + Vector3? From, + Vector3 To, + TimeSpan? Delay, + TimeSpan Duration, + EasingType EasingType, + EasingMode EasingMode) + : ICompositionAnimation + { + /// + public void StartAnimation(Visual visual) + { + visual.StopAnimation(Property); + + CompositionEasingFunction easingFunction = visual.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); + Vector3KeyFrameAnimation animation = visual.Compositor.CreateVector3KeyFrameAnimation(From, To, Duration, Delay, easingFunction); + + visual.StartAnimation(Property, animation); + } + } + + /// + /// A model representing a specified XAML animation. + /// + private sealed record XamlDoubleAnimation( + string Property, + double? From, + double To, + TimeSpan? Delay, + TimeSpan Duration, + EasingType EasingType, + EasingMode EasingMode, + bool EnableDependentAnimation) + : IXamlAnimationFactory + { + /// + public Timeline GetAnimation(UIElement element) + { + return element.CreateDoubleAnimation(Property, From, To, Delay, Duration, EasingType.ToEasingFunction(EasingMode), EnableDependentAnimation); + } + } + + /// + /// A model representing a specified XAML animation targeting a transform. + /// + private sealed record XamlTransformDoubleAnimation( + string Property, + double? From, + double To, + TimeSpan? Delay, + TimeSpan Duration, + EasingType EasingType, + EasingMode EasingMode) + : IXamlAnimationFactory + { + /// + public Timeline GetAnimation(UIElement element) + { + CompositeTransform transform = element.GetTransform(); + + return transform.CreateDoubleAnimation(Property, From, To, Delay, Duration, EasingType.ToEasingFunction(EasingMode)); + } + } + + /// + /// An interface for factories of XAML animations. + /// + private interface IXamlAnimationFactory + { + /// + /// Gets a instance representing the animation to start. + /// + /// The target instance to animate. + /// A instance with the specified animation. + Timeline GetAnimation(UIElement element); + } + + /// + /// An interface for animations targeting the composition layer. + /// + private interface ICompositionAnimation + { + /// + /// Starts the current animation. + /// + /// The target instance to animate. + void StartAnimation(Visual visual); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs new file mode 100644 index 00000000000..c3e9963aa4a --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs @@ -0,0 +1,137 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Numerics; +using Windows.UI.Xaml.Media.Animation; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// A that allows to build custom animations targeting both the XAML and composition layers. + /// + public sealed partial class AnimationBuilder + { + /// + /// The list of instances representing composition animations to run. + /// + private readonly List compositionAnimations = new(); + + /// + /// The list of instances representing factories for XAML animations to run. + /// + private readonly List xamlAnimationFactories = new(); + + /// + /// Adds a new composition scalar animation to the current schedule. + /// + /// The target property to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The easing function for the animation. + /// The easing mode for the animation. + /// The current instance. + private AnimationBuilder OnCompositionScalarAnimation( + string property, + float? from, + float to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType, + EasingMode easingMode) + { + CompositionScalarAnimation animation = new(property, from, to, delay, duration, easingType, easingMode); + + this.compositionAnimations.Add(animation); + + return this; + } + + /// + /// Adds a new composition animation to the current schedule. + /// + /// The target property to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The easing function for the animation. + /// The easing mode for the animation. + /// The current instance. + private AnimationBuilder OnCompositionVector3Animation( + string property, + Vector3? from, + Vector3 to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType, + EasingMode easingMode) + { + CompositionVector3Animation animation = new(property, from, to, delay, duration, easingType, easingMode); + + this.compositionAnimations.Add(animation); + + return this; + } + + /// + /// Adds a new XAML animation to the current schedule. + /// + /// The target property to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The easing function for the animation. + /// The easing mode for the animation. + /// Whether to set . + /// The current instance. + private AnimationBuilder OnXamlDoubleAnimation( + string property, + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType, + EasingMode easingMode, + bool enableDependentAnimation) + { + XamlDoubleAnimation animation = new(property, from, to, delay, duration, easingType, easingMode, enableDependentAnimation); + + this.xamlAnimationFactories.Add(animation); + + return this; + } + + /// + /// Adds a new XAML transform animation to the current schedule. + /// + /// The target property to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The easing function for the animation. + /// The easing mode for the animation. + /// The current instance. + private AnimationBuilder OnXamlTransformDoubleAnimation( + string property, + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType, + EasingMode easingMode) + { + XamlTransformDoubleAnimation animation = new(property, from, to, delay, duration, easingType, easingMode); + + this.xamlAnimationFactories.Add(animation); + + return this; + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs new file mode 100644 index 00000000000..7ccc02241bb --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs @@ -0,0 +1,159 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Threading.Tasks; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Hosting; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// A that allows to build custom animations targeting both the XAML and composition layers. + /// + public sealed partial class AnimationBuilder + { + /// + /// Adds a new opacity animation to the current schedule. + /// + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder Opacity( + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return OnCompositionScalarAnimation(nameof(Visual.Opacity), (float?)from, (float)to, delay, duration, easingType, easingMode); + } + else + { + return OnXamlDoubleAnimation(nameof(UIElement.Opacity), from, to, delay, duration, easingType, easingMode, false); + } + } + + /// + /// Adds a new translation animation for a single axis to the current schedule. + /// + /// The target translation axis to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder Translation( + Axis axis, + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return OnCompositionScalarAnimation($"Translation.{axis}", (float?)from, (float)to, delay, duration, easingType, easingMode); + } + else + { + return OnXamlDoubleAnimation($"Translate{axis}", from, to, delay, duration, easingType, easingMode, false); + } + } + + /// + /// Starts the animations present in the current instance. + /// + /// The target to animate. + public void Start(UIElement element) + { + if (this.compositionAnimations.Count > 0) + { + Visual visual = ElementCompositionPreview.GetElementVisual(element); + + foreach (var animation in this.compositionAnimations) + { + animation.StartAnimation(visual); + } + } + + if (this.xamlAnimationFactories.Count > 0) + { + Storyboard storyboard = new(); + + foreach (var factory in this.xamlAnimationFactories) + { + storyboard.Children.Add(factory.GetAnimation(element)); + } + + storyboard.Begin(); + } + } + + /// + /// Starts the animations present in the current instance. + /// + /// The target to animate. + /// A that completes when all animations have completed. + public Task StartAsync(UIElement element) + { + Task + compositionTask = Task.CompletedTask, + xamlTask = Task.CompletedTask; + + if (this.compositionAnimations.Count > 0) + { + Visual visual = ElementCompositionPreview.GetElementVisual(element); + CompositionScopedBatch batch = visual.Compositor.CreateScopedBatch(CompositionBatchTypes.Animation); + TaskCompletionSource taskCompletionSource = new(); + + batch.Completed += (_, _) => taskCompletionSource.SetResult(null); + + foreach (var animation in this.compositionAnimations) + { + animation.StartAnimation(visual); + } + + batch.End(); + + compositionTask = taskCompletionSource.Task; + } + + if (this.xamlAnimationFactories.Count > 0) + { + Storyboard storyboard = new(); + TaskCompletionSource taskCompletionSource = new(); + + foreach (var factory in this.xamlAnimationFactories) + { + storyboard.Children.Add(factory.GetAnimation(element)); + } + + storyboard.Completed += (_, _) => taskCompletionSource.SetResult(null); + storyboard.Begin(); + + xamlTask = taskCompletionSource.Task; + } + + return Task.WhenAll(compositionTask, xamlTask); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs index bd90bf9b815..51f7ae5be96 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs @@ -21,6 +21,7 @@ public static class DependencyObjectExtensions /// The property to animate inside the target . /// The optional initial property value. /// The final property value. + /// The optional delay for the animation. /// The duration of the . /// The easing function to use inside the . /// Indicates whether or not to apply this animation to elements that need the visual tree to be rearranged. @@ -31,6 +32,7 @@ public static DoubleAnimation CreateDoubleAnimation( string property, double? from, double to, + TimeSpan? delay, TimeSpan duration, EasingFunctionBase? easing = null, bool enableDependecyAnimations = false) @@ -39,6 +41,7 @@ public static DoubleAnimation CreateDoubleAnimation( { From = from, To = to, + BeginTime = delay, Duration = duration, EasingFunction = easing, EnableDependentAnimation = enableDependecyAnimations, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/UIElementExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/UIElementExtensions.cs new file mode 100644 index 00000000000..69efa23b76e --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/UIElementExtensions.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.Contracts; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Hosting; +using Windows.UI.Xaml.Media; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Extensions +{ + /// + /// An extension for the type. + /// + public static class UIElementExtensions + { + /// + /// Returns the desired instance after assigning it to the property of the target . + /// + /// The desired type. + /// The target to modify. + /// A instance assigned to . + public static T GetTransform(this UIElement element) + where T : Transform, new() + { + if (element.RenderTransform is T transform) + { + return transform; + } + + return (T)(element.RenderTransform = new T()); + } + + /// + /// Returns the object for a given instance. + /// + /// The source element to get the visual for. + /// The object associated with . + [Pure] + public static Visual GetVisual(this UIElement element) + { + return ElementCompositionPreview.GetElementVisual(element); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Properties/IsExternalInit.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Properties/IsExternalInit.cs new file mode 100644 index 00000000000..cadcf5a8570 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Properties/IsExternalInit.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.ComponentModel; + +namespace System.Runtime.CompilerServices +{ + /// + /// Reserved to be used by the compiler for tracking metadata. + /// This class should not be used by developers in source code. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal static class IsExternalInit + { + } +} \ No newline at end of file From 8d466dbaa0312a4179b033536b93f5f46ec27bdd Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 18 Dec 2020 00:27:52 +0100 Subject: [PATCH 010/171] Added more animation APIs --- .../AnimationBuilder.Setup.cs | 30 +++ .../AnimationBuilder.cs | 199 ++++++++++++++++++ 2 files changed, 229 insertions(+) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs index c3e9963aa4a..7f66d234b56 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs @@ -51,6 +51,36 @@ private AnimationBuilder OnCompositionScalarAnimation( return this; } + /// + /// Adds a new composition animation to the current schedule. + /// + /// The target property to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The easing function for the animation. + /// The easing mode for the animation. + /// The current instance. + /// This will use a animation with a zero Z axis. + private AnimationBuilder OnCompositionVector2Animation( + string property, + Vector2? from, + Vector2 to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType, + EasingMode easingMode) + { + Vector3? from3 = from is null ? null : new(from.Value, 0); + Vector3 to3 = new(to, 0); + CompositionVector3Animation animation = new(property, from3, to3, delay, duration, easingType, easingMode); + + this.compositionAnimations.Add(animation); + + return this; + } + /// /// Adds a new composition animation to the current schedule. /// diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs index 7ccc02241bb..b66bca000c1 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs @@ -3,10 +3,12 @@ // See the LICENSE file in the project root for more information. using System; +using System.Numerics; using System.Threading.Tasks; using Windows.UI.Composition; using Windows.UI.Xaml; using Windows.UI.Xaml.Hosting; +using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -79,6 +81,203 @@ public AnimationBuilder Translation( } } + /// + /// Adds a new translation animation for the X and Y axes to the current schedule. + /// + /// The optional starting point for the animation. + /// The final point for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder Translation( + Vector2? from, + Vector2 to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return OnCompositionVector2Animation("Translation", from, to, delay, duration, easingType, easingMode); + } + else + { + OnXamlTransformDoubleAnimation(nameof(CompositeTransform.TranslateX), from?.X, to.X, delay, duration, easingType, easingMode); + OnXamlTransformDoubleAnimation(nameof(CompositeTransform.TranslateY), from?.Y, to.Y, delay, duration, easingType, easingMode); + + return this; + } + } + + /// + /// Adds a new composition translation animation for all axes to the current schedule. + /// + /// The optional starting point for the animation. + /// The final point for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder Translation( + Vector3? from, + Vector3 to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + return OnCompositionVector3Animation("Translation", from, to, delay, duration, easingType, easingMode); + } + + /// + /// Adds a new composition offset animation for a single axis to the current schedule. + /// + /// The target translation axis to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder Offset( + Axis axis, + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + return OnCompositionScalarAnimation($"{nameof(Visual.Offset)}.{axis}", (float?)from, (float)to, delay, duration, easingType, easingMode); + } + + /// + /// Adds a new composition offset animation for the X and Y axes to the current schedule. + /// + /// The optional starting point for the animation. + /// The final point for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder Offset( + Vector2? from, + Vector2 to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + return OnCompositionVector2Animation(nameof(Visual.Offset), from, to, delay, duration, easingType, easingMode); + } + + /// + /// Adds a new composition offset translation animation for all axes to the current schedule. + /// + /// The optional starting point for the animation. + /// The final point for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder Offset( + Vector3? from, + Vector3 to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + return OnCompositionVector3Animation(nameof(Visual.Offset), from, to, delay, duration, easingType, easingMode); + } + + /// + /// Adds a new uniform scale animation on the X and Y axes to the current schedule. + /// + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder Scale( + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + Vector2? from2 = from is null ? null : new((float)(double)from); + Vector2 to2 = new((float)to); + + return OnCompositionVector2Animation(nameof(Visual.Scale), from2, to2, delay, duration, easingType, easingMode); + } + else + { + OnXamlTransformDoubleAnimation(nameof(CompositeTransform.ScaleX), from, to, delay, duration, easingType, easingMode); + OnXamlTransformDoubleAnimation(nameof(CompositeTransform.ScaleY), from, to, delay, duration, easingType, easingMode); + + return this; + } + } + + /// + /// Adds a new scale animation on a specified axis to the current schedule. + /// + /// The target scale axis to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder Scale( + Axis axis, + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + Vector2? from2 = from is null ? null : new((float)(double)from); + Vector2 to2 = new((float)to); + + return OnCompositionVector2Animation(nameof(Visual.Scale), from2, to2, delay, duration, easingType, easingMode); + } + else + { + OnXamlTransformDoubleAnimation(nameof(CompositeTransform.ScaleX), from, to, delay, duration, easingType, easingMode); + OnXamlTransformDoubleAnimation(nameof(CompositeTransform.ScaleY), from, to, delay, duration, easingType, easingMode); + + return this; + } + } + /// /// Starts the animations present in the current instance. /// From ac844159556491a1a60bf0c3ecec553b6fbf60d2 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 18 Dec 2020 01:00:01 +0100 Subject: [PATCH 011/171] Added initial XAML mapping types --- .../Xaml/Abstract/TypedAnimation{T}.cs | 48 +++++++++++++++++++ .../Xaml/AnimationSet.cs | 33 +++++++++++++ .../Xaml/Interfaces/ITimeline.cs | 23 +++++++++ .../Xaml/OpacityAnimation.cs | 25 ++++++++++ .../Xaml/TranslationAnimation.cs | 30 ++++++++++++ 5 files changed, 159 insertions(+) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITimeline.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/OpacityAnimation.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/TranslationAnimation.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs new file mode 100644 index 00000000000..6fa96463805 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs @@ -0,0 +1,48 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// A base model representing a typed animation that can be used in XAML. + /// + /// The type of values for the animation. + public abstract class TypedAnimation + where T : unmanaged + { + /// + /// Gets or sets the optional starting value for the animation. + /// + public double? From { get; set; } + + /// + /// Gets or sets the final value for the animation. + /// + public double To { get; set; } + + /// + /// Gets or sets the optional initial delay for the animation. + /// + public TimeSpan? Delay { get; set; } + + /// + /// Gets or sets the animation duration. + /// + public TimeSpan? Duration { get; set; } + + /// + /// Gets or sets the optional easing function type for the animation. + /// + public EasingType EasingType { get; set; } = DefaultEasingType; + + /// + /// Gets or sets the optional easing function mode for the animation. + /// + public EasingMode EasingMode { get; set; } = DefaultEasingMode; + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs new file mode 100644 index 00000000000..6570a29e7a3 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using Windows.UI.Xaml.Markup; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// A set of animations that can be grouped together. + /// + [ContentProperty(Name = nameof(Elements))] + public class AnimationSet : ITimeline + { + /// + /// Gets or sets the collection of items for the current set. + /// + public IList Elements { get; set; } = new List(); + + /// + AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint) + { + foreach (ITimeline element in Elements) + { + builder = element.AppendToBuilder(builder, delayHint, durationHint); + } + + return builder; + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITimeline.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITimeline.cs new file mode 100644 index 00000000000..23e5c5094de --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITimeline.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// An interface representing a XAML model for a custom animation. + /// + public interface ITimeline + { + /// + /// Appens the current animation to a target instance. + /// + /// The target instance to schedule the animation on. + /// A hint for the animation delay, if present. + /// A hint for the animation duration, if present. + /// The same instance as . + AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint = null, TimeSpan? durationHint = null); + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/OpacityAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/OpacityAnimation.cs new file mode 100644 index 00000000000..1c00f55bcab --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/OpacityAnimation.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// A set of animations that can be grouped together. + /// + public class OpacityAnimation : TypedAnimation, ITimeline + { + /// + /// Gets or sets the target framework layer to animate. + /// + public FrameworkLayer Layer { get; set; } + + /// + AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint) + { + return builder.Opacity(From, To, Delay ?? delayHint, Duration ?? durationHint.GetValueOrDefault(), EasingType, EasingMode, Layer); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/TranslationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/TranslationAnimation.cs new file mode 100644 index 00000000000..f8c538b9e82 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/TranslationAnimation.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// A set of animations that can be grouped together. + /// + public class TranslationAnimation : TypedAnimation, ITimeline + { + /// + /// Gets or sets the target translation axis to animate. + /// + public Axis Axis { get; set; } + + /// + /// Gets or sets the target framework layer to animate. + /// + public FrameworkLayer Layer { get; set; } + + /// + AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint) + { + return builder.Translation(Axis, From, To, Delay ?? delayHint, Duration ?? durationHint.GetValueOrDefault(), EasingType, EasingMode, Layer); + } + } +} From 800f5d898d409a486b4b29ee968138885827ea95 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 18 Dec 2020 01:16:48 +0100 Subject: [PATCH 012/171] Added StartAnimationAction type --- .../Animations/StartAnimationAction.cs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs new file mode 100644 index 00000000000..bb30e53cb65 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs @@ -0,0 +1,44 @@ +using Microsoft.Toolkit.Diagnostics; +using Microsoft.Toolkit.Uwp.UI.Animations; +using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; +using Microsoft.Xaml.Interactivity; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Behaviors.Animations +{ + /// + /// An implementation that can trigger a target animation. + /// + public sealed class StartAnimationAction : DependencyObject, IAction + { + /// + /// Gets or sets the linked animation to invoke. + /// + public ITimeline Animation + { + get => (ITimeline)GetValue(AnimationProperty); + set => SetValue(AnimationProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty AnimationProperty = DependencyProperty.Register( + "Animation", + typeof(ITimeline), + typeof(StartAnimationAction), + new PropertyMetadata(null)); + + /// + public object Execute(object sender, object parameter) + { + Guard.IsNotNull(sender, nameof(sender)); + Guard.IsAssignableToType(sender, nameof(sender)); + Guard.IsNotNull(Animation, nameof(Animation)); + + Animation.AppendToBuilder(new AnimationBuilder()).Start((UIElement)sender); + + return null; + } + } +} From dd467d25145e96400642765b49594e19aafac54f Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 18 Dec 2020 12:24:53 +0100 Subject: [PATCH 013/171] Minor code refactoring --- .../AnimationBuilder.Models.cs | 29 +++++++++---------- .../AnimationBuilder.Setup.cs | 10 +++---- .../AnimationBuilder.cs | 18 ++++++++---- .../Extensions/CompositorExtensions.cs | 12 ++++++++ 4 files changed, 42 insertions(+), 27 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs index 46b36d5ac86..cc2f3f4db58 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs @@ -26,17 +26,15 @@ private sealed record CompositionScalarAnimation( TimeSpan Duration, EasingType EasingType, EasingMode EasingMode) - : ICompositionAnimation + : ICompositionAnimationFactory { /// - public void StartAnimation(Visual visual) + public CompositionAnimation GetAnimation(Visual visual) { - visual.StopAnimation(Property); - CompositionEasingFunction easingFunction = visual.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); - ScalarKeyFrameAnimation animation = visual.Compositor.CreateScalarKeyFrameAnimation(From, To, Duration, Delay, easingFunction); + ScalarKeyFrameAnimation animation = visual.Compositor.CreateScalarKeyFrameAnimation(Property, From, To, Duration, Delay, easingFunction); - visual.StartAnimation(Property, animation); + return animation; } } @@ -51,17 +49,15 @@ private sealed record CompositionVector3Animation( TimeSpan Duration, EasingType EasingType, EasingMode EasingMode) - : ICompositionAnimation + : ICompositionAnimationFactory { /// - public void StartAnimation(Visual visual) + public CompositionAnimation GetAnimation(Visual visual) { - visual.StopAnimation(Property); - CompositionEasingFunction easingFunction = visual.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); - Vector3KeyFrameAnimation animation = visual.Compositor.CreateVector3KeyFrameAnimation(From, To, Duration, Delay, easingFunction); + Vector3KeyFrameAnimation animation = visual.Compositor.CreateVector3KeyFrameAnimation(Property, From, To, Duration, Delay, easingFunction); - visual.StartAnimation(Property, animation); + return animation; } } @@ -122,15 +118,16 @@ private interface IXamlAnimationFactory } /// - /// An interface for animations targeting the composition layer. + /// An interface for factories of composition animations. /// - private interface ICompositionAnimation + private interface ICompositionAnimationFactory { /// - /// Starts the current animation. + /// Gets a instance representing the animation to start. /// /// The target instance to animate. - void StartAnimation(Visual visual); + /// A instance with the specified animation. + CompositionAnimation GetAnimation(Visual visual); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs index 7f66d234b56..d15811cf930 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs @@ -15,9 +15,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations public sealed partial class AnimationBuilder { /// - /// The list of instances representing composition animations to run. + /// The list of instances representing factories for composition animations to run. /// - private readonly List compositionAnimations = new(); + private readonly List compositionAnimationFactories = new(); /// /// The list of instances representing factories for XAML animations to run. @@ -46,7 +46,7 @@ private AnimationBuilder OnCompositionScalarAnimation( { CompositionScalarAnimation animation = new(property, from, to, delay, duration, easingType, easingMode); - this.compositionAnimations.Add(animation); + this.compositionAnimationFactories.Add(animation); return this; } @@ -76,7 +76,7 @@ private AnimationBuilder OnCompositionVector2Animation( Vector3 to3 = new(to, 0); CompositionVector3Animation animation = new(property, from3, to3, delay, duration, easingType, easingMode); - this.compositionAnimations.Add(animation); + this.compositionAnimationFactories.Add(animation); return this; } @@ -103,7 +103,7 @@ private AnimationBuilder OnCompositionVector3Animation( { CompositionVector3Animation animation = new(property, from, to, delay, duration, easingType, easingMode); - this.compositionAnimations.Add(animation); + this.compositionAnimationFactories.Add(animation); return this; } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs index b66bca000c1..26d7f7a483e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs @@ -284,14 +284,17 @@ public AnimationBuilder Scale( /// The target to animate. public void Start(UIElement element) { - if (this.compositionAnimations.Count > 0) + if (this.compositionAnimationFactories.Count > 0) { Visual visual = ElementCompositionPreview.GetElementVisual(element); + CompositionAnimationGroup group = visual.Compositor.CreateAnimationGroup(); - foreach (var animation in this.compositionAnimations) + foreach (var factory in this.compositionAnimationFactories) { - animation.StartAnimation(visual); + group.Add(factory.GetAnimation(visual)); } + + visual.StartAnimationGroup(group); } if (this.xamlAnimationFactories.Count > 0) @@ -318,19 +321,22 @@ public Task StartAsync(UIElement element) compositionTask = Task.CompletedTask, xamlTask = Task.CompletedTask; - if (this.compositionAnimations.Count > 0) + if (this.compositionAnimationFactories.Count > 0) { Visual visual = ElementCompositionPreview.GetElementVisual(element); + CompositionAnimationGroup group = visual.Compositor.CreateAnimationGroup(); CompositionScopedBatch batch = visual.Compositor.CreateScopedBatch(CompositionBatchTypes.Animation); TaskCompletionSource taskCompletionSource = new(); batch.Completed += (_, _) => taskCompletionSource.SetResult(null); - foreach (var animation in this.compositionAnimations) + foreach (var factory in this.compositionAnimationFactories) { - animation.StartAnimation(visual); + group.Add(factory.GetAnimation(visual)); } + visual.StartAnimationGroup(group); + batch.End(); compositionTask = taskCompletionSource.Task; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs index b80d82efa9d..6f3bf2bac12 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs @@ -49,6 +49,7 @@ public static CubicBezierEasingFunction CreateCubicBezierEasingFunction(this Com /// Creates a instance with the given parameters to on a target element. /// /// The current instance used to create the animation. + /// The target property to animate. /// The optional starting value for the animation. /// The final value for the animation. /// The animation duration. @@ -58,6 +59,7 @@ public static CubicBezierEasingFunction CreateCubicBezierEasingFunction(this Com [Pure] public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation( this Compositor compositor, + string target, float? from, float to, TimeSpan duration, @@ -80,6 +82,8 @@ public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation( animation.InsertKeyFrame(0, from.Value); } + animation.Target = target; + return animation; } @@ -87,6 +91,7 @@ public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation( /// Creates a instance with the given parameters to on a target element. /// /// The current instance used to create the animation. + /// The target property to animate. /// The optional starting value for the animation. /// The final value for the animation. /// The animation duration. @@ -96,6 +101,7 @@ public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation( [Pure] public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation( this Compositor compositor, + string target, Vector2? from, Vector2 to, TimeSpan duration, @@ -118,6 +124,8 @@ public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation( animation.InsertKeyFrame(0, from.Value); } + animation.Target = target; + return animation; } @@ -125,6 +133,7 @@ public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation( /// Creates a instance with the given parameters to on a target element. /// /// The current instance used to create the animation. + /// The target property to animate. /// The optional starting value for the animation. /// The final value for the animation. /// The animation duration. @@ -134,6 +143,7 @@ public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation( [Pure] public static Vector3KeyFrameAnimation CreateVector3KeyFrameAnimation( this Compositor compositor, + string target, Vector3? from, Vector3 to, TimeSpan duration, @@ -156,6 +166,8 @@ public static Vector3KeyFrameAnimation CreateVector3KeyFrameAnimation( animation.InsertKeyFrame(0, from.Value); } + animation.Target = target; + return animation; } } From e77296f8aac49645d6e3fb31390538f91a277fee Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 18 Dec 2020 13:21:13 +0100 Subject: [PATCH 014/171] Added Explicit class, enabled auto-binding to parent --- .../AnimationBuilder.cs | 4 ++ .../Explicit.cs | 66 +++++++++++++++++++ .../Extensions/CompositionObjectExtensions.cs | 6 +- .../Extensions/CompositorExtensions.cs | 12 ++-- .../Xaml/Abstract/Animation.cs | 36 ++++++++++ .../Xaml/Abstract/TypedAnimation{T}.cs | 31 +-------- .../Xaml/AnimationCollection2.cs | 61 +++++++++++++++++ .../Xaml/AnimationSet.cs | 33 ---------- .../Xaml/TranslationAnimation.cs | 19 +++--- 9 files changed, 190 insertions(+), 78 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs index 26d7f7a483e..fc6f965f062 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs @@ -286,6 +286,8 @@ public void Start(UIElement element) { if (this.compositionAnimationFactories.Count > 0) { + ElementCompositionPreview.SetIsTranslationEnabled(element, true); + Visual visual = ElementCompositionPreview.GetElementVisual(element); CompositionAnimationGroup group = visual.Compositor.CreateAnimationGroup(); @@ -323,6 +325,8 @@ public Task StartAsync(UIElement element) if (this.compositionAnimationFactories.Count > 0) { + ElementCompositionPreview.SetIsTranslationEnabled(element, true); + Visual visual = ElementCompositionPreview.GetElementVisual(element); CompositionAnimationGroup group = visual.Compositor.CreateAnimationGroup(); CompositionScopedBatch batch = visual.Compositor.CreateScopedBatch(CompositionBatchTypes.Animation); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs new file mode 100644 index 00000000000..a6cac52c220 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs @@ -0,0 +1,66 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Xaml; +using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// Attached properties to support explicitly triggered animations for instances. + /// + public static class Explicit + { + /// + /// Identifies the Implicit.ShowAnimations XAML attached property. + /// + public static readonly DependencyProperty Animations = DependencyProperty.RegisterAttached( + "ShowAnimations", + typeof(AnimationCollection), + typeof(Implicit), + new PropertyMetadata(null, OnAnimationsChanged)); + + /// + /// Gets the value of the property. + /// + /// The to get the value for. + /// The retrieved item. + public static AnimationCollection2 GetAnimations(UIElement element) + { + if (element.GetValue(Animations) is AnimationCollection2 collection) + { + return collection; + } + + collection = new AnimationCollection2(); + + element.SetValue(Animations, collection); + + return collection; + } + + /// + /// Sets the value of the property. + /// + /// The to set the value for. + /// The value to set. + public static void SetAnimations(UIElement element, AnimationCollection2 value) + { + element.SetValue(Animations, value); + } + + /// + /// Callback to keep the attached parent in sync for animations linked to the property. + /// + /// The target object the property was changed for. + /// The instance for the current event. + private static void OnAnimationsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (e.NewValue is AnimationCollection2 animationCollection && d is UIElement element) + { + animationCollection.Parent = element; + } + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs index 566bb9ded76..a90faae4361 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs @@ -32,7 +32,7 @@ public static void StartScalarAnimation( TimeSpan? delay, CompositionEasingFunction? ease = null) { - target.StartAnimation(propertyPath, target.Compositor.CreateScalarKeyFrameAnimation(from, to, duration, delay, ease)); + target.StartAnimation(propertyPath, target.Compositor.CreateScalarKeyFrameAnimation(null, from, to, duration, delay, ease)); } /// @@ -54,7 +54,7 @@ public static void StartVector2Animation( TimeSpan? delay, CompositionEasingFunction? ease = null) { - target.StartAnimation(propertyPath, target.Compositor.CreateVector2KeyFrameAnimation(from, to, duration, delay, ease)); + target.StartAnimation(propertyPath, target.Compositor.CreateVector2KeyFrameAnimation(null, from, to, duration, delay, ease)); } /// @@ -76,7 +76,7 @@ public static void StartVector3Animation( TimeSpan? delay, CompositionEasingFunction? ease = null) { - target.StartAnimation(propertyPath, target.Compositor.CreateVector3KeyFrameAnimation(from, to, duration, delay, ease)); + target.StartAnimation(propertyPath, target.Compositor.CreateVector3KeyFrameAnimation(null, from, to, duration, delay, ease)); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs index 6f3bf2bac12..6a92d382c86 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs @@ -49,7 +49,7 @@ public static CubicBezierEasingFunction CreateCubicBezierEasingFunction(this Com /// Creates a instance with the given parameters to on a target element. /// /// The current instance used to create the animation. - /// The target property to animate. + /// The optional target property to animate. /// The optional starting value for the animation. /// The final value for the animation. /// The animation duration. @@ -59,7 +59,7 @@ public static CubicBezierEasingFunction CreateCubicBezierEasingFunction(this Com [Pure] public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation( this Compositor compositor, - string target, + string? target, float? from, float to, TimeSpan duration, @@ -91,7 +91,7 @@ public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation( /// Creates a instance with the given parameters to on a target element. /// /// The current instance used to create the animation. - /// The target property to animate. + /// The optional target property to animate. /// The optional starting value for the animation. /// The final value for the animation. /// The animation duration. @@ -101,7 +101,7 @@ public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation( [Pure] public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation( this Compositor compositor, - string target, + string? target, Vector2? from, Vector2 to, TimeSpan duration, @@ -133,7 +133,7 @@ public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation( /// Creates a instance with the given parameters to on a target element. /// /// The current instance used to create the animation. - /// The target property to animate. + /// The optional target property to animate. /// The optional starting value for the animation. /// The final value for the animation. /// The animation duration. @@ -143,7 +143,7 @@ public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation( [Pure] public static Vector3KeyFrameAnimation CreateVector3KeyFrameAnimation( this Compositor compositor, - string target, + string? target, Vector3? from, Vector3 to, TimeSpan duration, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs new file mode 100644 index 00000000000..01ac07cc3ec --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// A base model representing an animation that can be used in XAML. + /// + public abstract class Animation + { + /// + /// Gets or sets the optional initial delay for the animation. + /// + public TimeSpan? Delay { get; set; } + + /// + /// Gets or sets the animation duration. + /// + public TimeSpan? Duration { get; set; } + + /// + /// Gets or sets the optional easing function type for the animation. + /// + public EasingType EasingType { get; set; } = DefaultEasingType; + + /// + /// Gets or sets the optional easing function mode for the animation. + /// + public EasingMode EasingMode { get; set; } = DefaultEasingMode; + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs index 6fa96463805..d6c95189b12 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs @@ -2,47 +2,22 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using Windows.UI.Xaml.Media.Animation; -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; - namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// /// A base model representing a typed animation that can be used in XAML. /// /// The type of values for the animation. - public abstract class TypedAnimation - where T : unmanaged + public abstract class TypedAnimation : Animation { /// /// Gets or sets the optional starting value for the animation. /// - public double? From { get; set; } + public T? From { get; set; } /// /// Gets or sets the final value for the animation. /// - public double To { get; set; } - - /// - /// Gets or sets the optional initial delay for the animation. - /// - public TimeSpan? Delay { get; set; } - - /// - /// Gets or sets the animation duration. - /// - public TimeSpan? Duration { get; set; } - - /// - /// Gets or sets the optional easing function type for the animation. - /// - public EasingType EasingType { get; set; } = DefaultEasingType; - - /// - /// Gets or sets the optional easing function mode for the animation. - /// - public EasingMode EasingMode { get; set; } = DefaultEasingMode; + public T? To { get; set; } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs new file mode 100644 index 00000000000..91dc1ab8b5b --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs @@ -0,0 +1,61 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.ObjectModel; +using System.Threading.Tasks; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// A collection of animations that can be grouped together. + /// + public sealed class AnimationCollection2 : ObservableCollection, ITimeline + { + /// + /// The reference to the parent that owns the current animation collection. + /// + private WeakReference? parent; + + /// + /// Gets or sets the parent for the current animation collection. + /// + internal UIElement? Parent + { + get + { + UIElement? element = null; + + _ = this.parent?.TryGetTarget(out element); + + return element; + } + set => parent = new(value!); + } + + /// + public void Start() + { + ((ITimeline)this).AppendToBuilder(new AnimationBuilder()).Start(Parent!); + } + + /// + public Task StartAsync() + { + return ((ITimeline)this).AppendToBuilder(new AnimationBuilder()).StartAsync(Parent!); + } + + /// + AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint) + { + foreach (ITimeline element in this) + { + builder = element.AppendToBuilder(builder, delayHint, durationHint); + } + + return builder; + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs deleted file mode 100644 index 6570a29e7a3..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using Windows.UI.Xaml.Markup; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml -{ - /// - /// A set of animations that can be grouped together. - /// - [ContentProperty(Name = nameof(Elements))] - public class AnimationSet : ITimeline - { - /// - /// Gets or sets the collection of items for the current set. - /// - public IList Elements { get; set; } = new List(); - - /// - AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint) - { - foreach (ITimeline element in Elements) - { - builder = element.AppendToBuilder(builder, delayHint, durationHint); - } - - return builder; - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/TranslationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/TranslationAnimation.cs index f8c538b9e82..4dc26f8cc9b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/TranslationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/TranslationAnimation.cs @@ -3,19 +3,15 @@ // See the LICENSE file in the project root for more information. using System; +using Microsoft.Toolkit.Uwp.UI.Extensions; namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// - /// A set of animations that can be grouped together. + /// A translation animation working on the composition or XAML layer. /// - public class TranslationAnimation : TypedAnimation, ITimeline + public class TranslationAnimation : TypedAnimation, ITimeline { - /// - /// Gets or sets the target translation axis to animate. - /// - public Axis Axis { get; set; } - /// /// Gets or sets the target framework layer to animate. /// @@ -24,7 +20,14 @@ public class TranslationAnimation : TypedAnimation, ITimeline /// AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint) { - return builder.Translation(Axis, From, To, Delay ?? delayHint, Duration ?? durationHint.GetValueOrDefault(), EasingType, EasingMode, Layer); + if (Layer == FrameworkLayer.Composition) + { + return builder.Translation(From?.ToVector3(), To!.ToVector3(), Delay ?? delayHint, Duration ?? durationHint.GetValueOrDefault(), EasingType, EasingMode); + } + else + { + return builder.Translation(From?.ToVector2(), To!.ToVector2(), Delay ?? delayHint, Duration ?? durationHint.GetValueOrDefault(), EasingType, EasingMode, FrameworkLayer.Xaml); + } } } } From 6afc1b0283af619271c109ebda6d306c05c5977a Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 18 Dec 2020 13:46:19 +0100 Subject: [PATCH 015/171] Switched AnimationCollection2 to DependencyObject --- .../Explicit.cs | 2 +- .../Xaml/AnimationCollection2.cs | 128 +++++++++++++++++- 2 files changed, 125 insertions(+), 5 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs index a6cac52c220..c2d6220500c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs @@ -2,8 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Windows.UI.Xaml; using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; +using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Animations { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs index 91dc1ab8b5b..f99e906176b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs @@ -3,7 +3,8 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.ObjectModel; +using System.Collections; +using System.Collections.Generic; using System.Threading.Tasks; using Windows.UI.Xaml; @@ -12,8 +13,28 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A collection of animations that can be grouped together. /// - public sealed class AnimationCollection2 : ObservableCollection, ITimeline + public sealed class AnimationCollection2 : DependencyObject, IList, ITimeline { + /// + /// Raised whenever the current animation is started. + /// + public event EventHandler? Started; + + /// + /// Raised whenever the current animation ends. + /// + public event EventHandler? Ended; + + /// + /// Raised whenever the current collection changes. + /// + public event EventHandler? CollectionChanged; + + /// + /// The underlying list of animations. + /// + private readonly List list = new(); + /// /// The reference to the parent that owns the current animation collection. /// @@ -35,16 +56,115 @@ internal UIElement? Parent set => parent = new(value!); } + /// + public Animation this[int index] + { + get => this.list[index]; + set + { + this.list[index] = value; + + CollectionChanged?.Invoke(this, EventArgs.Empty); + } + } + + /// + public int Count => this.list.Count; + + /// + public bool IsReadOnly => false; + + /// + public void Add(Animation item) + { + this.list.Add(item); + + CollectionChanged?.Invoke(this, EventArgs.Empty); + } + + /// + public void Clear() + { + this.list.Clear(); + + CollectionChanged?.Invoke(this, EventArgs.Empty); + } + + /// + public bool Contains(Animation item) + { + return this.list.Contains(item); + } + + /// + public void CopyTo(Animation[] array, int arrayIndex) + { + this.list.CopyTo(array, arrayIndex); + } + + /// + public IEnumerator GetEnumerator() + { + return this.list.GetEnumerator(); + } + + /// + IEnumerator IEnumerable.GetEnumerator() + { + return this.list.GetEnumerator(); + } + + /// + public int IndexOf(Animation item) + { + return this.list.IndexOf(item); + } + + /// + public void Insert(int index, Animation item) + { + this.list.Insert(index, item); + + CollectionChanged?.Invoke(this, EventArgs.Empty); + } + + /// + public bool Remove(Animation item) + { + bool removed = this.list.Remove(item); + + if (removed) + { + CollectionChanged?.Invoke(this, EventArgs.Empty); + } + + return removed; + } + + /// + public void RemoveAt(int index) + { + this.list.RemoveAt(index); + + CollectionChanged?.Invoke(this, EventArgs.Empty); + } + /// public void Start() { - ((ITimeline)this).AppendToBuilder(new AnimationBuilder()).Start(Parent!); + _ = StartAsync(); } /// public Task StartAsync() { - return ((ITimeline)this).AppendToBuilder(new AnimationBuilder()).StartAsync(Parent!); + Started?.Invoke(this, EventArgs.Empty); + + return + ((ITimeline)this) + .AppendToBuilder(new AnimationBuilder()) + .StartAsync(Parent!) + .ContinueWith(_ => Ended?.Invoke(this, EventArgs.Empty)); } /// From f8a8457fa854ee9076cc3a44c6700dceea0b22c1 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 18 Dec 2020 14:34:05 +0100 Subject: [PATCH 016/171] Added AnimationEndBehavior --- .../Xaml/AnimationCollection2.cs | 20 ++++-- .../Animations/AnimationEndBehavior.cs | 66 +++++++++++++++++++ .../Animations/StartAnimationAction.cs | 17 ++--- .../Microsoft.Toolkit.Uwp.UI.Behaviors.csproj | 3 +- 4 files changed, 90 insertions(+), 16 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs index f99e906176b..a3f31e28a07 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs @@ -157,14 +157,24 @@ public void Start() /// public Task StartAsync() + { + return StartAsync(Parent!); + } + + /// + public void Start(UIElement element) + { + _ = StartAsync(element); + } + + /// + public async Task StartAsync(UIElement element) { Started?.Invoke(this, EventArgs.Empty); - return - ((ITimeline)this) - .AppendToBuilder(new AnimationBuilder()) - .StartAsync(Parent!) - .ContinueWith(_ => Ended?.Invoke(this, EventArgs.Empty)); + await ((ITimeline)this).AppendToBuilder(new AnimationBuilder()).StartAsync(element); + + Ended?.Invoke(this, EventArgs.Empty); } /// diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs new file mode 100644 index 00000000000..1afe9f24ae1 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs @@ -0,0 +1,66 @@ +using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; +using Microsoft.Xaml.Interactivity; + +namespace Microsoft.Toolkit.Uwp.UI.Behaviors.Animations +{ + /// + /// An implementation that can trigger a target animation. + /// + public sealed class AnimationEndBehavior : Trigger + { + /// + /// The current instance in use. + /// + private AnimationCollection2? animationCollection; + + /// + protected override void OnAttached() + { + base.OnAttached(); + + SetResolvedCollection(AssociatedObject); + } + + /// + protected override void OnDetaching() + { + base.OnDetaching(); + + SetResolvedCollection(null); + } + + /// + /// Sets the current instance in use. + /// + /// The instance in use. + private void SetResolvedCollection(AnimationCollection2? animationCollection) + { + if (this.animationCollection == animationCollection) + { + return; + } + + if (this.animationCollection is not null) + { + this.animationCollection.Ended -= AnimationCollection_Ended; + } + + this.animationCollection = animationCollection; + + if (animationCollection is not null) + { + animationCollection.Ended += AnimationCollection_Ended; + } + } + + /// + /// Invokes the current actions when the linked animations complete. + /// + /// The source instance. + /// The arguments for the event (unused). + private void AnimationCollection_Ended(object sender, System.EventArgs e) + { + Interaction.ExecuteActions(sender, Actions, e); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs index bb30e53cb65..f174dd727a9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs @@ -1,5 +1,4 @@ using Microsoft.Toolkit.Diagnostics; -using Microsoft.Toolkit.Uwp.UI.Animations; using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; using Microsoft.Xaml.Interactivity; using Windows.UI.Xaml; @@ -7,16 +6,16 @@ namespace Microsoft.Toolkit.Uwp.UI.Behaviors.Animations { /// - /// An implementation that can trigger a target animation. + /// An implementation that can trigger a target instance. /// public sealed class StartAnimationAction : DependencyObject, IAction { /// - /// Gets or sets the linked animation to invoke. + /// Gets or sets the linked instance to invoke. /// - public ITimeline Animation + public AnimationCollection2 Animation { - get => (ITimeline)GetValue(AnimationProperty); + get => (AnimationCollection2)GetValue(AnimationProperty); set => SetValue(AnimationProperty, value); } @@ -25,20 +24,18 @@ public ITimeline Animation /// public static readonly DependencyProperty AnimationProperty = DependencyProperty.Register( "Animation", - typeof(ITimeline), + typeof(AnimationCollection2), typeof(StartAnimationAction), new PropertyMetadata(null)); /// public object Execute(object sender, object parameter) { - Guard.IsNotNull(sender, nameof(sender)); - Guard.IsAssignableToType(sender, nameof(sender)); Guard.IsNotNull(Animation, nameof(Animation)); - Animation.AppendToBuilder(new AnimationBuilder()).Start((UIElement)sender); + Animation.Start(); - return null; + return null!; } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Microsoft.Toolkit.Uwp.UI.Behaviors.csproj b/Microsoft.Toolkit.Uwp.UI.Behaviors/Microsoft.Toolkit.Uwp.UI.Behaviors.csproj index 045cbbc0cec..514ff0307e4 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Microsoft.Toolkit.Uwp.UI.Behaviors.csproj +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Microsoft.Toolkit.Uwp.UI.Behaviors.csproj @@ -2,7 +2,8 @@ uap10.0.17763 - 8.0 + 9.0 + enable Windows Community Toolkit UI Behaviors This library provides UI behaviors built on the XAML behaviors SDK. It is part of the Windows Community Toolkit. From a2eef1266515f993fc33fc939ed8e39eb727a81b Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 18 Dec 2020 14:37:47 +0100 Subject: [PATCH 017/171] Added AnimationStartBehavior type --- .../Animations/AnimationEndBehavior.cs | 4 +- .../Animations/AnimationStartBehavior.cs | 66 +++++++++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs index 1afe9f24ae1..807b1229c19 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs @@ -4,7 +4,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Behaviors.Animations { /// - /// An implementation that can trigger a target animation. + /// A custom that fires whenever a linked ends. /// public sealed class AnimationEndBehavior : Trigger { @@ -54,7 +54,7 @@ private void SetResolvedCollection(AnimationCollection2? animationCollection) } /// - /// Invokes the current actions when the linked animations complete. + /// Invokes the current actions when the linked animations completes. /// /// The source instance. /// The arguments for the event (unused). diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs new file mode 100644 index 00000000000..3dfdfc59926 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs @@ -0,0 +1,66 @@ +using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; +using Microsoft.Xaml.Interactivity; + +namespace Microsoft.Toolkit.Uwp.UI.Behaviors.Animations +{ + /// + /// A custom that fires whenever a linked starts. + /// + public sealed class AnimationStartBehavior : Trigger + { + /// + /// The current instance in use. + /// + private AnimationCollection2? animationCollection; + + /// + protected override void OnAttached() + { + base.OnAttached(); + + SetResolvedCollection(AssociatedObject); + } + + /// + protected override void OnDetaching() + { + base.OnDetaching(); + + SetResolvedCollection(null); + } + + /// + /// Sets the current instance in use. + /// + /// The instance in use. + private void SetResolvedCollection(AnimationCollection2? animationCollection) + { + if (this.animationCollection == animationCollection) + { + return; + } + + if (this.animationCollection is not null) + { + this.animationCollection.Started -= AnimationCollection_Started; + } + + this.animationCollection = animationCollection; + + if (animationCollection is not null) + { + animationCollection.Started += AnimationCollection_Started; + } + } + + /// + /// Invokes the current actions when the linked animations starts. + /// + /// The source instance. + /// The arguments for the event (unused). + private void AnimationCollection_Started(object sender, System.EventArgs e) + { + Interaction.ExecuteActions(sender, Actions, e); + } + } +} From 26aeba7a73a41c9f537fc02fd1c393c9ac0b41ff Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 18 Dec 2020 16:40:01 +0100 Subject: [PATCH 018/171] Added extension to attach pipeline effects to elements --- .../Brushes/PipelineBrush.cs | 4 +- .../Extensions/UIElementExtensions.cs | 51 +++++++++++++++++++ .../PipelineVisual.cs | 45 ++++++++++++++++ 3 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Extensions/UIElementExtensions.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/PipelineVisual.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/PipelineBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/PipelineBrush.cs index cf8916b7da5..acb380a580a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/PipelineBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/PipelineBrush.cs @@ -17,12 +17,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Media public sealed class PipelineBrush : XamlCompositionEffectBrushBase { /// - /// Gets or sets the source for the current pipeline (defaults to a with source). + /// Gets or sets the source for the current pipeline (defaults to a with source). /// public PipelineBuilder Source { get; set; } /// - /// Gets or sets the collection of effects to use in the current pipeline + /// Gets or sets the collection of effects to use in the current pipeline. /// public IList Effects { get; set; } = new List(); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Extensions/UIElementExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Extensions/UIElementExtensions.cs new file mode 100644 index 00000000000..d8f78c798f2 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Extensions/UIElementExtensions.cs @@ -0,0 +1,51 @@ +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Media +{ + /// + /// Attached properties to support attaching custom pipelines to UI elements. + /// + public static class UIElementExtensions + { + /// + /// Identifies the Visual XAML attached property. + /// + public static readonly DependencyProperty VisualProperty = DependencyProperty.RegisterAttached( + "Visual", + typeof(PipelineVisual), + typeof(UIElementExtensions), + new PropertyMetadata(null, OnVisualPropertyChanged)); + + /// + /// Gets the value of . + /// + /// The to get the value for. + /// The retrieved item. + public static PipelineVisual GetVisual(UIElement element) + { + return (PipelineVisual)element.GetValue(VisualProperty); + } + + /// + /// Sets the value of . + /// + /// The to set the value for. + /// The value to set. + public static void SetVisual(UIElement element, PipelineVisual value) + { + element.SetValue(VisualProperty, value); + } + + /// + /// Callback to apply the visual for . + /// + /// The target object the property was changed for. + /// The instance for the current event. + private static async void OnVisualPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var element = (UIElement)d; + + await ((PipelineVisual)e.NewValue).GetPipeline().AttachAsync(element, element); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/PipelineVisual.cs b/Microsoft.Toolkit.Uwp.UI.Media/PipelineVisual.cs new file mode 100644 index 00000000000..6a8278ff032 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/PipelineVisual.cs @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using Microsoft.Toolkit.Uwp.UI.Media.Effects; +using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Xaml.Markup; +using Windows.UI.Xaml.Media; + +namespace Microsoft.Toolkit.Uwp.UI.Media +{ + /// + /// A builder type for instance to apply to UI elements. + /// + [ContentProperty(Name = nameof(Effects))] + public sealed class PipelineVisual + { + /// + /// Gets or sets the source for the current pipeline (defaults to a with source). + /// + public PipelineBuilder Source { get; set; } + + /// + /// Gets or sets the collection of effects to use in the current pipeline. + /// + public IList Effects { get; set; } = new List(); + + /// + /// Gets the instance for the current effects tree. + /// + /// The instance for the current effects tree. + internal PipelineBuilder GetPipeline() + { + PipelineBuilder builder = Source ?? PipelineBuilder.FromBackdrop(); + + foreach (IPipelineEffect effect in Effects) + { + builder = effect.AppendToPipeline(builder); + } + + return builder; + } + } +} From 3fe603c4f93de7f5a679a15e59a3c916aef36802 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 18 Dec 2020 16:42:16 +0100 Subject: [PATCH 019/171] Minor code tweaks --- .../Brushes/AcrylicBrush.cs | 2 +- .../Brushes/BackdropBlurBrush.cs | 2 +- .../Brushes/BackdropInvertBrush.cs | 2 +- .../Brushes/BackdropSaturationBrush.cs | 2 +- .../Brushes/BackdropSepiaBrush.cs | 2 +- .../Base/XamlCompositionEffectBrushBase.cs | 47 ++++++++++--------- .../Brushes/PipelineBrush.cs | 2 +- .../Brushes/TilesBrush.cs | 2 +- .../Brushes/XamlCompositionBrush.cs | 2 +- 9 files changed, 32 insertions(+), 31 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/AcrylicBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/AcrylicBrush.cs index 30c67aa3a37..7d4df4e20a0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/AcrylicBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/AcrylicBrush.cs @@ -197,7 +197,7 @@ private static void OnTextureUriPropertyChanged(DependencyObject d, DependencyPr } /// - protected override PipelineBuilder OnBrushRequested() + protected override PipelineBuilder OnPipelineRequested() { switch (BackgroundSource) { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/BackdropBlurBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/BackdropBlurBrush.cs index 129fa289610..434eeada2b4 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/BackdropBlurBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/BackdropBlurBrush.cs @@ -54,7 +54,7 @@ private static void OnAmountChanged(DependencyObject d, DependencyPropertyChange } /// - protected override PipelineBuilder OnBrushRequested() + protected override PipelineBuilder OnPipelineRequested() { return PipelineBuilder.FromBackdrop().Blur((float)Amount, out this.amountSetter); } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/BackdropInvertBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/BackdropInvertBrush.cs index c225fa42fad..7bf161d6551 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/BackdropInvertBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/BackdropInvertBrush.cs @@ -15,7 +15,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media public class BackdropInvertBrush : XamlCompositionEffectBrushBase { /// - protected override PipelineBuilder OnBrushRequested() + protected override PipelineBuilder OnPipelineRequested() { return PipelineBuilder.FromBackdrop().Invert(); } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/BackdropSaturationBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/BackdropSaturationBrush.cs index 699ebe04849..c055b20982a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/BackdropSaturationBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/BackdropSaturationBrush.cs @@ -64,7 +64,7 @@ private static void OnSaturationChanged(DependencyObject d, DependencyPropertyCh } /// - protected override PipelineBuilder OnBrushRequested() + protected override PipelineBuilder OnPipelineRequested() { return PipelineBuilder.FromBackdrop().Saturation((float)Saturation, out setter); } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/BackdropSepiaBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/BackdropSepiaBrush.cs index 965d34de9ee..b7a36dcd514 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/BackdropSepiaBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/BackdropSepiaBrush.cs @@ -64,7 +64,7 @@ private static void OnIntensityChanged(DependencyObject d, DependencyPropertyCha } /// - protected override PipelineBuilder OnBrushRequested() + protected override PipelineBuilder OnPipelineRequested() { return PipelineBuilder.FromBackdrop().Sepia((float)Intensity, out setter); } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/XamlCompositionEffectBrushBase.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/XamlCompositionEffectBrushBase.cs index d9a4396e794..6f685735285 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/XamlCompositionEffectBrushBase.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/XamlCompositionEffectBrushBase.cs @@ -10,30 +10,31 @@ namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// A custom that's ready to be used with a custom pipeline + /// A custom that's ready to be used with a custom pipeline. /// public abstract class XamlCompositionEffectBrushBase : XamlCompositionBrushBase { /// - /// The initialization instance + /// The initialization instance. /// private readonly AsyncMutex connectedMutex = new AsyncMutex(); /// /// A method that builds and returns the pipeline to use in the current instance. - /// This method can also be used to store any needed or instances in local fields, for later use (they will need to be called upon ). + /// This method can also be used to store any needed or + /// instances in local fields, for later use (they will need to be called upon ). /// - /// A instance to create the brush to display - protected abstract PipelineBuilder OnBrushRequested(); + /// A instance to create the brush to display. + protected abstract PipelineBuilder OnPipelineRequested(); - private bool _isEnabled = true; + private bool isEnabled = true; /// - /// Gets or sets a value indicating whether the current brush is using the provided pipeline, or the fallback color + /// Gets or sets a value indicating whether the current brush is using the provided pipeline, or the fallback color. /// public bool IsEnabled { - get => this._isEnabled; + get => this.isEnabled; set => this.OnEnabledToggled(value); } @@ -42,7 +43,7 @@ protected override async void OnConnected() { using (await this.connectedMutex.LockAsync()) { - if (this.CompositionBrush == null) + if (CompositionBrush == null) { // Abort if effects aren't supported if (!CompositionCapabilities.GetForCurrentView().AreEffectsSupported()) @@ -50,13 +51,13 @@ protected override async void OnConnected() return; } - if (this._isEnabled) + if (this.isEnabled) { - this.CompositionBrush = await this.OnBrushRequested().BuildAsync(); + CompositionBrush = await OnPipelineRequested().BuildAsync(); } else { - this.CompositionBrush = await PipelineBuilder.FromColor(this.FallbackColor).BuildAsync(); + CompositionBrush = await PipelineBuilder.FromColor(FallbackColor).BuildAsync(); } } } @@ -69,10 +70,10 @@ protected override async void OnDisconnected() { using (await this.connectedMutex.LockAsync()) { - if (this.CompositionBrush != null) + if (CompositionBrush != null) { - this.CompositionBrush.Dispose(); - this.CompositionBrush = null; + CompositionBrush.Dispose(); + CompositionBrush = null; } } @@ -80,21 +81,21 @@ protected override async void OnDisconnected() } /// - /// Updates the property depending on the input value + /// Updates the property depending on the input value. /// - /// The new value being set to the property + /// The new value being set to the property. protected async void OnEnabledToggled(bool value) { using (await this.connectedMutex.LockAsync()) { - if (this._isEnabled == value) + if (this.isEnabled == value) { return; } - this._isEnabled = value; + this.isEnabled = value; - if (this.CompositionBrush != null) + if (CompositionBrush != null) { // Abort if effects aren't supported if (!CompositionCapabilities.GetForCurrentView().AreEffectsSupported()) @@ -102,13 +103,13 @@ protected async void OnEnabledToggled(bool value) return; } - if (this._isEnabled) + if (this.isEnabled) { - this.CompositionBrush = await this.OnBrushRequested().BuildAsync(); + CompositionBrush = await OnPipelineRequested().BuildAsync(); } else { - this.CompositionBrush = await PipelineBuilder.FromColor(this.FallbackColor).BuildAsync(); + CompositionBrush = await PipelineBuilder.FromColor(FallbackColor).BuildAsync(); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/PipelineBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/PipelineBrush.cs index acb380a580a..caa1460239c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/PipelineBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/PipelineBrush.cs @@ -27,7 +27,7 @@ public sealed class PipelineBrush : XamlCompositionEffectBrushBase public IList Effects { get; set; } = new List(); /// - protected override PipelineBuilder OnBrushRequested() + protected override PipelineBuilder OnPipelineRequested() { PipelineBuilder builder = Source ?? PipelineBuilder.FromBackdrop(); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/TilesBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/TilesBrush.cs index 3d75b4f3c53..50d96d3cac6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/TilesBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/TilesBrush.cs @@ -65,7 +65,7 @@ private static void OnDependencyPropertyChanged(DependencyObject d, DependencyPr } /// - protected override PipelineBuilder OnBrushRequested() + protected override PipelineBuilder OnPipelineRequested() { if (TextureUri is Uri uri) { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/XamlCompositionBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/XamlCompositionBrush.cs index 44f1b527f23..220a0261b77 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/XamlCompositionBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/XamlCompositionBrush.cs @@ -76,7 +76,7 @@ public XamlCompositionBrush Bind(EffectAnimation animation, out XamlEffect } /// - protected override PipelineBuilder OnBrushRequested() => this.Pipeline; + protected override PipelineBuilder OnPipelineRequested() => this.Pipeline; /// /// Clones the current instance by rebuilding the source . Use this method to reuse the same effects pipeline on a different From f971a94b3225fe76c68e4bba72d7c237e45a6e21 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 18 Dec 2020 17:03:00 +0100 Subject: [PATCH 020/171] Added extensibility to attached visuals --- .../Extensions/UIElementExtensions.cs | 39 +++++++++++-------- .../Pipelines/PipelineBuilder.cs | 2 +- .../Visuals/AttachedVisualFactoryBase.cs | 23 +++++++++++ .../PipelineVisualFactory.cs} | 9 ++--- .../Visuals/PipelineVisualFactoryBase.cs | 34 ++++++++++++++++ 5 files changed, 83 insertions(+), 24 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Visuals/AttachedVisualFactoryBase.cs rename Microsoft.Toolkit.Uwp.UI.Media/{PipelineVisual.cs => Visuals/PipelineVisualFactory.cs} (81%) create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Visuals/PipelineVisualFactoryBase.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Extensions/UIElementExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Extensions/UIElementExtensions.cs index d8f78c798f2..82eb8742e37 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Extensions/UIElementExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Extensions/UIElementExtensions.cs @@ -1,4 +1,6 @@ -using Windows.UI.Xaml; +using Microsoft.Toolkit.Uwp.UI.Media.Extensions; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Hosting; namespace Microsoft.Toolkit.Uwp.UI.Media { @@ -8,44 +10,47 @@ namespace Microsoft.Toolkit.Uwp.UI.Media public static class UIElementExtensions { /// - /// Identifies the Visual XAML attached property. + /// Identifies the VisualFactory XAML attached property. /// - public static readonly DependencyProperty VisualProperty = DependencyProperty.RegisterAttached( - "Visual", - typeof(PipelineVisual), + public static readonly DependencyProperty VisualFactoryProperty = DependencyProperty.RegisterAttached( + "VisualFactory", + typeof(AttachedVisualFactoryBase), typeof(UIElementExtensions), - new PropertyMetadata(null, OnVisualPropertyChanged)); + new PropertyMetadata(null, OnVisualFactoryPropertyChanged)); /// - /// Gets the value of . + /// Gets the value of . /// /// The to get the value for. - /// The retrieved item. - public static PipelineVisual GetVisual(UIElement element) + /// The retrieved item. + public static AttachedVisualFactoryBase GetVisualFactory(UIElement element) { - return (PipelineVisual)element.GetValue(VisualProperty); + return (AttachedVisualFactoryBase)element.GetValue(VisualFactoryProperty); } /// - /// Sets the value of . + /// Sets the value of . /// /// The to set the value for. - /// The value to set. - public static void SetVisual(UIElement element, PipelineVisual value) + /// The value to set. + public static void SetVisualFactory(UIElement element, AttachedVisualFactoryBase value) { - element.SetValue(VisualProperty, value); + element.SetValue(VisualFactoryProperty, value); } /// - /// Callback to apply the visual for . + /// Callback to apply the visual for . /// /// The target object the property was changed for. /// The instance for the current event. - private static async void OnVisualPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + private static async void OnVisualFactoryPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var element = (UIElement)d; + var attachedVisual = await ((AttachedVisualFactoryBase)e.NewValue).GetAttachedVisualAsync(element); - await ((PipelineVisual)e.NewValue).GetPipeline().AttachAsync(element, element); + attachedVisual.BindSize(element); + + ElementCompositionPreview.SetElementChildVisual(element, attachedVisual); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.cs index e6568aeee26..8f65d10a7f5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.cs @@ -190,7 +190,7 @@ public async Task AttachAsync(UIElement target, UIElement referenc { var visual = Window.Current.Compositor.CreateSpriteVisual(); - visual.Brush = await this.BuildAsync(); + visual.Brush = await BuildAsync(); ElementCompositionPreview.SetElementChildVisual(target, visual); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Visuals/AttachedVisualFactoryBase.cs b/Microsoft.Toolkit.Uwp.UI.Media/Visuals/AttachedVisualFactoryBase.cs new file mode 100644 index 00000000000..d6ce1661ef3 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Visuals/AttachedVisualFactoryBase.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Threading.Tasks; +using Windows.UI.Composition; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Media +{ + /// + /// A type responsible for creating instances to attach to target elements. + /// + public abstract class AttachedVisualFactoryBase + { + /// + /// Creates a to attach to the target element. + /// + /// The target the visual will be attached to. + /// A instance that the caller will attach to the target element. + public abstract ValueTask GetAttachedVisualAsync(UIElement element); + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/PipelineVisual.cs b/Microsoft.Toolkit.Uwp.UI.Media/Visuals/PipelineVisualFactory.cs similarity index 81% rename from Microsoft.Toolkit.Uwp.UI.Media/PipelineVisual.cs rename to Microsoft.Toolkit.Uwp.UI.Media/Visuals/PipelineVisualFactory.cs index 6a8278ff032..9caff911f89 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/PipelineVisual.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Visuals/PipelineVisualFactory.cs @@ -14,7 +14,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media /// A builder type for instance to apply to UI elements. /// [ContentProperty(Name = nameof(Effects))] - public sealed class PipelineVisual + public sealed class PipelineVisualFactory : PipelineVisualFactoryBase { /// /// Gets or sets the source for the current pipeline (defaults to a with source). @@ -26,11 +26,8 @@ public sealed class PipelineVisual /// public IList Effects { get; set; } = new List(); - /// - /// Gets the instance for the current effects tree. - /// - /// The instance for the current effects tree. - internal PipelineBuilder GetPipeline() + /// + protected override PipelineBuilder OnPipelineRequested() { PipelineBuilder builder = Source ?? PipelineBuilder.FromBackdrop(); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Visuals/PipelineVisualFactoryBase.cs b/Microsoft.Toolkit.Uwp.UI.Media/Visuals/PipelineVisualFactoryBase.cs new file mode 100644 index 00000000000..472167d5f63 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Visuals/PipelineVisualFactoryBase.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Threading.Tasks; +using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Hosting; + +namespace Microsoft.Toolkit.Uwp.UI.Media +{ + /// + /// A base class that extends by leveraging the APIs. + /// + public abstract class PipelineVisualFactoryBase : AttachedVisualFactoryBase + { + /// + public override async ValueTask GetAttachedVisualAsync(UIElement element) + { + var visual = ElementCompositionPreview.GetElementVisual(element).Compositor.CreateSpriteVisual(); + + visual.Brush = await OnPipelineRequested().BuildAsync(); + + return visual; + } + + /// + /// A method that builds and returns the pipeline to use in the current instance. + /// + /// A instance to create the to display. + protected abstract PipelineBuilder OnPipelineRequested(); + } +} From 5ec8ab3f735fb08bdf3d765a0a69fcdf772b0575 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 18 Dec 2020 17:39:07 +0100 Subject: [PATCH 021/171] Enabled notification for brush in use to effects --- .../Base/XamlCompositionEffectBrushBase.cs | 13 +++++ .../Brushes/PipelineBrush.cs | 9 ++++ .../Effects/BlendEffect.cs | 12 ++++- .../Effects/BlurEffect.cs | 28 ++++++++++- .../Effects/CrossFadeEffect.cs | 12 ++++- .../Effects/ExposureEffect.cs | 6 +++ .../Effects/GrayscaleEffect.cs | 6 +++ .../Effects/HueRotationEffect.cs | 6 +++ .../Effects/Interfaces/IPipelineEffect.cs | 7 +++ .../Effects/InvertEffect.cs | 6 +++ .../Effects/LuminanceToAlphaEffect.cs | 6 +++ .../Effects/OpacityEffect.cs | 6 +++ .../Effects/SaturationEffect.cs | 6 +++ .../Effects/SepiaEffect.cs | 6 +++ .../Effects/ShadeEffect.cs | 6 +++ .../Effects/TemperatureAndTintEffect.cs | 6 +++ .../Effects/TintEffect.cs | 6 +++ .../PipelineBuilder.Effects.Internals.cs | 48 +++++++++++++++++++ .../Visuals/PipelineVisualFactory.cs | 18 ++++++- 19 files changed, 209 insertions(+), 4 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.Effects.Internals.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/XamlCompositionEffectBrushBase.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/XamlCompositionEffectBrushBase.cs index 6f685735285..f92d3d16c6e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/XamlCompositionEffectBrushBase.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/XamlCompositionEffectBrushBase.cs @@ -59,6 +59,8 @@ protected override async void OnConnected() { CompositionBrush = await PipelineBuilder.FromColor(FallbackColor).BuildAsync(); } + + OnCompositionBrushUpdated(); } } @@ -74,6 +76,8 @@ protected override async void OnDisconnected() { CompositionBrush.Dispose(); CompositionBrush = null; + + OnCompositionBrushUpdated(); } } @@ -111,8 +115,17 @@ protected async void OnEnabledToggled(bool value) { CompositionBrush = await PipelineBuilder.FromColor(FallbackColor).BuildAsync(); } + + OnCompositionBrushUpdated(); } } } + + /// + /// Invoked whenever the property is updated. + /// + protected virtual void OnCompositionBrushUpdated() + { + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/PipelineBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/PipelineBrush.cs index caa1460239c..70e695c1600 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/PipelineBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/PipelineBrush.cs @@ -38,5 +38,14 @@ protected override PipelineBuilder OnPipelineRequested() return builder; } + + /// + protected override void OnCompositionBrushUpdated() + { + foreach (IPipelineEffect effect in Effects) + { + effect.NotifyCompositionBrushInUse(CompositionBrush); + } + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/BlendEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/BlendEffect.cs index ce282c29ced..5853df4cfb5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/BlendEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/BlendEffect.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using Microsoft.Graphics.Canvas.Effects; using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Composition; using Windows.UI.Xaml.Markup; namespace Microsoft.Toolkit.Uwp.UI.Media.Effects @@ -41,12 +42,21 @@ public PipelineBuilder AppendToPipeline(PipelineBuilder builder) { PipelineBuilder inputBuilder = Source ?? PipelineBuilder.FromBackdrop(); - foreach (IPipelineEffect effect in this.Effects) + foreach (IPipelineEffect effect in Effects) { inputBuilder = effect.AppendToPipeline(inputBuilder); } return builder.Blend(inputBuilder, (BlendEffectMode)Mode, Placement); } + + /// + void IPipelineEffect.NotifyCompositionBrushInUse(CompositionBrush brush) + { + foreach (IPipelineEffect effect in Effects) + { + effect.NotifyCompositionBrushInUse(brush); + } + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/BlurEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/BlurEffect.cs index b1e6c9437c2..247039bf1ca 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/BlurEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/BlurEffect.cs @@ -4,6 +4,7 @@ using System; using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Media.Effects { @@ -13,6 +14,21 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Effects /// This effect maps to the Win2D effect public sealed class BlurEffect : IPipelineEffect { + /// + /// The unique id for the effect, if is set. + /// + private string id; + + /// + /// The in use, if any. + /// + private CompositionBrush brush; + + /// + /// Gets or sets a value indicating whether the effect can be animated. + /// + public bool IsAnimatable { get; set; } + private double amount; /// @@ -27,7 +43,17 @@ public double Amount /// public PipelineBuilder AppendToPipeline(PipelineBuilder builder) { - return builder.Blur((float)Amount); + return IsAnimatable switch + { + true => builder.Blur((float)Amount, out this.id), + false => builder.Blur((float)Amount) + }; + } + + /// + void IPipelineEffect.NotifyCompositionBrushInUse(CompositionBrush brush) + { + this.brush = brush; } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/CrossFadeEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/CrossFadeEffect.cs index 8bd4d183f55..e3b0e117060 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/CrossFadeEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/CrossFadeEffect.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Composition; using Windows.UI.Xaml.Markup; namespace Microsoft.Toolkit.Uwp.UI.Media.Effects @@ -42,12 +43,21 @@ public PipelineBuilder AppendToPipeline(PipelineBuilder builder) { PipelineBuilder inputBuilder = Source ?? PipelineBuilder.FromBackdrop(); - foreach (IPipelineEffect effect in this.Effects) + foreach (IPipelineEffect effect in Effects) { inputBuilder = effect.AppendToPipeline(inputBuilder); } return builder.CrossFade(inputBuilder, (float)Factor); } + + /// + void IPipelineEffect.NotifyCompositionBrushInUse(CompositionBrush brush) + { + foreach (IPipelineEffect effect in Effects) + { + effect.NotifyCompositionBrushInUse(brush); + } + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/ExposureEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/ExposureEffect.cs index eeb6a708f8c..edd134cc7f3 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/ExposureEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/ExposureEffect.cs @@ -4,6 +4,7 @@ using System; using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Media.Effects { @@ -29,5 +30,10 @@ public PipelineBuilder AppendToPipeline(PipelineBuilder builder) { return builder.Exposure((float)Amount); } + + /// + void IPipelineEffect.NotifyCompositionBrushInUse(CompositionBrush brush) + { + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/GrayscaleEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/GrayscaleEffect.cs index 5e2070d148b..7369416e21a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/GrayscaleEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/GrayscaleEffect.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Media.Effects { @@ -17,5 +18,10 @@ public PipelineBuilder AppendToPipeline(PipelineBuilder builder) { return builder.Grayscale(); } + + /// + void IPipelineEffect.NotifyCompositionBrushInUse(CompositionBrush brush) + { + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/HueRotationEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/HueRotationEffect.cs index bf76744f3b4..f92b27ec9b5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/HueRotationEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/HueRotationEffect.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Media.Effects { @@ -22,5 +23,10 @@ public PipelineBuilder AppendToPipeline(PipelineBuilder builder) { return builder.HueRotation((float)Angle); } + + /// + void IPipelineEffect.NotifyCompositionBrushInUse(CompositionBrush brush) + { + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/Interfaces/IPipelineEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/Interfaces/IPipelineEffect.cs index 24a867442c3..5430b753371 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/Interfaces/IPipelineEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/Interfaces/IPipelineEffect.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Media.Effects { @@ -17,5 +18,11 @@ public interface IPipelineEffect /// The source instance to add the effect to. /// A new with the new effects added to it. PipelineBuilder AppendToPipeline(PipelineBuilder builder); + + /// + /// Notifies that a given is now in use. + /// + /// The in use. + internal void NotifyCompositionBrushInUse(CompositionBrush brush); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/InvertEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/InvertEffect.cs index 04c0fcd9bb8..6d8b433a4a9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/InvertEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/InvertEffect.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Media.Effects { @@ -17,5 +18,10 @@ public PipelineBuilder AppendToPipeline(PipelineBuilder builder) { return builder.Invert(); } + + /// + void IPipelineEffect.NotifyCompositionBrushInUse(CompositionBrush brush) + { + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/LuminanceToAlphaEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/LuminanceToAlphaEffect.cs index 527b55840e0..76842e9ad27 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/LuminanceToAlphaEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/LuminanceToAlphaEffect.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Media.Effects { @@ -17,5 +18,10 @@ public PipelineBuilder AppendToPipeline(PipelineBuilder builder) { return builder.LuminanceToAlpha(); } + + /// + void IPipelineEffect.NotifyCompositionBrushInUse(CompositionBrush brush) + { + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/OpacityEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/OpacityEffect.cs index 82b8ea33c56..4546aaef767 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/OpacityEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/OpacityEffect.cs @@ -4,6 +4,7 @@ using System; using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Media.Effects { @@ -29,5 +30,10 @@ public PipelineBuilder AppendToPipeline(PipelineBuilder builder) { return builder.Opacity((float)Value); } + + /// + void IPipelineEffect.NotifyCompositionBrushInUse(CompositionBrush brush) + { + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/SaturationEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/SaturationEffect.cs index cce6eee390f..8cb9291b8fe 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/SaturationEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/SaturationEffect.cs @@ -4,6 +4,7 @@ using System; using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Media.Effects { @@ -29,5 +30,10 @@ public PipelineBuilder AppendToPipeline(PipelineBuilder builder) { return builder.Saturation((float)Value); } + + /// + void IPipelineEffect.NotifyCompositionBrushInUse(CompositionBrush brush) + { + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/SepiaEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/SepiaEffect.cs index 8e3039d0980..60790a9f691 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/SepiaEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/SepiaEffect.cs @@ -4,6 +4,7 @@ using System; using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Media.Effects { @@ -29,5 +30,10 @@ public PipelineBuilder AppendToPipeline(PipelineBuilder builder) { return builder.Sepia((float)Intensity); } + + /// + void IPipelineEffect.NotifyCompositionBrushInUse(CompositionBrush brush) + { + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/ShadeEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/ShadeEffect.cs index 4b6e0debe2d..552d3b03c37 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/ShadeEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/ShadeEffect.cs @@ -5,6 +5,7 @@ using System; using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; using Windows.UI; +using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Media.Effects { @@ -34,5 +35,10 @@ public PipelineBuilder AppendToPipeline(PipelineBuilder builder) { return builder.Shade(Color, (float)Intensity); } + + /// + void IPipelineEffect.NotifyCompositionBrushInUse(CompositionBrush brush) + { + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/TemperatureAndTintEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/TemperatureAndTintEffect.cs index 2c31cbe1c65..ec68ff9d6d3 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/TemperatureAndTintEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/TemperatureAndTintEffect.cs @@ -4,6 +4,7 @@ using System; using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Media.Effects { @@ -40,5 +41,10 @@ public PipelineBuilder AppendToPipeline(PipelineBuilder builder) { return builder.TemperatureAndTint((float)Temperature, (float)Tint); } + + /// + void IPipelineEffect.NotifyCompositionBrushInUse(CompositionBrush brush) + { + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/TintEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/TintEffect.cs index 11994b21182..6438d693c43 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/TintEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/TintEffect.cs @@ -4,6 +4,7 @@ using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; using Windows.UI; +using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Media.Effects { @@ -23,5 +24,10 @@ public PipelineBuilder AppendToPipeline(PipelineBuilder builder) { return builder.Tint(Color); } + + /// + void IPipelineEffect.NotifyCompositionBrushInUse(CompositionBrush brush) + { + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.Effects.Internals.cs b/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.Effects.Internals.cs new file mode 100644 index 00000000000..aa948d4fbd0 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.Effects.Internals.cs @@ -0,0 +1,48 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Diagnostics.Contracts; +using System.Threading.Tasks; +using Microsoft.Graphics.Canvas.Effects; +using Microsoft.Toolkit.Uwp.UI.Media.Extensions; +using Windows.Graphics.Effects; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Pipelines +{ + /// + /// A that allows to build custom effects pipelines and create instances from them + /// + public sealed partial class PipelineBuilder + { + /// + /// Adds a new to the current pipeline + /// + /// The blur amount to apply + /// The assigned id for the created effect, to support animations. + /// The parameter for the effect, defaults to + /// The parameter to use, defaults to + /// A new instance to use to keep adding new effects + [Pure] + internal PipelineBuilder Blur( + float blur, + out string id, + EffectBorderMode mode = EffectBorderMode.Hard, + EffectOptimization optimization = EffectOptimization.Balanced) + { + id = Guid.NewGuid().ToUppercaseAsciiLetters(); + + async ValueTask Factory() => new GaussianBlurEffect + { + BlurAmount = blur, + BorderMode = mode, + Optimization = optimization, + Source = await this.sourceProducer() + }; + + return new PipelineBuilder(this, Factory, new[] { $"{id}.{nameof(GaussianBlurEffect.BlurAmount)}" }); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Visuals/PipelineVisualFactory.cs b/Microsoft.Toolkit.Uwp.UI.Media/Visuals/PipelineVisualFactory.cs index 9caff911f89..1788c0df71e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Visuals/PipelineVisualFactory.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Visuals/PipelineVisualFactory.cs @@ -3,15 +3,18 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Threading.Tasks; using Microsoft.Toolkit.Uwp.UI.Media.Effects; using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Composition; +using Windows.UI.Xaml; using Windows.UI.Xaml.Markup; using Windows.UI.Xaml.Media; namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// A builder type for instance to apply to UI elements. + /// A builder type for instance to apply to UI elements. /// [ContentProperty(Name = nameof(Effects))] public sealed class PipelineVisualFactory : PipelineVisualFactoryBase @@ -26,6 +29,19 @@ public sealed class PipelineVisualFactory : PipelineVisualFactoryBase /// public IList Effects { get; set; } = new List(); + /// + public override async ValueTask GetAttachedVisualAsync(UIElement element) + { + var visual = (SpriteVisual)await base.GetAttachedVisualAsync(element); + + foreach (IPipelineEffect effect in Effects) + { + effect.NotifyCompositionBrushInUse(visual.Brush); + } + + return visual; + } + /// protected override PipelineBuilder OnPipelineRequested() { From e88a6ac349c1bf520bd191e6633f344607e3d8bc Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 18 Dec 2020 19:45:01 +0100 Subject: [PATCH 022/171] Initial draft support for animating effects --- .../AnimationBuilder.Models.cs | 35 +++++++++++ .../AnimationBuilder.Setup.cs | 5 ++ .../AnimationBuilder.cs | 60 +++++++++++++++++-- .../Animations/EffectDoubleAnimation.cs | 36 +++++++++++ .../Effects/BlurEffect.cs | 4 +- .../Microsoft.Toolkit.Uwp.UI.Media.csproj | 4 ++ .../PipelineBuilder.Effects.Internals.cs | 7 ++- 7 files changed, 142 insertions(+), 9 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs index cc2f3f4db58..949e177dc86 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs @@ -15,6 +15,30 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// public sealed partial class AnimationBuilder { + /// + /// A model representing a specified composition double animation. + /// + private sealed record CompositionDoubleAnimation( + CompositionObject Target, + string Property, + float? From, + float To, + TimeSpan? Delay, + TimeSpan Duration, + EasingType EasingType, + EasingMode EasingMode) + : ICompositionAnimation + { + /// + public void StartAnimation() + { + CompositionEasingFunction easingFunction = Target.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); + ScalarKeyFrameAnimation animation = Target.Compositor.CreateScalarKeyFrameAnimation(Property, From, To, Duration, Delay, easingFunction); + + Target.StartAnimation(Property, animation); + } + } + /// /// A model representing a specified composition scalar animation. /// @@ -129,5 +153,16 @@ private interface ICompositionAnimationFactory /// A instance with the specified animation. CompositionAnimation GetAnimation(Visual visual); } + + /// + /// An interface for custom external composition animations. + /// + private interface ICompositionAnimation + { + /// + /// Starts a with some embedded parameters. + /// + void StartAnimation(); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs index d15811cf930..f0245d3cfbd 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs @@ -14,6 +14,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// public sealed partial class AnimationBuilder { + /// + /// The list of instances representing animations to run. + /// + private readonly List compositionAnimations = new(); + /// /// The list of instances representing factories for composition animations to run. /// diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs index fc6f965f062..9821a479537 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs @@ -19,6 +19,43 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// public sealed partial class AnimationBuilder { + /// + /// Adds a new custom double animation targeting an arbitrary composition object. + /// + /// The target to animate. + /// The target property to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + public AnimationBuilder DoubleAnimation( + CompositionObject target, + string property, + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + CompositionDoubleAnimation animation = new( + target, + property, + (float?)from, + (float)to, + delay, + duration, + easingType, + easingMode); + + this.compositionAnimations.Add(animation); + + return this; + } + /// /// Adds a new opacity animation to the current schedule. /// @@ -284,6 +321,14 @@ public AnimationBuilder Scale( /// The target to animate. public void Start(UIElement element) { + if (this.compositionAnimations.Count > 0) + { + foreach (var animation in this.compositionAnimations) + { + animation.StartAnimation(); + } + } + if (this.compositionAnimationFactories.Count > 0) { ElementCompositionPreview.SetIsTranslationEnabled(element, true); @@ -323,17 +368,24 @@ public Task StartAsync(UIElement element) compositionTask = Task.CompletedTask, xamlTask = Task.CompletedTask; - if (this.compositionAnimationFactories.Count > 0) + if (this.compositionAnimationFactories.Count > 0 || + this.compositionAnimations.Count > 0) { - ElementCompositionPreview.SetIsTranslationEnabled(element, true); - Visual visual = ElementCompositionPreview.GetElementVisual(element); - CompositionAnimationGroup group = visual.Compositor.CreateAnimationGroup(); CompositionScopedBatch batch = visual.Compositor.CreateScopedBatch(CompositionBatchTypes.Animation); TaskCompletionSource taskCompletionSource = new(); batch.Completed += (_, _) => taskCompletionSource.SetResult(null); + foreach (var animation in this.compositionAnimations) + { + animation.StartAnimation(); + } + + ElementCompositionPreview.SetIsTranslationEnabled(element, true); + + CompositionAnimationGroup group = visual.Compositor.CreateAnimationGroup(); + foreach (var factory in this.compositionAnimationFactories) { group.Add(factory.GetAnimation(visual)); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs new file mode 100644 index 00000000000..13655fe87fa --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.Graphics.Canvas.Effects; +using Microsoft.Toolkit.Uwp.UI.Animations; +using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; +using Microsoft.Toolkit.Uwp.UI.Media.Effects; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Animations +{ + /// + /// A set of animations that can be grouped together. + /// + public class EffectDoubleAnimation : TypedAnimation, ITimeline + { + public IPipelineEffect Target { get; set; } + + /// + AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint) + { + BlurEffect effect = (BlurEffect)Target; + + return builder.DoubleAnimation( + effect.brush, + $"{effect.id}.{nameof(GaussianBlurEffect.BlurAmount)}", + From, + To, + Delay ?? delayHint, + Duration ?? durationHint.GetValueOrDefault(), + EasingType, + EasingMode); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/BlurEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/BlurEffect.cs index 247039bf1ca..7b864291d47 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/BlurEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/BlurEffect.cs @@ -17,12 +17,12 @@ public sealed class BlurEffect : IPipelineEffect /// /// The unique id for the effect, if is set. /// - private string id; + internal string id; /// /// The in use, if any. /// - private CompositionBrush brush; + internal CompositionBrush brush; /// /// Gets or sets a value indicating whether the effect can be animated. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Microsoft.Toolkit.Uwp.UI.Media.csproj b/Microsoft.Toolkit.Uwp.UI.Media/Microsoft.Toolkit.Uwp.UI.Media.csproj index d7ba95d0111..68007be8c43 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Microsoft.Toolkit.Uwp.UI.Media.csproj +++ b/Microsoft.Toolkit.Uwp.UI.Media/Microsoft.Toolkit.Uwp.UI.Media.csproj @@ -43,4 +43,8 @@ + + + + diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.Effects.Internals.cs b/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.Effects.Internals.cs index aa948d4fbd0..3e901830224 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.Effects.Internals.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.Effects.Internals.cs @@ -32,17 +32,18 @@ internal PipelineBuilder Blur( EffectBorderMode mode = EffectBorderMode.Hard, EffectOptimization optimization = EffectOptimization.Balanced) { - id = Guid.NewGuid().ToUppercaseAsciiLetters(); + string name = id = Guid.NewGuid().ToUppercaseAsciiLetters(); async ValueTask Factory() => new GaussianBlurEffect { BlurAmount = blur, BorderMode = mode, Optimization = optimization, - Source = await this.sourceProducer() + Source = await this.sourceProducer(), + Name = name }; - return new PipelineBuilder(this, Factory, new[] { $"{id}.{nameof(GaussianBlurEffect.BlurAmount)}" }); + return new PipelineBuilder(this, Factory, new[] { $"{name}.{nameof(GaussianBlurEffect.BlurAmount)}" }); } } } From 9c0a50a7d2b1ee13c36152887323c65d547cd113 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 19 Dec 2020 00:32:11 +0100 Subject: [PATCH 023/171] Added missing file headers --- .../Animations/AnimationEndBehavior.cs | 6 +++++- .../Animations/AnimationStartBehavior.cs | 6 +++++- .../Animations/StartAnimationAction.cs | 6 +++++- .../Extensions/UIElementExtensions.cs | 6 +++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs index 807b1229c19..a041e864d9f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs @@ -1,4 +1,8 @@ -using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; using Microsoft.Xaml.Interactivity; namespace Microsoft.Toolkit.Uwp.UI.Behaviors.Animations diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs index 3dfdfc59926..1d5ab45946a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs @@ -1,4 +1,8 @@ -using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; using Microsoft.Xaml.Interactivity; namespace Microsoft.Toolkit.Uwp.UI.Behaviors.Animations diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs index f174dd727a9..41608115529 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs @@ -1,4 +1,8 @@ -using Microsoft.Toolkit.Diagnostics; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Toolkit.Diagnostics; using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; using Microsoft.Xaml.Interactivity; using Windows.UI.Xaml; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Extensions/UIElementExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Extensions/UIElementExtensions.cs index 82eb8742e37..bd0c7bc9a35 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Extensions/UIElementExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Extensions/UIElementExtensions.cs @@ -1,4 +1,8 @@ -using Microsoft.Toolkit.Uwp.UI.Media.Extensions; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Toolkit.Uwp.UI.Media.Extensions; using Windows.UI.Xaml; using Windows.UI.Xaml.Hosting; From ddb66d293bf3502a5be93d6857840e56282fe6f5 Mon Sep 17 00:00:00 2001 From: michael-hawker <24302614+michael-hawker@users.noreply.github.com> Date: Fri, 18 Dec 2020 16:19:41 -0800 Subject: [PATCH 024/171] Add new Behaviors project to Smoke Tests Also refactored list to make it easier to read. --- .../MainPage.xaml | 35 +++++++++++ .../MainPage.xaml.cs | 60 +++++++++++++++++++ .../Microsoft.Toolkit.Uwp.UI/MainPage.xaml | 30 +++------- .../Microsoft.Toolkit.Uwp.UI/MainPage.xaml.cs | 39 +----------- SmokeTests/SmokeTests.proj | 22 ++++++- 5 files changed, 127 insertions(+), 59 deletions(-) create mode 100644 SmokeTests/Microsoft.Toolkit.Uwp.UI.Behaviors/MainPage.xaml create mode 100644 SmokeTests/Microsoft.Toolkit.Uwp.UI.Behaviors/MainPage.xaml.cs diff --git a/SmokeTests/Microsoft.Toolkit.Uwp.UI.Behaviors/MainPage.xaml b/SmokeTests/Microsoft.Toolkit.Uwp.UI.Behaviors/MainPage.xaml new file mode 100644 index 00000000000..cef24c59c88 --- /dev/null +++ b/SmokeTests/Microsoft.Toolkit.Uwp.UI.Behaviors/MainPage.xaml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + diff --git a/SmokeTests/Microsoft.Toolkit.Uwp.UI.Behaviors/MainPage.xaml.cs b/SmokeTests/Microsoft.Toolkit.Uwp.UI.Behaviors/MainPage.xaml.cs new file mode 100644 index 00000000000..d1fe446c34f --- /dev/null +++ b/SmokeTests/Microsoft.Toolkit.Uwp.UI.Behaviors/MainPage.xaml.cs @@ -0,0 +1,60 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Diagnostics; +using System.Linq; +using Microsoft.Toolkit.Uwp.UI.Behaviors; +using Microsoft.Xaml.Interactivity; +using Windows.UI.Xaml.Media.Imaging; + +namespace SmokeTest +{ + public sealed partial class MainPage + { + public MainPage() + { + InitializeComponent(); + + Loaded += this.MainPage_Loaded; + } + + private void MainPage_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e) + { + var behaviors = Interaction.GetBehaviors(EffectElementHost); + var viewportBehavior = behaviors.OfType().FirstOrDefault(); + if (viewportBehavior != null) + { + viewportBehavior.EnteredViewport += EffectElementHost_EnteredViewport; + viewportBehavior.EnteringViewport += EffectElementHost_EnteringViewport; + viewportBehavior.ExitedViewport += EffectElementHost_ExitedViewport; + viewportBehavior.ExitingViewport += EffectElementHost_ExitingViewport; + } + } + + private void EffectElementHost_EnteredViewport(object sender, EventArgs e) + { + Debug.WriteLine("Entered viewport"); + } + + private void EffectElementHost_EnteringViewport(object sender, EventArgs e) + { + Debug.WriteLine("Entering viewport"); + + EffectElement.Source = new BitmapImage(new Uri("ms-appx:///Assets/ToolkitLogo.png")); + } + + private void EffectElementHost_ExitedViewport(object sender, EventArgs e) + { + Debug.WriteLine("Exited viewport"); + + EffectElement.Source = null; + } + + private void EffectElementHost_ExitingViewport(object sender, EventArgs e) + { + Debug.WriteLine("Exiting viewport"); + } + } +} diff --git a/SmokeTests/Microsoft.Toolkit.Uwp.UI/MainPage.xaml b/SmokeTests/Microsoft.Toolkit.Uwp.UI/MainPage.xaml index cef24c59c88..f6361b121cc 100644 --- a/SmokeTests/Microsoft.Toolkit.Uwp.UI/MainPage.xaml +++ b/SmokeTests/Microsoft.Toolkit.Uwp.UI/MainPage.xaml @@ -3,33 +3,19 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:SmokeTest" - xmlns:interactivity="using:Microsoft.Xaml.Interactivity" - xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors" + xmlns:extensions="using:Microsoft.Toolkit.Uwp.UI.Extensions" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> - - - - - - - - - - - + diff --git a/SmokeTests/Microsoft.Toolkit.Uwp.UI/MainPage.xaml.cs b/SmokeTests/Microsoft.Toolkit.Uwp.UI/MainPage.xaml.cs index d1fe446c34f..8acca918716 100644 --- a/SmokeTests/Microsoft.Toolkit.Uwp.UI/MainPage.xaml.cs +++ b/SmokeTests/Microsoft.Toolkit.Uwp.UI/MainPage.xaml.cs @@ -5,9 +5,8 @@ using System; using System.Diagnostics; using System.Linq; -using Microsoft.Toolkit.Uwp.UI.Behaviors; -using Microsoft.Xaml.Interactivity; -using Windows.UI.Xaml.Media.Imaging; +using Microsoft.Toolkit.Uwp.UI.Extensions; +using Windows.UI.Xaml.Controls; namespace SmokeTest { @@ -22,39 +21,7 @@ public MainPage() private void MainPage_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e) { - var behaviors = Interaction.GetBehaviors(EffectElementHost); - var viewportBehavior = behaviors.OfType().FirstOrDefault(); - if (viewportBehavior != null) - { - viewportBehavior.EnteredViewport += EffectElementHost_EnteredViewport; - viewportBehavior.EnteringViewport += EffectElementHost_EnteringViewport; - viewportBehavior.ExitedViewport += EffectElementHost_ExitedViewport; - viewportBehavior.ExitingViewport += EffectElementHost_ExitingViewport; - } - } - - private void EffectElementHost_EnteredViewport(object sender, EventArgs e) - { - Debug.WriteLine("Entered viewport"); - } - - private void EffectElementHost_EnteringViewport(object sender, EventArgs e) - { - Debug.WriteLine("Entering viewport"); - - EffectElement.Source = new BitmapImage(new Uri("ms-appx:///Assets/ToolkitLogo.png")); - } - - private void EffectElementHost_ExitedViewport(object sender, EventArgs e) - { - Debug.WriteLine("Exited viewport"); - - EffectElement.Source = null; - } - - private void EffectElementHost_ExitingViewport(object sender, EventArgs e) - { - Debug.WriteLine("Exiting viewport"); + var border = this.FindDescendant(); } } } diff --git a/SmokeTests/SmokeTests.proj b/SmokeTests/SmokeTests.proj index 18b9aee3a8b..ae2228c01c2 100644 --- a/SmokeTests/SmokeTests.proj +++ b/SmokeTests/SmokeTests.proj @@ -4,7 +4,27 @@ x86 Release - UWPBaseline;Microsoft.Toolkit;Microsoft.Toolkit.HighPerformance;Microsoft.Toolkit.Parsers;Microsoft.Toolkit.Mvvm;Microsoft.Toolkit.Services;Microsoft.Toolkit.Uwp;Microsoft.Toolkit.Uwp.Connectivity;Microsoft.Toolkit.Uwp.DeveloperTools;Microsoft.Toolkit.Uwp.Input.GazeInteraction;Microsoft.Toolkit.Uwp.Notifications;Microsoft.Toolkit.Uwp.UI;Microsoft.Toolkit.Uwp.UI.Animations;Microsoft.Toolkit.Uwp.UI.Controls;Microsoft.Toolkit.Uwp.UI.Controls.DataGrid;Microsoft.Toolkit.Uwp.UI.Controls.Layout;Microsoft.Toolkit.Uwp.UI.Media;Microsoft.Toolkit.Uwp.UI.Controls.Markdown + + UWPBaseline; + Microsoft.Toolkit; + Microsoft.Toolkit.HighPerformance; + Microsoft.Toolkit.Mvvm; + Microsoft.Toolkit.Parsers; + Microsoft.Toolkit.Services; + Microsoft.Toolkit.Uwp; + Microsoft.Toolkit.Uwp.Connectivity; + Microsoft.Toolkit.Uwp.DeveloperTools; + Microsoft.Toolkit.Uwp.Input.GazeInteraction; + Microsoft.Toolkit.Uwp.Notifications; + Microsoft.Toolkit.Uwp.UI; + Microsoft.Toolkit.Uwp.UI.Animations; + Microsoft.Toolkit.Uwp.UI.Behaviors; + Microsoft.Toolkit.Uwp.UI.Controls; + Microsoft.Toolkit.Uwp.UI.Controls.DataGrid; + Microsoft.Toolkit.Uwp.UI.Controls.Layout; + Microsoft.Toolkit.Uwp.UI.Controls.Markdown; + Microsoft.Toolkit.Uwp.UI.Media; + Date: Sat, 19 Dec 2020 13:02:29 +0100 Subject: [PATCH 025/171] Minor code tweaks --- .../AnimationBuilder.Models.cs | 18 +++++----- .../AnimationBuilder.Setup.cs | 20 +++++------ .../AnimationBuilder.cs | 34 +++++++++---------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs index 949e177dc86..10a2b876c16 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs @@ -16,7 +16,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations public sealed partial class AnimationBuilder { /// - /// A model representing a specified composition double animation. + /// A model representing a specified composition double animation for a target . /// private sealed record CompositionDoubleAnimation( CompositionObject Target, @@ -40,9 +40,9 @@ public void StartAnimation() } /// - /// A model representing a specified composition scalar animation. + /// A model representing a specified composition scalar animation factory. /// - private sealed record CompositionScalarAnimation( + private sealed record CompositionScalarAnimationFactory( string Property, float? From, float To, @@ -63,9 +63,9 @@ public CompositionAnimation GetAnimation(Visual visual) } /// - /// A model representing a specified composition animation. + /// A model representing a specified composition animation factory. /// - private sealed record CompositionVector3Animation( + private sealed record CompositionVector3AnimationFactory( string Property, Vector3? From, Vector3 To, @@ -86,9 +86,9 @@ public CompositionAnimation GetAnimation(Visual visual) } /// - /// A model representing a specified XAML animation. + /// A model representing a specified XAML animation factory. /// - private sealed record XamlDoubleAnimation( + private sealed record XamlDoubleAnimationFactory( string Property, double? From, double To, @@ -107,9 +107,9 @@ public Timeline GetAnimation(UIElement element) } /// - /// A model representing a specified XAML animation targeting a transform. + /// A model representing a specified XAML animation factory targeting a transform. /// - private sealed record XamlTransformDoubleAnimation( + private sealed record XamlTransformDoubleAnimationFactory( string Property, double? From, double To, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs index f0245d3cfbd..a7f8a2b5d83 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs @@ -40,7 +40,7 @@ public sealed partial class AnimationBuilder /// The easing function for the animation. /// The easing mode for the animation. /// The current instance. - private AnimationBuilder OnCompositionScalarAnimation( + private AnimationBuilder AddCompositionScalarAnimationFactory( string property, float? from, float to, @@ -49,7 +49,7 @@ private AnimationBuilder OnCompositionScalarAnimation( EasingType easingType, EasingMode easingMode) { - CompositionScalarAnimation animation = new(property, from, to, delay, duration, easingType, easingMode); + CompositionScalarAnimationFactory animation = new(property, from, to, delay, duration, easingType, easingMode); this.compositionAnimationFactories.Add(animation); @@ -68,7 +68,7 @@ private AnimationBuilder OnCompositionScalarAnimation( /// The easing mode for the animation. /// The current instance. /// This will use a animation with a zero Z axis. - private AnimationBuilder OnCompositionVector2Animation( + private AnimationBuilder AddCompositionVector2AnimationFactory( string property, Vector2? from, Vector2 to, @@ -79,7 +79,7 @@ private AnimationBuilder OnCompositionVector2Animation( { Vector3? from3 = from is null ? null : new(from.Value, 0); Vector3 to3 = new(to, 0); - CompositionVector3Animation animation = new(property, from3, to3, delay, duration, easingType, easingMode); + CompositionVector3AnimationFactory animation = new(property, from3, to3, delay, duration, easingType, easingMode); this.compositionAnimationFactories.Add(animation); @@ -97,7 +97,7 @@ private AnimationBuilder OnCompositionVector2Animation( /// The easing function for the animation. /// The easing mode for the animation. /// The current instance. - private AnimationBuilder OnCompositionVector3Animation( + private AnimationBuilder AddCompositionVector3AnimationFactory( string property, Vector3? from, Vector3 to, @@ -106,7 +106,7 @@ private AnimationBuilder OnCompositionVector3Animation( EasingType easingType, EasingMode easingMode) { - CompositionVector3Animation animation = new(property, from, to, delay, duration, easingType, easingMode); + CompositionVector3AnimationFactory animation = new(property, from, to, delay, duration, easingType, easingMode); this.compositionAnimationFactories.Add(animation); @@ -125,7 +125,7 @@ private AnimationBuilder OnCompositionVector3Animation( /// The easing mode for the animation. /// Whether to set . /// The current instance. - private AnimationBuilder OnXamlDoubleAnimation( + private AnimationBuilder AddXamlDoubleAnimationFactory( string property, double? from, double to, @@ -135,7 +135,7 @@ private AnimationBuilder OnXamlDoubleAnimation( EasingMode easingMode, bool enableDependentAnimation) { - XamlDoubleAnimation animation = new(property, from, to, delay, duration, easingType, easingMode, enableDependentAnimation); + XamlDoubleAnimationFactory animation = new(property, from, to, delay, duration, easingType, easingMode, enableDependentAnimation); this.xamlAnimationFactories.Add(animation); @@ -153,7 +153,7 @@ private AnimationBuilder OnXamlDoubleAnimation( /// The easing function for the animation. /// The easing mode for the animation. /// The current instance. - private AnimationBuilder OnXamlTransformDoubleAnimation( + private AnimationBuilder AddXamlTransformDoubleAnimationFactory( string property, double? from, double to, @@ -162,7 +162,7 @@ private AnimationBuilder OnXamlTransformDoubleAnimation( EasingType easingType, EasingMode easingMode) { - XamlTransformDoubleAnimation animation = new(property, from, to, delay, duration, easingType, easingMode); + XamlTransformDoubleAnimationFactory animation = new(property, from, to, delay, duration, easingType, easingMode); this.xamlAnimationFactories.Add(animation); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs index 9821a479537..4f79188cf26 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs @@ -78,11 +78,11 @@ public AnimationBuilder Opacity( { if (layer == FrameworkLayer.Composition) { - return OnCompositionScalarAnimation(nameof(Visual.Opacity), (float?)from, (float)to, delay, duration, easingType, easingMode); + return AddCompositionScalarAnimationFactory(nameof(Visual.Opacity), (float?)from, (float)to, delay, duration, easingType, easingMode); } else { - return OnXamlDoubleAnimation(nameof(UIElement.Opacity), from, to, delay, duration, easingType, easingMode, false); + return AddXamlDoubleAnimationFactory(nameof(UIElement.Opacity), from, to, delay, duration, easingType, easingMode, false); } } @@ -110,11 +110,11 @@ public AnimationBuilder Translation( { if (layer == FrameworkLayer.Composition) { - return OnCompositionScalarAnimation($"Translation.{axis}", (float?)from, (float)to, delay, duration, easingType, easingMode); + return AddCompositionScalarAnimationFactory($"Translation.{axis}", (float?)from, (float)to, delay, duration, easingType, easingMode); } else { - return OnXamlDoubleAnimation($"Translate{axis}", from, to, delay, duration, easingType, easingMode, false); + return AddXamlDoubleAnimationFactory($"Translate{axis}", from, to, delay, duration, easingType, easingMode, false); } } @@ -140,12 +140,12 @@ public AnimationBuilder Translation( { if (layer == FrameworkLayer.Composition) { - return OnCompositionVector2Animation("Translation", from, to, delay, duration, easingType, easingMode); + return AddCompositionVector2AnimationFactory("Translation", from, to, delay, duration, easingType, easingMode); } else { - OnXamlTransformDoubleAnimation(nameof(CompositeTransform.TranslateX), from?.X, to.X, delay, duration, easingType, easingMode); - OnXamlTransformDoubleAnimation(nameof(CompositeTransform.TranslateY), from?.Y, to.Y, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.TranslateX), from?.X, to.X, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.TranslateY), from?.Y, to.Y, delay, duration, easingType, easingMode); return this; } @@ -170,7 +170,7 @@ public AnimationBuilder Translation( EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - return OnCompositionVector3Animation("Translation", from, to, delay, duration, easingType, easingMode); + return AddCompositionVector3AnimationFactory("Translation", from, to, delay, duration, easingType, easingMode); } /// @@ -194,7 +194,7 @@ public AnimationBuilder Offset( EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - return OnCompositionScalarAnimation($"{nameof(Visual.Offset)}.{axis}", (float?)from, (float)to, delay, duration, easingType, easingMode); + return AddCompositionScalarAnimationFactory($"{nameof(Visual.Offset)}.{axis}", (float?)from, (float)to, delay, duration, easingType, easingMode); } /// @@ -216,7 +216,7 @@ public AnimationBuilder Offset( EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - return OnCompositionVector2Animation(nameof(Visual.Offset), from, to, delay, duration, easingType, easingMode); + return AddCompositionVector2AnimationFactory(nameof(Visual.Offset), from, to, delay, duration, easingType, easingMode); } /// @@ -238,7 +238,7 @@ public AnimationBuilder Offset( EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - return OnCompositionVector3Animation(nameof(Visual.Offset), from, to, delay, duration, easingType, easingMode); + return AddCompositionVector3AnimationFactory(nameof(Visual.Offset), from, to, delay, duration, easingType, easingMode); } /// @@ -266,12 +266,12 @@ public AnimationBuilder Scale( Vector2? from2 = from is null ? null : new((float)(double)from); Vector2 to2 = new((float)to); - return OnCompositionVector2Animation(nameof(Visual.Scale), from2, to2, delay, duration, easingType, easingMode); + return AddCompositionVector2AnimationFactory(nameof(Visual.Scale), from2, to2, delay, duration, easingType, easingMode); } else { - OnXamlTransformDoubleAnimation(nameof(CompositeTransform.ScaleX), from, to, delay, duration, easingType, easingMode); - OnXamlTransformDoubleAnimation(nameof(CompositeTransform.ScaleY), from, to, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleX), from, to, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleY), from, to, delay, duration, easingType, easingMode); return this; } @@ -304,12 +304,12 @@ public AnimationBuilder Scale( Vector2? from2 = from is null ? null : new((float)(double)from); Vector2 to2 = new((float)to); - return OnCompositionVector2Animation(nameof(Visual.Scale), from2, to2, delay, duration, easingType, easingMode); + return AddCompositionVector2AnimationFactory(nameof(Visual.Scale), from2, to2, delay, duration, easingType, easingMode); } else { - OnXamlTransformDoubleAnimation(nameof(CompositeTransform.ScaleX), from, to, delay, duration, easingType, easingMode); - OnXamlTransformDoubleAnimation(nameof(CompositeTransform.ScaleY), from, to, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleX), from, to, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleY), from, to, delay, duration, easingType, easingMode); return this; } From ce10ef3dc99644f1871cfbe6814b9861d37c9312 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 19 Dec 2020 13:06:37 +0100 Subject: [PATCH 026/171] Fixed some StyleCop warnings --- .../AnimationBuilder.cs | 2 ++ .../Extensions/CompositionObjectExtensions.cs | 2 ++ .../Extensions/CompositorExtensions.cs | 2 ++ .../Extensions/DependencyObjectExtensions.cs | 2 ++ .../Extensions/EasingTypeExtensions.cs | 2 ++ .../Extensions/StoryboardAnimations.cs | 2 ++ ...Microsoft.Toolkit.Uwp.UI.Animations.csproj | 1 - .../Xaml/Abstract/TypedAnimation{T}.cs | 2 ++ .../Xaml/AnimationCollection2.cs | 36 ++++++++++--------- .../Animations/AnimationEndBehavior.cs | 2 ++ .../Animations/AnimationStartBehavior.cs | 2 ++ .../Microsoft.Toolkit.Uwp.UI.Behaviors.csproj | 1 - 12 files changed, 37 insertions(+), 19 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs index 4f79188cf26..0014519b4b2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Numerics; using System.Threading.Tasks; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs index a90faae4361..d12081f4d9e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Numerics; using Windows.UI.Composition; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs index 6a92d382c86..c610ef4b866 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Diagnostics.Contracts; using System.Numerics; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs index 51f7ae5be96..4306f0310f7 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Diagnostics.Contracts; using Windows.UI.Xaml; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/EasingTypeExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/EasingTypeExtensions.cs index 5dff3dfe6a2..57fb05749b5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/EasingTypeExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/EasingTypeExtensions.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Diagnostics.Contracts; using Microsoft.Toolkit.Diagnostics; using Windows.UI.Xaml.Media.Animation; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/StoryboardAnimations.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/StoryboardAnimations.cs index 771fbc376d7..7e6651718f5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/StoryboardAnimations.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/StoryboardAnimations.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Threading.Tasks; using Windows.UI.Xaml.Media.Animation; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj b/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj index 57f66ccdcb9..e49f7af1cd7 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj @@ -16,7 +16,6 @@ UWP Toolkit Windows Animations Composition Connected Implicit XAML 9.0 - enable diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs index d6c95189b12..abdd6d15e1c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs index a3f31e28a07..100a7dba77f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Collections; using System.Collections.Generic; @@ -16,29 +18,29 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml public sealed class AnimationCollection2 : DependencyObject, IList, ITimeline { /// - /// Raised whenever the current animation is started. + /// The underlying list of animations. /// - public event EventHandler? Started; + private readonly List list = new(); /// - /// Raised whenever the current animation ends. + /// The reference to the parent that owns the current animation collection. /// - public event EventHandler? Ended; + private WeakReference? parent; /// - /// Raised whenever the current collection changes. + /// Raised whenever the current animation is started. /// - public event EventHandler? CollectionChanged; + public event EventHandler? Started; /// - /// The underlying list of animations. + /// Raised whenever the current animation ends. /// - private readonly List list = new(); + public event EventHandler? Ended; /// - /// The reference to the parent that owns the current animation collection. + /// Raised whenever the current collection changes. /// - private WeakReference? parent; + public event EventHandler? CollectionChanged; /// /// Gets or sets the parent for the current animation collection. @@ -53,9 +55,15 @@ internal UIElement? Parent return element; } - set => parent = new(value!); + set => this.parent = new(value!); } + /// + public int Count => this.list.Count; + + /// + public bool IsReadOnly => false; + /// public Animation this[int index] { @@ -68,12 +76,6 @@ public Animation this[int index] } } - /// - public int Count => this.list.Count; - - /// - public bool IsReadOnly => false; - /// public void Add(Animation item) { diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs index a041e864d9f..3f96634f6a4 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; using Microsoft.Xaml.Interactivity; diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs index 1d5ab45946a..fd49c019068 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; using Microsoft.Xaml.Interactivity; diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Microsoft.Toolkit.Uwp.UI.Behaviors.csproj b/Microsoft.Toolkit.Uwp.UI.Behaviors/Microsoft.Toolkit.Uwp.UI.Behaviors.csproj index 514ff0307e4..6ed65c4d436 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Microsoft.Toolkit.Uwp.UI.Behaviors.csproj +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Microsoft.Toolkit.Uwp.UI.Behaviors.csproj @@ -3,7 +3,6 @@ uap10.0.17763 9.0 - enable Windows Community Toolkit UI Behaviors This library provides UI behaviors built on the XAML behaviors SDK. It is part of the Windows Community Toolkit. From 789e26176102951355347fb0746fc33582647178 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 19 Dec 2020 13:40:23 +0100 Subject: [PATCH 027/171] Added AnimationDictionary type, code tweaks --- .../Explicit.cs | 48 +++--- .../Xaml/AnimationCollection2.cs | 113 ++----------- .../Xaml/AnimationDictionary.cs | 149 ++++++++++++++++++ 3 files changed, 189 insertions(+), 121 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationDictionary.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs index c2d6220500c..863e5c4fa2c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs @@ -13,41 +13,41 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations public static class Explicit { /// - /// Identifies the Implicit.ShowAnimations XAML attached property. + /// Identifies the property for the attached instance. /// - public static readonly DependencyProperty Animations = DependencyProperty.RegisterAttached( - "ShowAnimations", - typeof(AnimationCollection), - typeof(Implicit), - new PropertyMetadata(null, OnAnimationsChanged)); + public static readonly DependencyProperty AnimationsProperty = DependencyProperty.RegisterAttached( + "Animations", + typeof(AnimationDictionary), + typeof(Explicit), + new PropertyMetadata(null, OnAnimationsPropertyChanged)); /// - /// Gets the value of the property. + /// Gets the value of the property. /// /// The to get the value for. - /// The retrieved item. - public static AnimationCollection2 GetAnimations(UIElement element) + /// The retrieved item. + public static AnimationDictionary GetAnimations(UIElement element) { - if (element.GetValue(Animations) is AnimationCollection2 collection) + if (element.GetValue(AnimationsProperty) is AnimationDictionary collection) { return collection; } - collection = new AnimationCollection2(); + collection = new AnimationDictionary(); - element.SetValue(Animations, collection); + element.SetValue(AnimationsProperty, collection); return collection; } /// - /// Sets the value of the property. + /// Sets the value of the property. /// /// The to set the value for. - /// The value to set. - public static void SetAnimations(UIElement element, AnimationCollection2 value) + /// The value to set. + public static void SetAnimations(UIElement element, AnimationDictionary value) { - element.SetValue(Animations, value); + element.SetValue(AnimationsProperty, value); } /// @@ -55,11 +55,21 @@ public static void SetAnimations(UIElement element, AnimationCollection2 value) /// /// The target object the property was changed for. /// The instance for the current event. - private static void OnAnimationsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + private static void OnAnimationsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - if (e.NewValue is AnimationCollection2 animationCollection && d is UIElement element) + if (d is not UIElement element) { - animationCollection.Parent = element; + return; + } + + if (e.OldValue is AnimationDictionary oldDictionary) + { + oldDictionary.Parent = null; + } + + if (e.NewValue is AnimationDictionary newDictionary) + { + newDictionary.Parent = element; } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs index 100a7dba77f..0b963cbd5c9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs @@ -5,23 +5,20 @@ #nullable enable using System; -using System.Collections; using System.Collections.Generic; using System.Threading.Tasks; using Windows.UI.Xaml; +using Windows.UI.Xaml.Markup; namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// - /// A collection of animations that can be grouped together. + /// A collection of animations that can be grouped together. This type represents a composite animation + /// (such as ) that can be executed on a given element. /// - public sealed class AnimationCollection2 : DependencyObject, IList, ITimeline + [ContentProperty(Name = nameof(Animations))] + public sealed class AnimationCollection2 : DependencyObject, ITimeline { - /// - /// The underlying list of animations. - /// - private readonly List list = new(); - /// /// The reference to the parent that owns the current animation collection. /// @@ -42,6 +39,11 @@ public sealed class AnimationCollection2 : DependencyObject, IList, I /// public event EventHandler? CollectionChanged; + /// + /// Gets or sets the list of animations in the current collection. + /// + public IList Animations { get; set; } = new List(); + /// /// Gets or sets the parent for the current animation collection. /// @@ -58,99 +60,6 @@ internal UIElement? Parent set => this.parent = new(value!); } - /// - public int Count => this.list.Count; - - /// - public bool IsReadOnly => false; - - /// - public Animation this[int index] - { - get => this.list[index]; - set - { - this.list[index] = value; - - CollectionChanged?.Invoke(this, EventArgs.Empty); - } - } - - /// - public void Add(Animation item) - { - this.list.Add(item); - - CollectionChanged?.Invoke(this, EventArgs.Empty); - } - - /// - public void Clear() - { - this.list.Clear(); - - CollectionChanged?.Invoke(this, EventArgs.Empty); - } - - /// - public bool Contains(Animation item) - { - return this.list.Contains(item); - } - - /// - public void CopyTo(Animation[] array, int arrayIndex) - { - this.list.CopyTo(array, arrayIndex); - } - - /// - public IEnumerator GetEnumerator() - { - return this.list.GetEnumerator(); - } - - /// - IEnumerator IEnumerable.GetEnumerator() - { - return this.list.GetEnumerator(); - } - - /// - public int IndexOf(Animation item) - { - return this.list.IndexOf(item); - } - - /// - public void Insert(int index, Animation item) - { - this.list.Insert(index, item); - - CollectionChanged?.Invoke(this, EventArgs.Empty); - } - - /// - public bool Remove(Animation item) - { - bool removed = this.list.Remove(item); - - if (removed) - { - CollectionChanged?.Invoke(this, EventArgs.Empty); - } - - return removed; - } - - /// - public void RemoveAt(int index) - { - this.list.RemoveAt(index); - - CollectionChanged?.Invoke(this, EventArgs.Empty); - } - /// public void Start() { @@ -182,7 +91,7 @@ public async Task StartAsync(UIElement element) /// AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint) { - foreach (ITimeline element in this) + foreach (ITimeline element in Animations) { builder = element.AppendToBuilder(builder, delayHint, durationHint); } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationDictionary.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationDictionary.cs new file mode 100644 index 00000000000..48448eef17e --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationDictionary.cs @@ -0,0 +1,149 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable enable + +using System; +using System.Collections; +using System.Collections.Generic; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// A collection of animations that can be defined from XAML. + /// + public sealed class AnimationDictionary : DependencyObject, IList + { + /// + /// The underlying list of animations. + /// + private readonly List list = new(); + + /// + /// The reference to the parent that owns the current animation dictionary. + /// + private WeakReference? parent; + + /// + /// Gets or sets the parent for the current animation dictionary. + /// + internal UIElement? Parent + { + get + { + UIElement? element = null; + + _ = this.parent?.TryGetTarget(out element); + + return element; + } + set + { + this.parent = new(value!); + + foreach (var item in this.list) + { + item.Parent = value; + } + } + } + + /// + public int Count => this.list.Count; + + /// + public bool IsReadOnly => false; + + /// + public AnimationCollection2 this[int index] + { + get => this.list[index]; + set + { + this.list[index].Parent = null; + this.list[index] = value; + + value.Parent = Parent; + } + } + + /// + public void Add(AnimationCollection2 item) + { + this.list.Add(item); + + item.Parent = Parent; + } + + /// + public void Clear() + { + foreach (var item in this.list) + { + item.Parent = null; + } + + this.list.Clear(); + } + + /// + public bool Contains(AnimationCollection2 item) + { + return this.list.Contains(item); + } + + /// + public void CopyTo(AnimationCollection2[] array, int arrayIndex) + { + this.list.CopyTo(array, arrayIndex); + } + + /// + public IEnumerator GetEnumerator() + { + return this.list.GetEnumerator(); + } + + /// + IEnumerator IEnumerable.GetEnumerator() + { + return this.list.GetEnumerator(); + } + + /// + public int IndexOf(AnimationCollection2 item) + { + return this.list.IndexOf(item); + } + + /// + public void Insert(int index, AnimationCollection2 item) + { + this.list.Insert(index, item); + + item.Parent = Parent; + } + + /// + public bool Remove(AnimationCollection2 item) + { + bool removed = this.list.Remove(item); + + if (removed) + { + item.Parent = null; + } + + return removed; + } + + /// + public void RemoveAt(int index) + { + this.list[index].Parent = null; + this.list.RemoveAt(index); + } + } +} From 65c2c584c6933d9672797b04b704650295ce6f34 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 19 Dec 2020 13:48:16 +0100 Subject: [PATCH 028/171] Optimized reuse of weak parent references --- .../Xaml/AnimationCollection2.cs | 33 +++++-------------- .../Xaml/AnimationDictionary.cs | 28 ++++++---------- 2 files changed, 19 insertions(+), 42 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs index 0b963cbd5c9..9bd5fc7badf 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using Microsoft.Toolkit.Diagnostics; using Windows.UI.Xaml; using Windows.UI.Xaml.Markup; @@ -19,11 +20,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml [ContentProperty(Name = nameof(Animations))] public sealed class AnimationCollection2 : DependencyObject, ITimeline { - /// - /// The reference to the parent that owns the current animation collection. - /// - private WeakReference? parent; - /// /// Raised whenever the current animation is started. /// @@ -34,31 +30,15 @@ public sealed class AnimationCollection2 : DependencyObject, ITimeline /// public event EventHandler? Ended; - /// - /// Raised whenever the current collection changes. - /// - public event EventHandler? CollectionChanged; - /// /// Gets or sets the list of animations in the current collection. /// public IList Animations { get; set; } = new List(); /// - /// Gets or sets the parent for the current animation collection. + /// Gets or sets the weak reference to the parent that owns the current animation collection. /// - internal UIElement? Parent - { - get - { - UIElement? element = null; - - _ = this.parent?.TryGetTarget(out element); - - return element; - } - set => this.parent = new(value!); - } + internal WeakReference? ParentReference { get; set; } /// public void Start() @@ -69,7 +49,12 @@ public void Start() /// public Task StartAsync() { - return StartAsync(Parent!); + if (!ParentReference.TryGetTarget(out UIElement? parent)) + { + ThrowHelper.ThrowInvalidOperationException("The current animation collection isn't bound to a parent UIElement instance."); + } + + return StartAsync(parent); } /// diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationDictionary.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationDictionary.cs index 48448eef17e..58135c86021 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationDictionary.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationDictionary.cs @@ -27,25 +27,17 @@ public sealed class AnimationDictionary : DependencyObject, IList? parent; /// - /// Gets or sets the parent for the current animation dictionary. + /// Sets the parent for the current animation dictionary. /// internal UIElement? Parent { - get - { - UIElement? element = null; - - _ = this.parent?.TryGetTarget(out element); - - return element; - } set { - this.parent = new(value!); + WeakReference parent = this.parent = new(value!); foreach (var item in this.list) { - item.Parent = value; + item.ParentReference = parent; } } } @@ -62,10 +54,10 @@ public AnimationCollection2 this[int index] get => this.list[index]; set { - this.list[index].Parent = null; + this.list[index].ParentReference = null; this.list[index] = value; - value.Parent = Parent; + value.ParentReference = this.parent; } } @@ -74,7 +66,7 @@ public void Add(AnimationCollection2 item) { this.list.Add(item); - item.Parent = Parent; + item.ParentReference = this.parent; } /// @@ -82,7 +74,7 @@ public void Clear() { foreach (var item in this.list) { - item.Parent = null; + item.ParentReference = this.parent; } this.list.Clear(); @@ -123,7 +115,7 @@ public void Insert(int index, AnimationCollection2 item) { this.list.Insert(index, item); - item.Parent = Parent; + item.ParentReference = this.parent; } /// @@ -133,7 +125,7 @@ public bool Remove(AnimationCollection2 item) if (removed) { - item.Parent = null; + item.ParentReference = null; } return removed; @@ -142,7 +134,7 @@ public bool Remove(AnimationCollection2 item) /// public void RemoveAt(int index) { - this.list[index].Parent = null; + this.list[index].ParentReference = null; this.list.RemoveAt(index); } } From b30190ed9bf95e1c029ee031fbb72a951acacf8d Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 19 Dec 2020 14:34:27 +0100 Subject: [PATCH 029/171] Ported remaining animation types --- .../AnimationBuilder.Models.cs | 24 ++ .../AnimationBuilder.cs | 222 +++++++++++++++++- 2 files changed, 241 insertions(+), 5 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs index 10a2b876c16..0d1e6af48b3 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs @@ -85,6 +85,30 @@ public CompositionAnimation GetAnimation(Visual visual) } } + /// + /// A model representing a specified composition scalar animation factory targeting a clip. + /// + private sealed record CompositionClipScalarAnimation( + string Property, + float? From, + float To, + TimeSpan? Delay, + TimeSpan Duration, + EasingType EasingType, + EasingMode EasingMode) + : ICompositionAnimationFactory + { + /// + public CompositionAnimation GetAnimation(Visual visual) + { + InsetClip clip = visual.Clip as InsetClip ?? (InsetClip)(visual.Clip = visual.Compositor.CreateInsetClip()); + CompositionEasingFunction easingFunction = clip.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); + ScalarKeyFrameAnimation animation = visual.Compositor.CreateScalarKeyFrameAnimation(Property, From, To, Duration, Delay, easingFunction); + + return animation; + } + } + /// /// A model representing a specified XAML animation factory. /// diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs index 0014519b4b2..d6e6e36993e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs @@ -7,6 +7,7 @@ using System; using System.Numerics; using System.Threading.Tasks; +using Microsoft.Toolkit.Diagnostics; using Windows.UI.Composition; using Windows.UI.Xaml; using Windows.UI.Xaml.Hosting; @@ -289,9 +290,164 @@ public AnimationBuilder Scale( /// The animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the XAML layer. + public AnimationBuilder Scale( + Axis axis, + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + return AddXamlTransformDoubleAnimationFactory($"Scale{axis}", from, to, delay, duration, easingType, easingMode); + } + + /// + /// Adds a new scale animation for the X and Y axes to the current schedule. + /// + /// The optional starting point for the animation. + /// The final point for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. /// The target framework layer to animate. /// The current instance. public AnimationBuilder Scale( + Vector2? from, + Vector2 to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return AddCompositionVector2AnimationFactory(nameof(Visual.Scale), from, to, delay, duration, easingType, easingMode); + } + else + { + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleX), from?.X, to.X, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleY), from?.Y, to.Y, delay, duration, easingType, easingMode); + + return this; + } + } + + /// + /// Adds a new scale animation for all axes to the current schedule. + /// + /// The optional starting point for the animation. + /// The final point for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder Scale( + Vector3? from, + Vector3 to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + return AddCompositionVector3AnimationFactory(nameof(Visual.Scale), from, to, delay, duration, easingType, easingMode); + } + + /// + /// Adds a new rotation animation to the current schedule. + /// + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder Rotate( + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return AddCompositionScalarAnimationFactory(nameof(Visual.RotationAngleInDegrees), (float?)from, (float)to, delay, duration, easingType, easingMode); + } + else + { + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.Rotation), from, to, delay, duration, easingType, easingMode); + + return this; + } + } + + /// + /// Adds a new clip animation to the current schedule. + /// + /// The clip size to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder Clip( + Side side, + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + string property = side switch + { + Side.Top => nameof(InsetClip.TopInset), + Side.Bottom => nameof(InsetClip.BottomInset), + Side.Right => nameof(InsetClip.RightInset), + Side.Left => nameof(InsetClip.LeftInset), + _ => ThrowHelper.ThrowArgumentException("Invalid clip size") + }; + + CompositionClipScalarAnimation animation = new( + property, + (float?)from, + (float)to, + delay, + duration, + easingType, + easingMode); + + this.compositionAnimationFactories.Add(animation); + + return this; + } + + /// + /// Adds a new size animation for a single axis to the current schedule. + /// + /// The target size axis to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder Size( Axis axis, double? from, double to, @@ -303,20 +459,76 @@ public AnimationBuilder Scale( { if (layer == FrameworkLayer.Composition) { - Vector2? from2 = from is null ? null : new((float)(double)from); - Vector2 to2 = new((float)to); + return AddCompositionScalarAnimationFactory($"{nameof(Visual.Size)}.{axis}", (float?)from, (float)to, delay, duration, easingType, easingMode); + } + else + { + string property = axis switch + { + Axis.X => nameof(FrameworkElement.Width), + Axis.Y => nameof(FrameworkElement.Height), + _ => ThrowHelper.ThrowArgumentException("Invalid size axis") + }; - return AddCompositionVector2AnimationFactory(nameof(Visual.Scale), from2, to2, delay, duration, easingType, easingMode); + return AddXamlDoubleAnimationFactory(property, from, to, delay, duration, easingType, easingMode, true); + } + } + + /// + /// Adds a new size animation for the X and Y axes to the current schedule. + /// + /// The optional starting point for the animation. + /// The final point for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder Size( + Vector2? from, + Vector2 to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return AddCompositionVector2AnimationFactory(nameof(Visual.Size), from, to, delay, duration, easingType, easingMode); } else { - AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleX), from, to, delay, duration, easingType, easingMode); - AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleY), from, to, delay, duration, easingType, easingMode); + AddXamlDoubleAnimationFactory(nameof(FrameworkElement.Width), from?.X, to.X, delay, duration, easingType, easingMode, true); + AddXamlDoubleAnimationFactory(nameof(FrameworkElement.Height), from?.Y, to.Y, delay, duration, easingType, easingMode, true); return this; } } + /// + /// Adds a new composition size translation animation for all axes to the current schedule. + /// + /// The optional starting point for the animation. + /// The final point for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder Size( + Vector3? from, + Vector3 to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + return AddCompositionVector3AnimationFactory(nameof(Visual.Size), from, to, delay, duration, easingType, easingMode); + } + /// /// Starts the animations present in the current instance. /// From 4fdcae713fba90a4710b244bbb12fb4a9500bdfe Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 19 Dec 2020 14:38:28 +0100 Subject: [PATCH 030/171] Added RotateInDegrees builder API --- .../AnimationBuilder.cs | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs index d6e6e36993e..6de23016d20 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs @@ -378,6 +378,41 @@ public AnimationBuilder Rotate( EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode, FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return AddCompositionScalarAnimationFactory(nameof(Visual.RotationAngle), (float?)from, (float)to, delay, duration, easingType, easingMode); + } + else + { + double? fromDegrees = from * Math.PI / 180; + double toDegrees = to * Math.PI / 180; + + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.Rotation), fromDegrees, toDegrees, delay, duration, easingType, easingMode); + + return this; + } + } + + /// + /// Adds a new rotation animation in degrees to the current schedule. + /// + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder RotateInDegrees( + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) { if (layer == FrameworkLayer.Composition) { From df597c475c291bf7bffcd2cf211854010b4a817c Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 19 Dec 2020 16:48:04 +0100 Subject: [PATCH 031/171] Code refactoring --- .../AnimationBuilder.Default.cs | 526 ++++++++++++++++++ .../AnimationBuilder.cs | 508 ----------------- 2 files changed, 526 insertions(+), 508 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Default.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Default.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Default.cs new file mode 100644 index 00000000000..c2cee2cfb53 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Default.cs @@ -0,0 +1,526 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable enable + +using System; +using System.Numerics; +using Microsoft.Toolkit.Diagnostics; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + public sealed partial class AnimationBuilder + { + /// + /// Adds a new opacity animation to the current schedule. + /// + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder Opacity( + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return AddCompositionScalarAnimationFactory(nameof(Visual.Opacity), (float?)from, (float)to, delay, duration, easingType, easingMode); + } + else + { + return AddXamlDoubleAnimationFactory(nameof(UIElement.Opacity), from, to, delay, duration, easingType, easingMode, false); + } + } + + /// + /// Adds a new translation animation for a single axis to the current schedule. + /// + /// The target translation axis to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder Translation( + Axis axis, + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return AddCompositionScalarAnimationFactory($"Translation.{axis}", (float?)from, (float)to, delay, duration, easingType, easingMode); + } + else + { + return AddXamlDoubleAnimationFactory($"Translate{axis}", from, to, delay, duration, easingType, easingMode, false); + } + } + + /// + /// Adds a new translation animation for the X and Y axes to the current schedule. + /// + /// The optional starting point for the animation. + /// The final point for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder Translation( + Vector2? from, + Vector2 to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return AddCompositionVector2AnimationFactory("Translation", from, to, delay, duration, easingType, easingMode); + } + else + { + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.TranslateX), from?.X, to.X, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.TranslateY), from?.Y, to.Y, delay, duration, easingType, easingMode); + + return this; + } + } + + /// + /// Adds a new composition translation animation for all axes to the current schedule. + /// + /// The optional starting point for the animation. + /// The final point for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder Translation( + Vector3? from, + Vector3 to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + return AddCompositionVector3AnimationFactory("Translation", from, to, delay, duration, easingType, easingMode); + } + + /// + /// Adds a new composition offset animation for a single axis to the current schedule. + /// + /// The target translation axis to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder Offset( + Axis axis, + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + return AddCompositionScalarAnimationFactory($"{nameof(Visual.Offset)}.{axis}", (float?)from, (float)to, delay, duration, easingType, easingMode); + } + + /// + /// Adds a new composition offset animation for the X and Y axes to the current schedule. + /// + /// The optional starting point for the animation. + /// The final point for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder Offset( + Vector2? from, + Vector2 to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + return AddCompositionVector2AnimationFactory(nameof(Visual.Offset), from, to, delay, duration, easingType, easingMode); + } + + /// + /// Adds a new composition offset translation animation for all axes to the current schedule. + /// + /// The optional starting point for the animation. + /// The final point for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder Offset( + Vector3? from, + Vector3 to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + return AddCompositionVector3AnimationFactory(nameof(Visual.Offset), from, to, delay, duration, easingType, easingMode); + } + + /// + /// Adds a new uniform scale animation on the X and Y axes to the current schedule. + /// + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder Scale( + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + Vector2? from2 = from is null ? null : new((float)(double)from); + Vector2 to2 = new((float)to); + + return AddCompositionVector2AnimationFactory(nameof(Visual.Scale), from2, to2, delay, duration, easingType, easingMode); + } + else + { + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleX), from, to, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleY), from, to, delay, duration, easingType, easingMode); + + return this; + } + } + + /// + /// Adds a new scale animation on a specified axis to the current schedule. + /// + /// The target scale axis to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the XAML layer. + public AnimationBuilder Scale( + Axis axis, + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + return AddXamlTransformDoubleAnimationFactory($"Scale{axis}", from, to, delay, duration, easingType, easingMode); + } + + /// + /// Adds a new scale animation for the X and Y axes to the current schedule. + /// + /// The optional starting point for the animation. + /// The final point for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder Scale( + Vector2? from, + Vector2 to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return AddCompositionVector2AnimationFactory(nameof(Visual.Scale), from, to, delay, duration, easingType, easingMode); + } + else + { + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleX), from?.X, to.X, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleY), from?.Y, to.Y, delay, duration, easingType, easingMode); + + return this; + } + } + + /// + /// Adds a new scale animation for all axes to the current schedule. + /// + /// The optional starting point for the animation. + /// The final point for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder Scale( + Vector3? from, + Vector3 to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + return AddCompositionVector3AnimationFactory(nameof(Visual.Scale), from, to, delay, duration, easingType, easingMode); + } + + /// + /// Adds a new rotation animation to the current schedule. + /// + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder Rotate( + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return AddCompositionScalarAnimationFactory(nameof(Visual.RotationAngle), (float?)from, (float)to, delay, duration, easingType, easingMode); + } + else + { + double? fromDegrees = from * Math.PI / 180; + double toDegrees = to * Math.PI / 180; + + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.Rotation), fromDegrees, toDegrees, delay, duration, easingType, easingMode); + + return this; + } + } + + /// + /// Adds a new rotation animation in degrees to the current schedule. + /// + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder RotateInDegrees( + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return AddCompositionScalarAnimationFactory(nameof(Visual.RotationAngleInDegrees), (float?)from, (float)to, delay, duration, easingType, easingMode); + } + else + { + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.Rotation), from, to, delay, duration, easingType, easingMode); + + return this; + } + } + + /// + /// Adds a new clip animation to the current schedule. + /// + /// The clip size to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder Clip( + Side side, + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + string property = side switch + { + Side.Top => nameof(InsetClip.TopInset), + Side.Bottom => nameof(InsetClip.BottomInset), + Side.Right => nameof(InsetClip.RightInset), + Side.Left => nameof(InsetClip.LeftInset), + _ => ThrowHelper.ThrowArgumentException("Invalid clip size") + }; + + CompositionClipScalarAnimation animation = new( + property, + (float?)from, + (float)to, + delay, + duration, + easingType, + easingMode); + + this.compositionAnimationFactories.Add(animation); + + return this; + } + + /// + /// Adds a new size animation for a single axis to the current schedule. + /// + /// The target size axis to animate. + /// The optional starting value for the animation. + /// The final value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder Size( + Axis axis, + double? from, + double to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return AddCompositionScalarAnimationFactory($"{nameof(Visual.Size)}.{axis}", (float?)from, (float)to, delay, duration, easingType, easingMode); + } + else + { + string property = axis switch + { + Axis.X => nameof(FrameworkElement.Width), + Axis.Y => nameof(FrameworkElement.Height), + _ => ThrowHelper.ThrowArgumentException("Invalid size axis") + }; + + return AddXamlDoubleAnimationFactory(property, from, to, delay, duration, easingType, easingMode, true); + } + } + + /// + /// Adds a new size animation for the X and Y axes to the current schedule. + /// + /// The optional starting point for the animation. + /// The final point for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder Size( + Vector2? from, + Vector2 to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return AddCompositionVector2AnimationFactory(nameof(Visual.Size), from, to, delay, duration, easingType, easingMode); + } + else + { + AddXamlDoubleAnimationFactory(nameof(FrameworkElement.Width), from?.X, to.X, delay, duration, easingType, easingMode, true); + AddXamlDoubleAnimationFactory(nameof(FrameworkElement.Height), from?.Y, to.Y, delay, duration, easingType, easingMode, true); + + return this; + } + } + + /// + /// Adds a new composition size translation animation for all axes to the current schedule. + /// + /// The optional starting point for the animation. + /// The final point for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder Size( + Vector3? from, + Vector3 to, + TimeSpan? delay, + TimeSpan duration, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + return AddCompositionVector3AnimationFactory(nameof(Visual.Size), from, to, delay, duration, easingType, easingMode); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs index 6de23016d20..ac574228674 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs @@ -5,13 +5,10 @@ #nullable enable using System; -using System.Numerics; using System.Threading.Tasks; -using Microsoft.Toolkit.Diagnostics; using Windows.UI.Composition; using Windows.UI.Xaml; using Windows.UI.Xaml.Hosting; -using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -59,511 +56,6 @@ public AnimationBuilder DoubleAnimation( return this; } - /// - /// Adds a new opacity animation to the current schedule. - /// - /// The optional starting value for the animation. - /// The final value for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function type for the animation. - /// The optional easing function mode for the animation. - /// The target framework layer to animate. - /// The current instance. - public AnimationBuilder Opacity( - double? from, - double to, - TimeSpan? delay, - TimeSpan duration, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode, - FrameworkLayer layer = FrameworkLayer.Composition) - { - if (layer == FrameworkLayer.Composition) - { - return AddCompositionScalarAnimationFactory(nameof(Visual.Opacity), (float?)from, (float)to, delay, duration, easingType, easingMode); - } - else - { - return AddXamlDoubleAnimationFactory(nameof(UIElement.Opacity), from, to, delay, duration, easingType, easingMode, false); - } - } - - /// - /// Adds a new translation animation for a single axis to the current schedule. - /// - /// The target translation axis to animate. - /// The optional starting value for the animation. - /// The final value for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function type for the animation. - /// The optional easing function mode for the animation. - /// The target framework layer to animate. - /// The current instance. - public AnimationBuilder Translation( - Axis axis, - double? from, - double to, - TimeSpan? delay, - TimeSpan duration, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode, - FrameworkLayer layer = FrameworkLayer.Composition) - { - if (layer == FrameworkLayer.Composition) - { - return AddCompositionScalarAnimationFactory($"Translation.{axis}", (float?)from, (float)to, delay, duration, easingType, easingMode); - } - else - { - return AddXamlDoubleAnimationFactory($"Translate{axis}", from, to, delay, duration, easingType, easingMode, false); - } - } - - /// - /// Adds a new translation animation for the X and Y axes to the current schedule. - /// - /// The optional starting point for the animation. - /// The final point for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function type for the animation. - /// The optional easing function mode for the animation. - /// The target framework layer to animate. - /// The current instance. - public AnimationBuilder Translation( - Vector2? from, - Vector2 to, - TimeSpan? delay, - TimeSpan duration, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode, - FrameworkLayer layer = FrameworkLayer.Composition) - { - if (layer == FrameworkLayer.Composition) - { - return AddCompositionVector2AnimationFactory("Translation", from, to, delay, duration, easingType, easingMode); - } - else - { - AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.TranslateX), from?.X, to.X, delay, duration, easingType, easingMode); - AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.TranslateY), from?.Y, to.Y, delay, duration, easingType, easingMode); - - return this; - } - } - - /// - /// Adds a new composition translation animation for all axes to the current schedule. - /// - /// The optional starting point for the animation. - /// The final point for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function type for the animation. - /// The optional easing function mode for the animation. - /// The current instance. - /// This animation is only available on the composition layer. - public AnimationBuilder Translation( - Vector3? from, - Vector3 to, - TimeSpan? delay, - TimeSpan duration, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode) - { - return AddCompositionVector3AnimationFactory("Translation", from, to, delay, duration, easingType, easingMode); - } - - /// - /// Adds a new composition offset animation for a single axis to the current schedule. - /// - /// The target translation axis to animate. - /// The optional starting value for the animation. - /// The final value for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function type for the animation. - /// The optional easing function mode for the animation. - /// The current instance. - /// This animation is only available on the composition layer. - public AnimationBuilder Offset( - Axis axis, - double? from, - double to, - TimeSpan? delay, - TimeSpan duration, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode) - { - return AddCompositionScalarAnimationFactory($"{nameof(Visual.Offset)}.{axis}", (float?)from, (float)to, delay, duration, easingType, easingMode); - } - - /// - /// Adds a new composition offset animation for the X and Y axes to the current schedule. - /// - /// The optional starting point for the animation. - /// The final point for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function type for the animation. - /// The optional easing function mode for the animation. - /// The current instance. - /// This animation is only available on the composition layer. - public AnimationBuilder Offset( - Vector2? from, - Vector2 to, - TimeSpan? delay, - TimeSpan duration, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode) - { - return AddCompositionVector2AnimationFactory(nameof(Visual.Offset), from, to, delay, duration, easingType, easingMode); - } - - /// - /// Adds a new composition offset translation animation for all axes to the current schedule. - /// - /// The optional starting point for the animation. - /// The final point for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function type for the animation. - /// The optional easing function mode for the animation. - /// The current instance. - /// This animation is only available on the composition layer. - public AnimationBuilder Offset( - Vector3? from, - Vector3 to, - TimeSpan? delay, - TimeSpan duration, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode) - { - return AddCompositionVector3AnimationFactory(nameof(Visual.Offset), from, to, delay, duration, easingType, easingMode); - } - - /// - /// Adds a new uniform scale animation on the X and Y axes to the current schedule. - /// - /// The optional starting value for the animation. - /// The final value for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function type for the animation. - /// The optional easing function mode for the animation. - /// The target framework layer to animate. - /// The current instance. - public AnimationBuilder Scale( - double? from, - double to, - TimeSpan? delay, - TimeSpan duration, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode, - FrameworkLayer layer = FrameworkLayer.Composition) - { - if (layer == FrameworkLayer.Composition) - { - Vector2? from2 = from is null ? null : new((float)(double)from); - Vector2 to2 = new((float)to); - - return AddCompositionVector2AnimationFactory(nameof(Visual.Scale), from2, to2, delay, duration, easingType, easingMode); - } - else - { - AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleX), from, to, delay, duration, easingType, easingMode); - AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleY), from, to, delay, duration, easingType, easingMode); - - return this; - } - } - - /// - /// Adds a new scale animation on a specified axis to the current schedule. - /// - /// The target scale axis to animate. - /// The optional starting value for the animation. - /// The final value for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function type for the animation. - /// The optional easing function mode for the animation. - /// The current instance. - /// This animation is only available on the XAML layer. - public AnimationBuilder Scale( - Axis axis, - double? from, - double to, - TimeSpan? delay, - TimeSpan duration, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode) - { - return AddXamlTransformDoubleAnimationFactory($"Scale{axis}", from, to, delay, duration, easingType, easingMode); - } - - /// - /// Adds a new scale animation for the X and Y axes to the current schedule. - /// - /// The optional starting point for the animation. - /// The final point for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function type for the animation. - /// The optional easing function mode for the animation. - /// The target framework layer to animate. - /// The current instance. - public AnimationBuilder Scale( - Vector2? from, - Vector2 to, - TimeSpan? delay, - TimeSpan duration, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode, - FrameworkLayer layer = FrameworkLayer.Composition) - { - if (layer == FrameworkLayer.Composition) - { - return AddCompositionVector2AnimationFactory(nameof(Visual.Scale), from, to, delay, duration, easingType, easingMode); - } - else - { - AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleX), from?.X, to.X, delay, duration, easingType, easingMode); - AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleY), from?.Y, to.Y, delay, duration, easingType, easingMode); - - return this; - } - } - - /// - /// Adds a new scale animation for all axes to the current schedule. - /// - /// The optional starting point for the animation. - /// The final point for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function type for the animation. - /// The optional easing function mode for the animation. - /// The current instance. - /// This animation is only available on the composition layer. - public AnimationBuilder Scale( - Vector3? from, - Vector3 to, - TimeSpan? delay, - TimeSpan duration, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode) - { - return AddCompositionVector3AnimationFactory(nameof(Visual.Scale), from, to, delay, duration, easingType, easingMode); - } - - /// - /// Adds a new rotation animation to the current schedule. - /// - /// The optional starting value for the animation. - /// The final value for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function type for the animation. - /// The optional easing function mode for the animation. - /// The target framework layer to animate. - /// The current instance. - public AnimationBuilder Rotate( - double? from, - double to, - TimeSpan? delay, - TimeSpan duration, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode, - FrameworkLayer layer = FrameworkLayer.Composition) - { - if (layer == FrameworkLayer.Composition) - { - return AddCompositionScalarAnimationFactory(nameof(Visual.RotationAngle), (float?)from, (float)to, delay, duration, easingType, easingMode); - } - else - { - double? fromDegrees = from * Math.PI / 180; - double toDegrees = to * Math.PI / 180; - - AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.Rotation), fromDegrees, toDegrees, delay, duration, easingType, easingMode); - - return this; - } - } - - /// - /// Adds a new rotation animation in degrees to the current schedule. - /// - /// The optional starting value for the animation. - /// The final value for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function type for the animation. - /// The optional easing function mode for the animation. - /// The target framework layer to animate. - /// The current instance. - public AnimationBuilder RotateInDegrees( - double? from, - double to, - TimeSpan? delay, - TimeSpan duration, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode, - FrameworkLayer layer = FrameworkLayer.Composition) - { - if (layer == FrameworkLayer.Composition) - { - return AddCompositionScalarAnimationFactory(nameof(Visual.RotationAngleInDegrees), (float?)from, (float)to, delay, duration, easingType, easingMode); - } - else - { - AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.Rotation), from, to, delay, duration, easingType, easingMode); - - return this; - } - } - - /// - /// Adds a new clip animation to the current schedule. - /// - /// The clip size to animate. - /// The optional starting value for the animation. - /// The final value for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function type for the animation. - /// The optional easing function mode for the animation. - /// The current instance. - /// This animation is only available on the composition layer. - public AnimationBuilder Clip( - Side side, - double? from, - double to, - TimeSpan? delay, - TimeSpan duration, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode) - { - string property = side switch - { - Side.Top => nameof(InsetClip.TopInset), - Side.Bottom => nameof(InsetClip.BottomInset), - Side.Right => nameof(InsetClip.RightInset), - Side.Left => nameof(InsetClip.LeftInset), - _ => ThrowHelper.ThrowArgumentException("Invalid clip size") - }; - - CompositionClipScalarAnimation animation = new( - property, - (float?)from, - (float)to, - delay, - duration, - easingType, - easingMode); - - this.compositionAnimationFactories.Add(animation); - - return this; - } - - /// - /// Adds a new size animation for a single axis to the current schedule. - /// - /// The target size axis to animate. - /// The optional starting value for the animation. - /// The final value for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function type for the animation. - /// The optional easing function mode for the animation. - /// The target framework layer to animate. - /// The current instance. - public AnimationBuilder Size( - Axis axis, - double? from, - double to, - TimeSpan? delay, - TimeSpan duration, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode, - FrameworkLayer layer = FrameworkLayer.Composition) - { - if (layer == FrameworkLayer.Composition) - { - return AddCompositionScalarAnimationFactory($"{nameof(Visual.Size)}.{axis}", (float?)from, (float)to, delay, duration, easingType, easingMode); - } - else - { - string property = axis switch - { - Axis.X => nameof(FrameworkElement.Width), - Axis.Y => nameof(FrameworkElement.Height), - _ => ThrowHelper.ThrowArgumentException("Invalid size axis") - }; - - return AddXamlDoubleAnimationFactory(property, from, to, delay, duration, easingType, easingMode, true); - } - } - - /// - /// Adds a new size animation for the X and Y axes to the current schedule. - /// - /// The optional starting point for the animation. - /// The final point for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function type for the animation. - /// The optional easing function mode for the animation. - /// The target framework layer to animate. - /// The current instance. - public AnimationBuilder Size( - Vector2? from, - Vector2 to, - TimeSpan? delay, - TimeSpan duration, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode, - FrameworkLayer layer = FrameworkLayer.Composition) - { - if (layer == FrameworkLayer.Composition) - { - return AddCompositionVector2AnimationFactory(nameof(Visual.Size), from, to, delay, duration, easingType, easingMode); - } - else - { - AddXamlDoubleAnimationFactory(nameof(FrameworkElement.Width), from?.X, to.X, delay, duration, easingType, easingMode, true); - AddXamlDoubleAnimationFactory(nameof(FrameworkElement.Height), from?.Y, to.Y, delay, duration, easingType, easingMode, true); - - return this; - } - } - - /// - /// Adds a new composition size translation animation for all axes to the current schedule. - /// - /// The optional starting point for the animation. - /// The final point for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function type for the animation. - /// The optional easing function mode for the animation. - /// The current instance. - /// This animation is only available on the composition layer. - public AnimationBuilder Size( - Vector3? from, - Vector3 to, - TimeSpan? delay, - TimeSpan duration, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode) - { - return AddCompositionVector3AnimationFactory(nameof(Visual.Size), from, to, delay, duration, easingType, easingMode); - } - /// /// Starts the animations present in the current instance. /// From 0db9c1399f7daf3d29cf90702f4f88a3835fc635 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 19 Dec 2020 16:57:44 +0100 Subject: [PATCH 032/171] Added AnimationBuilder.New() and XML docs --- .../AnimationBuilder.cs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs index ac574228674..b0e7f2a109a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs @@ -5,6 +5,7 @@ #nullable enable using System; +using System.Diagnostics.Contracts; using System.Threading.Tasks; using Windows.UI.Composition; using Windows.UI.Xaml; @@ -19,6 +20,36 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// public sealed partial class AnimationBuilder { + /// + /// + /// A static constructor for the type. + /// This can be used as the entry point to construct a custom animation sequence. + /// + /// For instance: + /// + /// AnimationBuilder.New()
+ /// .Opacity(from: 0, to: 1, duration: 400)
+ /// .Translation(Axis.X, from: -40, to: 0, duration: 400)
+ /// .Start(MyButton); + ///
+ /// + /// Configured instances are also reusable, meaning that the same + /// one can be used to start an animation sequence on multiple elements as well. + /// + /// For instance: + /// + /// var animation = AnimationBuilder.New().Opacity(0, 1, duration: 400).Size(1.2, 1, duration: 400);
+ ///
+ /// animation.Start(MyButton);
+ /// animation.Start(MyGrid); + ///
+ /// Alternatively, the type can be used to configure animations directly + /// from XAML. The same APIs will still be used behind the scenes to handle animations. + ///
+ /// An empty instance to use to construct an animation sequence. + [Pure] + public static AnimationBuilder New() => new(); + /// /// Adds a new custom double animation targeting an arbitrary composition object. /// From a881c9fdf2bac1ba064c7b2d9b8bb0c024426b71 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 19 Dec 2020 17:32:19 +0100 Subject: [PATCH 033/171] Minor code tweaks --- .../Xaml/AnimationCollection2.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs index 9bd5fc7badf..695c18ae10c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs @@ -49,12 +49,14 @@ public void Start() /// public Task StartAsync() { - if (!ParentReference.TryGetTarget(out UIElement? parent)) + UIElement? parent = null; + + if (ParentReference?.TryGetTarget(out parent) != true) { ThrowHelper.ThrowInvalidOperationException("The current animation collection isn't bound to a parent UIElement instance."); } - return StartAsync(parent); + return StartAsync(parent!); } /// From 867354b0704abc6fd499e72b8d80ff4c11231471 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 19 Dec 2020 18:15:49 +0100 Subject: [PATCH 034/171] Added AnimationScope type, inherited easing type/mode --- .../Xaml/Abstract/Animation.cs | 5 +-- .../Xaml/AnimationCollection2.cs | 20 ++++------ .../Xaml/AnimationScope.cs | 37 +++++++++++++++++++ .../Xaml/{ => Default}/OpacityAnimation.cs | 14 ++++++- .../{ => Default}/TranslationAnimation.cs | 14 +++++-- .../Xaml/Interfaces/ITimeline.cs | 10 ++++- .../Animations/EffectDoubleAnimation.cs | 8 ++-- 7 files changed, 84 insertions(+), 24 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs rename Microsoft.Toolkit.Uwp.UI.Animations/Xaml/{ => Default}/OpacityAnimation.cs (50%) rename Microsoft.Toolkit.Uwp.UI.Animations/Xaml/{ => Default}/TranslationAnimation.cs (55%) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs index 01ac07cc3ec..2c572c5e2f9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs @@ -4,7 +4,6 @@ using System; using Windows.UI.Xaml.Media.Animation; -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { @@ -26,11 +25,11 @@ public abstract class Animation /// /// Gets or sets the optional easing function type for the animation. /// - public EasingType EasingType { get; set; } = DefaultEasingType; + public EasingType? EasingType { get; set; } /// /// Gets or sets the optional easing function mode for the animation. /// - public EasingMode EasingMode { get; set; } = DefaultEasingMode; + public EasingMode? EasingMode { get; set; } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs index 695c18ae10c..7c93b238586 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs @@ -18,7 +18,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// (such as ) that can be executed on a given element. ///
[ContentProperty(Name = nameof(Animations))] - public sealed class AnimationCollection2 : DependencyObject, ITimeline + public sealed class AnimationCollection2 : DependencyObject { /// /// Raised whenever the current animation is started. @@ -33,7 +33,7 @@ public sealed class AnimationCollection2 : DependencyObject, ITimeline /// /// Gets or sets the list of animations in the current collection. /// - public IList Animations { get; set; } = new List(); + public IList Animations { get; set; } = new List(); /// /// Gets or sets the weak reference to the parent that owns the current animation collection. @@ -70,20 +70,16 @@ public async Task StartAsync(UIElement element) { Started?.Invoke(this, EventArgs.Empty); - await ((ITimeline)this).AppendToBuilder(new AnimationBuilder()).StartAsync(element); + var builder = AnimationBuilder.New(); - Ended?.Invoke(this, EventArgs.Empty); - } - - /// - AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint) - { - foreach (ITimeline element in Animations) + foreach (ITimeline animation in Animations) { - builder = element.AppendToBuilder(builder, delayHint, durationHint); + builder = animation.AppendToBuilder(builder); } - return builder; + await builder.StartAsync(element); + + Ended?.Invoke(this, EventArgs.Empty); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs new file mode 100644 index 00000000000..31dc2ba0aaf --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable enable + +using System; +using System.Collections.Generic; +using Windows.UI.Xaml.Markup; +using Windows.UI.Xaml.Media.Animation; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// A container of elements that can be used to conceptually group animations + /// together and to assign shared properties to be applied to all the contained items automatically. + /// + [ContentProperty(Name = nameof(Animations))] + public sealed class AnimationScope : Animation, ITimeline + { + /// + /// Gets or sets the list of animations in the current scope. + /// + public IList Animations { get; set; } = new List(); + + /// + AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + { + foreach (ITimeline element in Animations) + { + builder = element.AppendToBuilder(builder, Delay ?? delayHint, Duration ?? durationHint, EasingType ?? easingTypeHint, EasingMode ?? easingModeHint); + } + + return builder; + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/OpacityAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs similarity index 50% rename from Microsoft.Toolkit.Uwp.UI.Animations/Xaml/OpacityAnimation.cs rename to Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs index 1c00f55bcab..69360dea80b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/OpacityAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs @@ -3,11 +3,14 @@ // See the LICENSE file in the project root for more information. using System; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// /// A set of animations that can be grouped together. + /// This animation maps to . /// public class OpacityAnimation : TypedAnimation, ITimeline { @@ -17,9 +20,16 @@ public class OpacityAnimation : TypedAnimation, ITimeline public FrameworkLayer Layer { get; set; } /// - AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint) + AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { - return builder.Opacity(From, To, Delay ?? delayHint, Duration ?? durationHint.GetValueOrDefault(), EasingType, EasingMode, Layer); + return builder.Opacity( + From, + To, + Delay ?? delayHint, + Duration ?? durationHint.GetValueOrDefault(), + EasingType ?? easingTypeHint ?? DefaultEasingType, + EasingMode ?? easingModeHint ?? DefaultEasingMode, + Layer); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/TranslationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs similarity index 55% rename from Microsoft.Toolkit.Uwp.UI.Animations/Xaml/TranslationAnimation.cs rename to Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs index 4dc26f8cc9b..996701e2a61 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/TranslationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs @@ -4,11 +4,14 @@ using System; using Microsoft.Toolkit.Uwp.UI.Extensions; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// /// A translation animation working on the composition or XAML layer. + /// This animation maps to . /// public class TranslationAnimation : TypedAnimation, ITimeline { @@ -18,15 +21,20 @@ public class TranslationAnimation : TypedAnimation, ITimeline public FrameworkLayer Layer { get; set; } /// - AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint) + AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { + TimeSpan? delay = Delay ?? delayHint; + TimeSpan duration = Duration ?? durationHint.GetValueOrDefault(); + EasingType easingType = EasingType ?? easingTypeHint ?? DefaultEasingType; + EasingMode easingMode = EasingMode ?? easingModeHint ?? DefaultEasingMode; + if (Layer == FrameworkLayer.Composition) { - return builder.Translation(From?.ToVector3(), To!.ToVector3(), Delay ?? delayHint, Duration ?? durationHint.GetValueOrDefault(), EasingType, EasingMode); + return builder.Translation(From?.ToVector3(), To!.ToVector3(), delay, duration, easingType, easingMode); } else { - return builder.Translation(From?.ToVector2(), To!.ToVector2(), Delay ?? delayHint, Duration ?? durationHint.GetValueOrDefault(), EasingType, EasingMode, FrameworkLayer.Xaml); + return builder.Translation(From?.ToVector2(), To!.ToVector2(), delay, duration, easingType, easingMode, FrameworkLayer.Xaml); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITimeline.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITimeline.cs index 23e5c5094de..24d15209d0f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITimeline.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITimeline.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using Windows.UI.Xaml.Media.Animation; namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { @@ -17,7 +18,14 @@ public interface ITimeline /// The target instance to schedule the animation on. /// A hint for the animation delay, if present. /// A hint for the animation duration, if present. + /// A hint for the easing type, if present. + /// A hint for the easing mode, if present. /// The same instance as . - AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint = null, TimeSpan? durationHint = null); + AnimationBuilder AppendToBuilder( + AnimationBuilder builder, + TimeSpan? delayHint = null, + TimeSpan? durationHint = null, + EasingType? easingTypeHint = null, + EasingMode? easingModeHint = null); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs index 13655fe87fa..a686e1173b6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs @@ -7,6 +7,8 @@ using Microsoft.Toolkit.Uwp.UI.Animations; using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; using Microsoft.Toolkit.Uwp.UI.Media.Effects; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Media.Animations { @@ -18,7 +20,7 @@ public class EffectDoubleAnimation : TypedAnimation, ITimeline public IPipelineEffect Target { get; set; } /// - AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint) + AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { BlurEffect effect = (BlurEffect)Target; @@ -29,8 +31,8 @@ AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? d To, Delay ?? delayHint, Duration ?? durationHint.GetValueOrDefault(), - EasingType, - EasingMode); + EasingType ?? easingTypeHint ?? DefaultEasingType, + EasingMode ?? easingModeHint ?? DefaultEasingMode); } } } From 738f2b68e7ceafce45e9929839b55661c404c0f5 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 19 Dec 2020 18:46:01 +0100 Subject: [PATCH 035/171] Added ScaleAnimation type --- .../Xaml/Default/OpacityAnimation.cs | 2 +- .../Xaml/Default/ScaleAnimation.cs | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs index 69360dea80b..9c5b4669840 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs @@ -9,7 +9,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// - /// A set of animations that can be grouped together. + /// An opacity animation working on the composition or XAML layer. /// This animation maps to . /// public class OpacityAnimation : TypedAnimation, ITimeline diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs new file mode 100644 index 00000000000..0e4b2fe41dc --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.Toolkit.Uwp.UI.Extensions; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// A scale animation working on the composition or XAML layer. + /// This animation maps to . + /// + public class ScaleAnimation : TypedAnimation, ITimeline + { + /// + /// Gets or sets the target framework layer to animate. + /// + public FrameworkLayer Layer { get; set; } + + /// + AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + { + TimeSpan? delay = Delay ?? delayHint; + TimeSpan duration = Duration ?? durationHint.GetValueOrDefault(); + EasingType easingType = EasingType ?? easingTypeHint ?? DefaultEasingType; + EasingMode easingMode = EasingMode ?? easingModeHint ?? DefaultEasingMode; + + if (Layer == FrameworkLayer.Composition) + { + return builder.Scale(From?.ToVector3(), To!.ToVector3(), delay, duration, easingType, easingMode); + } + else + { + return builder.Scale(From?.ToVector2(), To!.ToVector2(), delay, duration, easingType, easingMode, FrameworkLayer.Xaml); + } + } + } +} From 79a2ae436a9d4ec4cddc449ea4c7a2e52c170d52 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 19 Dec 2020 18:48:56 +0100 Subject: [PATCH 036/171] Fixed AnimationCollection2 exceptions being unobserved --- .../Xaml/AnimationCollection2.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs index 7c93b238586..fd7841b7f1f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs @@ -41,9 +41,14 @@ public sealed class AnimationCollection2 : DependencyObject internal WeakReference? ParentReference { get; set; } /// - public void Start() + public async void Start() { - _ = StartAsync(); + // Here we're using an async void method on purpose, in order to be able to await + // the completion of the animation and rethrow exceptions. We can't just use the + // synchronous AnimationBuilder.Start method here, as we also need to await for the + // animation to complete in either case in order to raise the Ended event when that + // happens. So we add an async state machine here to work around this. + await StartAsync(); } /// @@ -60,9 +65,9 @@ public Task StartAsync() } /// - public void Start(UIElement element) + public async void Start(UIElement element) { - _ = StartAsync(element); + await StartAsync(element); } /// From 9b2d3f6d7a30f92dcc93d9d7e4a9be697b5ccc87 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 20 Dec 2020 00:12:31 +0100 Subject: [PATCH 037/171] Minor code refactoring --- .../{ => Builders}/AnimationBuilder.Default.cs | 0 .../{ => Builders}/AnimationBuilder.Models.cs | 0 .../{ => Builders}/AnimationBuilder.Setup.cs | 0 .../{ => Builders}/AnimationBuilder.cs | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename Microsoft.Toolkit.Uwp.UI.Animations/{ => Builders}/AnimationBuilder.Default.cs (100%) rename Microsoft.Toolkit.Uwp.UI.Animations/{ => Builders}/AnimationBuilder.Models.cs (100%) rename Microsoft.Toolkit.Uwp.UI.Animations/{ => Builders}/AnimationBuilder.Setup.cs (100%) rename Microsoft.Toolkit.Uwp.UI.Animations/{ => Builders}/AnimationBuilder.cs (100%) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Default.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs similarity index 100% rename from Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Default.cs rename to Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs similarity index 100% rename from Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Models.cs rename to Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs similarity index 100% rename from Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.Setup.cs rename to Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs similarity index 100% rename from Microsoft.Toolkit.Uwp.UI.Animations/AnimationBuilder.cs rename to Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs From 50b0c218c08598769f5e9d71d068af50687b807d Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 20 Dec 2020 00:13:15 +0100 Subject: [PATCH 038/171] Added NormalizedKeyFrameAnimationBuilder types --- .../Builders/AnimationBuilder.Models.cs | 6 +- .../INormalizedKeyFrameAnimationBuilder{T}.cs | 31 ++++ ...KeyFrameAnimationBuilder{T}.Composition.cs | 151 ++++++++++++++++++ ...malizedKeyFrameAnimationBuilder{T}.Xaml.cs | 101 ++++++++++++ .../NormalizedKeyFrameAnimationBuilder{T}.cs | 122 ++++++++++++++ ...Microsoft.Toolkit.Uwp.UI.Animations.csproj | 1 + 6 files changed, 409 insertions(+), 3 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/INormalizedKeyFrameAnimationBuilder{T}.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs index 0d1e6af48b3..e4cf322ae69 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs @@ -155,7 +155,7 @@ public Timeline GetAnimation(UIElement element) /// /// An interface for factories of XAML animations. /// - private interface IXamlAnimationFactory + internal interface IXamlAnimationFactory { /// /// Gets a instance representing the animation to start. @@ -168,7 +168,7 @@ private interface IXamlAnimationFactory /// /// An interface for factories of composition animations. /// - private interface ICompositionAnimationFactory + internal interface ICompositionAnimationFactory { /// /// Gets a instance representing the animation to start. @@ -181,7 +181,7 @@ private interface ICompositionAnimationFactory /// /// An interface for custom external composition animations. /// - private interface ICompositionAnimation + internal interface ICompositionAnimation { /// /// Starts a with some embedded parameters. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/INormalizedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/INormalizedKeyFrameAnimationBuilder{T}.cs new file mode 100644 index 00000000000..39ec594fa92 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/INormalizedKeyFrameAnimationBuilder{T}.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// An interface for an animation builder using normalized keyframes. + /// + /// The type of values being set by the animation being constructed. + public interface INormalizedKeyFrameAnimationBuilder + where T : unmanaged + { + /// + /// Adds a new normalized keyframe to the builder in use. + /// + /// The normalized progress for the keyframe (must be in the [0, 1] range). + /// The value for the new keyframe to add. + /// The easing type to use to reach the new keyframe. + /// The easing mode to use to reach the new keyframe. + /// The same instance that the method was invoked upon. + public INormalizedKeyFrameAnimationBuilder KeyFrame( + double progress, + T value, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode); + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs new file mode 100644 index 00000000000..bcaa4163831 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs @@ -0,0 +1,151 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Numerics; +using Microsoft.Toolkit.Diagnostics; +using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; +using Windows.UI; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + internal abstract partial class NormalizedKeyFrameAnimationBuilder + { + /// + /// A custom class targeting the composition layer. + /// + public sealed class Composition : NormalizedKeyFrameAnimationBuilder, AnimationBuilder.ICompositionAnimationFactory + { + /// + /// Initializes a new instance of the class. + /// + /// + public Composition(string property, TimeSpan? delay, TimeSpan? duration) + : base(property, delay, duration) + { + } + + /// + public unsafe CompositionAnimation GetAnimation(Visual visual) + { + KeyFrameAnimation animation; + + if (typeof(T) == typeof(bool)) + { + BooleanKeyFrameAnimation boolAnimation = visual.Compositor.CreateBooleanKeyFrameAnimation(); + + foreach (var keyFrame in this.keyFrames) + { + boolAnimation.InsertKeyFrame( + (float)keyFrame.Progress, + *(bool*)&keyFrame.Value); + } + + animation = boolAnimation; + } + else if (typeof(T) == typeof(float)) + { + ScalarKeyFrameAnimation scalarAnimation = visual.Compositor.CreateScalarKeyFrameAnimation(); + + foreach (var keyFrame in this.keyFrames) + { + scalarAnimation.InsertKeyFrame( + (float)keyFrame.Progress, + *(float*)&keyFrame.Value, + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + } + + animation = scalarAnimation; + } + else if (typeof(T) == typeof(Vector2)) + { + Vector2KeyFrameAnimation vector2Animation = visual.Compositor.CreateVector2KeyFrameAnimation(); + + foreach (var keyFrame in this.keyFrames) + { + vector2Animation.InsertKeyFrame( + (float)keyFrame.Progress, + *(Vector2*)&keyFrame.Value, + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + } + + animation = vector2Animation; + } + else if (typeof(T) == typeof(Vector3)) + { + Vector3KeyFrameAnimation vector3Animation = visual.Compositor.CreateVector3KeyFrameAnimation(); + + foreach (var keyFrame in this.keyFrames) + { + vector3Animation.InsertKeyFrame( + (float)keyFrame.Progress, + *(Vector3*)&keyFrame.Value, + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + } + + animation = vector3Animation; + } + else if (typeof(T) == typeof(Vector4)) + { + Vector4KeyFrameAnimation vector4Animation = visual.Compositor.CreateVector4KeyFrameAnimation(); + + foreach (var keyFrame in this.keyFrames) + { + vector4Animation.InsertKeyFrame( + (float)keyFrame.Progress, + *(Vector4*)&keyFrame.Value, + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + } + + animation = vector4Animation; + } + else if (typeof(T) == typeof(Color)) + { + ColorKeyFrameAnimation colorAnimation = visual.Compositor.CreateColorKeyFrameAnimation(); + + foreach (var keyFrame in this.keyFrames) + { + colorAnimation.InsertKeyFrame( + (float)keyFrame.Progress, + *(Color*)&keyFrame.Value, + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + } + + animation = colorAnimation; + } + else if (typeof(T) == typeof(Quaternion)) + { + QuaternionKeyFrameAnimation quaternionAnimation = visual.Compositor.CreateQuaternionKeyFrameAnimation(); + + foreach (var keyFrame in this.keyFrames) + { + quaternionAnimation.InsertKeyFrame( + (float)keyFrame.Progress, + *(Quaternion*)&keyFrame.Value, + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + } + + animation = quaternionAnimation; + } + else + { + return ThrowHelper.ThrowInvalidOperationException("Invalid animation type"); + } + + animation.Duration = this.duration.GetValueOrDefault(); + + if (this.delay.HasValue) + { + animation.DelayTime = this.delay!.Value; + } + + animation.Target = this.property; + + return animation; + } + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs new file mode 100644 index 00000000000..6198dc543af --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -0,0 +1,101 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.Toolkit.Diagnostics; +using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; +using Windows.Foundation; +using Windows.UI; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Media.Animation; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + internal abstract partial class NormalizedKeyFrameAnimationBuilder : INormalizedKeyFrameAnimationBuilder + where T : unmanaged + { + /// + /// A custom class targeting the XAML layer. + /// + public sealed class Xaml : NormalizedKeyFrameAnimationBuilder, AnimationBuilder.IXamlAnimationFactory + { + /// + /// Initializes a new instance of the class. + /// + /// + public Xaml(string property, TimeSpan? delay, TimeSpan? duration) + : base(property, delay, duration) + { + } + + /// + public unsafe Timeline GetAnimation(UIElement element) + { + Timeline animation; + + if (typeof(T) == typeof(double)) + { + DoubleAnimationUsingKeyFrames doubleAnimation = new() { EnableDependentAnimation = true }; + + foreach (var keyFrame in this.keyFrames) + { + doubleAnimation.KeyFrames.Add(new EasingDoubleKeyFrame() + { + KeyTime = keyFrame.GetKeyTime(this.duration.GetValueOrDefault()), + Value = *(double*)&keyFrame.Value, + EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) + }); + } + + animation = doubleAnimation; + } + else if (typeof(T) == typeof(Point)) + { + PointAnimationUsingKeyFrames pointAnimation = new() { EnableDependentAnimation = true }; + + foreach (var keyFrame in this.keyFrames) + { + pointAnimation.KeyFrames.Add(new EasingPointKeyFrame() + { + KeyTime = keyFrame.GetKeyTime(this.duration.GetValueOrDefault()), + Value = *(Point*)&keyFrame.Value, + EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) + }); + } + + animation = pointAnimation; + } + else if (typeof(T) == typeof(Color)) + { + ColorAnimationUsingKeyFrames colorAnimation = new() { EnableDependentAnimation = true }; + + foreach (var keyFrame in this.keyFrames) + { + colorAnimation.KeyFrames.Add(new EasingColorKeyFrame() + { + KeyTime = keyFrame.GetKeyTime(this.duration.GetValueOrDefault()), + Value = *(Color*)&keyFrame.Value, + EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) + }); + } + + animation = colorAnimation; + } + else + { + return ThrowHelper.ThrowInvalidOperationException("Invalid animation type"); + } + + animation.BeginTime = this.delay; + animation.Duration = this.duration.GetValueOrDefault(); + + Storyboard.SetTarget(animation, element); + Storyboard.SetTargetProperty(animation, this.property); + + return animation; + } + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs new file mode 100644 index 00000000000..fb2b98f43c3 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs @@ -0,0 +1,122 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// A generic keyframe animation builder. + /// + /// The type of values being set by the animation being constructed. + internal abstract partial class NormalizedKeyFrameAnimationBuilder : INormalizedKeyFrameAnimationBuilder + where T : unmanaged + { + /// + /// The target property to animate. + /// + private readonly string property; + + /// + /// The target delay for the animation, if any. + /// + private readonly TimeSpan? delay; + + /// + /// The target duration for the animation. + /// + private readonly TimeSpan? duration; + + /// + /// The list of keyframes to use. + /// + private readonly List keyFrames = new(); + + /// + /// Initializes a new instance of the class. + /// + /// The target property to animate. + /// The target delay for the animation, if any. + /// The target duration for the animation. + protected NormalizedKeyFrameAnimationBuilder(string property, TimeSpan? delay, TimeSpan? duration) + { + this.property = property; + this.delay = delay; + this.duration = duration; + } + + /// + public INormalizedKeyFrameAnimationBuilder KeyFrame( + double progress, + T value, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + this.keyFrames.Add(new(progress, value, easingType, easingMode)); + + return this; + } + + /// + /// The abstracted info for a normalized animation keyframe. + /// + protected readonly struct KeyFrameInfo + { + /// + /// Initializes a new instance of the struct. + /// + /// The normalized progress for the keyframe. + /// The value for the new keyframe to add. + /// The easing type to use to reach the new keyframe. + /// The easing mode to use to reach the new keyframe. + public KeyFrameInfo( + double progress, + T value, + EasingType easingType, + EasingMode easingMode) + { + Progress = progress; + Value = value; + EasingType = easingType; + EasingMode = easingMode; + } + + /// + /// The normalized progress for the keyframe. + /// + public readonly double Progress; + + /// + /// The value for the new keyframe to add. + /// + public readonly T Value; + + /// + /// The easing type to use to reach the new keyframe. + /// + public readonly EasingType EasingType; + + /// + /// The easing mode to use to reach the new keyframe. + /// + public readonly EasingMode EasingMode; + + /// + /// Gets a for the current instance, relative to a value. + /// + /// The target value to use. + /// A normalized value relative to . + public KeyTime GetKeyTime(TimeSpan duration) + { + long ticks = duration.Ticks; + TimeSpan step = TimeSpan.FromTicks((long)(ticks * Progress)); + + return KeyTime.FromTimeSpan(step); + } + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj b/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj index e49f7af1cd7..f385ff525c9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj @@ -16,6 +16,7 @@ UWP Toolkit Windows Animations Composition Connected Implicit XAML 9.0 + true From 87ce48358150df70a3401b64bc931d42e53d1676 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 20 Dec 2020 00:44:30 +0100 Subject: [PATCH 039/171] Added AnimationBuilder.NormalizedKeyFrames --- .../Builders/AnimationBuilder.Custom.cs | 53 +++++++++++++++++++ ...KeyFrameAnimationBuilder{T}.Composition.cs | 4 +- ...malizedKeyFrameAnimationBuilder{T}.Xaml.cs | 10 ++-- .../NormalizedKeyFrameAnimationBuilder{T}.cs | 6 +-- .../Extensions/AnimationExtensions.cs | 6 +++ 5 files changed, 69 insertions(+), 10 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Custom.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Custom.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Custom.cs new file mode 100644 index 00000000000..e73ff159d47 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Custom.cs @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable enable + +using System; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + public sealed partial class AnimationBuilder + { + /// + /// Adds a custom animation based on normalized keyframes ot the current schedule. + /// + /// The type of values to animate. + /// The target property to animate. + /// The callback to use to construct the custom animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder NormalizedKeyFrames( + string property, + Action> build, + TimeSpan? delay = null, + TimeSpan? duration = null, + FrameworkLayer layer = FrameworkLayer.Composition) + where T : unmanaged + { + if (layer == FrameworkLayer.Composition) + { + NormalizedKeyFrameAnimationBuilder.Composition builder = new(property, delay, duration ?? DefaultDuration); + + build(builder); + + this.compositionAnimationFactories.Add(builder); + } + else + { + NormalizedKeyFrameAnimationBuilder.Xaml builder = new(property, delay, duration ?? DefaultDuration); + + build(builder); + + this.xamlAnimationFactories.Add(builder); + } + + return this; + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs index bcaa4163831..968e5999126 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs @@ -23,7 +23,7 @@ public sealed class Composition : NormalizedKeyFrameAnimationBuilder, Animati /// Initializes a new instance of the class. /// /// - public Composition(string property, TimeSpan? delay, TimeSpan? duration) + public Composition(string property, TimeSpan? delay, TimeSpan duration) : base(property, delay, duration) { } @@ -135,7 +135,7 @@ public unsafe CompositionAnimation GetAnimation(Visual visual) return ThrowHelper.ThrowInvalidOperationException("Invalid animation type"); } - animation.Duration = this.duration.GetValueOrDefault(); + animation.Duration = this.duration; if (this.delay.HasValue) { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs index 6198dc543af..cfa3a3b609e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -25,7 +25,7 @@ public sealed class Xaml : NormalizedKeyFrameAnimationBuilder, AnimationBuild /// Initializes a new instance of the class. /// /// - public Xaml(string property, TimeSpan? delay, TimeSpan? duration) + public Xaml(string property, TimeSpan? delay, TimeSpan duration) : base(property, delay, duration) { } @@ -43,7 +43,7 @@ public unsafe Timeline GetAnimation(UIElement element) { doubleAnimation.KeyFrames.Add(new EasingDoubleKeyFrame() { - KeyTime = keyFrame.GetKeyTime(this.duration.GetValueOrDefault()), + KeyTime = keyFrame.GetKeyTime(this.duration), Value = *(double*)&keyFrame.Value, EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) }); @@ -59,7 +59,7 @@ public unsafe Timeline GetAnimation(UIElement element) { pointAnimation.KeyFrames.Add(new EasingPointKeyFrame() { - KeyTime = keyFrame.GetKeyTime(this.duration.GetValueOrDefault()), + KeyTime = keyFrame.GetKeyTime(this.duration), Value = *(Point*)&keyFrame.Value, EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) }); @@ -75,7 +75,7 @@ public unsafe Timeline GetAnimation(UIElement element) { colorAnimation.KeyFrames.Add(new EasingColorKeyFrame() { - KeyTime = keyFrame.GetKeyTime(this.duration.GetValueOrDefault()), + KeyTime = keyFrame.GetKeyTime(this.duration), Value = *(Color*)&keyFrame.Value, EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) }); @@ -89,7 +89,7 @@ public unsafe Timeline GetAnimation(UIElement element) } animation.BeginTime = this.delay; - animation.Duration = this.duration.GetValueOrDefault(); + animation.Duration = this.duration; Storyboard.SetTarget(animation, element); Storyboard.SetTargetProperty(animation, this.property); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs index fb2b98f43c3..14245e8e8c5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs @@ -29,7 +29,7 @@ internal abstract partial class NormalizedKeyFrameAnimationBuilder : INormali /// /// The target duration for the animation. /// - private readonly TimeSpan? duration; + private readonly TimeSpan duration; /// /// The list of keyframes to use. @@ -40,9 +40,9 @@ internal abstract partial class NormalizedKeyFrameAnimationBuilder : INormali /// Initializes a new instance of the class. /// /// The target property to animate. - /// The target delay for the animation, if any. + /// The target delay for the animation. /// The target duration for the animation. - protected NormalizedKeyFrameAnimationBuilder(string property, TimeSpan? delay, TimeSpan? duration) + protected NormalizedKeyFrameAnimationBuilder(string property, TimeSpan? delay, TimeSpan duration) { this.property = property; this.delay = delay; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs index 6ce859556d2..8195d4893dc 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Collections.Generic; using System.Numerics; using Windows.UI.Xaml.Media.Animation; @@ -13,6 +14,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Extensions /// public static partial class AnimationExtensions { + /// + /// Gets the default duration of animations. + /// + public static TimeSpan DefaultDuration => TimeSpan.FromMilliseconds(400); + /// /// The default value used for animations. /// From 80164f1a4087f15e4959e2c3082df1ae8477c484 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 20 Dec 2020 16:08:26 +0100 Subject: [PATCH 040/171] Added AnimationBuilder.TimedKeyFrames --- .../Builders/AnimationBuilder.Custom.cs | 36 ++++ .../ITimedKeyFrameAnimationBuilder{T}.cs | 32 ++++ ...KeyFrameAnimationBuilder{T}.Composition.cs | 156 ++++++++++++++++++ .../TimedKeyFrameAnimationBuilder{T}.Xaml.cs | 100 +++++++++++ .../TimedKeyFrameAnimationBuilder{T}.cs | 112 +++++++++++++ 5 files changed, 436 insertions(+) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/ITimedKeyFrameAnimationBuilder{T}.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Custom.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Custom.cs index e73ff159d47..4456a8575a4 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Custom.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Custom.cs @@ -49,5 +49,41 @@ public AnimationBuilder NormalizedKeyFrames( return this; } + + /// + /// Adds a custom animation based on timed keyframes ot the current schedule. + /// + /// The type of values to animate. + /// The target property to animate. + /// The callback to use to construct the custom animation. + /// The optional initial delay for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder TimedKeyFrames( + string property, + Action> build, + TimeSpan? delay = null, + FrameworkLayer layer = FrameworkLayer.Composition) + where T : unmanaged + { + if (layer == FrameworkLayer.Composition) + { + TimedKeyFrameAnimationBuilder.Composition builder = new(property, delay); + + build(builder); + + this.compositionAnimationFactories.Add(builder); + } + else + { + TimedKeyFrameAnimationBuilder.Xaml builder = new(property, delay); + + build(builder); + + this.xamlAnimationFactories.Add(builder); + } + + return this; + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/ITimedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/ITimedKeyFrameAnimationBuilder{T}.cs new file mode 100644 index 00000000000..e9db4ad89f4 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/ITimedKeyFrameAnimationBuilder{T}.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// An interface for an animation builder using timed keyframes. + /// + /// The type of values being set by the animation being constructed. + public interface ITimedKeyFrameAnimationBuilder + where T : unmanaged + { + /// + /// Adds a new timed keyframe to the builder in use. + /// + /// The timed progress for the keyframe, relative to the start of the animation. + /// The value for the new keyframe to add. + /// The easing type to use to reach the new keyframe. + /// The easing mode to use to reach the new keyframe. + /// The same instance that the method was invoked upon. + public ITimedKeyFrameAnimationBuilder KeyFrame( + TimeSpan progress, + T value, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode); + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs new file mode 100644 index 00000000000..6676ab7fa16 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs @@ -0,0 +1,156 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Numerics; +using Microsoft.Toolkit.Diagnostics; +using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; +using Windows.UI; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + internal abstract partial class TimedKeyFrameAnimationBuilder : ITimedKeyFrameAnimationBuilder + where T : unmanaged + { + /// + /// A custom class targeting the composition layer. + /// + public class Composition : TimedKeyFrameAnimationBuilder, AnimationBuilder.ICompositionAnimationFactory + { + /// + /// Initializes a new instance of the class. + /// + /// + public Composition(string property, TimeSpan? delay) + : base(property, delay) + { + } + + /// + public unsafe CompositionAnimation GetAnimation(Visual visual) + { + KeyFrameAnimation animation; + + // We can retrieve the total duration from the last timed keyframe, and then set + // this as the target duration and use it to normalize the keyframe progresses. + TimeSpan duration = this.keyFrames[this.keyFrames.Count - 1].Progress; + + if (typeof(T) == typeof(bool)) + { + BooleanKeyFrameAnimation boolAnimation = visual.Compositor.CreateBooleanKeyFrameAnimation(); + + foreach (var keyFrame in this.keyFrames) + { + boolAnimation.InsertKeyFrame( + (float)keyFrame.GetNormalizedProgress(duration), + *(bool*)&keyFrame.Value); + } + + animation = boolAnimation; + } + else if (typeof(T) == typeof(float)) + { + ScalarKeyFrameAnimation scalarAnimation = visual.Compositor.CreateScalarKeyFrameAnimation(); + + foreach (var keyFrame in this.keyFrames) + { + scalarAnimation.InsertKeyFrame( + (float)keyFrame.GetNormalizedProgress(duration), + *(float*)&keyFrame.Value, + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + } + + animation = scalarAnimation; + } + else if (typeof(T) == typeof(Vector2)) + { + Vector2KeyFrameAnimation vector2Animation = visual.Compositor.CreateVector2KeyFrameAnimation(); + + foreach (var keyFrame in this.keyFrames) + { + vector2Animation.InsertKeyFrame( + (float)keyFrame.GetNormalizedProgress(duration), + *(Vector2*)&keyFrame.Value, + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + } + + animation = vector2Animation; + } + else if (typeof(T) == typeof(Vector3)) + { + Vector3KeyFrameAnimation vector3Animation = visual.Compositor.CreateVector3KeyFrameAnimation(); + + foreach (var keyFrame in this.keyFrames) + { + vector3Animation.InsertKeyFrame( + (float)keyFrame.GetNormalizedProgress(duration), + *(Vector3*)&keyFrame.Value, + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + } + + animation = vector3Animation; + } + else if (typeof(T) == typeof(Vector4)) + { + Vector4KeyFrameAnimation vector4Animation = visual.Compositor.CreateVector4KeyFrameAnimation(); + + foreach (var keyFrame in this.keyFrames) + { + vector4Animation.InsertKeyFrame( + (float)keyFrame.GetNormalizedProgress(duration), + *(Vector4*)&keyFrame.Value, + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + } + + animation = vector4Animation; + } + else if (typeof(T) == typeof(Color)) + { + ColorKeyFrameAnimation colorAnimation = visual.Compositor.CreateColorKeyFrameAnimation(); + + foreach (var keyFrame in this.keyFrames) + { + colorAnimation.InsertKeyFrame( + (float)keyFrame.GetNormalizedProgress(duration), + *(Color*)&keyFrame.Value, + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + } + + animation = colorAnimation; + } + else if (typeof(T) == typeof(Quaternion)) + { + QuaternionKeyFrameAnimation quaternionAnimation = visual.Compositor.CreateQuaternionKeyFrameAnimation(); + + foreach (var keyFrame in this.keyFrames) + { + quaternionAnimation.InsertKeyFrame( + (float)keyFrame.GetNormalizedProgress(duration), + *(Quaternion*)&keyFrame.Value, + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + } + + animation = quaternionAnimation; + } + else + { + return ThrowHelper.ThrowInvalidOperationException("Invalid animation type"); + } + + animation.Duration = duration; + + if (this.delay.HasValue) + { + animation.DelayTime = this.delay!.Value; + } + + animation.Target = this.property; + + return animation; + } + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs new file mode 100644 index 00000000000..69ecaeb9cc2 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -0,0 +1,100 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.Toolkit.Diagnostics; +using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; +using Windows.Foundation; +using Windows.UI; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Media.Animation; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + internal abstract partial class TimedKeyFrameAnimationBuilder : ITimedKeyFrameAnimationBuilder + where T : unmanaged + { + /// + /// A custom class targeting the XAML layer. + /// + public class Xaml : TimedKeyFrameAnimationBuilder, AnimationBuilder.IXamlAnimationFactory + { + /// + /// Initializes a new instance of the class. + /// + /// + public Xaml(string property, TimeSpan? delay) + : base(property, delay) + { + } + + /// + public virtual unsafe Timeline GetAnimation(UIElement element) + { + Timeline animation; + + if (typeof(T) == typeof(double)) + { + DoubleAnimationUsingKeyFrames doubleAnimation = new() { EnableDependentAnimation = true }; + + foreach (var keyFrame in this.keyFrames) + { + doubleAnimation.KeyFrames.Add(new EasingDoubleKeyFrame() + { + KeyTime = keyFrame.Progress, + Value = *(double*)&keyFrame.Value, + EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) + }); + } + + animation = doubleAnimation; + } + else if (typeof(T) == typeof(Point)) + { + PointAnimationUsingKeyFrames pointAnimation = new() { EnableDependentAnimation = true }; + + foreach (var keyFrame in this.keyFrames) + { + pointAnimation.KeyFrames.Add(new EasingPointKeyFrame() + { + KeyTime = keyFrame.Progress, + Value = *(Point*)&keyFrame.Value, + EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) + }); + } + + animation = pointAnimation; + } + else if (typeof(T) == typeof(Color)) + { + ColorAnimationUsingKeyFrames colorAnimation = new() { EnableDependentAnimation = true }; + + foreach (var keyFrame in this.keyFrames) + { + colorAnimation.KeyFrames.Add(new EasingColorKeyFrame() + { + KeyTime = keyFrame.Progress, + Value = *(Color*)&keyFrame.Value, + EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) + }); + } + + animation = colorAnimation; + } + else + { + return ThrowHelper.ThrowInvalidOperationException("Invalid animation type"); + } + + animation.BeginTime = this.delay; + + Storyboard.SetTarget(animation, element); + Storyboard.SetTargetProperty(animation, this.property); + + return animation; + } + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs new file mode 100644 index 00000000000..5ca3f536a3a --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs @@ -0,0 +1,112 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// A generic keyframe animation builder. + /// + /// The type of values being set by the animation being constructed. + internal abstract partial class TimedKeyFrameAnimationBuilder : ITimedKeyFrameAnimationBuilder + where T : unmanaged + { + /// + /// The target property to animate. + /// + private readonly string property; + + /// + /// The target delay for the animation, if any. + /// + private readonly TimeSpan? delay; + + /// + /// The list of keyframes to use. + /// + private readonly List keyFrames = new(); + + /// + /// Initializes a new instance of the class. + /// + /// The target property to animate. + /// The target delay for the animation. + protected TimedKeyFrameAnimationBuilder(string property, TimeSpan? delay) + { + this.property = property; + this.delay = delay; + } + + /// + public ITimedKeyFrameAnimationBuilder KeyFrame( + TimeSpan progress, + T value, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + this.keyFrames.Add(new(progress, value, easingType, easingMode)); + + return this; + } + + /// + /// The abstracted info for a timed animation keyframe. + /// + protected readonly struct KeyFrameInfo + { + /// + /// Initializes a new instance of the struct. + /// + /// The progress for the keyframe. + /// The value for the new keyframe to add. + /// The easing type to use to reach the new keyframe. + /// The easing mode to use to reach the new keyframe. + public KeyFrameInfo( + TimeSpan progress, + T value, + EasingType easingType, + EasingMode easingMode) + { + Progress = progress; + Value = value; + EasingType = easingType; + EasingMode = easingMode; + } + + /// + /// The progress for the keyframe. + /// + public readonly TimeSpan Progress; + + /// + /// The value for the new keyframe to add. + /// + public readonly T Value; + + /// + /// The easing type to use to reach the new keyframe. + /// + public readonly EasingType EasingType; + + /// + /// The easing mode to use to reach the new keyframe. + /// + public readonly EasingMode EasingMode; + + /// + /// Gets a normalized duration for the current instance, relative to a value. + /// + /// The target value to use. + /// A normalized value relative to . + public double GetNormalizedProgress(TimeSpan duration) + { + return Math.Clamp(Progress.TotalMilliseconds * 100 / duration.TotalMilliseconds, 0, 1); + } + } + } +} From 57a8456e5bb15ef9c5ec0fe96de0105c8fac09d4 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 20 Dec 2020 16:11:54 +0100 Subject: [PATCH 041/171] Suppressed XML docs warning Not sure why the cref was being marked as ambiguous, since it was still resolved properly. Using a pragma disable for now as a workaround, the functionality is still working correctly from IntelliSense anyway. --- .../Builders/NormalizedKeyFrameAnimationBuilder{T}.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs index 14245e8e8c5..45e9cb2365a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs @@ -7,6 +7,8 @@ using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; +#pragma warning disable CS0419 + namespace Microsoft.Toolkit.Uwp.UI.Animations { /// From 9a301794b6272ab6c31f43fa280fe5f41f70784d Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 20 Dec 2020 16:21:43 +0100 Subject: [PATCH 042/171] Added ITimedKeyFrameAnimationBuilderExtensions --- ...TimedKeyFrameAnimationBuilderExtensions.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/ITimedKeyFrameAnimationBuilderExtensions.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/ITimedKeyFrameAnimationBuilderExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/ITimedKeyFrameAnimationBuilderExtensions.cs new file mode 100644 index 00000000000..fb342988aef --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/ITimedKeyFrameAnimationBuilderExtensions.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable enable + +using System; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Extensions +{ + /// + /// An extension for the type. + /// + public static class ITimedKeyFrameAnimationBuilderExtensions + { + /// + /// Adds a new timed keyframe to the builder in use. + /// + /// The type of values being set by the animation being constructed. + /// The target instance in use. + /// The timed progress for the keyframe (in milliseconds), relative to the start of the animation. + /// The value for the new keyframe to add. + /// The easing type to use to reach the new keyframe. + /// The easing mode to use to reach the new keyframe. + /// The same instance that the method was invoked upon. + public static ITimedKeyFrameAnimationBuilder KeyFrame( + this ITimedKeyFrameAnimationBuilder builder, + int progress, + T value, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + where T : unmanaged + { + return builder.KeyFrame(TimeSpan.FromMilliseconds(progress), value, easingType, easingMode); + } + } +} From 2c2b96a02865a03d9b465364a361e4ab3dc64279 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 20 Dec 2020 16:50:12 +0100 Subject: [PATCH 043/171] Fixed StyleCop warnings --- .../Animations/EffectDoubleAnimation.cs | 7 ++-- .../Effects/BlurEffect.cs | 35 +++++++++++-------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs index a686e1173b6..88c2083b992 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs @@ -17,6 +17,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Animations /// public class EffectDoubleAnimation : TypedAnimation, ITimeline { + /// + /// Gets or sets the linked instance to animate. + /// public IPipelineEffect Target { get; set; } /// @@ -25,8 +28,8 @@ AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? d BlurEffect effect = (BlurEffect)Target; return builder.DoubleAnimation( - effect.brush, - $"{effect.id}.{nameof(GaussianBlurEffect.BlurAmount)}", + effect.Brush, + $"{effect.Id}.{nameof(GaussianBlurEffect.BlurAmount)}", From, To, Delay ?? delayHint, diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/BlurEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/BlurEffect.cs index 7b864291d47..9c6714df5ba 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/BlurEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/BlurEffect.cs @@ -14,16 +14,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Effects /// This effect maps to the Win2D effect public sealed class BlurEffect : IPipelineEffect { - /// - /// The unique id for the effect, if is set. - /// - internal string id; - - /// - /// The in use, if any. - /// - internal CompositionBrush brush; - /// /// Gets or sets a value indicating whether the effect can be animated. /// @@ -40,20 +30,35 @@ public double Amount set => this.amount = Math.Max(value, 0); } + /// + /// Gets the unique id for the effect, if is set. + /// + internal string Id { get; private set; } + + /// + /// Gets in use, if any. + /// + internal CompositionBrush Brush { get; private set; } + /// public PipelineBuilder AppendToPipeline(PipelineBuilder builder) { - return IsAnimatable switch + if (IsAnimatable) { - true => builder.Blur((float)Amount, out this.id), - false => builder.Blur((float)Amount) - }; + builder = builder.Blur((float)Amount, out string id); + + Id = id; + + return builder; + } + + return builder.Blur((float)Amount); } /// void IPipelineEffect.NotifyCompositionBrushInUse(CompositionBrush brush) { - this.brush = brush; + Brush = brush; } } } From 916915f80b704b0befcc46ab19ef001c6ffa040f Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 20 Dec 2020 17:48:44 +0100 Subject: [PATCH 044/171] Code refactoring to keyframe animation builders --- .../Builders/Interfaces/IKeyFrameInfo.cs | 51 ++++ ...KeyFrameAnimationBuilder{T}.Composition.cs | 227 ++++++++++-------- ...malizedKeyFrameAnimationBuilder{T}.Xaml.cs | 74 +----- .../NormalizedKeyFrameAnimationBuilder{T}.cs | 67 +++--- ...KeyFrameAnimationBuilder{T}.Composition.cs | 132 +--------- .../TimedKeyFrameAnimationBuilder{T}.Xaml.cs | 145 ++++++----- .../TimedKeyFrameAnimationBuilder{T}.cs | 62 +++-- ...Microsoft.Toolkit.Uwp.UI.Animations.csproj | 1 - 8 files changed, 353 insertions(+), 406 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IKeyFrameInfo.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IKeyFrameInfo.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IKeyFrameInfo.cs new file mode 100644 index 00000000000..63764ea2299 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IKeyFrameInfo.cs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Diagnostics.Contracts; +using Windows.UI.Xaml.Media.Animation; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// An interface representing a generic model containing info for an abstract keyframe. + /// + internal interface IKeyFrameInfo + { + /// + /// Gets the easing type to use to reach the new keyframe. + /// + EasingType EasingType { get; } + + /// + /// Gets the easing mode to use to reach the new keyframe. + /// + EasingMode EasingMode { get; } + + /// + /// Gets the value for the new keyframe to add. + /// + /// The type of values being set by the animation being constructed. + /// The value for the current keyframe. + [Pure] + T GetValueAs() + where T : unmanaged; + + /// + /// Gets the normalized progress for the current keyframe. + /// + /// The total duration for the full animation. + /// The normalized progress for the current keyframe. + [Pure] + double GetNormalizedProgress(TimeSpan duration); + + /// + /// Gets the timed progress for the current keyframe. + /// + /// The total duration for the full animation. + /// The timed progress for the current keyframe. + [Pure] + TimeSpan GetTimedProgress(TimeSpan duration); + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs index 968e5999126..68fb3e8ef32 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections.Generic; using System.Numerics; using Microsoft.Toolkit.Diagnostics; using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; @@ -15,136 +16,162 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations internal abstract partial class NormalizedKeyFrameAnimationBuilder { /// - /// A custom class targeting the composition layer. + /// Gets a instance representing the animation to start. /// - public sealed class Composition : NormalizedKeyFrameAnimationBuilder, AnimationBuilder.ICompositionAnimationFactory + /// The type of keyframes being used to define the animation. + /// The target instance to animate. + /// The target property to animate. + /// The optional initial delay for the animation. + /// The animation duration. + /// The list of keyframes to use to build the animation. + /// A instance with the specified animation. + public static CompositionAnimation GetAnimation( + Visual visual, + string property, + TimeSpan? delay, + TimeSpan duration, + List keyFrames) + where TKeyFrame : struct, IKeyFrameInfo { - /// - /// Initializes a new instance of the class. - /// - /// - public Composition(string property, TimeSpan? delay, TimeSpan duration) - : base(property, delay, duration) - { - } + KeyFrameAnimation animation; - /// - public unsafe CompositionAnimation GetAnimation(Visual visual) + if (typeof(T) == typeof(bool)) { - KeyFrameAnimation animation; + BooleanKeyFrameAnimation boolAnimation = visual.Compositor.CreateBooleanKeyFrameAnimation(); - if (typeof(T) == typeof(bool)) + foreach (var keyFrame in keyFrames) { - BooleanKeyFrameAnimation boolAnimation = visual.Compositor.CreateBooleanKeyFrameAnimation(); - - foreach (var keyFrame in this.keyFrames) - { - boolAnimation.InsertKeyFrame( - (float)keyFrame.Progress, - *(bool*)&keyFrame.Value); - } - - animation = boolAnimation; + boolAnimation.InsertKeyFrame( + (float)keyFrame.GetNormalizedProgress(duration), + keyFrame.GetValueAs()); } - else if (typeof(T) == typeof(float)) - { - ScalarKeyFrameAnimation scalarAnimation = visual.Compositor.CreateScalarKeyFrameAnimation(); - foreach (var keyFrame in this.keyFrames) - { - scalarAnimation.InsertKeyFrame( - (float)keyFrame.Progress, - *(float*)&keyFrame.Value, - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); - } + animation = boolAnimation; + } + else if (typeof(T) == typeof(float)) + { + ScalarKeyFrameAnimation scalarAnimation = visual.Compositor.CreateScalarKeyFrameAnimation(); - animation = scalarAnimation; - } - else if (typeof(T) == typeof(Vector2)) + foreach (var keyFrame in keyFrames) { - Vector2KeyFrameAnimation vector2Animation = visual.Compositor.CreateVector2KeyFrameAnimation(); - - foreach (var keyFrame in this.keyFrames) - { - vector2Animation.InsertKeyFrame( - (float)keyFrame.Progress, - *(Vector2*)&keyFrame.Value, - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); - } - - animation = vector2Animation; + scalarAnimation.InsertKeyFrame( + (float)keyFrame.GetNormalizedProgress(duration), + keyFrame.GetValueAs(), + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); } - else if (typeof(T) == typeof(Vector3)) - { - Vector3KeyFrameAnimation vector3Animation = visual.Compositor.CreateVector3KeyFrameAnimation(); - foreach (var keyFrame in this.keyFrames) - { - vector3Animation.InsertKeyFrame( - (float)keyFrame.Progress, - *(Vector3*)&keyFrame.Value, - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); - } + animation = scalarAnimation; + } + else if (typeof(T) == typeof(Vector2)) + { + Vector2KeyFrameAnimation vector2Animation = visual.Compositor.CreateVector2KeyFrameAnimation(); - animation = vector3Animation; - } - else if (typeof(T) == typeof(Vector4)) + foreach (var keyFrame in keyFrames) { - Vector4KeyFrameAnimation vector4Animation = visual.Compositor.CreateVector4KeyFrameAnimation(); + vector2Animation.InsertKeyFrame( + (float)keyFrame.GetNormalizedProgress(duration), + keyFrame.GetValueAs(), + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + } - foreach (var keyFrame in this.keyFrames) - { - vector4Animation.InsertKeyFrame( - (float)keyFrame.Progress, - *(Vector4*)&keyFrame.Value, - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); - } + animation = vector2Animation; + } + else if (typeof(T) == typeof(Vector3)) + { + Vector3KeyFrameAnimation vector3Animation = visual.Compositor.CreateVector3KeyFrameAnimation(); - animation = vector4Animation; - } - else if (typeof(T) == typeof(Color)) + foreach (var keyFrame in keyFrames) { - ColorKeyFrameAnimation colorAnimation = visual.Compositor.CreateColorKeyFrameAnimation(); + vector3Animation.InsertKeyFrame( + (float)keyFrame.GetNormalizedProgress(duration), + keyFrame.GetValueAs(), + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + } - foreach (var keyFrame in this.keyFrames) - { - colorAnimation.InsertKeyFrame( - (float)keyFrame.Progress, - *(Color*)&keyFrame.Value, - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); - } + animation = vector3Animation; + } + else if (typeof(T) == typeof(Vector4)) + { + Vector4KeyFrameAnimation vector4Animation = visual.Compositor.CreateVector4KeyFrameAnimation(); - animation = colorAnimation; - } - else if (typeof(T) == typeof(Quaternion)) + foreach (var keyFrame in keyFrames) { - QuaternionKeyFrameAnimation quaternionAnimation = visual.Compositor.CreateQuaternionKeyFrameAnimation(); + vector4Animation.InsertKeyFrame( + (float)keyFrame.GetNormalizedProgress(duration), + keyFrame.GetValueAs(), + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + } - foreach (var keyFrame in this.keyFrames) - { - quaternionAnimation.InsertKeyFrame( - (float)keyFrame.Progress, - *(Quaternion*)&keyFrame.Value, - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); - } + animation = vector4Animation; + } + else if (typeof(T) == typeof(Color)) + { + ColorKeyFrameAnimation colorAnimation = visual.Compositor.CreateColorKeyFrameAnimation(); - animation = quaternionAnimation; - } - else + foreach (var keyFrame in keyFrames) { - return ThrowHelper.ThrowInvalidOperationException("Invalid animation type"); + colorAnimation.InsertKeyFrame( + (float)keyFrame.GetNormalizedProgress(duration), + keyFrame.GetValueAs(), + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); } - animation.Duration = this.duration; + animation = colorAnimation; + } + else if (typeof(T) == typeof(Quaternion)) + { + QuaternionKeyFrameAnimation quaternionAnimation = visual.Compositor.CreateQuaternionKeyFrameAnimation(); - if (this.delay.HasValue) + foreach (var keyFrame in keyFrames) { - animation.DelayTime = this.delay!.Value; + quaternionAnimation.InsertKeyFrame( + (float)keyFrame.GetNormalizedProgress(duration), + keyFrame.GetValueAs(), + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); } - animation.Target = this.property; + animation = quaternionAnimation; + } + else + { + return ThrowHelper.ThrowInvalidOperationException("Invalid animation type"); + } + + animation.Duration = duration; + + if (delay.HasValue) + { + animation.DelayTime = delay!.Value; + } + + animation.Target = property; + + return animation; + } - return animation; + /// + /// A custom class targeting the composition layer. + /// + public sealed class Composition : NormalizedKeyFrameAnimationBuilder, AnimationBuilder.ICompositionAnimationFactory + { + /// + /// Initializes a new instance of the class. + /// + /// + public Composition(string property, TimeSpan? delay, TimeSpan duration) + : base(property, delay, duration) + { + } + + /// + public CompositionAnimation GetAnimation(Visual visual) + { + return GetAnimation( + visual, + this.property, + this.delay, + this.duration, + this.keyFrames); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs index cfa3a3b609e..e4ca796c97b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -3,10 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using Microsoft.Toolkit.Diagnostics; -using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; -using Windows.Foundation; -using Windows.UI; using Windows.UI.Xaml; using Windows.UI.Xaml.Media.Animation; @@ -31,70 +27,14 @@ public Xaml(string property, TimeSpan? delay, TimeSpan duration) } /// - public unsafe Timeline GetAnimation(UIElement element) + public Timeline GetAnimation(UIElement element) { - Timeline animation; - - if (typeof(T) == typeof(double)) - { - DoubleAnimationUsingKeyFrames doubleAnimation = new() { EnableDependentAnimation = true }; - - foreach (var keyFrame in this.keyFrames) - { - doubleAnimation.KeyFrames.Add(new EasingDoubleKeyFrame() - { - KeyTime = keyFrame.GetKeyTime(this.duration), - Value = *(double*)&keyFrame.Value, - EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) - }); - } - - animation = doubleAnimation; - } - else if (typeof(T) == typeof(Point)) - { - PointAnimationUsingKeyFrames pointAnimation = new() { EnableDependentAnimation = true }; - - foreach (var keyFrame in this.keyFrames) - { - pointAnimation.KeyFrames.Add(new EasingPointKeyFrame() - { - KeyTime = keyFrame.GetKeyTime(this.duration), - Value = *(Point*)&keyFrame.Value, - EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) - }); - } - - animation = pointAnimation; - } - else if (typeof(T) == typeof(Color)) - { - ColorAnimationUsingKeyFrames colorAnimation = new() { EnableDependentAnimation = true }; - - foreach (var keyFrame in this.keyFrames) - { - colorAnimation.KeyFrames.Add(new EasingColorKeyFrame() - { - KeyTime = keyFrame.GetKeyTime(this.duration), - Value = *(Color*)&keyFrame.Value, - EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) - }); - } - - animation = colorAnimation; - } - else - { - return ThrowHelper.ThrowInvalidOperationException("Invalid animation type"); - } - - animation.BeginTime = this.delay; - animation.Duration = this.duration; - - Storyboard.SetTarget(animation, element); - Storyboard.SetTargetProperty(animation, this.property); - - return animation; + return TimedKeyFrameAnimationBuilder.GetAnimation( + element, + this.property, + this.delay, + this.duration, + this.keyFrames); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs index 45e9cb2365a..85e2d11cb0c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs @@ -4,11 +4,10 @@ using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; -#pragma warning disable CS0419 - namespace Microsoft.Toolkit.Uwp.UI.Animations { /// @@ -66,8 +65,18 @@ public INormalizedKeyFrameAnimationBuilder KeyFrame( /// /// The abstracted info for a normalized animation keyframe. /// - protected readonly struct KeyFrameInfo + protected readonly struct KeyFrameInfo : IKeyFrameInfo { + /// + /// The normalized progress for the keyframe. + /// + private readonly double progress; + + /// + /// The value for the current keyframe. + /// + private readonly T value; + /// /// Initializes a new instance of the struct. /// @@ -81,43 +90,39 @@ public KeyFrameInfo( EasingType easingType, EasingMode easingMode) { - Progress = progress; - Value = value; + this.progress = progress; + this.value = value; + EasingType = easingType; EasingMode = easingMode; } - /// - /// The normalized progress for the keyframe. - /// - public readonly double Progress; + /// + public EasingType EasingType { get; } - /// - /// The value for the new keyframe to add. - /// - public readonly T Value; - - /// - /// The easing type to use to reach the new keyframe. - /// - public readonly EasingType EasingType; + /// + public EasingMode EasingMode { get; } - /// - /// The easing mode to use to reach the new keyframe. - /// - public readonly EasingMode EasingMode; + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TValue GetValueAs() + where TValue : unmanaged + { + return Unsafe.As(ref Unsafe.AsRef(in this.value)); + } - /// - /// Gets a for the current instance, relative to a value. - /// - /// The target value to use. - /// A normalized value relative to . - public KeyTime GetKeyTime(TimeSpan duration) + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public double GetNormalizedProgress(TimeSpan duration) { - long ticks = duration.Ticks; - TimeSpan step = TimeSpan.FromTicks((long)(ticks * Progress)); + return this.progress; + } - return KeyTime.FromTimeSpan(step); + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TimeSpan GetTimedProgress(TimeSpan duration) + { + return TimeSpan.FromMilliseconds(duration.TotalMilliseconds * this.progress); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs index 6676ab7fa16..6c01782e47f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs @@ -3,10 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Numerics; -using Microsoft.Toolkit.Diagnostics; -using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; -using Windows.UI; using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Animations @@ -18,7 +14,7 @@ internal abstract partial class TimedKeyFrameAnimationBuilder : ITimedKeyFram /// /// A custom class targeting the composition layer. /// - public class Composition : TimedKeyFrameAnimationBuilder, AnimationBuilder.ICompositionAnimationFactory + public sealed class Composition : TimedKeyFrameAnimationBuilder, AnimationBuilder.ICompositionAnimationFactory { /// /// Initializes a new instance of the class. @@ -30,126 +26,18 @@ public Composition(string property, TimeSpan? delay) } /// - public unsafe CompositionAnimation GetAnimation(Visual visual) + public CompositionAnimation GetAnimation(Visual visual) { - KeyFrameAnimation animation; - // We can retrieve the total duration from the last timed keyframe, and then set // this as the target duration and use it to normalize the keyframe progresses. - TimeSpan duration = this.keyFrames[this.keyFrames.Count - 1].Progress; - - if (typeof(T) == typeof(bool)) - { - BooleanKeyFrameAnimation boolAnimation = visual.Compositor.CreateBooleanKeyFrameAnimation(); - - foreach (var keyFrame in this.keyFrames) - { - boolAnimation.InsertKeyFrame( - (float)keyFrame.GetNormalizedProgress(duration), - *(bool*)&keyFrame.Value); - } - - animation = boolAnimation; - } - else if (typeof(T) == typeof(float)) - { - ScalarKeyFrameAnimation scalarAnimation = visual.Compositor.CreateScalarKeyFrameAnimation(); - - foreach (var keyFrame in this.keyFrames) - { - scalarAnimation.InsertKeyFrame( - (float)keyFrame.GetNormalizedProgress(duration), - *(float*)&keyFrame.Value, - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); - } - - animation = scalarAnimation; - } - else if (typeof(T) == typeof(Vector2)) - { - Vector2KeyFrameAnimation vector2Animation = visual.Compositor.CreateVector2KeyFrameAnimation(); - - foreach (var keyFrame in this.keyFrames) - { - vector2Animation.InsertKeyFrame( - (float)keyFrame.GetNormalizedProgress(duration), - *(Vector2*)&keyFrame.Value, - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); - } - - animation = vector2Animation; - } - else if (typeof(T) == typeof(Vector3)) - { - Vector3KeyFrameAnimation vector3Animation = visual.Compositor.CreateVector3KeyFrameAnimation(); - - foreach (var keyFrame in this.keyFrames) - { - vector3Animation.InsertKeyFrame( - (float)keyFrame.GetNormalizedProgress(duration), - *(Vector3*)&keyFrame.Value, - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); - } - - animation = vector3Animation; - } - else if (typeof(T) == typeof(Vector4)) - { - Vector4KeyFrameAnimation vector4Animation = visual.Compositor.CreateVector4KeyFrameAnimation(); - - foreach (var keyFrame in this.keyFrames) - { - vector4Animation.InsertKeyFrame( - (float)keyFrame.GetNormalizedProgress(duration), - *(Vector4*)&keyFrame.Value, - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); - } - - animation = vector4Animation; - } - else if (typeof(T) == typeof(Color)) - { - ColorKeyFrameAnimation colorAnimation = visual.Compositor.CreateColorKeyFrameAnimation(); - - foreach (var keyFrame in this.keyFrames) - { - colorAnimation.InsertKeyFrame( - (float)keyFrame.GetNormalizedProgress(duration), - *(Color*)&keyFrame.Value, - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); - } - - animation = colorAnimation; - } - else if (typeof(T) == typeof(Quaternion)) - { - QuaternionKeyFrameAnimation quaternionAnimation = visual.Compositor.CreateQuaternionKeyFrameAnimation(); - - foreach (var keyFrame in this.keyFrames) - { - quaternionAnimation.InsertKeyFrame( - (float)keyFrame.GetNormalizedProgress(duration), - *(Quaternion*)&keyFrame.Value, - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); - } - - animation = quaternionAnimation; - } - else - { - return ThrowHelper.ThrowInvalidOperationException("Invalid animation type"); - } - - animation.Duration = duration; - - if (this.delay.HasValue) - { - animation.DelayTime = this.delay!.Value; - } - - animation.Target = this.property; - - return animation; + TimeSpan duration = this.keyFrames[this.keyFrames.Count - 1].GetTimedProgress(default); + + return NormalizedKeyFrameAnimationBuilder.GetAnimation( + visual, + this.property, + this.delay, + duration, + this.keyFrames); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs index 69ecaeb9cc2..15b37bfe0ad 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections.Generic; using Microsoft.Toolkit.Diagnostics; using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; using Windows.Foundation; @@ -17,83 +18,109 @@ internal abstract partial class TimedKeyFrameAnimationBuilder : ITimedKeyFram where T : unmanaged { /// - /// A custom class targeting the XAML layer. + /// Gets a instance representing the animation to start. /// - public class Xaml : TimedKeyFrameAnimationBuilder, AnimationBuilder.IXamlAnimationFactory + /// The type of keyframes being used to define the animation. + /// The target instance to animate. + /// The target property to animate. + /// The optional initial delay for the animation. + /// The animation duration. + /// The list of keyframes to use to build the animation. + /// A instance with the specified animation. + public static Timeline GetAnimation( + UIElement element, + string property, + TimeSpan? delay, + TimeSpan duration, + List keyFrames) + where TKeyFrame : struct, IKeyFrameInfo { - /// - /// Initializes a new instance of the class. - /// - /// - public Xaml(string property, TimeSpan? delay) - : base(property, delay) - { - } + Timeline animation; - /// - public virtual unsafe Timeline GetAnimation(UIElement element) + if (typeof(T) == typeof(double)) { - Timeline animation; + DoubleAnimationUsingKeyFrames doubleAnimation = new() { EnableDependentAnimation = true }; - if (typeof(T) == typeof(double)) + foreach (var keyFrame in keyFrames) { - DoubleAnimationUsingKeyFrames doubleAnimation = new() { EnableDependentAnimation = true }; - - foreach (var keyFrame in this.keyFrames) + doubleAnimation.KeyFrames.Add(new EasingDoubleKeyFrame() { - doubleAnimation.KeyFrames.Add(new EasingDoubleKeyFrame() - { - KeyTime = keyFrame.Progress, - Value = *(double*)&keyFrame.Value, - EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) - }); - } - - animation = doubleAnimation; + KeyTime = keyFrame.GetTimedProgress(duration), + Value = keyFrame.GetValueAs(), + EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) + }); } - else if (typeof(T) == typeof(Point)) - { - PointAnimationUsingKeyFrames pointAnimation = new() { EnableDependentAnimation = true }; - foreach (var keyFrame in this.keyFrames) - { - pointAnimation.KeyFrames.Add(new EasingPointKeyFrame() - { - KeyTime = keyFrame.Progress, - Value = *(Point*)&keyFrame.Value, - EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) - }); - } + animation = doubleAnimation; + } + else if (typeof(T) == typeof(Point)) + { + PointAnimationUsingKeyFrames pointAnimation = new() { EnableDependentAnimation = true }; - animation = pointAnimation; - } - else if (typeof(T) == typeof(Color)) + foreach (var keyFrame in keyFrames) { - ColorAnimationUsingKeyFrames colorAnimation = new() { EnableDependentAnimation = true }; - - foreach (var keyFrame in this.keyFrames) + pointAnimation.KeyFrames.Add(new EasingPointKeyFrame() { - colorAnimation.KeyFrames.Add(new EasingColorKeyFrame() - { - KeyTime = keyFrame.Progress, - Value = *(Color*)&keyFrame.Value, - EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) - }); - } - - animation = colorAnimation; + KeyTime = keyFrame.GetTimedProgress(duration), + Value = keyFrame.GetValueAs(), + EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) + }); } - else + + animation = pointAnimation; + } + else if (typeof(T) == typeof(Color)) + { + ColorAnimationUsingKeyFrames colorAnimation = new() { EnableDependentAnimation = true }; + + foreach (var keyFrame in keyFrames) { - return ThrowHelper.ThrowInvalidOperationException("Invalid animation type"); + colorAnimation.KeyFrames.Add(new EasingColorKeyFrame() + { + KeyTime = keyFrame.GetTimedProgress(duration), + Value = keyFrame.GetValueAs(), + EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) + }); } - animation.BeginTime = this.delay; + animation = colorAnimation; + } + else + { + return ThrowHelper.ThrowInvalidOperationException("Invalid animation type"); + } + + animation.BeginTime = delay; + + Storyboard.SetTarget(animation, element); + Storyboard.SetTargetProperty(animation, property); - Storyboard.SetTarget(animation, element); - Storyboard.SetTargetProperty(animation, this.property); + return animation; + } + + /// + /// A custom class targeting the XAML layer. + /// + public sealed class Xaml : TimedKeyFrameAnimationBuilder, AnimationBuilder.IXamlAnimationFactory + { + /// + /// Initializes a new instance of the class. + /// + /// + public Xaml(string property, TimeSpan? delay) + : base(property, delay) + { + } - return animation; + /// + public Timeline GetAnimation(UIElement element) + { + return GetAnimation( + element, + this.property, + this.delay, + default, + this.keyFrames); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs index 5ca3f536a3a..6ad0400c2f3 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -57,8 +58,18 @@ public ITimedKeyFrameAnimationBuilder KeyFrame( /// /// The abstracted info for a timed animation keyframe. /// - protected readonly struct KeyFrameInfo + protected readonly struct KeyFrameInfo : IKeyFrameInfo { + /// + /// The progress for the keyframe. + /// + private readonly TimeSpan progress; + + /// + /// The value for the current keyframe. + /// + private readonly T value; + /// /// Initializes a new instance of the struct. /// @@ -72,40 +83,39 @@ public KeyFrameInfo( EasingType easingType, EasingMode easingMode) { - Progress = progress; - Value = value; + this.progress = progress; + this.value = value; + EasingType = easingType; EasingMode = easingMode; } - /// - /// The progress for the keyframe. - /// - public readonly TimeSpan Progress; + /// + public EasingType EasingType { get; } - /// - /// The value for the new keyframe to add. - /// - public readonly T Value; + /// + public EasingMode EasingMode { get; } - /// - /// The easing type to use to reach the new keyframe. - /// - public readonly EasingType EasingType; - - /// - /// The easing mode to use to reach the new keyframe. - /// - public readonly EasingMode EasingMode; + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TValue GetValueAs() + where TValue : unmanaged + { + return Unsafe.As(ref Unsafe.AsRef(in this.value)); + } - /// - /// Gets a normalized duration for the current instance, relative to a value. - /// - /// The target value to use. - /// A normalized value relative to . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public double GetNormalizedProgress(TimeSpan duration) { - return Math.Clamp(Progress.TotalMilliseconds * 100 / duration.TotalMilliseconds, 0, 1); + return Math.Clamp(this.progress.TotalMilliseconds * 100 / duration.TotalMilliseconds, 0, 1); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TimeSpan GetTimedProgress(TimeSpan duration) + { + return this.progress; } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj b/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj index f385ff525c9..e49f7af1cd7 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Microsoft.Toolkit.Uwp.UI.Animations.csproj @@ -16,7 +16,6 @@ UWP Toolkit Windows Animations Composition Connected Implicit XAML 9.0 - true From c3d139b11ca11a4ea3f355675a47ff38801e975d Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 20 Dec 2020 18:31:46 +0100 Subject: [PATCH 045/171] Uniformed type support for keyframed animations --- ...KeyFrameAnimationBuilder{T}.Composition.cs | 14 +++++++ .../TimedKeyFrameAnimationBuilder{T}.Xaml.cs | 37 ++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs index 68fb3e8ef32..015dc487541 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs @@ -62,6 +62,20 @@ public static CompositionAnimation GetAnimation( animation = scalarAnimation; } + else if (typeof(T) == typeof(double)) + { + ScalarKeyFrameAnimation scalarAnimation = visual.Compositor.CreateScalarKeyFrameAnimation(); + + foreach (var keyFrame in keyFrames) + { + scalarAnimation.InsertKeyFrame( + (float)keyFrame.GetNormalizedProgress(duration), + (float)keyFrame.GetValueAs(), + visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + } + + animation = scalarAnimation; + } else if (typeof(T) == typeof(Vector2)) { Vector2KeyFrameAnimation vector2Animation = visual.Compositor.CreateVector2KeyFrameAnimation(); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs index 15b37bfe0ad..43e7dff65f8 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.Numerics; using Microsoft.Toolkit.Diagnostics; using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; using Windows.Foundation; @@ -37,7 +38,23 @@ public static Timeline GetAnimation( { Timeline animation; - if (typeof(T) == typeof(double)) + if (typeof(T) == typeof(float)) + { + DoubleAnimationUsingKeyFrames doubleAnimation = new() { EnableDependentAnimation = true }; + + foreach (var keyFrame in keyFrames) + { + doubleAnimation.KeyFrames.Add(new EasingDoubleKeyFrame() + { + KeyTime = keyFrame.GetTimedProgress(duration), + Value = keyFrame.GetValueAs(), + EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) + }); + } + + animation = doubleAnimation; + } + else if (typeof(T) == typeof(double)) { DoubleAnimationUsingKeyFrames doubleAnimation = new() { EnableDependentAnimation = true }; @@ -53,6 +70,24 @@ public static Timeline GetAnimation( animation = doubleAnimation; } + else if (typeof(T) == typeof(Vector2)) + { + PointAnimationUsingKeyFrames pointAnimation = new() { EnableDependentAnimation = true }; + + foreach (var keyFrame in keyFrames) + { + Vector2 vector = keyFrame.GetValueAs(); + + pointAnimation.KeyFrames.Add(new EasingPointKeyFrame() + { + KeyTime = keyFrame.GetTimedProgress(duration), + Value = new Point(vector.X, vector.Y), + EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) + }); + } + + animation = pointAnimation; + } else if (typeof(T) == typeof(Point)) { PointAnimationUsingKeyFrames pointAnimation = new() { EnableDependentAnimation = true }; From 01e2cb334592aa85544ed64c3962de6dbee39d10 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 20 Dec 2020 18:46:18 +0100 Subject: [PATCH 046/171] Minor tweaks to the default animations --- .../Builders/AnimationBuilder.Default.cs | 48 ++++++++++++------- .../Builders/AnimationBuilder.Setup.cs | 30 ------------ 2 files changed, 31 insertions(+), 47 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs index c2cee2cfb53..5ce5a087c7f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs @@ -102,15 +102,16 @@ public AnimationBuilder Translation( { if (layer == FrameworkLayer.Composition) { - return AddCompositionVector2AnimationFactory("Translation", from, to, delay, duration, easingType, easingMode); + AddCompositionScalarAnimationFactory("Translation.X", from?.X, to.X, delay, duration, easingType, easingMode); + AddCompositionScalarAnimationFactory("Translation.Y", from?.Y, to.Y, delay, duration, easingType, easingMode); } else { AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.TranslateX), from?.X, to.X, delay, duration, easingType, easingMode); AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.TranslateY), from?.Y, to.Y, delay, duration, easingType, easingMode); - - return this; } + + return this; } /// @@ -178,7 +179,10 @@ public AnimationBuilder Offset( EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - return AddCompositionVector2AnimationFactory(nameof(Visual.Offset), from, to, delay, duration, easingType, easingMode); + AddCompositionScalarAnimationFactory($"{nameof(Visual.Offset)}.X", from?.X, to.X, delay, duration, easingType, easingMode); + AddCompositionScalarAnimationFactory($"{nameof(Visual.Offset)}.Y", from?.Y, to.Y, delay, duration, easingType, easingMode); + + return this; } /// @@ -204,7 +208,7 @@ public AnimationBuilder Offset( } /// - /// Adds a new uniform scale animation on the X and Y axes to the current schedule. + /// Adds a new uniform scale animation for all axes to the current schedule. /// /// The optional starting value for the animation. /// The final value for the animation. @@ -225,10 +229,10 @@ public AnimationBuilder Scale( { if (layer == FrameworkLayer.Composition) { - Vector2? from2 = from is null ? null : new((float)(double)from); - Vector2 to2 = new((float)to); + Vector3? from3 = from is null ? null : new((float)(double)from); + Vector3 to3 = new((float)to); - return AddCompositionVector2AnimationFactory(nameof(Visual.Scale), from2, to2, delay, duration, easingType, easingMode); + return AddCompositionVector3AnimationFactory(nameof(Visual.Scale), from3, to3, delay, duration, easingType, easingMode); } else { @@ -249,8 +253,8 @@ public AnimationBuilder Scale( /// The animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. + /// The target framework layer to animate. /// The current instance. - /// This animation is only available on the XAML layer. public AnimationBuilder Scale( Axis axis, double? from, @@ -258,9 +262,17 @@ public AnimationBuilder Scale( TimeSpan? delay, TimeSpan duration, EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode) + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) { - return AddXamlTransformDoubleAnimationFactory($"Scale{axis}", from, to, delay, duration, easingType, easingMode); + if (layer == FrameworkLayer.Composition) + { + return AddCompositionScalarAnimationFactory($"{nameof(Visual.Scale)}.{axis}", (float?)from, (float)to, delay, duration, easingType, easingMode); + } + else + { + return AddXamlTransformDoubleAnimationFactory($"Scale{axis}", from, to, delay, duration, easingType, easingMode); + } } /// @@ -285,15 +297,16 @@ public AnimationBuilder Scale( { if (layer == FrameworkLayer.Composition) { - return AddCompositionVector2AnimationFactory(nameof(Visual.Scale), from, to, delay, duration, easingType, easingMode); + AddCompositionScalarAnimationFactory($"{nameof(Visual.Scale)}.X", from?.X, to.X, delay, duration, easingType, easingMode); + AddCompositionScalarAnimationFactory($"{nameof(Visual.Scale)}.Y", from?.Y, to.Y, delay, duration, easingType, easingMode); } else { AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleX), from?.X, to.X, delay, duration, easingType, easingMode); AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleY), from?.Y, to.Y, delay, duration, easingType, easingMode); - - return this; } + + return this; } /// @@ -490,15 +503,16 @@ public AnimationBuilder Size( { if (layer == FrameworkLayer.Composition) { - return AddCompositionVector2AnimationFactory(nameof(Visual.Size), from, to, delay, duration, easingType, easingMode); + AddCompositionScalarAnimationFactory($"{nameof(Visual.Size)}.X", from?.X, to.X, delay, duration, easingType, easingMode); + AddCompositionScalarAnimationFactory($"{nameof(Visual.Size)}.Y", from?.Y, to.Y, delay, duration, easingType, easingMode); } else { AddXamlDoubleAnimationFactory(nameof(FrameworkElement.Width), from?.X, to.X, delay, duration, easingType, easingMode, true); AddXamlDoubleAnimationFactory(nameof(FrameworkElement.Height), from?.Y, to.Y, delay, duration, easingType, easingMode, true); - - return this; } + + return this; } /// diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs index a7f8a2b5d83..16fbc6a622a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs @@ -56,36 +56,6 @@ private AnimationBuilder AddCompositionScalarAnimationFactory( return this; } - /// - /// Adds a new composition animation to the current schedule. - /// - /// The target property to animate. - /// The optional starting value for the animation. - /// The final value for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The easing function for the animation. - /// The easing mode for the animation. - /// The current instance. - /// This will use a animation with a zero Z axis. - private AnimationBuilder AddCompositionVector2AnimationFactory( - string property, - Vector2? from, - Vector2 to, - TimeSpan? delay, - TimeSpan duration, - EasingType easingType, - EasingMode easingMode) - { - Vector3? from3 = from is null ? null : new(from.Value, 0); - Vector3 to3 = new(to, 0); - CompositionVector3AnimationFactory animation = new(property, from3, to3, delay, duration, easingType, easingMode); - - this.compositionAnimationFactories.Add(animation); - - return this; - } - /// /// Adds a new composition animation to the current schedule. /// From e3dab22a53037352089a07a51a24abe1e8fa0940 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 20 Dec 2020 19:53:49 +0100 Subject: [PATCH 047/171] Changed animation duration to be nullable --- .../Builders/AnimationBuilder.Default.cs | 106 +++++++++--------- .../Builders/AnimationBuilder.Models.cs | 12 +- .../Builders/AnimationBuilder.Setup.cs | 46 ++++++-- .../Builders/AnimationBuilder.cs | 6 +- .../Extensions/AnimationExtensions.cs | 5 + 5 files changed, 105 insertions(+), 70 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs index 5ce5a087c7f..32ebc2c1f17 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs @@ -24,7 +24,7 @@ public sealed partial class AnimationBuilder /// The optional starting value for the animation. /// The final value for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. /// The target framework layer to animate. @@ -32,8 +32,8 @@ public sealed partial class AnimationBuilder public AnimationBuilder Opacity( double? from, double to, - TimeSpan? delay, - TimeSpan duration, + TimeSpan? delay = null, + TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode, FrameworkLayer layer = FrameworkLayer.Composition) @@ -55,7 +55,7 @@ public AnimationBuilder Opacity( /// The optional starting value for the animation. /// The final value for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. /// The target framework layer to animate. @@ -64,8 +64,8 @@ public AnimationBuilder Translation( Axis axis, double? from, double to, - TimeSpan? delay, - TimeSpan duration, + TimeSpan? delay = null, + TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode, FrameworkLayer layer = FrameworkLayer.Composition) @@ -86,7 +86,7 @@ public AnimationBuilder Translation( /// The optional starting point for the animation. /// The final point for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. /// The target framework layer to animate. @@ -94,8 +94,8 @@ public AnimationBuilder Translation( public AnimationBuilder Translation( Vector2? from, Vector2 to, - TimeSpan? delay, - TimeSpan duration, + TimeSpan? delay = null, + TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode, FrameworkLayer layer = FrameworkLayer.Composition) @@ -120,7 +120,7 @@ public AnimationBuilder Translation( /// The optional starting point for the animation. /// The final point for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. /// The current instance. @@ -128,8 +128,8 @@ public AnimationBuilder Translation( public AnimationBuilder Translation( Vector3? from, Vector3 to, - TimeSpan? delay, - TimeSpan duration, + TimeSpan? delay = null, + TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { @@ -143,7 +143,7 @@ public AnimationBuilder Translation( /// The optional starting value for the animation. /// The final value for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. /// The current instance. @@ -152,8 +152,8 @@ public AnimationBuilder Offset( Axis axis, double? from, double to, - TimeSpan? delay, - TimeSpan duration, + TimeSpan? delay = null, + TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { @@ -166,7 +166,7 @@ public AnimationBuilder Offset( /// The optional starting point for the animation. /// The final point for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. /// The current instance. @@ -174,8 +174,8 @@ public AnimationBuilder Offset( public AnimationBuilder Offset( Vector2? from, Vector2 to, - TimeSpan? delay, - TimeSpan duration, + TimeSpan? delay = null, + TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { @@ -191,7 +191,7 @@ public AnimationBuilder Offset( /// The optional starting point for the animation. /// The final point for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. /// The current instance. @@ -199,8 +199,8 @@ public AnimationBuilder Offset( public AnimationBuilder Offset( Vector3? from, Vector3 to, - TimeSpan? delay, - TimeSpan duration, + TimeSpan? delay = null, + TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { @@ -213,7 +213,7 @@ public AnimationBuilder Offset( /// The optional starting value for the animation. /// The final value for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. /// The target framework layer to animate. @@ -221,8 +221,8 @@ public AnimationBuilder Offset( public AnimationBuilder Scale( double? from, double to, - TimeSpan? delay, - TimeSpan duration, + TimeSpan? delay = null, + TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode, FrameworkLayer layer = FrameworkLayer.Composition) @@ -250,7 +250,7 @@ public AnimationBuilder Scale( /// The optional starting value for the animation. /// The final value for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. /// The target framework layer to animate. @@ -259,8 +259,8 @@ public AnimationBuilder Scale( Axis axis, double? from, double to, - TimeSpan? delay, - TimeSpan duration, + TimeSpan? delay = null, + TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode, FrameworkLayer layer = FrameworkLayer.Composition) @@ -281,7 +281,7 @@ public AnimationBuilder Scale( /// The optional starting point for the animation. /// The final point for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. /// The target framework layer to animate. @@ -289,8 +289,8 @@ public AnimationBuilder Scale( public AnimationBuilder Scale( Vector2? from, Vector2 to, - TimeSpan? delay, - TimeSpan duration, + TimeSpan? delay = null, + TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode, FrameworkLayer layer = FrameworkLayer.Composition) @@ -315,7 +315,7 @@ public AnimationBuilder Scale( /// The optional starting point for the animation. /// The final point for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. /// The current instance. @@ -323,8 +323,8 @@ public AnimationBuilder Scale( public AnimationBuilder Scale( Vector3? from, Vector3 to, - TimeSpan? delay, - TimeSpan duration, + TimeSpan? delay = null, + TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { @@ -337,7 +337,7 @@ public AnimationBuilder Scale( /// The optional starting value for the animation. /// The final value for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. /// The target framework layer to animate. @@ -345,8 +345,8 @@ public AnimationBuilder Scale( public AnimationBuilder Rotate( double? from, double to, - TimeSpan? delay, - TimeSpan duration, + TimeSpan? delay = null, + TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode, FrameworkLayer layer = FrameworkLayer.Composition) @@ -372,7 +372,7 @@ public AnimationBuilder Rotate( /// The optional starting value for the animation. /// The final value for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. /// The target framework layer to animate. @@ -380,8 +380,8 @@ public AnimationBuilder Rotate( public AnimationBuilder RotateInDegrees( double? from, double to, - TimeSpan? delay, - TimeSpan duration, + TimeSpan? delay = null, + TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode, FrameworkLayer layer = FrameworkLayer.Composition) @@ -405,7 +405,7 @@ public AnimationBuilder RotateInDegrees( /// The optional starting value for the animation. /// The final value for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. /// The current instance. @@ -414,8 +414,8 @@ public AnimationBuilder Clip( Side side, double? from, double to, - TimeSpan? delay, - TimeSpan duration, + TimeSpan? delay = null, + TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { @@ -432,8 +432,8 @@ public AnimationBuilder Clip( property, (float?)from, (float)to, - delay, - duration, + delay ?? DefaultDelay, + duration ?? DefaultDuration, easingType, easingMode); @@ -449,7 +449,7 @@ public AnimationBuilder Clip( /// The optional starting value for the animation. /// The final value for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. /// The target framework layer to animate. @@ -458,8 +458,8 @@ public AnimationBuilder Size( Axis axis, double? from, double to, - TimeSpan? delay, - TimeSpan duration, + TimeSpan? delay = null, + TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode, FrameworkLayer layer = FrameworkLayer.Composition) @@ -487,7 +487,7 @@ public AnimationBuilder Size( /// The optional starting point for the animation. /// The final point for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. /// The target framework layer to animate. @@ -495,8 +495,8 @@ public AnimationBuilder Size( public AnimationBuilder Size( Vector2? from, Vector2 to, - TimeSpan? delay, - TimeSpan duration, + TimeSpan? delay = null, + TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode, FrameworkLayer layer = FrameworkLayer.Composition) @@ -521,7 +521,7 @@ public AnimationBuilder Size( /// The optional starting point for the animation. /// The final point for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. /// The current instance. @@ -529,8 +529,8 @@ public AnimationBuilder Size( public AnimationBuilder Size( Vector3? from, Vector3 to, - TimeSpan? delay, - TimeSpan duration, + TimeSpan? delay = null, + TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs index e4cf322ae69..5f747c58205 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs @@ -23,7 +23,7 @@ private sealed record CompositionDoubleAnimation( string Property, float? From, float To, - TimeSpan? Delay, + TimeSpan Delay, TimeSpan Duration, EasingType EasingType, EasingMode EasingMode) @@ -46,7 +46,7 @@ private sealed record CompositionScalarAnimationFactory( string Property, float? From, float To, - TimeSpan? Delay, + TimeSpan Delay, TimeSpan Duration, EasingType EasingType, EasingMode EasingMode) @@ -69,7 +69,7 @@ private sealed record CompositionVector3AnimationFactory( string Property, Vector3? From, Vector3 To, - TimeSpan? Delay, + TimeSpan Delay, TimeSpan Duration, EasingType EasingType, EasingMode EasingMode) @@ -92,7 +92,7 @@ private sealed record CompositionClipScalarAnimation( string Property, float? From, float To, - TimeSpan? Delay, + TimeSpan Delay, TimeSpan Duration, EasingType EasingType, EasingMode EasingMode) @@ -116,7 +116,7 @@ private sealed record XamlDoubleAnimationFactory( string Property, double? From, double To, - TimeSpan? Delay, + TimeSpan Delay, TimeSpan Duration, EasingType EasingType, EasingMode EasingMode, @@ -137,7 +137,7 @@ private sealed record XamlTransformDoubleAnimationFactory( string Property, double? From, double To, - TimeSpan? Delay, + TimeSpan Delay, TimeSpan Duration, EasingType EasingType, EasingMode EasingMode) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs index 16fbc6a622a..76747c0a46c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Numerics; using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations { @@ -45,11 +46,18 @@ private AnimationBuilder AddCompositionScalarAnimationFactory( float? from, float to, TimeSpan? delay, - TimeSpan duration, + TimeSpan? duration, EasingType easingType, EasingMode easingMode) { - CompositionScalarAnimationFactory animation = new(property, from, to, delay, duration, easingType, easingMode); + CompositionScalarAnimationFactory animation = new( + property, + from, + to, + delay ?? DefaultDelay, + duration ?? DefaultDuration, + easingType, + easingMode); this.compositionAnimationFactories.Add(animation); @@ -72,11 +80,18 @@ private AnimationBuilder AddCompositionVector3AnimationFactory( Vector3? from, Vector3 to, TimeSpan? delay, - TimeSpan duration, + TimeSpan? duration, EasingType easingType, EasingMode easingMode) { - CompositionVector3AnimationFactory animation = new(property, from, to, delay, duration, easingType, easingMode); + CompositionVector3AnimationFactory animation = new( + property, + from, + to, + delay ?? DefaultDelay, + duration ?? DefaultDuration, + easingType, + easingMode); this.compositionAnimationFactories.Add(animation); @@ -100,12 +115,20 @@ private AnimationBuilder AddXamlDoubleAnimationFactory( double? from, double to, TimeSpan? delay, - TimeSpan duration, + TimeSpan? duration, EasingType easingType, EasingMode easingMode, bool enableDependentAnimation) { - XamlDoubleAnimationFactory animation = new(property, from, to, delay, duration, easingType, easingMode, enableDependentAnimation); + XamlDoubleAnimationFactory animation = new( + property, + from, + to, + delay ?? DefaultDelay, + duration ?? DefaultDuration, + easingType, + easingMode, + enableDependentAnimation); this.xamlAnimationFactories.Add(animation); @@ -128,11 +151,18 @@ private AnimationBuilder AddXamlTransformDoubleAnimationFactory( double? from, double to, TimeSpan? delay, - TimeSpan duration, + TimeSpan? duration, EasingType easingType, EasingMode easingMode) { - XamlTransformDoubleAnimationFactory animation = new(property, from, to, delay, duration, easingType, easingMode); + XamlTransformDoubleAnimationFactory animation = new( + property, + from, + to, + delay ?? DefaultDelay, + duration ?? DefaultDuration, + easingType, + easingMode); this.xamlAnimationFactories.Add(animation); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs index b0e7f2a109a..891f9765609 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs @@ -68,7 +68,7 @@ public AnimationBuilder DoubleAnimation( double? from, double to, TimeSpan? delay, - TimeSpan duration, + TimeSpan? duration, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { @@ -77,8 +77,8 @@ public AnimationBuilder DoubleAnimation( property, (float?)from, (float)to, - delay, - duration, + delay ?? DefaultDelay, + duration ?? DefaultDuration, easingType, easingMode); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs index 8195d4893dc..2d7ee81fd58 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs @@ -14,6 +14,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Extensions /// public static partial class AnimationExtensions { + /// + /// Gets the default delay of animations. + /// + public static TimeSpan DefaultDelay => default; + /// /// Gets the default duration of animations. /// From ec9cae6ea36f542ed950a2ecbf34c008c8a510eb Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 20 Dec 2020 19:56:53 +0100 Subject: [PATCH 048/171] Minor code tweaks --- .../Xaml/Default/OpacityAnimation.cs | 4 ++-- .../Xaml/Default/ScaleAnimation.cs | 4 ++-- .../Xaml/Default/TranslationAnimation.cs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs index 9c5b4669840..2271593f89d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs @@ -10,7 +10,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// /// An opacity animation working on the composition or XAML layer. - /// This animation maps to . + /// This animation maps to . /// public class OpacityAnimation : TypedAnimation, ITimeline { @@ -26,7 +26,7 @@ AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? d From, To, Delay ?? delayHint, - Duration ?? durationHint.GetValueOrDefault(), + Duration ?? durationHint, EasingType ?? easingTypeHint ?? DefaultEasingType, EasingMode ?? easingModeHint ?? DefaultEasingMode, Layer); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs index 0e4b2fe41dc..65008eb39c6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs @@ -11,7 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// /// A scale animation working on the composition or XAML layer. - /// This animation maps to . + /// This animation maps to . /// public class ScaleAnimation : TypedAnimation, ITimeline { @@ -24,7 +24,7 @@ public class ScaleAnimation : TypedAnimation, ITimeline AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { TimeSpan? delay = Delay ?? delayHint; - TimeSpan duration = Duration ?? durationHint.GetValueOrDefault(); + TimeSpan? duration = Duration ?? durationHint; EasingType easingType = EasingType ?? easingTypeHint ?? DefaultEasingType; EasingMode easingMode = EasingMode ?? easingModeHint ?? DefaultEasingMode; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs index 996701e2a61..8ddeca89c10 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs @@ -11,7 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// /// A translation animation working on the composition or XAML layer. - /// This animation maps to . + /// This animation maps to . /// public class TranslationAnimation : TypedAnimation, ITimeline { @@ -24,7 +24,7 @@ public class TranslationAnimation : TypedAnimation, ITimeline AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { TimeSpan? delay = Delay ?? delayHint; - TimeSpan duration = Duration ?? durationHint.GetValueOrDefault(); + TimeSpan? duration = Duration ?? durationHint; EasingType easingType = EasingType ?? easingTypeHint ?? DefaultEasingType; EasingMode easingMode = EasingMode ?? easingModeHint ?? DefaultEasingMode; From 56bc3fc4ea319dd32f61cb0c47ed951f0a867f3e Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 20 Dec 2020 20:22:53 +0100 Subject: [PATCH 049/171] Changed "from" parameters to be optional --- .../Builders/AnimationBuilder.Default.cs | 138 +++++++++--------- .../Builders/AnimationBuilder.Models.cs | 12 +- .../Builders/AnimationBuilder.Setup.cs | 24 +-- .../Builders/AnimationBuilder.cs | 12 +- .../Xaml/Abstract/TypedAnimation{T}.cs | 8 +- .../Xaml/Default/OpacityAnimation.cs | 6 +- .../Xaml/Default/ScaleAnimation.cs | 6 +- .../Xaml/Default/TranslationAnimation.cs | 6 +- 8 files changed, 106 insertions(+), 106 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs index 32ebc2c1f17..00d0307c6f6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs @@ -21,8 +21,8 @@ public sealed partial class AnimationBuilder /// /// Adds a new opacity animation to the current schedule. /// - /// The optional starting value for the animation. /// The final value for the animation. + /// The optional starting value for the animation. /// The optional initial delay for the animation. /// The optional animation duration. /// The optional easing function type for the animation. @@ -30,8 +30,8 @@ public sealed partial class AnimationBuilder /// The target framework layer to animate. /// The current instance. public AnimationBuilder Opacity( - double? from, double to, + double? from = null, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -40,11 +40,11 @@ public AnimationBuilder Opacity( { if (layer == FrameworkLayer.Composition) { - return AddCompositionScalarAnimationFactory(nameof(Visual.Opacity), (float?)from, (float)to, delay, duration, easingType, easingMode); + return AddCompositionScalarAnimationFactory(nameof(Visual.Opacity), (float)to, (float?)from, delay, duration, easingType, easingMode); } else { - return AddXamlDoubleAnimationFactory(nameof(UIElement.Opacity), from, to, delay, duration, easingType, easingMode, false); + return AddXamlDoubleAnimationFactory(nameof(UIElement.Opacity), to, from, delay, duration, easingType, easingMode, false); } } @@ -52,8 +52,8 @@ public AnimationBuilder Opacity( /// Adds a new translation animation for a single axis to the current schedule. /// /// The target translation axis to animate. - /// The optional starting value for the animation. /// The final value for the animation. + /// The optional starting value for the animation. /// The optional initial delay for the animation. /// The optional animation duration. /// The optional easing function type for the animation. @@ -62,8 +62,8 @@ public AnimationBuilder Opacity( /// The current instance. public AnimationBuilder Translation( Axis axis, - double? from, double to, + double? from = null, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -72,19 +72,19 @@ public AnimationBuilder Translation( { if (layer == FrameworkLayer.Composition) { - return AddCompositionScalarAnimationFactory($"Translation.{axis}", (float?)from, (float)to, delay, duration, easingType, easingMode); + return AddCompositionScalarAnimationFactory($"Translation.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); } else { - return AddXamlDoubleAnimationFactory($"Translate{axis}", from, to, delay, duration, easingType, easingMode, false); + return AddXamlDoubleAnimationFactory($"Translate{axis}", to, from, delay, duration, easingType, easingMode, false); } } /// /// Adds a new translation animation for the X and Y axes to the current schedule. /// - /// The optional starting point for the animation. /// The final point for the animation. + /// The optional starting point for the animation. /// The optional initial delay for the animation. /// The optional animation duration. /// The optional easing function type for the animation. @@ -92,8 +92,8 @@ public AnimationBuilder Translation( /// The target framework layer to animate. /// The current instance. public AnimationBuilder Translation( - Vector2? from, Vector2 to, + Vector2? from, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -102,13 +102,13 @@ public AnimationBuilder Translation( { if (layer == FrameworkLayer.Composition) { - AddCompositionScalarAnimationFactory("Translation.X", from?.X, to.X, delay, duration, easingType, easingMode); - AddCompositionScalarAnimationFactory("Translation.Y", from?.Y, to.Y, delay, duration, easingType, easingMode); + AddCompositionScalarAnimationFactory("Translation.X", to.X, from?.X, delay, duration, easingType, easingMode); + AddCompositionScalarAnimationFactory("Translation.Y", to.Y, from?.Y, delay, duration, easingType, easingMode); } else { - AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.TranslateX), from?.X, to.X, delay, duration, easingType, easingMode); - AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.TranslateY), from?.Y, to.Y, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.TranslateX), to.X, from?.X, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.TranslateY), to.Y, from?.Y, delay, duration, easingType, easingMode); } return this; @@ -117,8 +117,8 @@ public AnimationBuilder Translation( /// /// Adds a new composition translation animation for all axes to the current schedule. /// - /// The optional starting point for the animation. /// The final point for the animation. + /// The optional starting point for the animation. /// The optional initial delay for the animation. /// The optional animation duration. /// The optional easing function type for the animation. @@ -126,22 +126,22 @@ public AnimationBuilder Translation( /// The current instance. /// This animation is only available on the composition layer. public AnimationBuilder Translation( - Vector3? from, Vector3 to, + Vector3? from, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - return AddCompositionVector3AnimationFactory("Translation", from, to, delay, duration, easingType, easingMode); + return AddCompositionVector3AnimationFactory("Translation", to, from, delay, duration, easingType, easingMode); } /// /// Adds a new composition offset animation for a single axis to the current schedule. /// /// The target translation axis to animate. - /// The optional starting value for the animation. /// The final value for the animation. + /// The optional starting value for the animation. /// The optional initial delay for the animation. /// The optional animation duration. /// The optional easing function type for the animation. @@ -150,21 +150,21 @@ public AnimationBuilder Translation( /// This animation is only available on the composition layer. public AnimationBuilder Offset( Axis axis, - double? from, double to, + double? from, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - return AddCompositionScalarAnimationFactory($"{nameof(Visual.Offset)}.{axis}", (float?)from, (float)to, delay, duration, easingType, easingMode); + return AddCompositionScalarAnimationFactory($"{nameof(Visual.Offset)}.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); } /// /// Adds a new composition offset animation for the X and Y axes to the current schedule. /// - /// The optional starting point for the animation. /// The final point for the animation. + /// The optional starting point for the animation. /// The optional initial delay for the animation. /// The optional animation duration. /// The optional easing function type for the animation. @@ -172,15 +172,15 @@ public AnimationBuilder Offset( /// The current instance. /// This animation is only available on the composition layer. public AnimationBuilder Offset( - Vector2? from, Vector2 to, + Vector2? from, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - AddCompositionScalarAnimationFactory($"{nameof(Visual.Offset)}.X", from?.X, to.X, delay, duration, easingType, easingMode); - AddCompositionScalarAnimationFactory($"{nameof(Visual.Offset)}.Y", from?.Y, to.Y, delay, duration, easingType, easingMode); + AddCompositionScalarAnimationFactory($"{nameof(Visual.Offset)}.X", to.X, from?.X, delay, duration, easingType, easingMode); + AddCompositionScalarAnimationFactory($"{nameof(Visual.Offset)}.Y", to.Y, from?.Y, delay, duration, easingType, easingMode); return this; } @@ -188,8 +188,8 @@ public AnimationBuilder Offset( /// /// Adds a new composition offset translation animation for all axes to the current schedule. /// - /// The optional starting point for the animation. /// The final point for the animation. + /// The optional starting point for the animation. /// The optional initial delay for the animation. /// The optional animation duration. /// The optional easing function type for the animation. @@ -197,21 +197,21 @@ public AnimationBuilder Offset( /// The current instance. /// This animation is only available on the composition layer. public AnimationBuilder Offset( - Vector3? from, Vector3 to, + Vector3? from, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - return AddCompositionVector3AnimationFactory(nameof(Visual.Offset), from, to, delay, duration, easingType, easingMode); + return AddCompositionVector3AnimationFactory(nameof(Visual.Offset), to, from, delay, duration, easingType, easingMode); } /// /// Adds a new uniform scale animation for all axes to the current schedule. /// - /// The optional starting value for the animation. /// The final value for the animation. + /// The optional starting value for the animation. /// The optional initial delay for the animation. /// The optional animation duration. /// The optional easing function type for the animation. @@ -219,8 +219,8 @@ public AnimationBuilder Offset( /// The target framework layer to animate. /// The current instance. public AnimationBuilder Scale( - double? from, double to, + double? from, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -232,12 +232,12 @@ public AnimationBuilder Scale( Vector3? from3 = from is null ? null : new((float)(double)from); Vector3 to3 = new((float)to); - return AddCompositionVector3AnimationFactory(nameof(Visual.Scale), from3, to3, delay, duration, easingType, easingMode); + return AddCompositionVector3AnimationFactory(nameof(Visual.Scale), to3, from3, delay, duration, easingType, easingMode); } else { - AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleX), from, to, delay, duration, easingType, easingMode); - AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleY), from, to, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleX), to, from, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleY), to, from, delay, duration, easingType, easingMode); return this; } @@ -247,8 +247,8 @@ public AnimationBuilder Scale( /// Adds a new scale animation on a specified axis to the current schedule. /// /// The target scale axis to animate. - /// The optional starting value for the animation. /// The final value for the animation. + /// The optional starting value for the animation. /// The optional initial delay for the animation. /// The optional animation duration. /// The optional easing function type for the animation. @@ -257,8 +257,8 @@ public AnimationBuilder Scale( /// The current instance. public AnimationBuilder Scale( Axis axis, - double? from, double to, + double? from, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -267,19 +267,19 @@ public AnimationBuilder Scale( { if (layer == FrameworkLayer.Composition) { - return AddCompositionScalarAnimationFactory($"{nameof(Visual.Scale)}.{axis}", (float?)from, (float)to, delay, duration, easingType, easingMode); + return AddCompositionScalarAnimationFactory($"{nameof(Visual.Scale)}.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); } else { - return AddXamlTransformDoubleAnimationFactory($"Scale{axis}", from, to, delay, duration, easingType, easingMode); + return AddXamlTransformDoubleAnimationFactory($"Scale{axis}", to, from, delay, duration, easingType, easingMode); } } /// /// Adds a new scale animation for the X and Y axes to the current schedule. /// - /// The optional starting point for the animation. /// The final point for the animation. + /// The optional starting point for the animation. /// The optional initial delay for the animation. /// The optional animation duration. /// The optional easing function type for the animation. @@ -287,8 +287,8 @@ public AnimationBuilder Scale( /// The target framework layer to animate. /// The current instance. public AnimationBuilder Scale( - Vector2? from, Vector2 to, + Vector2? from, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -297,13 +297,13 @@ public AnimationBuilder Scale( { if (layer == FrameworkLayer.Composition) { - AddCompositionScalarAnimationFactory($"{nameof(Visual.Scale)}.X", from?.X, to.X, delay, duration, easingType, easingMode); - AddCompositionScalarAnimationFactory($"{nameof(Visual.Scale)}.Y", from?.Y, to.Y, delay, duration, easingType, easingMode); + AddCompositionScalarAnimationFactory($"{nameof(Visual.Scale)}.X", to.X, from?.X, delay, duration, easingType, easingMode); + AddCompositionScalarAnimationFactory($"{nameof(Visual.Scale)}.Y", to.Y, from?.Y, delay, duration, easingType, easingMode); } else { - AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleX), from?.X, to.X, delay, duration, easingType, easingMode); - AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleY), from?.Y, to.Y, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleX), to.X, from?.X, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleY), to.Y, from?.Y, delay, duration, easingType, easingMode); } return this; @@ -312,8 +312,8 @@ public AnimationBuilder Scale( /// /// Adds a new scale animation for all axes to the current schedule. /// - /// The optional starting point for the animation. /// The final point for the animation. + /// The optional starting point for the animation. /// The optional initial delay for the animation. /// The optional animation duration. /// The optional easing function type for the animation. @@ -321,21 +321,21 @@ public AnimationBuilder Scale( /// The current instance. /// This animation is only available on the composition layer. public AnimationBuilder Scale( - Vector3? from, Vector3 to, + Vector3? from, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - return AddCompositionVector3AnimationFactory(nameof(Visual.Scale), from, to, delay, duration, easingType, easingMode); + return AddCompositionVector3AnimationFactory(nameof(Visual.Scale), to, from, delay, duration, easingType, easingMode); } /// /// Adds a new rotation animation to the current schedule. /// - /// The optional starting value for the animation. /// The final value for the animation. + /// The optional starting value for the animation. /// The optional initial delay for the animation. /// The optional animation duration. /// The optional easing function type for the animation. @@ -343,8 +343,8 @@ public AnimationBuilder Scale( /// The target framework layer to animate. /// The current instance. public AnimationBuilder Rotate( - double? from, double to, + double? from, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -353,14 +353,14 @@ public AnimationBuilder Rotate( { if (layer == FrameworkLayer.Composition) { - return AddCompositionScalarAnimationFactory(nameof(Visual.RotationAngle), (float?)from, (float)to, delay, duration, easingType, easingMode); + return AddCompositionScalarAnimationFactory(nameof(Visual.RotationAngle), (float)to, (float?)from, delay, duration, easingType, easingMode); } else { double? fromDegrees = from * Math.PI / 180; double toDegrees = to * Math.PI / 180; - AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.Rotation), fromDegrees, toDegrees, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.Rotation), toDegrees, fromDegrees, delay, duration, easingType, easingMode); return this; } @@ -369,8 +369,8 @@ public AnimationBuilder Rotate( /// /// Adds a new rotation animation in degrees to the current schedule. /// - /// The optional starting value for the animation. /// The final value for the animation. + /// The optional starting value for the animation. /// The optional initial delay for the animation. /// The optional animation duration. /// The optional easing function type for the animation. @@ -378,8 +378,8 @@ public AnimationBuilder Rotate( /// The target framework layer to animate. /// The current instance. public AnimationBuilder RotateInDegrees( - double? from, double to, + double? from, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -388,11 +388,11 @@ public AnimationBuilder RotateInDegrees( { if (layer == FrameworkLayer.Composition) { - return AddCompositionScalarAnimationFactory(nameof(Visual.RotationAngleInDegrees), (float?)from, (float)to, delay, duration, easingType, easingMode); + return AddCompositionScalarAnimationFactory(nameof(Visual.RotationAngleInDegrees), (float)to, (float?)from, delay, duration, easingType, easingMode); } else { - AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.Rotation), from, to, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.Rotation), to, from, delay, duration, easingType, easingMode); return this; } @@ -402,8 +402,8 @@ public AnimationBuilder RotateInDegrees( /// Adds a new clip animation to the current schedule. /// /// The clip size to animate. - /// The optional starting value for the animation. /// The final value for the animation. + /// The optional starting value for the animation. /// The optional initial delay for the animation. /// The optional animation duration. /// The optional easing function type for the animation. @@ -412,8 +412,8 @@ public AnimationBuilder RotateInDegrees( /// This animation is only available on the composition layer. public AnimationBuilder Clip( Side side, - double? from, double to, + double? from, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -430,8 +430,8 @@ public AnimationBuilder Clip( CompositionClipScalarAnimation animation = new( property, - (float?)from, (float)to, + (float?)from, delay ?? DefaultDelay, duration ?? DefaultDuration, easingType, @@ -446,8 +446,8 @@ public AnimationBuilder Clip( /// Adds a new size animation for a single axis to the current schedule. /// /// The target size axis to animate. - /// The optional starting value for the animation. /// The final value for the animation. + /// The optional starting value for the animation. /// The optional initial delay for the animation. /// The optional animation duration. /// The optional easing function type for the animation. @@ -456,8 +456,8 @@ public AnimationBuilder Clip( /// The current instance. public AnimationBuilder Size( Axis axis, - double? from, double to, + double? from, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -466,7 +466,7 @@ public AnimationBuilder Size( { if (layer == FrameworkLayer.Composition) { - return AddCompositionScalarAnimationFactory($"{nameof(Visual.Size)}.{axis}", (float?)from, (float)to, delay, duration, easingType, easingMode); + return AddCompositionScalarAnimationFactory($"{nameof(Visual.Size)}.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); } else { @@ -477,15 +477,15 @@ public AnimationBuilder Size( _ => ThrowHelper.ThrowArgumentException("Invalid size axis") }; - return AddXamlDoubleAnimationFactory(property, from, to, delay, duration, easingType, easingMode, true); + return AddXamlDoubleAnimationFactory(property, to, from, delay, duration, easingType, easingMode, true); } } /// /// Adds a new size animation for the X and Y axes to the current schedule. /// - /// The optional starting point for the animation. /// The final point for the animation. + /// The optional starting point for the animation. /// The optional initial delay for the animation. /// The optional animation duration. /// The optional easing function type for the animation. @@ -493,8 +493,8 @@ public AnimationBuilder Size( /// The target framework layer to animate. /// The current instance. public AnimationBuilder Size( - Vector2? from, Vector2 to, + Vector2? from, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -503,13 +503,13 @@ public AnimationBuilder Size( { if (layer == FrameworkLayer.Composition) { - AddCompositionScalarAnimationFactory($"{nameof(Visual.Size)}.X", from?.X, to.X, delay, duration, easingType, easingMode); - AddCompositionScalarAnimationFactory($"{nameof(Visual.Size)}.Y", from?.Y, to.Y, delay, duration, easingType, easingMode); + AddCompositionScalarAnimationFactory($"{nameof(Visual.Size)}.X", to.X, from?.X, delay, duration, easingType, easingMode); + AddCompositionScalarAnimationFactory($"{nameof(Visual.Size)}.Y", to.Y, from?.Y, delay, duration, easingType, easingMode); } else { - AddXamlDoubleAnimationFactory(nameof(FrameworkElement.Width), from?.X, to.X, delay, duration, easingType, easingMode, true); - AddXamlDoubleAnimationFactory(nameof(FrameworkElement.Height), from?.Y, to.Y, delay, duration, easingType, easingMode, true); + AddXamlDoubleAnimationFactory(nameof(FrameworkElement.Width), to.X, from?.X, delay, duration, easingType, easingMode, true); + AddXamlDoubleAnimationFactory(nameof(FrameworkElement.Height), to.Y, from?.Y, delay, duration, easingType, easingMode, true); } return this; @@ -518,8 +518,8 @@ public AnimationBuilder Size( /// /// Adds a new composition size translation animation for all axes to the current schedule. /// - /// The optional starting point for the animation. /// The final point for the animation. + /// The optional starting point for the animation. /// The optional initial delay for the animation. /// The optional animation duration. /// The optional easing function type for the animation. @@ -527,14 +527,14 @@ public AnimationBuilder Size( /// The current instance. /// This animation is only available on the composition layer. public AnimationBuilder Size( - Vector3? from, Vector3 to, + Vector3? from, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - return AddCompositionVector3AnimationFactory(nameof(Visual.Size), from, to, delay, duration, easingType, easingMode); + return AddCompositionVector3AnimationFactory(nameof(Visual.Size), to, from, delay, duration, easingType, easingMode); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs index 5f747c58205..bc3ccb51421 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs @@ -21,8 +21,8 @@ public sealed partial class AnimationBuilder private sealed record CompositionDoubleAnimation( CompositionObject Target, string Property, - float? From, float To, + float? From, TimeSpan Delay, TimeSpan Duration, EasingType EasingType, @@ -44,8 +44,8 @@ public void StartAnimation() /// private sealed record CompositionScalarAnimationFactory( string Property, - float? From, float To, + float? From, TimeSpan Delay, TimeSpan Duration, EasingType EasingType, @@ -67,8 +67,8 @@ public CompositionAnimation GetAnimation(Visual visual) /// private sealed record CompositionVector3AnimationFactory( string Property, - Vector3? From, Vector3 To, + Vector3? From, TimeSpan Delay, TimeSpan Duration, EasingType EasingType, @@ -90,8 +90,8 @@ public CompositionAnimation GetAnimation(Visual visual) /// private sealed record CompositionClipScalarAnimation( string Property, - float? From, float To, + float? From, TimeSpan Delay, TimeSpan Duration, EasingType EasingType, @@ -114,8 +114,8 @@ public CompositionAnimation GetAnimation(Visual visual) /// private sealed record XamlDoubleAnimationFactory( string Property, - double? From, double To, + double? From, TimeSpan Delay, TimeSpan Duration, EasingType EasingType, @@ -135,8 +135,8 @@ public Timeline GetAnimation(UIElement element) ///
private sealed record XamlTransformDoubleAnimationFactory( string Property, - double? From, double To, + double? From, TimeSpan Delay, TimeSpan Duration, EasingType EasingType, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs index 76747c0a46c..47efc17574d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs @@ -34,8 +34,8 @@ public sealed partial class AnimationBuilder /// Adds a new composition scalar animation to the current schedule. ///
/// The target property to animate. - /// The optional starting value for the animation. /// The final value for the animation. + /// The optional starting value for the animation. /// The optional initial delay for the animation. /// The animation duration. /// The easing function for the animation. @@ -43,8 +43,8 @@ public sealed partial class AnimationBuilder /// The current instance. private AnimationBuilder AddCompositionScalarAnimationFactory( string property, - float? from, float to, + float? from, TimeSpan? delay, TimeSpan? duration, EasingType easingType, @@ -52,8 +52,8 @@ private AnimationBuilder AddCompositionScalarAnimationFactory( { CompositionScalarAnimationFactory animation = new( property, - from, to, + from, delay ?? DefaultDelay, duration ?? DefaultDuration, easingType, @@ -68,8 +68,8 @@ private AnimationBuilder AddCompositionScalarAnimationFactory( /// Adds a new composition animation to the current schedule. ///
/// The target property to animate. - /// The optional starting value for the animation. /// The final value for the animation. + /// The optional starting value for the animation. /// The optional initial delay for the animation. /// The animation duration. /// The easing function for the animation. @@ -77,8 +77,8 @@ private AnimationBuilder AddCompositionScalarAnimationFactory( /// The current instance. private AnimationBuilder AddCompositionVector3AnimationFactory( string property, - Vector3? from, Vector3 to, + Vector3? from, TimeSpan? delay, TimeSpan? duration, EasingType easingType, @@ -86,8 +86,8 @@ private AnimationBuilder AddCompositionVector3AnimationFactory( { CompositionVector3AnimationFactory animation = new( property, - from, to, + from, delay ?? DefaultDelay, duration ?? DefaultDuration, easingType, @@ -102,8 +102,8 @@ private AnimationBuilder AddCompositionVector3AnimationFactory( /// Adds a new XAML animation to the current schedule. /// /// The target property to animate. - /// The optional starting value for the animation. /// The final value for the animation. + /// The optional starting value for the animation. /// The optional initial delay for the animation. /// The animation duration. /// The easing function for the animation. @@ -112,8 +112,8 @@ private AnimationBuilder AddCompositionVector3AnimationFactory( /// The current instance. private AnimationBuilder AddXamlDoubleAnimationFactory( string property, - double? from, double to, + double? from, TimeSpan? delay, TimeSpan? duration, EasingType easingType, @@ -122,8 +122,8 @@ private AnimationBuilder AddXamlDoubleAnimationFactory( { XamlDoubleAnimationFactory animation = new( property, - from, to, + from, delay ?? DefaultDelay, duration ?? DefaultDuration, easingType, @@ -139,8 +139,8 @@ private AnimationBuilder AddXamlDoubleAnimationFactory( /// Adds a new XAML transform animation to the current schedule. /// /// The target property to animate. - /// The optional starting value for the animation. /// The final value for the animation. + /// The optional starting value for the animation. /// The optional initial delay for the animation. /// The animation duration. /// The easing function for the animation. @@ -148,8 +148,8 @@ private AnimationBuilder AddXamlDoubleAnimationFactory( /// The current instance. private AnimationBuilder AddXamlTransformDoubleAnimationFactory( string property, - double? from, double to, + double? from, TimeSpan? delay, TimeSpan? duration, EasingType easingType, @@ -157,8 +157,8 @@ private AnimationBuilder AddXamlTransformDoubleAnimationFactory( { XamlTransformDoubleAnimationFactory animation = new( property, - from, to, + from, delay ?? DefaultDelay, duration ?? DefaultDuration, easingType, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs index 891f9765609..d8c57e25caf 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs @@ -55,28 +55,28 @@ public sealed partial class AnimationBuilder /// /// The target to animate. /// The target property to animate. - /// The optional starting value for the animation. /// The final value for the animation. + /// The optional starting value for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. /// The optional easing function type for the animation. /// The optional easing function mode for the animation. /// The current instance. public AnimationBuilder DoubleAnimation( CompositionObject target, string property, - double? from, double to, - TimeSpan? delay, - TimeSpan? duration, + double? from = null, + TimeSpan? delay = null, + TimeSpan? duration = null, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { CompositionDoubleAnimation animation = new( target, property, - (float?)from, (float)to, + (float?)from, delay ?? DefaultDelay, duration ?? DefaultDuration, easingType, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs index abdd6d15e1c..d37a5efc8e9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs @@ -13,13 +13,13 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml public abstract class TypedAnimation : Animation { /// - /// Gets or sets the optional starting value for the animation. + /// Gets or sets the final value for the animation. /// - public T? From { get; set; } + public T? To { get; set; } /// - /// Gets or sets the final value for the animation. + /// Gets or sets the optional starting value for the animation. /// - public T? To { get; set; } + public T? From { get; set; } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs index 2271593f89d..9a837ce65da 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs @@ -10,9 +10,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// /// An opacity animation working on the composition or XAML layer. - /// This animation maps to . + /// This animation maps to . /// - public class OpacityAnimation : TypedAnimation, ITimeline + public class OpacityAnimation : TypedAnimation, ITimeline { /// /// Gets or sets the target framework layer to animate. @@ -23,8 +23,8 @@ public class OpacityAnimation : TypedAnimation, ITimeline AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { return builder.Opacity( + To!.Value, From, - To, Delay ?? delayHint, Duration ?? durationHint, EasingType ?? easingTypeHint ?? DefaultEasingType, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs index 65008eb39c6..7a5024c59af 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs @@ -11,7 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// /// A scale animation working on the composition or XAML layer. - /// This animation maps to . + /// This animation maps to . /// public class ScaleAnimation : TypedAnimation, ITimeline { @@ -30,11 +30,11 @@ AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? d if (Layer == FrameworkLayer.Composition) { - return builder.Scale(From?.ToVector3(), To!.ToVector3(), delay, duration, easingType, easingMode); + return builder.Scale(To!.ToVector3(), From?.ToVector3(), delay, duration, easingType, easingMode); } else { - return builder.Scale(From?.ToVector2(), To!.ToVector2(), delay, duration, easingType, easingMode, FrameworkLayer.Xaml); + return builder.Scale(To!.ToVector2(), From?.ToVector2(), delay, duration, easingType, easingMode, FrameworkLayer.Xaml); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs index 8ddeca89c10..75964ed10dd 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs @@ -11,7 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// /// A translation animation working on the composition or XAML layer. - /// This animation maps to . + /// This animation maps to . /// public class TranslationAnimation : TypedAnimation, ITimeline { @@ -30,11 +30,11 @@ AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? d if (Layer == FrameworkLayer.Composition) { - return builder.Translation(From?.ToVector3(), To!.ToVector3(), delay, duration, easingType, easingMode); + return builder.Translation(To!.ToVector3(), From?.ToVector3(), delay, duration, easingType, easingMode); } else { - return builder.Translation(From?.ToVector2(), To!.ToVector2(), delay, duration, easingType, easingMode, FrameworkLayer.Xaml); + return builder.Translation(To!.ToVector2(), From?.ToVector2(), delay, duration, easingType, easingMode, FrameworkLayer.Xaml); } } } From 4458505b374f0faf9fdc5c3d16832a49e56ae698 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 20 Dec 2020 22:42:08 +0100 Subject: [PATCH 050/171] Added missing nullable default values --- .../Builders/AnimationBuilder.Default.cs | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs index 00d0307c6f6..f5ed4a85fdd 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs @@ -93,7 +93,7 @@ public AnimationBuilder Translation( /// The current instance. public AnimationBuilder Translation( Vector2 to, - Vector2? from, + Vector2? from = null, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -127,7 +127,7 @@ public AnimationBuilder Translation( /// This animation is only available on the composition layer. public AnimationBuilder Translation( Vector3 to, - Vector3? from, + Vector3? from = null, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -151,7 +151,7 @@ public AnimationBuilder Translation( public AnimationBuilder Offset( Axis axis, double to, - double? from, + double? from = null, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -173,7 +173,7 @@ public AnimationBuilder Offset( /// This animation is only available on the composition layer. public AnimationBuilder Offset( Vector2 to, - Vector2? from, + Vector2? from = null, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -198,7 +198,7 @@ public AnimationBuilder Offset( /// This animation is only available on the composition layer. public AnimationBuilder Offset( Vector3 to, - Vector3? from, + Vector3? from = null, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -220,7 +220,7 @@ public AnimationBuilder Offset( /// The current instance. public AnimationBuilder Scale( double to, - double? from, + double? from = null, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -258,7 +258,7 @@ public AnimationBuilder Scale( public AnimationBuilder Scale( Axis axis, double to, - double? from, + double? from = null, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -288,7 +288,7 @@ public AnimationBuilder Scale( /// The current instance. public AnimationBuilder Scale( Vector2 to, - Vector2? from, + Vector2? from = null, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -322,7 +322,7 @@ public AnimationBuilder Scale( /// This animation is only available on the composition layer. public AnimationBuilder Scale( Vector3 to, - Vector3? from, + Vector3? from = null, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -344,7 +344,7 @@ public AnimationBuilder Scale( /// The current instance. public AnimationBuilder Rotate( double to, - double? from, + double? from = null, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -379,7 +379,7 @@ public AnimationBuilder Rotate( /// The current instance. public AnimationBuilder RotateInDegrees( double to, - double? from, + double? from = null, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -413,7 +413,7 @@ public AnimationBuilder RotateInDegrees( public AnimationBuilder Clip( Side side, double to, - double? from, + double? from = null, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -457,7 +457,7 @@ public AnimationBuilder Clip( public AnimationBuilder Size( Axis axis, double to, - double? from, + double? from = null, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -494,7 +494,7 @@ public AnimationBuilder Size( /// The current instance. public AnimationBuilder Size( Vector2 to, - Vector2? from, + Vector2? from = null, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, @@ -528,7 +528,7 @@ public AnimationBuilder Size( /// This animation is only available on the composition layer. public AnimationBuilder Size( Vector3 to, - Vector3? from, + Vector3? from = null, TimeSpan? delay = null, TimeSpan? duration = null, EasingType easingType = DefaultEasingType, From 07a85858ab58f832b489b522b90d27a53b3f799a Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Mon, 21 Dec 2020 13:39:30 +0100 Subject: [PATCH 051/171] Added more compositor animation extensions --- .../Builders/AnimationBuilder.Models.cs | 12 +- .../Extensions/CompositionObjectExtensions.cs | 84 ------ .../Extensions/CompositorExtensions.cs | 239 ++++++++++++++++-- .../Extensions/DependencyObjectExtensions.cs | 4 +- 4 files changed, 232 insertions(+), 107 deletions(-) delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs index bc3ccb51421..1b1ad4cb574 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs @@ -33,7 +33,7 @@ private sealed record CompositionDoubleAnimation( public void StartAnimation() { CompositionEasingFunction easingFunction = Target.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); - ScalarKeyFrameAnimation animation = Target.Compositor.CreateScalarKeyFrameAnimation(Property, From, To, Duration, Delay, easingFunction); + ScalarKeyFrameAnimation animation = Target.Compositor.CreateScalarKeyFrameAnimation(Property, To, From, Delay, Duration, easingFunction); Target.StartAnimation(Property, animation); } @@ -56,7 +56,7 @@ private sealed record CompositionScalarAnimationFactory( public CompositionAnimation GetAnimation(Visual visual) { CompositionEasingFunction easingFunction = visual.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); - ScalarKeyFrameAnimation animation = visual.Compositor.CreateScalarKeyFrameAnimation(Property, From, To, Duration, Delay, easingFunction); + ScalarKeyFrameAnimation animation = visual.Compositor.CreateScalarKeyFrameAnimation(Property, To, From, Delay, Duration, easingFunction); return animation; } @@ -79,7 +79,7 @@ private sealed record CompositionVector3AnimationFactory( public CompositionAnimation GetAnimation(Visual visual) { CompositionEasingFunction easingFunction = visual.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); - Vector3KeyFrameAnimation animation = visual.Compositor.CreateVector3KeyFrameAnimation(Property, From, To, Duration, Delay, easingFunction); + Vector3KeyFrameAnimation animation = visual.Compositor.CreateVector3KeyFrameAnimation(Property, To, From, Delay, Duration, easingFunction); return animation; } @@ -103,7 +103,7 @@ public CompositionAnimation GetAnimation(Visual visual) { InsetClip clip = visual.Clip as InsetClip ?? (InsetClip)(visual.Clip = visual.Compositor.CreateInsetClip()); CompositionEasingFunction easingFunction = clip.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); - ScalarKeyFrameAnimation animation = visual.Compositor.CreateScalarKeyFrameAnimation(Property, From, To, Duration, Delay, easingFunction); + ScalarKeyFrameAnimation animation = visual.Compositor.CreateScalarKeyFrameAnimation(Property, To, From, Delay, Duration, easingFunction); return animation; } @@ -126,7 +126,7 @@ private sealed record XamlDoubleAnimationFactory( /// public Timeline GetAnimation(UIElement element) { - return element.CreateDoubleAnimation(Property, From, To, Delay, Duration, EasingType.ToEasingFunction(EasingMode), EnableDependentAnimation); + return element.CreateDoubleAnimation(Property, To, From, Duration, Delay, EasingType.ToEasingFunction(EasingMode), EnableDependentAnimation); } } @@ -148,7 +148,7 @@ public Timeline GetAnimation(UIElement element) { CompositeTransform transform = element.GetTransform(); - return transform.CreateDoubleAnimation(Property, From, To, Delay, Duration, EasingType.ToEasingFunction(EasingMode)); + return transform.CreateDoubleAnimation(Property, To, From, Duration, Delay, EasingType.ToEasingFunction(EasingMode)); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs deleted file mode 100644 index d12081f4d9e..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs +++ /dev/null @@ -1,84 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#nullable enable - -using System; -using System.Numerics; -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.Extensions -{ - /// - /// An extension for the type. - /// - public static class CompositionObjectExtensions - { - /// - /// Creates and starts a scalar animation on the current . - /// - /// The target to animate. - /// The path that identifies the property to animate. - /// The optional starting value for the animation. - /// The final value for the animation. - /// The animation duration. - /// The optional initial delay for the animation. - /// The optional easing function for the animation. - public static void StartScalarAnimation( - this CompositionObject target, - string propertyPath, - float? from, - float to, - TimeSpan duration, - TimeSpan? delay, - CompositionEasingFunction? ease = null) - { - target.StartAnimation(propertyPath, target.Compositor.CreateScalarKeyFrameAnimation(null, from, to, duration, delay, ease)); - } - - /// - /// Creates and starts a animation on the current . - /// - /// The target to animate. - /// The path that identifies the property to animate. - /// The optional starting value for the animation. - /// The final value for the animation. - /// The animation duration. - /// The optional initial delay for the animation. - /// The optional easing function for the animation. - public static void StartVector2Animation( - this CompositionObject target, - string propertyPath, - Vector2? from, - Vector2 to, - TimeSpan duration, - TimeSpan? delay, - CompositionEasingFunction? ease = null) - { - target.StartAnimation(propertyPath, target.Compositor.CreateVector2KeyFrameAnimation(null, from, to, duration, delay, ease)); - } - - /// - /// Creates and starts a animation on the current . - /// - /// The target to animate. - /// The path that identifies the property to animate. - /// The optional starting value for the animation. - /// The final value for the animation. - /// The animation duration. - /// The optional initial delay for the animation. - /// The optional easing function for the animation. - public static void StartVector3Animation( - this CompositionObject target, - string propertyPath, - Vector3? from, - Vector3 to, - TimeSpan duration, - TimeSpan? delay, - CompositionEasingFunction? ease = null) - { - target.StartAnimation(propertyPath, target.Compositor.CreateVector3KeyFrameAnimation(null, from, to, duration, delay, ease)); - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs index c610ef4b866..293ec4a81a3 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs @@ -7,6 +7,7 @@ using System; using System.Diagnostics.Contracts; using System.Numerics; +using Windows.UI; using Windows.UI.Composition; using Windows.UI.Xaml.Media.Animation; @@ -48,24 +49,64 @@ public static CubicBezierEasingFunction CreateCubicBezierEasingFunction(this Com } /// - /// Creates a instance with the given parameters to on a target element. + /// Creates a instance with the given parameters to on a target element. /// /// The current instance used to create the animation. /// The optional target property to animate. - /// The optional starting value for the animation. /// The final value for the animation. + /// The optional starting value for the animation. + /// The optional initial delay for the animation. /// The animation duration. + /// A instance with the specified parameters. + [Pure] + public static BooleanKeyFrameAnimation CreateBooleanKeyFrameAnimation( + this Compositor compositor, + string? target, + bool to, + bool? from, + TimeSpan? delay, + TimeSpan duration) + { + BooleanKeyFrameAnimation animation = compositor.CreateBooleanKeyFrameAnimation(); + + animation.Duration = duration; + + if (delay.HasValue) + { + animation.DelayTime = delay.Value; + } + + animation.InsertKeyFrame(1, to); + + if (from.HasValue) + { + animation.InsertKeyFrame(0, from.Value); + } + + animation.Target = target; + + return animation; + } + + /// + /// Creates a instance with the given parameters to on a target element. + /// + /// The current instance used to create the animation. + /// The optional target property to animate. + /// The final value for the animation. + /// The optional starting value for the animation. /// The optional initial delay for the animation. + /// The animation duration. /// The optional easing function for the animation. /// A instance with the specified parameters. [Pure] public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation( this Compositor compositor, string? target, - float? from, float to, - TimeSpan duration, + float? from, TimeSpan? delay, + TimeSpan duration, CompositionEasingFunction? ease = null) { ScalarKeyFrameAnimation animation = compositor.CreateScalarKeyFrameAnimation(); @@ -77,7 +118,14 @@ public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation( animation.DelayTime = delay.Value; } - animation.InsertKeyFrame(1, to, ease ?? compositor.CreateLinearEasingFunction()); + if (ease is null) + { + animation.InsertKeyFrame(1, to); + } + else + { + animation.InsertKeyFrame(1, to, ease); + } if (from.HasValue) { @@ -94,20 +142,20 @@ public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation( /// /// The current instance used to create the animation. /// The optional target property to animate. - /// The optional starting value for the animation. /// The final value for the animation. - /// The animation duration. + /// The optional starting value for the animation. /// The optional initial delay for the animation. + /// The animation duration. /// The optional easing function for the animation. /// A instance with the specified parameters. [Pure] public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation( this Compositor compositor, string? target, - Vector2? from, Vector2 to, - TimeSpan duration, + Vector2? from, TimeSpan? delay, + TimeSpan duration, CompositionEasingFunction? ease = null) { Vector2KeyFrameAnimation animation = compositor.CreateVector2KeyFrameAnimation(); @@ -119,7 +167,14 @@ public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation( animation.DelayTime = delay.Value; } - animation.InsertKeyFrame(1, to, ease ?? compositor.CreateLinearEasingFunction()); + if (ease is null) + { + animation.InsertKeyFrame(1, to); + } + else + { + animation.InsertKeyFrame(1, to, ease); + } if (from.HasValue) { @@ -136,20 +191,20 @@ public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation( /// /// The current instance used to create the animation. /// The optional target property to animate. - /// The optional starting value for the animation. /// The final value for the animation. - /// The animation duration. + /// The optional starting value for the animation. /// The optional initial delay for the animation. + /// The animation duration. /// The optional easing function for the animation. /// A instance with the specified parameters. [Pure] public static Vector3KeyFrameAnimation CreateVector3KeyFrameAnimation( this Compositor compositor, string? target, - Vector3? from, Vector3 to, - TimeSpan duration, + Vector3? from, TimeSpan? delay, + TimeSpan duration, CompositionEasingFunction? ease = null) { Vector3KeyFrameAnimation animation = compositor.CreateVector3KeyFrameAnimation(); @@ -161,7 +216,161 @@ public static Vector3KeyFrameAnimation CreateVector3KeyFrameAnimation( animation.DelayTime = delay.Value; } - animation.InsertKeyFrame(1, to, ease ?? compositor.CreateLinearEasingFunction()); + if (ease is null) + { + animation.InsertKeyFrame(1, to); + } + else + { + animation.InsertKeyFrame(1, to, ease); + } + + if (from.HasValue) + { + animation.InsertKeyFrame(0, from.Value); + } + + animation.Target = target; + + return animation; + } + + /// + /// Creates a instance with the given parameters to on a target element. + /// + /// The current instance used to create the animation. + /// The optional target property to animate. + /// The final value for the animation. + /// The optional starting value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function for the animation. + /// A instance with the specified parameters. + [Pure] + public static Vector4KeyFrameAnimation CreateVector4KeyFrameAnimation( + this Compositor compositor, + string? target, + Vector4 to, + Vector4? from, + TimeSpan? delay, + TimeSpan duration, + CompositionEasingFunction? ease = null) + { + Vector4KeyFrameAnimation animation = compositor.CreateVector4KeyFrameAnimation(); + + animation.Duration = duration; + + if (delay.HasValue) + { + animation.DelayTime = delay.Value; + } + + if (ease is null) + { + animation.InsertKeyFrame(1, to); + } + else + { + animation.InsertKeyFrame(1, to, ease); + } + + if (from.HasValue) + { + animation.InsertKeyFrame(0, from.Value); + } + + animation.Target = target; + + return animation; + } + + /// + /// Creates a instance with the given parameters to on a target element. + /// + /// The current instance used to create the animation. + /// The optional target property to animate. + /// The final value for the animation. + /// The optional starting value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function for the animation. + /// A instance with the specified parameters. + [Pure] + public static ColorKeyFrameAnimation CreateColorKeyFrameAnimation( + this Compositor compositor, + string? target, + Color to, + Color? from, + TimeSpan? delay, + TimeSpan duration, + CompositionEasingFunction? ease = null) + { + ColorKeyFrameAnimation animation = compositor.CreateColorKeyFrameAnimation(); + + animation.Duration = duration; + + if (delay.HasValue) + { + animation.DelayTime = delay.Value; + } + + if (ease is null) + { + animation.InsertKeyFrame(1, to); + } + else + { + animation.InsertKeyFrame(1, to, ease); + } + + if (from.HasValue) + { + animation.InsertKeyFrame(0, from.Value); + } + + animation.Target = target; + + return animation; + } + + /// + /// Creates a instance with the given parameters to on a target element. + /// + /// The current instance used to create the animation. + /// The optional target property to animate. + /// The final value for the animation. + /// The optional starting value for the animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The optional easing function for the animation. + /// A instance with the specified parameters. + [Pure] + public static QuaternionKeyFrameAnimation CreateQuaternionKeyFrameAnimation( + this Compositor compositor, + string? target, + Quaternion to, + Quaternion? from, + TimeSpan? delay, + TimeSpan duration, + CompositionEasingFunction? ease = null) + { + QuaternionKeyFrameAnimation animation = compositor.CreateQuaternionKeyFrameAnimation(); + + animation.Duration = duration; + + if (delay.HasValue) + { + animation.DelayTime = delay.Value; + } + + if (ease is null) + { + animation.InsertKeyFrame(1, to); + } + else + { + animation.InsertKeyFrame(1, to, ease); + } if (from.HasValue) { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs index 4306f0310f7..071471ba778 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs @@ -21,8 +21,8 @@ public static class DependencyObjectExtensions /// /// The target to animate. /// The property to animate inside the target . - /// The optional initial property value. /// The final property value. + /// The optional initial property value. /// The optional delay for the animation. /// The duration of the . /// The easing function to use inside the . @@ -32,8 +32,8 @@ public static class DependencyObjectExtensions public static DoubleAnimation CreateDoubleAnimation( this DependencyObject target, string property, - double? from, double to, + double? from, TimeSpan? delay, TimeSpan duration, EasingFunctionBase? easing = null, From 406a298f1571ad461c419e2740a56357aca306a6 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Mon, 21 Dec 2020 13:46:39 +0100 Subject: [PATCH 052/171] Added missing XAML animation creation extensions --- .../Extensions/DependencyObjectExtensions.cs | 79 ++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs index 071471ba778..642dde9b8f7 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs @@ -6,6 +6,8 @@ using System; using System.Diagnostics.Contracts; +using Windows.Foundation; +using Windows.UI; using Windows.UI.Xaml; using Windows.UI.Xaml.Media.Animation; @@ -41,12 +43,87 @@ public static DoubleAnimation CreateDoubleAnimation( { DoubleAnimation animation = new() { + To = to, From = from, + BeginTime = delay, + Duration = duration, + EasingFunction = easing, + EnableDependentAnimation = enableDependecyAnimations + }; + + Storyboard.SetTarget(animation, target); + Storyboard.SetTargetProperty(animation, property); + + return animation; + } + + /// + /// Prepares a with the given info. + /// + /// The target to animate. + /// The property to animate inside the target . + /// The final property value. + /// The optional initial property value. + /// The optional delay for the animation. + /// The duration of the . + /// The easing function to use inside the . + /// Indicates whether or not to apply this animation to elements that need the visual tree to be rearranged. + /// A instance with the specified parameters. + [Pure] + public static PointAnimation CreatePointAnimation( + this DependencyObject target, + string property, + Point to, + Point? from, + TimeSpan? delay, + TimeSpan duration, + EasingFunctionBase? easing = null, + bool enableDependecyAnimations = false) + { + PointAnimation animation = new() + { To = to, + From = from, BeginTime = delay, Duration = duration, EasingFunction = easing, - EnableDependentAnimation = enableDependecyAnimations, + EnableDependentAnimation = enableDependecyAnimations + }; + + Storyboard.SetTarget(animation, target); + Storyboard.SetTargetProperty(animation, property); + + return animation; + } + + /// + /// Prepares a with the given info. + /// + /// The target to animate. + /// The property to animate inside the target . + /// The final property value. + /// The optional initial property value. + /// The optional delay for the animation. + /// The duration of the . + /// The easing function to use inside the . + /// A instance with the specified parameters. + [Pure] + public static ColorAnimation CreateColorAnimation( + this DependencyObject target, + string property, + Color to, + Color? from, + TimeSpan? delay, + TimeSpan duration, + EasingFunctionBase? easing = null) + { + ColorAnimation animation = new() + { + To = to, + From = from, + BeginTime = delay, + Duration = duration, + EasingFunction = easing }; Storyboard.SetTarget(animation, target); From a60c4280e3394c0ad191411ff0e4d8901408c83f Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Mon, 21 Dec 2020 14:15:10 +0100 Subject: [PATCH 053/171] Code refactoring, improved AnimationBuilder flexibility --- .../Builders/AnimationBuilder.Default.cs | 50 ++-- .../Builders/AnimationBuilder.Models.cs | 248 ++++++++++++++---- .../Builders/AnimationBuilder.Setup.cs | 62 +---- .../TimedKeyFrameAnimationBuilder{T}.Xaml.cs | 18 -- 4 files changed, 229 insertions(+), 149 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs index f5ed4a85fdd..d45af783d56 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs @@ -40,11 +40,11 @@ public AnimationBuilder Opacity( { if (layer == FrameworkLayer.Composition) { - return AddCompositionScalarAnimationFactory(nameof(Visual.Opacity), (float)to, (float?)from, delay, duration, easingType, easingMode); + return AddCompositionAnimationFactory(nameof(Visual.Opacity), (float)to, (float?)from, delay, duration, easingType, easingMode); } else { - return AddXamlDoubleAnimationFactory(nameof(UIElement.Opacity), to, from, delay, duration, easingType, easingMode, false); + return AddXamlAnimationFactory(nameof(UIElement.Opacity), to, from, delay, duration, easingType, easingMode); } } @@ -72,11 +72,11 @@ public AnimationBuilder Translation( { if (layer == FrameworkLayer.Composition) { - return AddCompositionScalarAnimationFactory($"Translation.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); + return AddCompositionAnimationFactory($"Translation.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); } else { - return AddXamlDoubleAnimationFactory($"Translate{axis}", to, from, delay, duration, easingType, easingMode, false); + return AddXamlAnimationFactory($"Translate{axis}", to, from, delay, duration, easingType, easingMode); } } @@ -102,8 +102,8 @@ public AnimationBuilder Translation( { if (layer == FrameworkLayer.Composition) { - AddCompositionScalarAnimationFactory("Translation.X", to.X, from?.X, delay, duration, easingType, easingMode); - AddCompositionScalarAnimationFactory("Translation.Y", to.Y, from?.Y, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory("Translation.X", to.X, from?.X, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory("Translation.Y", to.Y, from?.Y, delay, duration, easingType, easingMode); } else { @@ -133,7 +133,7 @@ public AnimationBuilder Translation( EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - return AddCompositionVector3AnimationFactory("Translation", to, from, delay, duration, easingType, easingMode); + return AddCompositionAnimationFactory("Translation", to, from, delay, duration, easingType, easingMode); } /// @@ -157,7 +157,7 @@ public AnimationBuilder Offset( EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - return AddCompositionScalarAnimationFactory($"{nameof(Visual.Offset)}.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); + return AddCompositionAnimationFactory($"{nameof(Visual.Offset)}.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); } /// @@ -179,8 +179,8 @@ public AnimationBuilder Offset( EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - AddCompositionScalarAnimationFactory($"{nameof(Visual.Offset)}.X", to.X, from?.X, delay, duration, easingType, easingMode); - AddCompositionScalarAnimationFactory($"{nameof(Visual.Offset)}.Y", to.Y, from?.Y, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory($"{nameof(Visual.Offset)}.X", to.X, from?.X, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory($"{nameof(Visual.Offset)}.Y", to.Y, from?.Y, delay, duration, easingType, easingMode); return this; } @@ -204,7 +204,7 @@ public AnimationBuilder Offset( EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - return AddCompositionVector3AnimationFactory(nameof(Visual.Offset), to, from, delay, duration, easingType, easingMode); + return AddCompositionAnimationFactory(nameof(Visual.Offset), to, from, delay, duration, easingType, easingMode); } /// @@ -232,7 +232,7 @@ public AnimationBuilder Scale( Vector3? from3 = from is null ? null : new((float)(double)from); Vector3 to3 = new((float)to); - return AddCompositionVector3AnimationFactory(nameof(Visual.Scale), to3, from3, delay, duration, easingType, easingMode); + return AddCompositionAnimationFactory(nameof(Visual.Scale), to3, from3, delay, duration, easingType, easingMode); } else { @@ -267,7 +267,7 @@ public AnimationBuilder Scale( { if (layer == FrameworkLayer.Composition) { - return AddCompositionScalarAnimationFactory($"{nameof(Visual.Scale)}.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); + return AddCompositionAnimationFactory($"{nameof(Visual.Scale)}.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); } else { @@ -297,8 +297,8 @@ public AnimationBuilder Scale( { if (layer == FrameworkLayer.Composition) { - AddCompositionScalarAnimationFactory($"{nameof(Visual.Scale)}.X", to.X, from?.X, delay, duration, easingType, easingMode); - AddCompositionScalarAnimationFactory($"{nameof(Visual.Scale)}.Y", to.Y, from?.Y, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory($"{nameof(Visual.Scale)}.X", to.X, from?.X, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory($"{nameof(Visual.Scale)}.Y", to.Y, from?.Y, delay, duration, easingType, easingMode); } else { @@ -328,7 +328,7 @@ public AnimationBuilder Scale( EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - return AddCompositionVector3AnimationFactory(nameof(Visual.Scale), to, from, delay, duration, easingType, easingMode); + return AddCompositionAnimationFactory(nameof(Visual.Scale), to, from, delay, duration, easingType, easingMode); } /// @@ -353,7 +353,7 @@ public AnimationBuilder Rotate( { if (layer == FrameworkLayer.Composition) { - return AddCompositionScalarAnimationFactory(nameof(Visual.RotationAngle), (float)to, (float?)from, delay, duration, easingType, easingMode); + return AddCompositionAnimationFactory(nameof(Visual.RotationAngle), (float)to, (float?)from, delay, duration, easingType, easingMode); } else { @@ -388,7 +388,7 @@ public AnimationBuilder RotateInDegrees( { if (layer == FrameworkLayer.Composition) { - return AddCompositionScalarAnimationFactory(nameof(Visual.RotationAngleInDegrees), (float)to, (float?)from, delay, duration, easingType, easingMode); + return AddCompositionAnimationFactory(nameof(Visual.RotationAngleInDegrees), (float)to, (float?)from, delay, duration, easingType, easingMode); } else { @@ -466,7 +466,7 @@ public AnimationBuilder Size( { if (layer == FrameworkLayer.Composition) { - return AddCompositionScalarAnimationFactory($"{nameof(Visual.Size)}.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); + return AddCompositionAnimationFactory($"{nameof(Visual.Size)}.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); } else { @@ -477,7 +477,7 @@ public AnimationBuilder Size( _ => ThrowHelper.ThrowArgumentException("Invalid size axis") }; - return AddXamlDoubleAnimationFactory(property, to, from, delay, duration, easingType, easingMode, true); + return AddXamlAnimationFactory(property, to, from, delay, duration, easingType, easingMode); } } @@ -503,13 +503,13 @@ public AnimationBuilder Size( { if (layer == FrameworkLayer.Composition) { - AddCompositionScalarAnimationFactory($"{nameof(Visual.Size)}.X", to.X, from?.X, delay, duration, easingType, easingMode); - AddCompositionScalarAnimationFactory($"{nameof(Visual.Size)}.Y", to.Y, from?.Y, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory($"{nameof(Visual.Size)}.X", to.X, from?.X, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory($"{nameof(Visual.Size)}.Y", to.Y, from?.Y, delay, duration, easingType, easingMode); } else { - AddXamlDoubleAnimationFactory(nameof(FrameworkElement.Width), to.X, from?.X, delay, duration, easingType, easingMode, true); - AddXamlDoubleAnimationFactory(nameof(FrameworkElement.Height), to.Y, from?.Y, delay, duration, easingType, easingMode, true); + AddXamlAnimationFactory(nameof(FrameworkElement.Width), to.X, from?.X, delay, duration, easingType, easingMode); + AddXamlAnimationFactory(nameof(FrameworkElement.Height), to.Y, from?.Y, delay, duration, easingType, easingMode); } return this; @@ -534,7 +534,7 @@ public AnimationBuilder Size( EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - return AddCompositionVector3AnimationFactory(nameof(Visual.Size), to, from, delay, duration, easingType, easingMode); + return AddCompositionAnimationFactory(nameof(Visual.Size), to, from, delay, duration, easingType, easingMode); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs index 1b1ad4cb574..d77f1445c26 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs @@ -3,8 +3,13 @@ // See the LICENSE file in the project root for more information. using System; +using System.Diagnostics.Contracts; using System.Numerics; +using System.Runtime.CompilerServices; +using Microsoft.Toolkit.Diagnostics; using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; +using Windows.Foundation; +using Windows.UI; using Windows.UI.Composition; using Windows.UI.Xaml; using Windows.UI.Xaml.Media; @@ -16,72 +21,220 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations public sealed partial class AnimationBuilder { /// - /// A model representing a specified composition double animation for a target . + /// A model representing a generic animation for a target object. /// - private sealed record CompositionDoubleAnimation( - CompositionObject Target, + private sealed record AnimationFactory( string Property, - float To, - float? From, + T To, + T? From, TimeSpan Delay, TimeSpan Duration, EasingType EasingType, EasingMode EasingMode) - : ICompositionAnimation + : ICompositionAnimationFactory, IXamlAnimationFactory + where T : unmanaged { /// - public void StartAnimation() + public CompositionAnimation GetAnimation(Visual visual) { - CompositionEasingFunction easingFunction = Target.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); - ScalarKeyFrameAnimation animation = Target.Compositor.CreateScalarKeyFrameAnimation(Property, To, From, Delay, Duration, easingFunction); + CompositionEasingFunction easingFunction = visual.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); - Target.StartAnimation(Property, animation); + if (typeof(T) == typeof(bool)) + { + return visual.Compositor.CreateBooleanKeyFrameAnimation( + Property, + GetToAs(), + GetFromAs(), + Delay, + Duration); + } + else if (typeof(T) == typeof(float)) + { + return visual.Compositor.CreateScalarKeyFrameAnimation( + Property, + GetToAs(), + GetFromAs(), + Delay, + Duration, + easingFunction); + } + else if (typeof(T) == typeof(double)) + { + return visual.Compositor.CreateScalarKeyFrameAnimation( + Property, + (float)GetToAs(), + (float)GetFromAs(), + Delay, + Duration, + easingFunction); + } + else if (typeof(T) == typeof(Vector2)) + { + return visual.Compositor.CreateVector2KeyFrameAnimation( + Property, + GetToAs(), + GetFromAs(), + Delay, + Duration, + easingFunction); + } + else if (typeof(T) == typeof(Vector3)) + { + return visual.Compositor.CreateVector3KeyFrameAnimation( + Property, + GetToAs(), + GetFromAs(), + Delay, + Duration, + easingFunction); + } + else if (typeof(T) == typeof(Vector4)) + { + return visual.Compositor.CreateVector4KeyFrameAnimation( + Property, + GetToAs(), + GetFromAs(), + Delay, + Duration, + easingFunction); + } + else if (typeof(T) == typeof(Color)) + { + return visual.Compositor.CreateColorKeyFrameAnimation( + Property, + GetToAs(), + GetFromAs(), + Delay, + Duration, + easingFunction); + } + else if (typeof(T) == typeof(Quaternion)) + { + return visual.Compositor.CreateQuaternionKeyFrameAnimation( + Property, + GetToAs(), + GetFromAs(), + Delay, + Duration, + easingFunction); + } + else + { + return ThrowHelper.ThrowInvalidOperationException("Invalid animation type"); + } } - } - /// - /// A model representing a specified composition scalar animation factory. - /// - private sealed record CompositionScalarAnimationFactory( - string Property, - float To, - float? From, - TimeSpan Delay, - TimeSpan Duration, - EasingType EasingType, - EasingMode EasingMode) - : ICompositionAnimationFactory - { /// - public CompositionAnimation GetAnimation(Visual visual) + public Timeline GetAnimation(UIElement element) { - CompositionEasingFunction easingFunction = visual.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); - ScalarKeyFrameAnimation animation = visual.Compositor.CreateScalarKeyFrameAnimation(Property, To, From, Delay, Duration, easingFunction); + EasingFunctionBase easingFunction = EasingType.ToEasingFunction(EasingMode); - return animation; + if (typeof(T) == typeof(float)) + { + return element.CreateDoubleAnimation( + Property, + GetToAs(), + GetFromAs(), + Delay, + Duration, + easingFunction, + true); + } + else if (typeof(T) == typeof(double)) + { + return element.CreateDoubleAnimation( + Property, + GetToAs(), + GetFromAs(), + Delay, + Duration, + easingFunction, + true); + } + else if (typeof(T) == typeof(Point)) + { + return element.CreatePointAnimation( + Property, + GetToAs(), + GetFromAs(), + Delay, + Duration, + easingFunction, + true); + } + else if (typeof(T) == typeof(Color)) + { + return element.CreateColorAnimation( + Property, + GetToAs(), + GetFromAs(), + Delay, + Duration, + easingFunction); + } + else + { + return ThrowHelper.ThrowInvalidOperationException("Invalid animation type"); + } + } + + /// + /// Gets the current target value as . + /// + /// The target value type to use. + /// The target type cast to . + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private TValue GetToAs() + where TValue : unmanaged + { + T to = To; + + return Unsafe.As(ref to); + } + + /// + /// Gets the current starting value as . + /// + /// The starting value type to use. + /// The starting type cast to nullable . + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private TValue? GetFromAs() + where TValue : unmanaged + { + if (From is null) + { + return null; + } + + T from = From.GetValueOrDefault(); + + return Unsafe.As(ref from); } } /// - /// A model representing a specified composition animation factory. + /// A model representing a specified composition double animation for a target . /// - private sealed record CompositionVector3AnimationFactory( + private sealed record CompositionDoubleAnimation( + CompositionObject Target, string Property, - Vector3 To, - Vector3? From, + float To, + float? From, TimeSpan Delay, TimeSpan Duration, EasingType EasingType, EasingMode EasingMode) - : ICompositionAnimationFactory + : ICompositionAnimation { /// - public CompositionAnimation GetAnimation(Visual visual) + public void StartAnimation() { - CompositionEasingFunction easingFunction = visual.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); - Vector3KeyFrameAnimation animation = visual.Compositor.CreateVector3KeyFrameAnimation(Property, To, From, Delay, Duration, easingFunction); + CompositionEasingFunction easingFunction = Target.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); + ScalarKeyFrameAnimation animation = Target.Compositor.CreateScalarKeyFrameAnimation(Property, To, From, Delay, Duration, easingFunction); - return animation; + Target.StartAnimation(Property, animation); } } @@ -109,27 +262,6 @@ public CompositionAnimation GetAnimation(Visual visual) } } - /// - /// A model representing a specified XAML animation factory. - /// - private sealed record XamlDoubleAnimationFactory( - string Property, - double To, - double? From, - TimeSpan Delay, - TimeSpan Duration, - EasingType EasingType, - EasingMode EasingMode, - bool EnableDependentAnimation) - : IXamlAnimationFactory - { - /// - public Timeline GetAnimation(UIElement element) - { - return element.CreateDoubleAnimation(Property, To, From, Duration, Delay, EasingType.ToEasingFunction(EasingMode), EnableDependentAnimation); - } - } - /// /// A model representing a specified XAML animation factory targeting a transform. /// diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs index 47efc17574d..593cb959d60 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; -using System.Numerics; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -31,8 +30,9 @@ public sealed partial class AnimationBuilder private readonly List xamlAnimationFactories = new(); /// - /// Adds a new composition scalar animation to the current schedule. + /// Adds a new composition animation to the current schedule. /// + /// The type of values to animate. /// The target property to animate. /// The final value for the animation. /// The optional starting value for the animation. @@ -41,16 +41,17 @@ public sealed partial class AnimationBuilder /// The easing function for the animation. /// The easing mode for the animation. /// The current instance. - private AnimationBuilder AddCompositionScalarAnimationFactory( + private AnimationBuilder AddCompositionAnimationFactory( string property, - float to, - float? from, + T to, + T? from, TimeSpan? delay, TimeSpan? duration, EasingType easingType, EasingMode easingMode) + where T : unmanaged { - CompositionScalarAnimationFactory animation = new( + AnimationFactory animation = new( property, to, from, @@ -65,8 +66,9 @@ private AnimationBuilder AddCompositionScalarAnimationFactory( } /// - /// Adds a new composition animation to the current schedule. + /// Adds a new XAML animation to the current schedule. /// + /// The type of values to animate. /// The target property to animate. /// The final value for the animation. /// The optional starting value for the animation. @@ -75,16 +77,17 @@ private AnimationBuilder AddCompositionScalarAnimationFactory( /// The easing function for the animation. /// The easing mode for the animation. /// The current instance. - private AnimationBuilder AddCompositionVector3AnimationFactory( + private AnimationBuilder AddXamlAnimationFactory( string property, - Vector3 to, - Vector3? from, + T to, + T? from, TimeSpan? delay, TimeSpan? duration, EasingType easingType, EasingMode easingMode) + where T : unmanaged { - CompositionVector3AnimationFactory animation = new( + AnimationFactory animation = new( property, to, from, @@ -93,43 +96,6 @@ private AnimationBuilder AddCompositionVector3AnimationFactory( easingType, easingMode); - this.compositionAnimationFactories.Add(animation); - - return this; - } - - /// - /// Adds a new XAML animation to the current schedule. - /// - /// The target property to animate. - /// The final value for the animation. - /// The optional starting value for the animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The easing function for the animation. - /// The easing mode for the animation. - /// Whether to set . - /// The current instance. - private AnimationBuilder AddXamlDoubleAnimationFactory( - string property, - double to, - double? from, - TimeSpan? delay, - TimeSpan? duration, - EasingType easingType, - EasingMode easingMode, - bool enableDependentAnimation) - { - XamlDoubleAnimationFactory animation = new( - property, - to, - from, - delay ?? DefaultDelay, - duration ?? DefaultDuration, - easingType, - easingMode, - enableDependentAnimation); - this.xamlAnimationFactories.Add(animation); return this; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs index 43e7dff65f8..15c23046387 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -70,24 +70,6 @@ public static Timeline GetAnimation( animation = doubleAnimation; } - else if (typeof(T) == typeof(Vector2)) - { - PointAnimationUsingKeyFrames pointAnimation = new() { EnableDependentAnimation = true }; - - foreach (var keyFrame in keyFrames) - { - Vector2 vector = keyFrame.GetValueAs(); - - pointAnimation.KeyFrames.Add(new EasingPointKeyFrame() - { - KeyTime = keyFrame.GetTimedProgress(duration), - Value = new Point(vector.X, vector.Y), - EasingFunction = keyFrame.EasingType.ToEasingFunction(keyFrame.EasingMode) - }); - } - - animation = pointAnimation; - } else if (typeof(T) == typeof(Point)) { PointAnimationUsingKeyFrames pointAnimation = new() { EnableDependentAnimation = true }; From 9105cf0313b04e2adf3025e357973286f6a218ee Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Mon, 21 Dec 2020 15:58:27 +0100 Subject: [PATCH 054/171] Minor code refactoring --- .../Xaml/Abstract/{TypedAnimation{T}.cs => Animation{T}.cs} | 2 +- .../Xaml/Default/OpacityAnimation.cs | 2 +- .../Xaml/Default/ScaleAnimation.cs | 2 +- .../Xaml/Default/TranslationAnimation.cs | 2 +- .../Animations/EffectDoubleAnimation.cs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/{TypedAnimation{T}.cs => Animation{T}.cs} (93%) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{T}.cs similarity index 93% rename from Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs rename to Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{T}.cs index d37a5efc8e9..8eac45cb5dc 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/TypedAnimation{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{T}.cs @@ -10,7 +10,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// A base model representing a typed animation that can be used in XAML. /// /// The type of values for the animation. - public abstract class TypedAnimation : Animation + public abstract class Animation : Animation { /// /// Gets or sets the final value for the animation. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs index 9a837ce65da..e5c1f0af3ad 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// An opacity animation working on the composition or XAML layer. /// This animation maps to . /// - public class OpacityAnimation : TypedAnimation, ITimeline + public class OpacityAnimation : Animation, ITimeline { /// /// Gets or sets the target framework layer to animate. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs index 7a5024c59af..cbeb0a6d234 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs @@ -13,7 +13,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// A scale animation working on the composition or XAML layer. /// This animation maps to . /// - public class ScaleAnimation : TypedAnimation, ITimeline + public class ScaleAnimation : Animation, ITimeline { /// /// Gets or sets the target framework layer to animate. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs index 75964ed10dd..255c52565f1 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs @@ -13,7 +13,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// A translation animation working on the composition or XAML layer. /// This animation maps to . /// - public class TranslationAnimation : TypedAnimation, ITimeline + public class TranslationAnimation : Animation, ITimeline { /// /// Gets or sets the target framework layer to animate. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs index 88c2083b992..0f804a9487d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs @@ -15,7 +15,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Animations /// /// A set of animations that can be grouped together. /// - public class EffectDoubleAnimation : TypedAnimation, ITimeline + public class EffectDoubleAnimation : Animation, ITimeline { /// /// Gets or sets the linked instance to animate. From 1d3de3c1e5ae4eb4332089d6b107a08560372c8c Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Mon, 21 Dec 2020 17:46:06 +0100 Subject: [PATCH 055/171] Improved internal AnimationBuilder architecture --- .../Builders/AnimationBuilder.Models.cs | 100 +++++++++--------- .../Builders/AnimationBuilder.Setup.cs | 5 - .../Builders/AnimationBuilder.cs | 51 +++++---- ...KeyFrameAnimationBuilder{T}.Composition.cs | 42 ++++---- ...malizedKeyFrameAnimationBuilder{T}.Xaml.cs | 4 +- ...KeyFrameAnimationBuilder{T}.Composition.cs | 8 +- .../TimedKeyFrameAnimationBuilder{T}.Xaml.cs | 11 +- .../Animations/EffectDoubleAnimation.cs | 2 +- 8 files changed, 113 insertions(+), 110 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs index d77f1445c26..8fe4b6dc2e4 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs @@ -15,6 +15,8 @@ using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media.Animation; +#nullable enable + namespace Microsoft.Toolkit.Uwp.UI.Animations { /// @@ -35,13 +37,15 @@ private sealed record AnimationFactory( where T : unmanaged { /// - public CompositionAnimation GetAnimation(Visual visual) + public CompositionAnimation GetAnimation(CompositionObject targetHint, out CompositionObject? target) { - CompositionEasingFunction easingFunction = visual.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); + CompositionEasingFunction easingFunction = targetHint.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); + + target = null; if (typeof(T) == typeof(bool)) { - return visual.Compositor.CreateBooleanKeyFrameAnimation( + return targetHint.Compositor.CreateBooleanKeyFrameAnimation( Property, GetToAs(), GetFromAs(), @@ -50,7 +54,7 @@ public CompositionAnimation GetAnimation(Visual visual) } else if (typeof(T) == typeof(float)) { - return visual.Compositor.CreateScalarKeyFrameAnimation( + return targetHint.Compositor.CreateScalarKeyFrameAnimation( Property, GetToAs(), GetFromAs(), @@ -60,17 +64,17 @@ public CompositionAnimation GetAnimation(Visual visual) } else if (typeof(T) == typeof(double)) { - return visual.Compositor.CreateScalarKeyFrameAnimation( + return targetHint.Compositor.CreateScalarKeyFrameAnimation( Property, (float)GetToAs(), - (float)GetFromAs(), + (float?)GetFromAs(), Delay, Duration, easingFunction); } else if (typeof(T) == typeof(Vector2)) { - return visual.Compositor.CreateVector2KeyFrameAnimation( + return targetHint.Compositor.CreateVector2KeyFrameAnimation( Property, GetToAs(), GetFromAs(), @@ -80,7 +84,7 @@ public CompositionAnimation GetAnimation(Visual visual) } else if (typeof(T) == typeof(Vector3)) { - return visual.Compositor.CreateVector3KeyFrameAnimation( + return targetHint.Compositor.CreateVector3KeyFrameAnimation( Property, GetToAs(), GetFromAs(), @@ -90,7 +94,7 @@ public CompositionAnimation GetAnimation(Visual visual) } else if (typeof(T) == typeof(Vector4)) { - return visual.Compositor.CreateVector4KeyFrameAnimation( + return targetHint.Compositor.CreateVector4KeyFrameAnimation( Property, GetToAs(), GetFromAs(), @@ -100,7 +104,7 @@ public CompositionAnimation GetAnimation(Visual visual) } else if (typeof(T) == typeof(Color)) { - return visual.Compositor.CreateColorKeyFrameAnimation( + return targetHint.Compositor.CreateColorKeyFrameAnimation( Property, GetToAs(), GetFromAs(), @@ -110,7 +114,7 @@ public CompositionAnimation GetAnimation(Visual visual) } else if (typeof(T) == typeof(Quaternion)) { - return visual.Compositor.CreateQuaternionKeyFrameAnimation( + return targetHint.Compositor.CreateQuaternionKeyFrameAnimation( Property, GetToAs(), GetFromAs(), @@ -125,13 +129,13 @@ public CompositionAnimation GetAnimation(Visual visual) } /// - public Timeline GetAnimation(UIElement element) + public Timeline GetAnimation(DependencyObject targetHint) { - EasingFunctionBase easingFunction = EasingType.ToEasingFunction(EasingMode); + EasingFunctionBase? easingFunction = EasingType.ToEasingFunction(EasingMode); if (typeof(T) == typeof(float)) { - return element.CreateDoubleAnimation( + return targetHint.CreateDoubleAnimation( Property, GetToAs(), GetFromAs(), @@ -142,7 +146,7 @@ public Timeline GetAnimation(UIElement element) } else if (typeof(T) == typeof(double)) { - return element.CreateDoubleAnimation( + return targetHint.CreateDoubleAnimation( Property, GetToAs(), GetFromAs(), @@ -153,7 +157,7 @@ public Timeline GetAnimation(UIElement element) } else if (typeof(T) == typeof(Point)) { - return element.CreatePointAnimation( + return targetHint.CreatePointAnimation( Property, GetToAs(), GetFromAs(), @@ -164,7 +168,7 @@ public Timeline GetAnimation(UIElement element) } else if (typeof(T) == typeof(Color)) { - return element.CreateColorAnimation( + return targetHint.CreateColorAnimation( Property, GetToAs(), GetFromAs(), @@ -215,10 +219,9 @@ private TValue GetToAs() } /// - /// A model representing a specified composition double animation for a target . + /// A model representing a specified composition scalar animation factory targeting a clip. /// - private sealed record CompositionDoubleAnimation( - CompositionObject Target, + private sealed record CompositionClipScalarAnimation( string Property, float To, float? From, @@ -226,22 +229,27 @@ private sealed record CompositionDoubleAnimation( TimeSpan Duration, EasingType EasingType, EasingMode EasingMode) - : ICompositionAnimation + : ICompositionAnimationFactory { /// - public void StartAnimation() + public CompositionAnimation GetAnimation(CompositionObject targetHint, out CompositionObject? target) { - CompositionEasingFunction easingFunction = Target.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); - ScalarKeyFrameAnimation animation = Target.Compositor.CreateScalarKeyFrameAnimation(Property, To, From, Delay, Duration, easingFunction); + Visual visual = (Visual)targetHint; + InsetClip clip = visual.Clip as InsetClip ?? (InsetClip)(visual.Clip = visual.Compositor.CreateInsetClip()); + CompositionEasingFunction easingFunction = clip.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); + ScalarKeyFrameAnimation animation = clip.Compositor.CreateScalarKeyFrameAnimation(Property, To, From, Delay, Duration, easingFunction); - Target.StartAnimation(Property, animation); + target = clip; + + return animation; } } /// - /// A model representing a specified composition scalar animation factory targeting a clip. + /// A model representing a specified composition double animation for a target . /// - private sealed record CompositionClipScalarAnimation( + private sealed record CompositionDoubleAnimation( + CompositionObject Target, string Property, float To, float? From, @@ -252,11 +260,12 @@ private sealed record CompositionClipScalarAnimation( : ICompositionAnimationFactory { /// - public CompositionAnimation GetAnimation(Visual visual) + public CompositionAnimation GetAnimation(CompositionObject targetHint, out CompositionObject? target) { - InsetClip clip = visual.Clip as InsetClip ?? (InsetClip)(visual.Clip = visual.Compositor.CreateInsetClip()); - CompositionEasingFunction easingFunction = clip.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); - ScalarKeyFrameAnimation animation = visual.Compositor.CreateScalarKeyFrameAnimation(Property, To, From, Delay, Duration, easingFunction); + CompositionEasingFunction easingFunction = Target.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); + ScalarKeyFrameAnimation animation = Target.Compositor.CreateScalarKeyFrameAnimation(Property, To, From, Delay, Duration, easingFunction); + + target = Target; return animation; } @@ -276,9 +285,9 @@ private sealed record XamlTransformDoubleAnimationFactory( : IXamlAnimationFactory { /// - public Timeline GetAnimation(UIElement element) + public Timeline GetAnimation(DependencyObject targetHint) { - CompositeTransform transform = element.GetTransform(); + CompositeTransform transform = ((UIElement)targetHint).GetTransform(); return transform.CreateDoubleAnimation(Property, To, From, Duration, Delay, EasingType.ToEasingFunction(EasingMode)); } @@ -292,9 +301,9 @@ internal interface IXamlAnimationFactory /// /// Gets a instance representing the animation to start. /// - /// The target instance to animate. + /// The suggested target instance to animate. /// A instance with the specified animation. - Timeline GetAnimation(UIElement element); + Timeline GetAnimation(DependencyObject targetHint); } /// @@ -305,20 +314,15 @@ internal interface ICompositionAnimationFactory /// /// Gets a instance representing the animation to start. /// - /// The target instance to animate. + /// The suggested target instance to animate. + /// An optional instance to animate instead of the suggested one. /// A instance with the specified animation. - CompositionAnimation GetAnimation(Visual visual); - } - - /// - /// An interface for custom external composition animations. - /// - internal interface ICompositionAnimation - { - /// - /// Starts a with some embedded parameters. - /// - void StartAnimation(); + /// + /// The separate parameter is needed because unlike with XAML animations, composition animations + /// can't store the target instance internally, and need to be started on the target object directly. This means that custom + /// animation factories that want to target an external object need to return that object separately to inform the callers. + /// + CompositionAnimation GetAnimation(CompositionObject targetHint, out CompositionObject? target); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs index 593cb959d60..240ea88bb65 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Setup.cs @@ -14,11 +14,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// public sealed partial class AnimationBuilder { - /// - /// The list of instances representing animations to run. - /// - private readonly List compositionAnimations = new(); - /// /// The list of instances representing factories for composition animations to run. /// diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs index d8c57e25caf..24804087c31 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs @@ -82,7 +82,7 @@ public AnimationBuilder DoubleAnimation( easingType, easingMode); - this.compositionAnimations.Add(animation); + this.compositionAnimationFactories.Add(animation); return this; } @@ -93,27 +93,25 @@ public AnimationBuilder DoubleAnimation( /// The target to animate. public void Start(UIElement element) { - if (this.compositionAnimations.Count > 0) - { - foreach (var animation in this.compositionAnimations) - { - animation.StartAnimation(); - } - } - if (this.compositionAnimationFactories.Count > 0) { ElementCompositionPreview.SetIsTranslationEnabled(element, true); Visual visual = ElementCompositionPreview.GetElementVisual(element); - CompositionAnimationGroup group = visual.Compositor.CreateAnimationGroup(); foreach (var factory in this.compositionAnimationFactories) { - group.Add(factory.GetAnimation(visual)); + var animation = factory.GetAnimation(visual, out var target); + + if (target is null) + { + visual.StartAnimation(animation.Target, animation); + } + else + { + target.StartAnimation(animation.Target, animation); + } } - - visual.StartAnimationGroup(group); } if (this.xamlAnimationFactories.Count > 0) @@ -140,31 +138,30 @@ public Task StartAsync(UIElement element) compositionTask = Task.CompletedTask, xamlTask = Task.CompletedTask; - if (this.compositionAnimationFactories.Count > 0 || - this.compositionAnimations.Count > 0) + if (this.compositionAnimationFactories.Count > 0) { + ElementCompositionPreview.SetIsTranslationEnabled(element, true); + Visual visual = ElementCompositionPreview.GetElementVisual(element); CompositionScopedBatch batch = visual.Compositor.CreateScopedBatch(CompositionBatchTypes.Animation); TaskCompletionSource taskCompletionSource = new(); batch.Completed += (_, _) => taskCompletionSource.SetResult(null); - foreach (var animation in this.compositionAnimations) - { - animation.StartAnimation(); - } - - ElementCompositionPreview.SetIsTranslationEnabled(element, true); - - CompositionAnimationGroup group = visual.Compositor.CreateAnimationGroup(); - foreach (var factory in this.compositionAnimationFactories) { - group.Add(factory.GetAnimation(visual)); + var animation = factory.GetAnimation(visual, out var target); + + if (target is null) + { + visual.StartAnimation(animation.Target, animation); + } + else + { + target.StartAnimation(animation.Target, animation); + } } - visual.StartAnimationGroup(group); - batch.End(); compositionTask = taskCompletionSource.Task; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs index 015dc487541..8269d9538c8 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs @@ -10,6 +10,8 @@ using Windows.UI; using Windows.UI.Composition; +#nullable enable + namespace Microsoft.Toolkit.Uwp.UI.Animations { /// @@ -19,14 +21,14 @@ internal abstract partial class NormalizedKeyFrameAnimationBuilder /// Gets a instance representing the animation to start. /// /// The type of keyframes being used to define the animation. - /// The target instance to animate. + /// The target instance to animate. /// The target property to animate. /// The optional initial delay for the animation. /// The animation duration. /// The list of keyframes to use to build the animation. /// A instance with the specified animation. public static CompositionAnimation GetAnimation( - Visual visual, + CompositionObject target, string property, TimeSpan? delay, TimeSpan duration, @@ -37,7 +39,7 @@ public static CompositionAnimation GetAnimation( if (typeof(T) == typeof(bool)) { - BooleanKeyFrameAnimation boolAnimation = visual.Compositor.CreateBooleanKeyFrameAnimation(); + BooleanKeyFrameAnimation boolAnimation = target.Compositor.CreateBooleanKeyFrameAnimation(); foreach (var keyFrame in keyFrames) { @@ -50,98 +52,98 @@ public static CompositionAnimation GetAnimation( } else if (typeof(T) == typeof(float)) { - ScalarKeyFrameAnimation scalarAnimation = visual.Compositor.CreateScalarKeyFrameAnimation(); + ScalarKeyFrameAnimation scalarAnimation = target.Compositor.CreateScalarKeyFrameAnimation(); foreach (var keyFrame in keyFrames) { scalarAnimation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs(), - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + target.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); } animation = scalarAnimation; } else if (typeof(T) == typeof(double)) { - ScalarKeyFrameAnimation scalarAnimation = visual.Compositor.CreateScalarKeyFrameAnimation(); + ScalarKeyFrameAnimation scalarAnimation = target.Compositor.CreateScalarKeyFrameAnimation(); foreach (var keyFrame in keyFrames) { scalarAnimation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), (float)keyFrame.GetValueAs(), - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + target.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); } animation = scalarAnimation; } else if (typeof(T) == typeof(Vector2)) { - Vector2KeyFrameAnimation vector2Animation = visual.Compositor.CreateVector2KeyFrameAnimation(); + Vector2KeyFrameAnimation vector2Animation = target.Compositor.CreateVector2KeyFrameAnimation(); foreach (var keyFrame in keyFrames) { vector2Animation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs(), - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + target.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); } animation = vector2Animation; } else if (typeof(T) == typeof(Vector3)) { - Vector3KeyFrameAnimation vector3Animation = visual.Compositor.CreateVector3KeyFrameAnimation(); + Vector3KeyFrameAnimation vector3Animation = target.Compositor.CreateVector3KeyFrameAnimation(); foreach (var keyFrame in keyFrames) { vector3Animation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs(), - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + target.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); } animation = vector3Animation; } else if (typeof(T) == typeof(Vector4)) { - Vector4KeyFrameAnimation vector4Animation = visual.Compositor.CreateVector4KeyFrameAnimation(); + Vector4KeyFrameAnimation vector4Animation = target.Compositor.CreateVector4KeyFrameAnimation(); foreach (var keyFrame in keyFrames) { vector4Animation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs(), - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + target.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); } animation = vector4Animation; } else if (typeof(T) == typeof(Color)) { - ColorKeyFrameAnimation colorAnimation = visual.Compositor.CreateColorKeyFrameAnimation(); + ColorKeyFrameAnimation colorAnimation = target.Compositor.CreateColorKeyFrameAnimation(); foreach (var keyFrame in keyFrames) { colorAnimation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs(), - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + target.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); } animation = colorAnimation; } else if (typeof(T) == typeof(Quaternion)) { - QuaternionKeyFrameAnimation quaternionAnimation = visual.Compositor.CreateQuaternionKeyFrameAnimation(); + QuaternionKeyFrameAnimation quaternionAnimation = target.Compositor.CreateQuaternionKeyFrameAnimation(); foreach (var keyFrame in keyFrames) { quaternionAnimation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs(), - visual.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + target.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); } animation = quaternionAnimation; @@ -178,10 +180,12 @@ public Composition(string property, TimeSpan? delay, TimeSpan duration) } /// - public CompositionAnimation GetAnimation(Visual visual) + public CompositionAnimation GetAnimation(CompositionObject targetHint, out CompositionObject? target) { + target = null; + return GetAnimation( - visual, + targetHint, this.property, this.delay, this.duration, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs index e4ca796c97b..1f98e954866 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -27,10 +27,10 @@ public Xaml(string property, TimeSpan? delay, TimeSpan duration) } /// - public Timeline GetAnimation(UIElement element) + public Timeline GetAnimation(DependencyObject targetHint) { return TimedKeyFrameAnimationBuilder.GetAnimation( - element, + targetHint, this.property, this.delay, this.duration, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs index 6c01782e47f..d3ba7ac0084 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs @@ -5,6 +5,8 @@ using System; using Windows.UI.Composition; +#nullable enable + namespace Microsoft.Toolkit.Uwp.UI.Animations { /// @@ -26,14 +28,16 @@ public Composition(string property, TimeSpan? delay) } /// - public CompositionAnimation GetAnimation(Visual visual) + public CompositionAnimation GetAnimation(CompositionObject targetHint, out CompositionObject? target) { + target = null; + // We can retrieve the total duration from the last timed keyframe, and then set // this as the target duration and use it to normalize the keyframe progresses. TimeSpan duration = this.keyFrames[this.keyFrames.Count - 1].GetTimedProgress(default); return NormalizedKeyFrameAnimationBuilder.GetAnimation( - visual, + targetHint, this.property, this.delay, duration, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs index 15c23046387..6678f6bc2ed 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; -using System.Numerics; using Microsoft.Toolkit.Diagnostics; using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; using Windows.Foundation; @@ -22,14 +21,14 @@ internal abstract partial class TimedKeyFrameAnimationBuilder : ITimedKeyFram /// Gets a instance representing the animation to start. /// /// The type of keyframes being used to define the animation. - /// The target instance to animate. + /// The target instance to animate. /// The target property to animate. /// The optional initial delay for the animation. /// The animation duration. /// The list of keyframes to use to build the animation. /// A instance with the specified animation. public static Timeline GetAnimation( - UIElement element, + DependencyObject target, string property, TimeSpan? delay, TimeSpan duration, @@ -109,7 +108,7 @@ public static Timeline GetAnimation( animation.BeginTime = delay; - Storyboard.SetTarget(animation, element); + Storyboard.SetTarget(animation, target); Storyboard.SetTargetProperty(animation, property); return animation; @@ -130,10 +129,10 @@ public Xaml(string property, TimeSpan? delay) } /// - public Timeline GetAnimation(UIElement element) + public Timeline GetAnimation(DependencyObject targetHint) { return GetAnimation( - element, + targetHint, this.property, this.delay, default, diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs index 0f804a9487d..01c3d830575 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs @@ -30,8 +30,8 @@ AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? d return builder.DoubleAnimation( effect.Brush, $"{effect.Id}.{nameof(GaussianBlurEffect.BlurAmount)}", - From, To, + From, Delay ?? delayHint, Duration ?? durationHint.GetValueOrDefault(), EasingType ?? easingTypeHint ?? DefaultEasingType, From 203b9077bff88ce614a838e0990c6efb6b4833f1 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Mon, 21 Dec 2020 19:13:45 +0100 Subject: [PATCH 056/171] Added new Clip animation overload --- .../Builders/AnimationBuilder.Default.cs | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs index d45af783d56..b71dcf550c9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs @@ -442,6 +442,64 @@ public AnimationBuilder Clip( return this; } + /// + /// Adds a new clip animation to the current schedule. + /// + /// The final value for the animation. + /// The optional starting value for the animation. + /// The optional initial delay for the animation. + /// The optional animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder Clip( + Thickness to, + Thickness? from = null, + TimeSpan? delay = null, + TimeSpan? duration = null, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + this.compositionAnimationFactories.Add(new CompositionClipScalarAnimation( + nameof(InsetClip.LeftInset), + (float)to.Left, + (float?)from?.Left, + delay ?? DefaultDelay, + duration ?? DefaultDuration, + easingType, + easingMode)); + + this.compositionAnimationFactories.Add(new CompositionClipScalarAnimation( + nameof(InsetClip.TopInset), + (float)to.Top, + (float?)from?.Top, + delay ?? DefaultDelay, + duration ?? DefaultDuration, + easingType, + easingMode)); + + this.compositionAnimationFactories.Add(new CompositionClipScalarAnimation( + nameof(InsetClip.RightInset), + (float)to.Right, + (float?)from?.Right, + delay ?? DefaultDelay, + duration ?? DefaultDuration, + easingType, + easingMode)); + + this.compositionAnimationFactories.Add(new CompositionClipScalarAnimation( + nameof(InsetClip.BottomInset), + (float)to.Bottom, + (float?)from?.Bottom, + delay ?? DefaultDelay, + duration ?? DefaultDuration, + easingType, + easingMode)); + + return this; + } + /// /// Adds a new size animation for a single axis to the current schedule. /// From 89e097a7454b333dbd8b7b582cefcfa7c107e44a Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Mon, 21 Dec 2020 21:51:33 +0100 Subject: [PATCH 057/171] Added missing default animation XAML nodes --- .../Xaml/Default/ClipAnimation.cs | 29 ++++++++++++++ .../Xaml/Default/OffsetAnimation.cs | 29 ++++++++++++++ .../Xaml/Default/OpacityAnimation.cs | 1 - .../Xaml/Default/RotationAnimation.cs | 34 ++++++++++++++++ .../Default/RotationInDegreesAnimation.cs | 34 ++++++++++++++++ .../Xaml/Default/ScaleAnimation.cs | 1 - .../Xaml/Default/SizeAnimation.cs | 40 +++++++++++++++++++ .../Xaml/Default/TranslationAnimation.cs | 1 - 8 files changed, 166 insertions(+), 3 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs new file mode 100644 index 00000000000..96761a3d469 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// A clip animation working on the composition layer. + /// + public class ClipAnimation : Animation, ITimeline + { + /// + AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + { + return builder.Clip( + To!.Value, + From, + Delay ?? delayHint, + Duration ?? durationHint, + EasingType ?? easingTypeHint ?? DefaultEasingType, + EasingMode ?? easingModeHint ?? DefaultEasingMode); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs new file mode 100644 index 00000000000..4ab0528c873 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.Toolkit.Uwp.UI.Extensions; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// An offset animation working on the composition layer. + /// + public class OffsetAnimation : Animation, ITimeline + { + /// + AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + { + return builder.Translation( + To!.ToVector3(), + From?.ToVector3(), + Delay ?? delayHint, + Duration ?? durationHint, + EasingType ?? easingTypeHint ?? DefaultEasingType, + EasingMode ?? easingModeHint ?? DefaultEasingMode); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs index e5c1f0af3ad..5dc950b6061 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs @@ -10,7 +10,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// /// An opacity animation working on the composition or XAML layer. - /// This animation maps to . /// public class OpacityAnimation : Animation, ITimeline { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs new file mode 100644 index 00000000000..984404b8d29 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// A rotation animation working on the composition or XAML layer. + /// + public class RotationAnimation : Animation, ITimeline + { + /// + /// Gets or sets the target framework layer to animate. + /// + public FrameworkLayer Layer { get; set; } + + /// + AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + { + return builder.Rotate( + To!.Value, + From, + Delay ?? delayHint, + Duration ?? durationHint, + EasingType ?? easingTypeHint ?? DefaultEasingType, + EasingMode ?? easingModeHint ?? DefaultEasingMode, + Layer); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs new file mode 100644 index 00000000000..a42f3847c70 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// A rotation in degrees animation working on the composition or XAML layer. + /// + public class RotationInDegreesAnimation : Animation, ITimeline + { + /// + /// Gets or sets the target framework layer to animate. + /// + public FrameworkLayer Layer { get; set; } + + /// + AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + { + return builder.RotateInDegrees( + To!.Value, + From, + Delay ?? delayHint, + Duration ?? durationHint, + EasingType ?? easingTypeHint ?? DefaultEasingType, + EasingMode ?? easingModeHint ?? DefaultEasingMode, + Layer); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs index cbeb0a6d234..cd4b5a46ef1 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs @@ -11,7 +11,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// /// A scale animation working on the composition or XAML layer. - /// This animation maps to . /// public class ScaleAnimation : Animation, ITimeline { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs new file mode 100644 index 00000000000..fddbaa03979 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.Toolkit.Uwp.UI.Extensions; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// A size animation working on the composition or XAML layer. + /// + public class SizeAnimation : Animation, ITimeline + { + /// + /// Gets or sets the target framework layer to animate. + /// + public FrameworkLayer Layer { get; set; } + + /// + AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + { + TimeSpan? delay = Delay ?? delayHint; + TimeSpan? duration = Duration ?? durationHint; + EasingType easingType = EasingType ?? easingTypeHint ?? DefaultEasingType; + EasingMode easingMode = EasingMode ?? easingModeHint ?? DefaultEasingMode; + + if (Layer == FrameworkLayer.Composition) + { + return builder.Size(To!.ToVector3(), From?.ToVector3(), delay, duration, easingType, easingMode); + } + else + { + return builder.Size(To!.ToVector2(), From?.ToVector2(), delay, duration, easingType, easingMode, FrameworkLayer.Xaml); + } + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs index 255c52565f1..3b7c5974952 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs @@ -11,7 +11,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// /// A translation animation working on the composition or XAML layer. - /// This animation maps to . /// public class TranslationAnimation : Animation, ITimeline { From 22b605153046a9d3e583e09ba926e236c7410a8b Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 22 Dec 2020 00:01:25 +0100 Subject: [PATCH 058/171] Minor code tweaks --- .../NormalizedKeyFrameAnimationBuilder{T}.Composition.cs | 2 +- .../Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs | 4 ++-- .../Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs | 4 ++-- .../Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs index 8269d9538c8..a13a322c70a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs @@ -171,7 +171,7 @@ public static CompositionAnimation GetAnimation( public sealed class Composition : NormalizedKeyFrameAnimationBuilder, AnimationBuilder.ICompositionAnimationFactory { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// public Composition(string property, TimeSpan? delay, TimeSpan duration) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs index 1f98e954866..a3bfca3c7a5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -9,7 +9,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - internal abstract partial class NormalizedKeyFrameAnimationBuilder : INormalizedKeyFrameAnimationBuilder + internal abstract partial class NormalizedKeyFrameAnimationBuilder where T : unmanaged { /// @@ -18,7 +18,7 @@ internal abstract partial class NormalizedKeyFrameAnimationBuilder : INormali public sealed class Xaml : NormalizedKeyFrameAnimationBuilder, AnimationBuilder.IXamlAnimationFactory { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// public Xaml(string property, TimeSpan? delay, TimeSpan duration) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs index d3ba7ac0084..eb89c2288ad 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs @@ -10,7 +10,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - internal abstract partial class TimedKeyFrameAnimationBuilder : ITimedKeyFrameAnimationBuilder + internal abstract partial class TimedKeyFrameAnimationBuilder where T : unmanaged { /// @@ -19,7 +19,7 @@ internal abstract partial class TimedKeyFrameAnimationBuilder : ITimedKeyFram public sealed class Composition : TimedKeyFrameAnimationBuilder, AnimationBuilder.ICompositionAnimationFactory { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// public Composition(string property, TimeSpan? delay) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs index 6678f6bc2ed..333c7d25dce 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -14,7 +14,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - internal abstract partial class TimedKeyFrameAnimationBuilder : ITimedKeyFrameAnimationBuilder + internal abstract partial class TimedKeyFrameAnimationBuilder where T : unmanaged { /// @@ -120,7 +120,7 @@ public static Timeline GetAnimation( public sealed class Xaml : TimedKeyFrameAnimationBuilder, AnimationBuilder.IXamlAnimationFactory { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// public Xaml(string property, TimeSpan? delay) From a59bb79ce5b5c39327c389ea0c76d4c56f79d91a Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 22 Dec 2020 00:04:08 +0100 Subject: [PATCH 059/171] More small code tweaks --- .../Builders/AnimationBuilder.Models.cs | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs index 8fe4b6dc2e4..adcad50390c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs @@ -52,7 +52,8 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo Delay, Duration); } - else if (typeof(T) == typeof(float)) + + if (typeof(T) == typeof(float)) { return targetHint.Compositor.CreateScalarKeyFrameAnimation( Property, @@ -62,7 +63,8 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo Duration, easingFunction); } - else if (typeof(T) == typeof(double)) + + if (typeof(T) == typeof(double)) { return targetHint.Compositor.CreateScalarKeyFrameAnimation( Property, @@ -72,7 +74,8 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo Duration, easingFunction); } - else if (typeof(T) == typeof(Vector2)) + + if (typeof(T) == typeof(Vector2)) { return targetHint.Compositor.CreateVector2KeyFrameAnimation( Property, @@ -82,7 +85,8 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo Duration, easingFunction); } - else if (typeof(T) == typeof(Vector3)) + + if (typeof(T) == typeof(Vector3)) { return targetHint.Compositor.CreateVector3KeyFrameAnimation( Property, @@ -92,7 +96,8 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo Duration, easingFunction); } - else if (typeof(T) == typeof(Vector4)) + + if (typeof(T) == typeof(Vector4)) { return targetHint.Compositor.CreateVector4KeyFrameAnimation( Property, @@ -102,7 +107,8 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo Duration, easingFunction); } - else if (typeof(T) == typeof(Color)) + + if (typeof(T) == typeof(Color)) { return targetHint.Compositor.CreateColorKeyFrameAnimation( Property, @@ -112,7 +118,8 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo Duration, easingFunction); } - else if (typeof(T) == typeof(Quaternion)) + + if (typeof(T) == typeof(Quaternion)) { return targetHint.Compositor.CreateQuaternionKeyFrameAnimation( Property, @@ -122,10 +129,8 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo Duration, easingFunction); } - else - { - return ThrowHelper.ThrowInvalidOperationException("Invalid animation type"); - } + + return ThrowHelper.ThrowInvalidOperationException("Invalid animation type"); } /// @@ -144,7 +149,8 @@ public Timeline GetAnimation(DependencyObject targetHint) easingFunction, true); } - else if (typeof(T) == typeof(double)) + + if (typeof(T) == typeof(double)) { return targetHint.CreateDoubleAnimation( Property, @@ -155,7 +161,8 @@ public Timeline GetAnimation(DependencyObject targetHint) easingFunction, true); } - else if (typeof(T) == typeof(Point)) + + if (typeof(T) == typeof(Point)) { return targetHint.CreatePointAnimation( Property, @@ -166,7 +173,8 @@ public Timeline GetAnimation(DependencyObject targetHint) easingFunction, true); } - else if (typeof(T) == typeof(Color)) + + if (typeof(T) == typeof(Color)) { return targetHint.CreateColorAnimation( Property, @@ -176,10 +184,8 @@ public Timeline GetAnimation(DependencyObject targetHint) Duration, easingFunction); } - else - { - return ThrowHelper.ThrowInvalidOperationException("Invalid animation type"); - } + + return ThrowHelper.ThrowInvalidOperationException("Invalid animation type"); } /// From 829f15af9651e74f865eacccf7c02000360fb5b7 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 22 Dec 2020 01:17:38 +0100 Subject: [PATCH 060/171] Added ListBuilder type --- .../Builders/Helpers/ListBuilder{T}.cs | 69 +++++++++++++++++++ ...KeyFrameAnimationBuilder{T}.Composition.cs | 21 +++--- ...malizedKeyFrameAnimationBuilder{T}.Xaml.cs | 2 +- .../NormalizedKeyFrameAnimationBuilder{T}.cs | 8 +-- ...KeyFrameAnimationBuilder{T}.Composition.cs | 5 +- .../TimedKeyFrameAnimationBuilder{T}.Xaml.cs | 5 +- .../TimedKeyFrameAnimationBuilder{T}.cs | 8 +-- 7 files changed, 93 insertions(+), 25 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Builders/Helpers/ListBuilder{T}.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Helpers/ListBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Helpers/ListBuilder{T}.cs new file mode 100644 index 00000000000..df9bc575253 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Helpers/ListBuilder{T}.cs @@ -0,0 +1,69 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Diagnostics.Contracts; +using System.Runtime.CompilerServices; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Builders.Helpers +{ + /// + /// A small generic builder type that allows to create instances. + /// + /// The type of items to create a sequence of. + internal struct ListBuilder + { + /// + /// The array in use. + /// + private T[] array; + + /// + /// The current index. + /// + private int index; + + /// + /// Gets an emoty instance. + /// + public static ListBuilder Empty + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + ListBuilder builder; + builder.array = new T[1]; + builder.index = 0; + + return builder; + } + } + + /// + /// Appens an item to the current builder. + /// + /// The item to append. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(T item) + { + if (this.index >= this.array.Length) + { + Array.Resize(ref this.array, this.array.Length * 2); + } + + this.array[this.index++] = item; + } + + /// + /// Gets a instance with the current items. + /// + /// A instance with the current items. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ReadOnlySpan AsSpan() + { + return this.array.AsSpan(0, this.index); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs index a13a322c70a..d25869055c1 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; using System.Numerics; using Microsoft.Toolkit.Diagnostics; using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; @@ -32,7 +31,7 @@ public static CompositionAnimation GetAnimation( string property, TimeSpan? delay, TimeSpan duration, - List keyFrames) + ReadOnlySpan keyFrames) where TKeyFrame : struct, IKeyFrameInfo { KeyFrameAnimation animation; @@ -41,7 +40,7 @@ public static CompositionAnimation GetAnimation( { BooleanKeyFrameAnimation boolAnimation = target.Compositor.CreateBooleanKeyFrameAnimation(); - foreach (var keyFrame in keyFrames) + foreach (ref readonly var keyFrame in keyFrames) { boolAnimation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), @@ -54,7 +53,7 @@ public static CompositionAnimation GetAnimation( { ScalarKeyFrameAnimation scalarAnimation = target.Compositor.CreateScalarKeyFrameAnimation(); - foreach (var keyFrame in keyFrames) + foreach (ref readonly var keyFrame in keyFrames) { scalarAnimation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), @@ -68,7 +67,7 @@ public static CompositionAnimation GetAnimation( { ScalarKeyFrameAnimation scalarAnimation = target.Compositor.CreateScalarKeyFrameAnimation(); - foreach (var keyFrame in keyFrames) + foreach (ref readonly var keyFrame in keyFrames) { scalarAnimation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), @@ -82,7 +81,7 @@ public static CompositionAnimation GetAnimation( { Vector2KeyFrameAnimation vector2Animation = target.Compositor.CreateVector2KeyFrameAnimation(); - foreach (var keyFrame in keyFrames) + foreach (ref readonly var keyFrame in keyFrames) { vector2Animation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), @@ -96,7 +95,7 @@ public static CompositionAnimation GetAnimation( { Vector3KeyFrameAnimation vector3Animation = target.Compositor.CreateVector3KeyFrameAnimation(); - foreach (var keyFrame in keyFrames) + foreach (ref readonly var keyFrame in keyFrames) { vector3Animation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), @@ -110,7 +109,7 @@ public static CompositionAnimation GetAnimation( { Vector4KeyFrameAnimation vector4Animation = target.Compositor.CreateVector4KeyFrameAnimation(); - foreach (var keyFrame in keyFrames) + foreach (ref readonly var keyFrame in keyFrames) { vector4Animation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), @@ -124,7 +123,7 @@ public static CompositionAnimation GetAnimation( { ColorKeyFrameAnimation colorAnimation = target.Compositor.CreateColorKeyFrameAnimation(); - foreach (var keyFrame in keyFrames) + foreach (ref readonly var keyFrame in keyFrames) { colorAnimation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), @@ -138,7 +137,7 @@ public static CompositionAnimation GetAnimation( { QuaternionKeyFrameAnimation quaternionAnimation = target.Compositor.CreateQuaternionKeyFrameAnimation(); - foreach (var keyFrame in keyFrames) + foreach (ref readonly var keyFrame in keyFrames) { quaternionAnimation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), @@ -189,7 +188,7 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo this.property, this.delay, this.duration, - this.keyFrames); + this.keyFrames.AsSpan()); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs index a3bfca3c7a5..4c9479e4b57 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -34,7 +34,7 @@ public Timeline GetAnimation(DependencyObject targetHint) this.property, this.delay, this.duration, - this.keyFrames); + this.keyFrames.AsSpan()); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs index 85e2d11cb0c..46d1cc4eaf8 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs @@ -3,8 +3,8 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; using System.Runtime.CompilerServices; +using Microsoft.Toolkit.Uwp.UI.Animations.Builders.Helpers; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -33,9 +33,9 @@ internal abstract partial class NormalizedKeyFrameAnimationBuilder : INormali private readonly TimeSpan duration; /// - /// The list of keyframes to use. + /// The list builder of keyframes to use. /// - private readonly List keyFrames = new(); + private ListBuilder keyFrames = ListBuilder.Empty; /// /// Initializes a new instance of the class. @@ -57,7 +57,7 @@ public INormalizedKeyFrameAnimationBuilder KeyFrame( EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - this.keyFrames.Add(new(progress, value, easingType, easingMode)); + this.keyFrames.Append(new(progress, value, easingType, easingMode)); return this; } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs index eb89c2288ad..1f9428a5016 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs @@ -34,14 +34,15 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo // We can retrieve the total duration from the last timed keyframe, and then set // this as the target duration and use it to normalize the keyframe progresses. - TimeSpan duration = this.keyFrames[this.keyFrames.Count - 1].GetTimedProgress(default); + ReadOnlySpan keyFrames = this.keyFrames.AsSpan(); + TimeSpan duration = keyFrames[keyFrames.Length - 1].GetTimedProgress(default); return NormalizedKeyFrameAnimationBuilder.GetAnimation( targetHint, this.property, this.delay, duration, - this.keyFrames); + keyFrames); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs index 333c7d25dce..c94da75dc6b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; using Microsoft.Toolkit.Diagnostics; using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; using Windows.Foundation; @@ -32,7 +31,7 @@ public static Timeline GetAnimation( string property, TimeSpan? delay, TimeSpan duration, - List keyFrames) + ReadOnlySpan keyFrames) where TKeyFrame : struct, IKeyFrameInfo { Timeline animation; @@ -136,7 +135,7 @@ public Timeline GetAnimation(DependencyObject targetHint) this.property, this.delay, default, - this.keyFrames); + this.keyFrames.AsSpan()); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs index 6ad0400c2f3..05319991138 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs @@ -3,8 +3,8 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; using System.Runtime.CompilerServices; +using Microsoft.Toolkit.Uwp.UI.Animations.Builders.Helpers; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -28,9 +28,9 @@ internal abstract partial class TimedKeyFrameAnimationBuilder : ITimedKeyFram private readonly TimeSpan? delay; /// - /// The list of keyframes to use. + /// The list builder of keyframes to use. /// - private readonly List keyFrames = new(); + private ListBuilder keyFrames = ListBuilder.Empty; /// /// Initializes a new instance of the class. @@ -50,7 +50,7 @@ public ITimedKeyFrameAnimationBuilder KeyFrame( EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - this.keyFrames.Add(new(progress, value, easingType, easingMode)); + this.keyFrames.Append(new(progress, value, easingType, easingMode)); return this; } From 126797db169cb667577bf26e259f0f217ed9289a Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 22 Dec 2020 01:39:56 +0100 Subject: [PATCH 061/171] Minor code style tweaks --- .../Builders/AnimationBuilder.Default.cs | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs index b71dcf550c9..203e4201428 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs @@ -40,12 +40,14 @@ public AnimationBuilder Opacity( { if (layer == FrameworkLayer.Composition) { - return AddCompositionAnimationFactory(nameof(Visual.Opacity), (float)to, (float?)from, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory(nameof(Visual.Opacity), (float)to, (float?)from, delay, duration, easingType, easingMode); } else { - return AddXamlAnimationFactory(nameof(UIElement.Opacity), to, from, delay, duration, easingType, easingMode); + AddXamlAnimationFactory(nameof(UIElement.Opacity), to, from, delay, duration, easingType, easingMode); } + + return this; } /// @@ -72,12 +74,14 @@ public AnimationBuilder Translation( { if (layer == FrameworkLayer.Composition) { - return AddCompositionAnimationFactory($"Translation.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory($"Translation.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); } else { - return AddXamlAnimationFactory($"Translate{axis}", to, from, delay, duration, easingType, easingMode); + AddXamlAnimationFactory($"Translate{axis}", to, from, delay, duration, easingType, easingMode); } + + return this; } /// @@ -232,15 +236,15 @@ public AnimationBuilder Scale( Vector3? from3 = from is null ? null : new((float)(double)from); Vector3 to3 = new((float)to); - return AddCompositionAnimationFactory(nameof(Visual.Scale), to3, from3, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory(nameof(Visual.Scale), to3, from3, delay, duration, easingType, easingMode); } else { AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleX), to, from, delay, duration, easingType, easingMode); AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.ScaleY), to, from, delay, duration, easingType, easingMode); - - return this; } + + return this; } /// @@ -267,12 +271,14 @@ public AnimationBuilder Scale( { if (layer == FrameworkLayer.Composition) { - return AddCompositionAnimationFactory($"{nameof(Visual.Scale)}.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory($"{nameof(Visual.Scale)}.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); } else { - return AddXamlTransformDoubleAnimationFactory($"Scale{axis}", to, from, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory($"Scale{axis}", to, from, delay, duration, easingType, easingMode); } + + return this; } /// @@ -353,7 +359,7 @@ public AnimationBuilder Rotate( { if (layer == FrameworkLayer.Composition) { - return AddCompositionAnimationFactory(nameof(Visual.RotationAngle), (float)to, (float?)from, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory(nameof(Visual.RotationAngle), (float)to, (float?)from, delay, duration, easingType, easingMode); } else { @@ -361,9 +367,9 @@ public AnimationBuilder Rotate( double toDegrees = to * Math.PI / 180; AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.Rotation), toDegrees, fromDegrees, delay, duration, easingType, easingMode); - - return this; } + + return this; } /// @@ -388,14 +394,14 @@ public AnimationBuilder RotateInDegrees( { if (layer == FrameworkLayer.Composition) { - return AddCompositionAnimationFactory(nameof(Visual.RotationAngleInDegrees), (float)to, (float?)from, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory(nameof(Visual.RotationAngleInDegrees), (float)to, (float?)from, delay, duration, easingType, easingMode); } else { AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.Rotation), to, from, delay, duration, easingType, easingMode); - - return this; } + + return this; } /// @@ -524,7 +530,7 @@ public AnimationBuilder Size( { if (layer == FrameworkLayer.Composition) { - return AddCompositionAnimationFactory($"{nameof(Visual.Size)}.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory($"{nameof(Visual.Size)}.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); } else { @@ -535,8 +541,10 @@ public AnimationBuilder Size( _ => ThrowHelper.ThrowArgumentException("Invalid size axis") }; - return AddXamlAnimationFactory(property, to, from, delay, duration, easingType, easingMode); + AddXamlAnimationFactory(property, to, from, delay, duration, easingType, easingMode); } + + return this; } /// From c8e0567cee4a73645fe85fcd2511d8d352e1e72b Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 22 Dec 2020 01:58:40 +0100 Subject: [PATCH 062/171] Added missing animation APIs --- .../Builders/AnimationBuilder.Default.cs | 189 +++++++++++++++++- .../Xaml/Default/RotationAnimation.cs | 2 +- .../Default/RotationInDegreesAnimation.cs | 2 +- 3 files changed, 189 insertions(+), 4 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs index 203e4201428..6ca522abfe5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs @@ -18,6 +18,57 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// public sealed partial class AnimationBuilder { + /// + /// Adds a new anchor point animation for a single axis to the current schedule. + /// + /// The target anchor point axis to animate. + /// The final value for the animation. + /// The optional starting value for the animation. + /// The optional initial delay for the animation. + /// The optional animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder AnchorPoint( + Axis axis, + double to, + double? from = null, + TimeSpan? delay = null, + TimeSpan? duration = null, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + AddCompositionAnimationFactory($"{nameof(Visual.AnchorPoint)}.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory($"{nameof(Visual.AnchorPoint)}.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); + + return this; + } + + /// + /// Adds a new anchor point animation for the X and Y axes to the current schedule. + /// + /// The final point for the animation. + /// The optional starting point for the animation. + /// The optional initial delay for the animation. + /// The optional animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder AnchorPoint( + Vector2 to, + Vector2? from = null, + TimeSpan? delay = null, + TimeSpan? duration = null, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + AddCompositionAnimationFactory(nameof(Visual.AnchorPoint), to, from, delay, duration, easingType, easingMode); + + return this; + } + /// /// Adds a new opacity animation to the current schedule. /// @@ -337,6 +388,96 @@ public AnimationBuilder Scale( return AddCompositionAnimationFactory(nameof(Visual.Scale), to, from, delay, duration, easingType, easingMode); } + /// + /// Adds a new center point animation on a specified axis to the current schedule. + /// + /// The target scale axis to animate. + /// The final value for the animation. + /// The optional starting value for the animation. + /// The optional initial delay for the animation. + /// The optional animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder CenterPoint( + Axis axis, + double to, + double? from = null, + TimeSpan? delay = null, + TimeSpan? duration = null, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + AddCompositionAnimationFactory($"{nameof(Visual.CenterPoint)}.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); + } + else + { + AddXamlTransformDoubleAnimationFactory($"Center{axis}", to, from, delay, duration, easingType, easingMode); + } + + return this; + } + + /// + /// Adds a new center point animation for the X and Y axes to the current schedule. + /// + /// The final point for the animation. + /// The optional starting point for the animation. + /// The optional initial delay for the animation. + /// The optional animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder CenterPoint( + Vector2 to, + Vector2? from = null, + TimeSpan? delay = null, + TimeSpan? duration = null, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode, + FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + AddCompositionAnimationFactory($"{nameof(Visual.CenterPoint)}.X", to.X, from?.X, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory($"{nameof(Visual.CenterPoint)}.Y", to.Y, from?.Y, delay, duration, easingType, easingMode); + } + else + { + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.CenterX), to.X, from?.X, delay, duration, easingType, easingMode); + AddXamlTransformDoubleAnimationFactory(nameof(CompositeTransform.CenterY), to.Y, from?.Y, delay, duration, easingType, easingMode); + } + + return this; + } + + /// + /// Adds a new center point animation for all axes to the current schedule. + /// + /// The final point for the animation. + /// The optional starting point for the animation. + /// The optional initial delay for the animation. + /// The optional animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder CenterPoint( + Vector3 to, + Vector3? from = null, + TimeSpan? delay = null, + TimeSpan? duration = null, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + return AddCompositionAnimationFactory(nameof(Visual.CenterPoint), to, from, delay, duration, easingType, easingMode); + } + /// /// Adds a new rotation animation to the current schedule. /// @@ -348,7 +489,7 @@ public AnimationBuilder Scale( /// The optional easing function mode for the animation. /// The target framework layer to animate. /// The current instance. - public AnimationBuilder Rotate( + public AnimationBuilder Rotation( double to, double? from = null, TimeSpan? delay = null, @@ -383,7 +524,7 @@ public AnimationBuilder Rotate( /// The optional easing function mode for the animation. /// The target framework layer to animate. /// The current instance. - public AnimationBuilder RotateInDegrees( + public AnimationBuilder RotationInDegrees( double to, double? from = null, TimeSpan? delay = null, @@ -404,6 +545,50 @@ public AnimationBuilder RotateInDegrees( return this; } + /// + /// Adds a new rotation axis animation to the current schedule. + /// + /// The final value for the animation. + /// The optional starting value for the animation. + /// The optional initial delay for the animation. + /// The optional animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder RotationAxis( + Vector3 to, + Vector3? from = null, + TimeSpan? delay = null, + TimeSpan? duration = null, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + return AddCompositionAnimationFactory(nameof(Visual.RotationAxis), to, from, delay, duration, easingType, easingMode); + } + + /// + /// Adds a new orientation animation to the current schedule. + /// + /// The final value for the animation. + /// The optional starting value for the animation. + /// The optional initial delay for the animation. + /// The optional animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder Orientation( + Quaternion to, + Quaternion? from = null, + TimeSpan? delay = null, + TimeSpan? duration = null, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + return AddCompositionAnimationFactory(nameof(Visual.Orientation), to, from, delay, duration, easingType, easingMode); + } + /// /// Adds a new clip animation to the current schedule. /// diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs index 984404b8d29..01967762b81 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs @@ -21,7 +21,7 @@ public class RotationAnimation : Animation, ITimeline /// AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { - return builder.Rotate( + return builder.Rotation( To!.Value, From, Delay ?? delayHint, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs index a42f3847c70..445480921e6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs @@ -21,7 +21,7 @@ public class RotationInDegreesAnimation : Animation, ITimeline /// AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { - return builder.RotateInDegrees( + return builder.RotationInDegrees( To!.Value, From, Delay ?? delayHint, From aa79263da2f1b599aa12c76ec95d7a4bdc43dd51 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 22 Dec 2020 02:07:50 +0100 Subject: [PATCH 063/171] Added AnimationBuilder.Transform API --- .../Builders/AnimationBuilder.Default.cs | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs index 6ca522abfe5..838c2d42508 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs @@ -589,6 +589,53 @@ public AnimationBuilder Orientation( return AddCompositionAnimationFactory(nameof(Visual.Orientation), to, from, delay, duration, easingType, easingMode); } + /// + /// Adds a new transform animation to the current schedule. + /// + /// The final value for the animation. + /// The optional starting value for the animation. + /// The optional initial delay for the animation. + /// The optional animation duration. + /// The optional easing function type for the animation. + /// The optional easing function mode for the animation. + /// The current instance. + /// This animation is only available on the composition layer. + public AnimationBuilder Transform( + Matrix4x4 to, + Matrix4x4? from = null, + TimeSpan? delay = null, + TimeSpan? duration = null, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode) + { + if (!Matrix4x4.Decompose(to, out Vector3 toScale, out Quaternion toRotation, out Vector3 toTranslation)) + { + ThrowHelper.ThrowArgumentException("The destination matrix could not be decomposed"); + } + + Vector3? fromScale = null; + Quaternion? fromRotation = null; + Vector3? fromTranslation = null; + + if (from.HasValue) + { + if (!Matrix4x4.Decompose(from.GetValueOrDefault(), out Vector3 scale3, out Quaternion rotation4, out Vector3 translation3)) + { + ThrowHelper.ThrowArgumentException("The initial matrix could not be decomposed"); + } + + fromScale = scale3; + fromRotation = rotation4; + fromTranslation = translation3; + } + + Scale(toScale, fromScale, delay, duration, easingType, easingMode); + Orientation(toRotation, fromRotation, delay, duration, easingType, easingMode); + Translation(toTranslation, fromTranslation, delay, duration, easingType, easingMode); + + return this; + } + /// /// Adds a new clip animation to the current schedule. /// From 2ca1542e3cda8f67e7d084f00e5ef2f2234cc937 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 22 Dec 2020 02:20:32 +0100 Subject: [PATCH 064/171] Minor tweaks to public keyframe builder interfaces --- .../Interfaces/INormalizedKeyFrameAnimationBuilder{T}.cs | 4 ++-- .../Builders/Interfaces/ITimedKeyFrameAnimationBuilder{T}.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/INormalizedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/INormalizedKeyFrameAnimationBuilder{T}.cs index 39ec594fa92..20087a60882 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/INormalizedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/INormalizedKeyFrameAnimationBuilder{T}.cs @@ -11,7 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// An interface for an animation builder using normalized keyframes. /// /// The type of values being set by the animation being constructed. - public interface INormalizedKeyFrameAnimationBuilder + public interface INormalizedKeyFrameAnimationBuilder where T : unmanaged { /// @@ -22,7 +22,7 @@ public interface INormalizedKeyFrameAnimationBuilder /// The easing type to use to reach the new keyframe. /// The easing mode to use to reach the new keyframe. /// The same instance that the method was invoked upon. - public INormalizedKeyFrameAnimationBuilder KeyFrame( + INormalizedKeyFrameAnimationBuilder KeyFrame( double progress, T value, EasingType easingType = DefaultEasingType, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/ITimedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/ITimedKeyFrameAnimationBuilder{T}.cs index e9db4ad89f4..188a154a8fe 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/ITimedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/ITimedKeyFrameAnimationBuilder{T}.cs @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// An interface for an animation builder using timed keyframes. /// /// The type of values being set by the animation being constructed. - public interface ITimedKeyFrameAnimationBuilder + public interface ITimedKeyFrameAnimationBuilder where T : unmanaged { /// @@ -23,7 +23,7 @@ public interface ITimedKeyFrameAnimationBuilder /// The easing type to use to reach the new keyframe. /// The easing mode to use to reach the new keyframe. /// The same instance that the method was invoked upon. - public ITimedKeyFrameAnimationBuilder KeyFrame( + ITimedKeyFrameAnimationBuilder KeyFrame( TimeSpan progress, T value, EasingType easingType = DefaultEasingType, From 8385b6e8e6c5d89dca7715992d4372b1c49c82f7 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 22 Dec 2020 02:25:12 +0100 Subject: [PATCH 065/171] Removed unnecessary extensions --- .../Builders/AnimationBuilder.Models.cs | 7 ++- .../Extensions/AnimationExtensions.cs | 2 +- .../Extensions/UIElementExtensions.cs | 46 ------------------- 3 files changed, 7 insertions(+), 48 deletions(-) delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/UIElementExtensions.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs index adcad50390c..61606bda045 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs @@ -293,7 +293,12 @@ private sealed record XamlTransformDoubleAnimationFactory( /// public Timeline GetAnimation(DependencyObject targetHint) { - CompositeTransform transform = ((UIElement)targetHint).GetTransform(); + UIElement element = (UIElement)targetHint; + + if (element.RenderTransform is not CompositeTransform transform) + { + element.RenderTransform = transform = new CompositeTransform(); + } return transform.CreateDoubleAnimation(Property, To, From, Duration, Delay, EasingType.ToEasingFunction(EasingMode)); } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs index 2d7ee81fd58..d115669f336 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Extensions /// /// Common properties related to extensions. /// - public static partial class AnimationExtensions + public static class AnimationExtensions { /// /// Gets the default delay of animations. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/UIElementExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/UIElementExtensions.cs deleted file mode 100644 index 69efa23b76e..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/UIElementExtensions.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Diagnostics.Contracts; -using Windows.UI.Composition; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Hosting; -using Windows.UI.Xaml.Media; - -namespace Microsoft.Toolkit.Uwp.UI.Animations.Extensions -{ - /// - /// An extension for the type. - /// - public static class UIElementExtensions - { - /// - /// Returns the desired instance after assigning it to the property of the target . - /// - /// The desired type. - /// The target to modify. - /// A instance assigned to . - public static T GetTransform(this UIElement element) - where T : Transform, new() - { - if (element.RenderTransform is T transform) - { - return transform; - } - - return (T)(element.RenderTransform = new T()); - } - - /// - /// Returns the object for a given instance. - /// - /// The source element to get the visual for. - /// The object associated with . - [Pure] - public static Visual GetVisual(this UIElement element) - { - return ElementCompositionPreview.GetElementVisual(element); - } - } -} From 66746f9e1f41d0aab7eba5cfc2c4004da8d663d4 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 22 Dec 2020 17:48:01 +0100 Subject: [PATCH 066/171] Added builder types for new keyframe APIs --- .../AnimationBuilder.PropertyBuilders.cs | 191 ++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs new file mode 100644 index 00000000000..7f652b1b3a0 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs @@ -0,0 +1,191 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +#nullable enable + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + public sealed partial class AnimationBuilder + { + /// + /// An animation for an animation builder using keyframes, targeting a specific property. + /// + /// The type of values being set by the animation being constructed. + public interface IPropertyAnimationBuilder + where T : unmanaged + { + /// + /// Adds a custom animation based on normalized keyframes ot the current schedule. + /// + /// The callback to use to construct the custom animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The current instance. + public AnimationBuilder NormalizedKeyFrames( + Action> build, + TimeSpan? delay = null, + TimeSpan? duration = null); + + /// + /// Adds a custom animation based on timed keyframes to the current schedule. + /// + /// The callback to use to construct the custom animation. + /// The optional initial delay for the animation. + /// The current instance. + public AnimationBuilder TimedKeyFrames( + Action> build, + TimeSpan? delay = null); + } + + /// + /// A custom for a shared animation. + /// + /// The type of property to animate. + private sealed record PropertyAnimationBuilder( + AnimationBuilder Builder, + string Property, + FrameworkLayer Layer) + : IPropertyAnimationBuilder + where T : unmanaged + { + /// + public AnimationBuilder NormalizedKeyFrames( + Action> build, + TimeSpan? delay = null, + TimeSpan? duration = null) + { + return Builder.NormalizedKeyFrames(Property, build, delay, duration, Layer); + } + + /// + public AnimationBuilder TimedKeyFrames( + Action> build, + TimeSpan? delay = null) + { + return Builder.TimedKeyFrames(Property, build, delay, Layer); + } + } + + /// + /// A custom for a composition clip animation. + /// + private sealed record CompositionClipAnimationBuilder( + AnimationBuilder Builder, + string Property) + : IPropertyAnimationBuilder + { + /// + public AnimationBuilder NormalizedKeyFrames( + Action> build, + TimeSpan? delay = null, + TimeSpan? duration = null) + { + NormalizedKeyFrameAnimationBuilder.Composition builder = new(Property, delay, duration ?? DefaultDuration); + + build(builder); + + Builder.compositionAnimationFactories.Add(new Factory(builder)); + + return Builder; + } + + /// + public AnimationBuilder TimedKeyFrames( + Action> build, + TimeSpan? delay = null) + { + TimedKeyFrameAnimationBuilder.Composition builder = new(Property, delay); + + build(builder); + + Builder.compositionAnimationFactories.Add(new Factory(builder)); + + return Builder; + } + + /// + /// A private factory implementing . + /// + private sealed record Factory(ICompositionAnimationFactory Builder) : ICompositionAnimationFactory + { + /// + public CompositionAnimation GetAnimation(CompositionObject targetHint, out CompositionObject? target) + { + Visual visual = (Visual)targetHint; + InsetClip clip = visual.Clip as InsetClip ?? (InsetClip)(visual.Clip = visual.Compositor.CreateInsetClip()); + CompositionAnimation animation = Builder.GetAnimation(clip, out _); + + target = clip; + + return animation; + } + } + } + + /// + /// A custom for a XAML transform animation. + /// + private sealed record XamlTransformPropertyAnimationBuilder( + AnimationBuilder Builder, + string Property) + : IPropertyAnimationBuilder + { + /// + public AnimationBuilder NormalizedKeyFrames( + Action> build, + TimeSpan? delay = null, + TimeSpan? duration = null) + { + NormalizedKeyFrameAnimationBuilder.Xaml builder = new(Property, delay, duration ?? DefaultDuration); + + build(builder); + + Builder.xamlAnimationFactories.Add(new Factory(builder)); + + return Builder; + } + + /// + public AnimationBuilder TimedKeyFrames( + Action> build, + TimeSpan? delay = null) + { + TimedKeyFrameAnimationBuilder.Xaml builder = new(Property, delay); + + build(builder); + + Builder.xamlAnimationFactories.Add(new Factory(builder)); + + return Builder; + } + + /// + /// A private factory implementing . + /// + private sealed record Factory(IXamlAnimationFactory Builder) : IXamlAnimationFactory + { + /// + public Timeline GetAnimation(DependencyObject targetHint) + { + UIElement element = (UIElement)targetHint; + + if (element.RenderTransform is not CompositeTransform transform) + { + element.RenderTransform = transform = new CompositeTransform(); + } + + return Builder.GetAnimation(transform); + } + } + } + } +} From df043fbf3c9eaae2fa4374b5db507b94cae93105 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 22 Dec 2020 17:49:06 +0100 Subject: [PATCH 067/171] Minor code tweaks and bug fixes --- .../Builders/AnimationBuilder.Custom.cs | 4 +- .../Builders/AnimationBuilder.Default.cs | 1 - ...odels.cs => AnimationBuilder.Factories.cs} | 66 +++++++++---------- .../Builders/AnimationBuilder.cs | 2 +- 4 files changed, 36 insertions(+), 37 deletions(-) rename Microsoft.Toolkit.Uwp.UI.Animations/Builders/{AnimationBuilder.Models.cs => AnimationBuilder.Factories.cs} (99%) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Custom.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Custom.cs index 4456a8575a4..82b3cbcacf2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Custom.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Custom.cs @@ -13,7 +13,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations public sealed partial class AnimationBuilder { /// - /// Adds a custom animation based on normalized keyframes ot the current schedule. + /// Adds a custom animation based on normalized keyframes to the current schedule. /// /// The type of values to animate. /// The target property to animate. @@ -51,7 +51,7 @@ public AnimationBuilder NormalizedKeyFrames( } /// - /// Adds a custom animation based on timed keyframes ot the current schedule. + /// Adds a custom animation based on timed keyframes to the current schedule. /// /// The type of values to animate. /// The target property to animate. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs index 838c2d42508..3c85424851c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs @@ -40,7 +40,6 @@ public AnimationBuilder AnchorPoint( EasingMode easingMode = DefaultEasingMode) { AddCompositionAnimationFactory($"{nameof(Visual.AnchorPoint)}.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); - AddCompositionAnimationFactory($"{nameof(Visual.AnchorPoint)}.{axis}", (float)to, (float?)from, delay, duration, easingType, easingMode); return this; } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs similarity index 99% rename from Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs rename to Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs index 61606bda045..031a887775f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Models.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs @@ -22,6 +22,38 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// public sealed partial class AnimationBuilder { + /// + /// An interface for factories of XAML animations. + /// + internal interface IXamlAnimationFactory + { + /// + /// Gets a instance representing the animation to start. + /// + /// The suggested target instance to animate. + /// A instance with the specified animation. + Timeline GetAnimation(DependencyObject targetHint); + } + + /// + /// An interface for factories of composition animations. + /// + internal interface ICompositionAnimationFactory + { + /// + /// Gets a instance representing the animation to start. + /// + /// The suggested target instance to animate. + /// An optional instance to animate instead of the suggested one. + /// A instance with the specified animation. + /// + /// The separate parameter is needed because unlike with XAML animations, composition animations + /// can't store the target instance internally, and need to be started on the target object directly. This means that custom + /// animation factories that want to target an external object need to return that object separately to inform the callers. + /// + CompositionAnimation GetAnimation(CompositionObject targetHint, out CompositionObject? target); + } + /// /// A model representing a generic animation for a target object. /// @@ -254,7 +286,7 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo /// /// A model representing a specified composition double animation for a target . /// - private sealed record CompositionDoubleAnimation( + private sealed record CompositionDoubleAnimationFactory( CompositionObject Target, string Property, float To, @@ -303,37 +335,5 @@ public Timeline GetAnimation(DependencyObject targetHint) return transform.CreateDoubleAnimation(Property, To, From, Duration, Delay, EasingType.ToEasingFunction(EasingMode)); } } - - /// - /// An interface for factories of XAML animations. - /// - internal interface IXamlAnimationFactory - { - /// - /// Gets a instance representing the animation to start. - /// - /// The suggested target instance to animate. - /// A instance with the specified animation. - Timeline GetAnimation(DependencyObject targetHint); - } - - /// - /// An interface for factories of composition animations. - /// - internal interface ICompositionAnimationFactory - { - /// - /// Gets a instance representing the animation to start. - /// - /// The suggested target instance to animate. - /// An optional instance to animate instead of the suggested one. - /// A instance with the specified animation. - /// - /// The separate parameter is needed because unlike with XAML animations, composition animations - /// can't store the target instance internally, and need to be started on the target object directly. This means that custom - /// animation factories that want to target an external object need to return that object separately to inform the callers. - /// - CompositionAnimation GetAnimation(CompositionObject targetHint, out CompositionObject? target); - } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs index 24804087c31..773d916daee 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs @@ -72,7 +72,7 @@ public AnimationBuilder DoubleAnimation( EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - CompositionDoubleAnimation animation = new( + CompositionDoubleAnimationFactory animation = new( target, property, (float)to, From 6c8b949155b4be460484c7562185e2aa91a99624 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 22 Dec 2020 18:10:20 +0100 Subject: [PATCH 068/171] Added strongly-typed keyframed animation APIs --- .../Builders/AnimationBuilder.Custom.cs | 233 ++++++++++++++++++ 1 file changed, 233 insertions(+) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Custom.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Custom.cs index 82b3cbcacf2..db8195f96d2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Custom.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Custom.cs @@ -5,6 +5,11 @@ #nullable enable using System; +using System.Numerics; +using Microsoft.Toolkit.Diagnostics; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Media; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations @@ -12,6 +17,234 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// public sealed partial class AnimationBuilder { + /// + /// Adds a new anchor point animation for a single axis to the current schedule. + /// + /// The target anchor point axis to animate. + /// An instance to configure the animation. + /// This animation is only available on the composition layer. + public IPropertyAnimationBuilder AnchorPoint(Axis axis) + { + return new PropertyAnimationBuilder(this, $"{nameof(Visual.AnchorPoint)}.{axis}", FrameworkLayer.Composition); + } + + /// + /// Adds a new anchor point animation for the X and Y axes to the current schedule. + /// + /// An instance to configure the animation. + /// This animation is only available on the composition layer. + public IPropertyAnimationBuilder AnchorPoint() + { + return new PropertyAnimationBuilder(this, nameof(Visual.AnchorPoint), FrameworkLayer.Composition); + } + + /// + /// Adds a new opacity animation to the current schedule. + /// + /// The target framework layer to animate. + /// An instance to configure the animation. + public IPropertyAnimationBuilder Opacity(FrameworkLayer layer = FrameworkLayer.Composition) + { + return new PropertyAnimationBuilder(this, nameof(Visual.Opacity), layer); + } + + /// + /// Adds a new translation animation for a single axis to the current schedule. + /// + /// The target translation axis to animate. + /// The target framework layer to animate. + /// An instance to configure the animation. + public IPropertyAnimationBuilder Translation(Axis axis, FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return new PropertyAnimationBuilder(this, $"Translation.{axis}", layer); + } + + return new XamlTransformPropertyAnimationBuilder(this, $"Translate{axis}"); + } + + /// + /// Adds a new composition translation animation for all axes to the current schedule. + /// + /// An instance to configure the animation. + /// This animation is only available on the composition layer. + public IPropertyAnimationBuilder Translation() + { + return new PropertyAnimationBuilder(this, "Translation", FrameworkLayer.Composition); + } + + /// + /// Adds a new composition offset animation for a single axis to the current schedule. + /// + /// The target translation axis to animate. + /// An instance to configure the animation. + /// This animation is only available on the composition layer. + public IPropertyAnimationBuilder Offset(Axis axis) + { + return new PropertyAnimationBuilder(this, $"{nameof(Visual.Offset)}.{axis}", FrameworkLayer.Composition); + } + + /// + /// Adds a new composition offset translation animation for all axes to the current schedule. + /// + /// An instance to configure the animation. + /// This animation is only available on the composition layer. + public IPropertyAnimationBuilder Offset() + { + return new PropertyAnimationBuilder(this, nameof(Visual.Offset), FrameworkLayer.Composition); + } + + /// + /// Adds a new scale animation on a specified axis to the current schedule. + /// + /// The target scale axis to animate. + /// The target framework layer to animate. + /// An instance to configure the animation. + public IPropertyAnimationBuilder Scale(Axis axis, FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return new PropertyAnimationBuilder(this, $"{nameof(Visual.Scale)}.{axis}", layer); + } + + return new XamlTransformPropertyAnimationBuilder(this, $"Scale{axis}"); + } + + /// + /// Adds a new scale animation for all axes to the current schedule. + /// + /// An instance to configure the animation. + /// This animation is only available on the composition layer. + public IPropertyAnimationBuilder Scale() + { + return new PropertyAnimationBuilder(this, nameof(Visual.Scale), FrameworkLayer.Composition); + } + + /// + /// Adds a new center point animation on a specified axis to the current schedule. + /// + /// The target scale axis to animate. + /// The target framework layer to animate. + /// An instance to configure the animation. + public IPropertyAnimationBuilder CenterPoint(Axis axis, FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return new PropertyAnimationBuilder(this, $"{nameof(Visual.CenterPoint)}.{axis}", layer); + } + + return new XamlTransformPropertyAnimationBuilder(this, $"Center{axis}"); + } + + /// + /// Adds a new center point animation for all axes to the current schedule. + /// + /// An instance to configure the animation. + /// This animation is only available on the composition layer. + public IPropertyAnimationBuilder CenterPoint() + { + return new PropertyAnimationBuilder(this, nameof(Visual.CenterPoint), FrameworkLayer.Composition); + } + + /// + /// Adds a new rotation animation to the current schedule. + /// + /// An instance to configure the animation. + /// This animation is only available on the composition layer. + public IPropertyAnimationBuilder Rotation() + { + return new PropertyAnimationBuilder(this, nameof(Visual.RotationAngle), FrameworkLayer.Composition); + } + + /// + /// Adds a new rotation animation in degrees to the current schedule. + /// + /// The target framework layer to animate. + /// An instance to configure the animation. + public IPropertyAnimationBuilder RotationInDegrees(FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return new PropertyAnimationBuilder(this, nameof(Visual.RotationAngleInDegrees), layer); + } + + return new XamlTransformPropertyAnimationBuilder(this, nameof(CompositeTransform.Rotation)); + } + + /// + /// Adds a new rotation axis animation to the current schedule. + /// + /// An instance to configure the animation. + /// This animation is only available on the composition layer. + public IPropertyAnimationBuilder RotationAxis() + { + return new PropertyAnimationBuilder(this, nameof(Visual.RotationAxis), FrameworkLayer.Composition); + } + + /// + /// Adds a new orientation animation to the current schedule. + /// + /// An instance to configure the animation. + /// This animation is only available on the composition layer. + public IPropertyAnimationBuilder Orientation() + { + return new PropertyAnimationBuilder(this, nameof(Visual.Orientation), FrameworkLayer.Composition); + } + + /// + /// Adds a new clip animation to the current schedule. + /// + /// The clip size to animate. + /// An instance to configure the animation. + /// This animation is only available on the composition layer. + public IPropertyAnimationBuilder Clip(Side side) + { + string property = side switch + { + Side.Top => nameof(InsetClip.TopInset), + Side.Bottom => nameof(InsetClip.BottomInset), + Side.Right => nameof(InsetClip.RightInset), + Side.Left => nameof(InsetClip.LeftInset), + _ => ThrowHelper.ThrowArgumentException("Invalid clip size") + }; + + return new CompositionClipAnimationBuilder(this, property); + } + + /// + /// Adds a new size animation for a single axis to the current schedule. + /// + /// The target size axis to animate. + /// The target framework layer to animate. + /// An instance to configure the animation. + public IPropertyAnimationBuilder Size(Axis axis, FrameworkLayer layer = FrameworkLayer.Composition) + { + if (layer == FrameworkLayer.Composition) + { + return new PropertyAnimationBuilder(this, $"{nameof(Visual.Size)}.{axis}", layer); + } + + string property = axis switch + { + Axis.X => nameof(FrameworkElement.Width), + Axis.Y => nameof(FrameworkElement.Height), + _ => ThrowHelper.ThrowArgumentException("Invalid size axis") + }; + + return new PropertyAnimationBuilder(this, property, layer); + } + + /// + /// Adds a new composition size translation animation for all axes to the current schedule. + /// + /// An instance to configure the animation. + /// This animation is only available on the composition layer. + public IPropertyAnimationBuilder Size() + { + return new PropertyAnimationBuilder(this, nameof(Visual.Size), FrameworkLayer.Composition); + } + /// /// Adds a custom animation based on normalized keyframes to the current schedule. /// From ca8038478d0a345749f5c4ec4b605613e153cc56 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 22 Dec 2020 18:23:43 +0100 Subject: [PATCH 069/171] Renamed AnimationBuilder.New() to Create() --- .../Builders/AnimationBuilder.cs | 8 ++++---- .../Xaml/AnimationCollection2.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs index 773d916daee..4b9b0933c8b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs @@ -22,12 +22,12 @@ public sealed partial class AnimationBuilder { /// /// - /// A static constructor for the type. + /// Creates a new instance to setup an animation schedule. /// This can be used as the entry point to construct a custom animation sequence. /// /// For instance: /// - /// AnimationBuilder.New()
+ /// AnimationBuilder.Create()
/// .Opacity(from: 0, to: 1, duration: 400)
/// .Translation(Axis.X, from: -40, to: 0, duration: 400)
/// .Start(MyButton); @@ -38,7 +38,7 @@ public sealed partial class AnimationBuilder /// /// For instance: /// - /// var animation = AnimationBuilder.New().Opacity(0, 1, duration: 400).Size(1.2, 1, duration: 400);
+ /// var animation = AnimationBuilder.Create().Opacity(0, 1, duration: 400).Size(1.2, 1, duration: 400);
///
/// animation.Start(MyButton);
/// animation.Start(MyGrid); @@ -48,7 +48,7 @@ public sealed partial class AnimationBuilder ///
/// An empty instance to use to construct an animation sequence. [Pure] - public static AnimationBuilder New() => new(); + public static AnimationBuilder Create() => new(); /// /// Adds a new custom double animation targeting an arbitrary composition object. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs index fd7841b7f1f..c7dc05cbb0b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs @@ -75,7 +75,7 @@ public async Task StartAsync(UIElement element) { Started?.Invoke(this, EventArgs.Empty); - var builder = AnimationBuilder.New(); + var builder = AnimationBuilder.Create(); foreach (ITimeline animation in Animations) { From ef4a24924fe829ac783ad73ea18eb8cb2571c9cd Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 22 Dec 2020 18:25:36 +0100 Subject: [PATCH 070/171] Added missing AnimationBuilder private constructor --- .../Builders/AnimationBuilder.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs index 4b9b0933c8b..d5117cfcdda 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs @@ -20,6 +20,14 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// public sealed partial class AnimationBuilder { + /// + /// Initializes a new instance of the class. + /// + /// This is private as the public entry point is the method. + private AnimationBuilder() + { + } + /// /// /// Creates a new instance to setup an animation schedule. From 2790c4f621696378ec32095d4e90d23c3cbef9a9 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 22 Dec 2020 19:08:29 +0100 Subject: [PATCH 071/171] Removed unnecessary visibility modifiers --- .../Builders/AnimationBuilder.PropertyBuilders.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs index 7f652b1b3a0..9391108d5f7 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs @@ -30,7 +30,7 @@ public interface IPropertyAnimationBuilder /// The optional initial delay for the animation. /// The animation duration. /// The current instance. - public AnimationBuilder NormalizedKeyFrames( + AnimationBuilder NormalizedKeyFrames( Action> build, TimeSpan? delay = null, TimeSpan? duration = null); @@ -41,7 +41,7 @@ public AnimationBuilder NormalizedKeyFrames( /// The callback to use to construct the custom animation. /// The optional initial delay for the animation. /// The current instance. - public AnimationBuilder TimedKeyFrames( + AnimationBuilder TimedKeyFrames( Action> build, TimeSpan? delay = null); } From 921061cf66ca1037cd0aff5976914b69dafe3b7d Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 22 Dec 2020 19:59:19 +0100 Subject: [PATCH 072/171] Added APIs to insert external animations --- .../Builders/AnimationBuilder.External.cs | 55 +++++++++++++++++++ .../Builders/AnimationBuilder.Factories.cs | 52 +++++++++--------- ...ustom.cs => AnimationBuilder.KeyFrames.cs} | 0 .../Builders/AnimationBuilder.cs | 39 ------------- .../Animations/EffectDoubleAnimation.cs | 19 ++++--- 5 files changed, 92 insertions(+), 73 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.External.cs rename Microsoft.Toolkit.Uwp.UI.Animations/Builders/{AnimationBuilder.Custom.cs => AnimationBuilder.KeyFrames.cs} (100%) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.External.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.External.cs new file mode 100644 index 00000000000..68dd890babd --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.External.cs @@ -0,0 +1,55 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable enable + +using Windows.UI.Composition; +using Windows.UI.Xaml.Media.Animation; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + public sealed partial class AnimationBuilder + { + /// + /// Adds a new external animation to the current schedule, which will be executed on the same + /// target object the current instance will be invoked upon. + /// + /// The external instance to add to the schedule. + /// The current instance. + public AnimationBuilder ExternalAnimation(CompositionAnimation animation) + { + this.compositionAnimationFactories.Add(new ExternalCompositionAnimation(null, animation)); + + return this; + } + + /// + /// Adds a new external animation to the current schedule, which will be executed on a given + /// when the current instance is invoked. + /// + /// The target to invoke the animation upon. + /// The external instance to add to the schedule. + /// The current instance. + public AnimationBuilder ExternalAnimation(CompositionObject target, CompositionAnimation animation) + { + this.compositionAnimationFactories.Add(new ExternalCompositionAnimation(target, animation)); + + return this; + } + + /// + /// Adds a new external animation to the current schedule, which will be executed on the same + /// target object the current instance will be invoked upon. + /// + /// The external instance to add to the schedule. + /// The current instance. + public AnimationBuilder ExternalAnimation(Timeline animation) + { + this.xamlAnimationFactories.Add(new ExternalXamlAnimation(animation)); + + return this; + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs index 031a887775f..09a59be3360 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs @@ -283,32 +283,6 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo } } - /// - /// A model representing a specified composition double animation for a target . - /// - private sealed record CompositionDoubleAnimationFactory( - CompositionObject Target, - string Property, - float To, - float? From, - TimeSpan Delay, - TimeSpan Duration, - EasingType EasingType, - EasingMode EasingMode) - : ICompositionAnimationFactory - { - /// - public CompositionAnimation GetAnimation(CompositionObject targetHint, out CompositionObject? target) - { - CompositionEasingFunction easingFunction = Target.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); - ScalarKeyFrameAnimation animation = Target.Compositor.CreateScalarKeyFrameAnimation(Property, To, From, Delay, Duration, easingFunction); - - target = Target; - - return animation; - } - } - /// /// A model representing a specified XAML animation factory targeting a transform. /// @@ -335,5 +309,31 @@ public Timeline GetAnimation(DependencyObject targetHint) return transform.CreateDoubleAnimation(Property, To, From, Duration, Delay, EasingType.ToEasingFunction(EasingMode)); } } + + /// + /// A model representing an external composition animation with an optional target . + /// + private sealed record ExternalCompositionAnimation(CompositionObject? Target, CompositionAnimation Animation) : ICompositionAnimationFactory + { + /// + public CompositionAnimation GetAnimation(CompositionObject targetHint, out CompositionObject? target) + { + target = Target; + + return Animation; + } + } + + /// + /// A model representing an external composition animation with an optional target . + /// + private sealed record ExternalXamlAnimation(Timeline Animation) : IXamlAnimationFactory + { + /// + public Timeline GetAnimation(DependencyObject targetHint) + { + return Animation; + } + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Custom.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.KeyFrames.cs similarity index 100% rename from Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Custom.cs rename to Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.KeyFrames.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs index d5117cfcdda..87d85875906 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs @@ -4,14 +4,12 @@ #nullable enable -using System; using System.Diagnostics.Contracts; using System.Threading.Tasks; using Windows.UI.Composition; using Windows.UI.Xaml; using Windows.UI.Xaml.Hosting; using Windows.UI.Xaml.Media.Animation; -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations { @@ -58,43 +56,6 @@ private AnimationBuilder() [Pure] public static AnimationBuilder Create() => new(); - /// - /// Adds a new custom double animation targeting an arbitrary composition object. - /// - /// The target to animate. - /// The target property to animate. - /// The final value for the animation. - /// The optional starting value for the animation. - /// The optional initial delay for the animation. - /// The optional animation duration. - /// The optional easing function type for the animation. - /// The optional easing function mode for the animation. - /// The current instance. - public AnimationBuilder DoubleAnimation( - CompositionObject target, - string property, - double to, - double? from = null, - TimeSpan? delay = null, - TimeSpan? duration = null, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode) - { - CompositionDoubleAnimationFactory animation = new( - target, - property, - (float)to, - (float?)from, - delay ?? DefaultDelay, - duration ?? DefaultDuration, - easingType, - easingMode); - - this.compositionAnimationFactories.Add(animation); - - return this; - } - /// /// Starts the animations present in the current instance. /// diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs index 01c3d830575..3dc529f548d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs @@ -5,8 +5,10 @@ using System; using Microsoft.Graphics.Canvas.Effects; using Microsoft.Toolkit.Uwp.UI.Animations; +using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; using Microsoft.Toolkit.Uwp.UI.Media.Effects; +using Windows.UI.Composition; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -27,15 +29,16 @@ AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? d { BlurEffect effect = (BlurEffect)Target; - return builder.DoubleAnimation( - effect.Brush, + CompositionAnimation animation = effect.Brush.Compositor.CreateScalarKeyFrameAnimation( $"{effect.Id}.{nameof(GaussianBlurEffect.BlurAmount)}", - To, - From, - Delay ?? delayHint, - Duration ?? durationHint.GetValueOrDefault(), - EasingType ?? easingTypeHint ?? DefaultEasingType, - EasingMode ?? easingModeHint ?? DefaultEasingMode); + (float)To, + (float?)From, + Delay ?? delayHint ?? DefaultDelay, + Duration ?? durationHint ?? DefaultDuration, + effect.Brush.Compositor.CreateCubicBezierEasingFunction( + EasingMode ?? easingModeHint ?? DefaultEasingMode)); + + return builder.ExternalAnimation(effect.Brush, animation); } } } From 232ea5922fff1f1a2cc3e0bf2f3c2efe88485723 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 22 Dec 2020 20:05:29 +0100 Subject: [PATCH 073/171] Minor code refactoring --- .../AnimationBuilder.PropertyBuilders.cs | 30 --------------- .../IPropertyAnimationBuilder{T}.cs | 38 +++++++++++++++++++ .../Animations/EffectDoubleAnimation.cs | 1 + 3 files changed, 39 insertions(+), 30 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs index 9391108d5f7..43660ec787c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs @@ -16,36 +16,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// public sealed partial class AnimationBuilder { - /// - /// An animation for an animation builder using keyframes, targeting a specific property. - /// - /// The type of values being set by the animation being constructed. - public interface IPropertyAnimationBuilder - where T : unmanaged - { - /// - /// Adds a custom animation based on normalized keyframes ot the current schedule. - /// - /// The callback to use to construct the custom animation. - /// The optional initial delay for the animation. - /// The animation duration. - /// The current instance. - AnimationBuilder NormalizedKeyFrames( - Action> build, - TimeSpan? delay = null, - TimeSpan? duration = null); - - /// - /// Adds a custom animation based on timed keyframes to the current schedule. - /// - /// The callback to use to construct the custom animation. - /// The optional initial delay for the animation. - /// The current instance. - AnimationBuilder TimedKeyFrames( - Action> build, - TimeSpan? delay = null); - } - /// /// A custom for a shared animation. /// diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs new file mode 100644 index 00000000000..e04a5dd6c62 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// An animation for an animation builder using keyframes, targeting a specific property. + /// + /// The type of values being set by the animation being constructed. + public interface IPropertyAnimationBuilder + where T : unmanaged + { + /// + /// Adds a custom animation based on normalized keyframes ot the current schedule. + /// + /// The callback to use to construct the custom animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The current instance. + AnimationBuilder NormalizedKeyFrames( + Action> build, + TimeSpan? delay = null, + TimeSpan? duration = null); + + /// + /// Adds a custom animation based on timed keyframes to the current schedule. + /// + /// The callback to use to construct the custom animation. + /// The optional initial delay for the animation. + /// The current instance. + AnimationBuilder TimedKeyFrames( + Action> build, + TimeSpan? delay = null); + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs index 3dc529f548d..5816e8fd176 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs @@ -36,6 +36,7 @@ AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? d Delay ?? delayHint ?? DefaultDelay, Duration ?? durationHint ?? DefaultDuration, effect.Brush.Compositor.CreateCubicBezierEasingFunction( + EasingType ?? easingTypeHint ?? DefaultEasingType, EasingMode ?? easingModeHint ?? DefaultEasingMode)); return builder.ExternalAnimation(effect.Brush, animation); From 1f4806b72118d3a4a9fdcb82c8c558fa80acefcb Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 23 Dec 2020 01:57:39 +0100 Subject: [PATCH 074/171] Added IsSequential property to animation collections --- .../Xaml/AnimationCollection2.cs | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs index c7dc05cbb0b..cbbd62b0235 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs @@ -35,6 +35,24 @@ public sealed class AnimationCollection2 : DependencyObject /// public IList Animations { get; set; } = new List(); + /// + /// Gets or sets a value indicating whether top level animation nodes in this collection are invoked + /// sequentially. This applies to both nodes (which will still trigger + /// contained animations at the same time), and other top level animation nodes. The default value + /// is , which means that all contained animations will start at the same time. + /// + /// Note that this property will also cause a change in behavior for the animation. With the default + /// configuration, with all animations starting at the same time, it's not possible to use multiple + /// animations targeting the same property (as they'll cause a conflict and be ignored when on the + /// composition layer, or cause a crash when on the XAML layer). When animations are started sequentially + /// instead, each sequential block will be able to share target properties with animations from other + /// sequential blocks, without issues. Note that especially for simple scenarios (eg. an opacity animation + /// that just transitions to a state and then back, or between two states), it is recommended to use a single + /// keyframe animation instead, which will result in less overhead when creating and starting the animation. + /// + /// + public bool IsSequential { get; set; } + /// /// Gets or sets the weak reference to the parent that owns the current animation collection. /// @@ -75,14 +93,28 @@ public async Task StartAsync(UIElement element) { Started?.Invoke(this, EventArgs.Empty); - var builder = AnimationBuilder.Create(); - - foreach (ITimeline animation in Animations) + if (IsSequential) { - builder = animation.AppendToBuilder(builder); + foreach (ITimeline animation in Animations) + { + var builder = AnimationBuilder.Create(); + + animation.AppendToBuilder(builder); + + await builder.StartAsync(element); + } } + else + { + var builder = AnimationBuilder.Create(); - await builder.StartAsync(element); + foreach (ITimeline animation in Animations) + { + builder = animation.AppendToBuilder(builder); + } + + await builder.StartAsync(element); + } Ended?.Invoke(this, EventArgs.Empty); } From 86dc1d38642928fd28bc39ca2ce57cc324b03f5f Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 23 Dec 2020 12:26:31 +0100 Subject: [PATCH 075/171] Moved XAML keyframe types --- .../Xaml/Abstract/Animation{T}.cs | 8 ++++++ .../Xaml/Abstract/KeyFrame{T}.cs | 26 +++++++++++++++++++ .../KeyFrames/ScalarKeyFrame.cs} | 6 ++--- .../KeyFrames/Vector2KeyFrame.cs} | 7 +++-- .../KeyFrames/Vector3KeyFrame.cs | 5 ++-- .../KeyFrames/Vector4KeyFrame.cs | 5 ++-- 6 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{T}.cs rename Microsoft.Toolkit.Uwp.UI.Animations/{CompositionAnimations/KeyFrames/Vector2KeyFrame.cs => Xaml/KeyFrames/ScalarKeyFrame.cs} (65%) rename Microsoft.Toolkit.Uwp.UI.Animations/{CompositionAnimations/KeyFrames/ScalarKeyFrame.cs => Xaml/KeyFrames/Vector2KeyFrame.cs} (59%) rename Microsoft.Toolkit.Uwp.UI.Animations/{CompositionAnimations => Xaml}/KeyFrames/Vector3KeyFrame.cs (64%) rename Microsoft.Toolkit.Uwp.UI.Animations/{CompositionAnimations => Xaml}/KeyFrames/Vector4KeyFrame.cs (64%) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{T}.cs index 8eac45cb5dc..29ee3721a4c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{T}.cs @@ -4,6 +4,8 @@ #nullable enable +using System.Collections.Generic; + namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// @@ -21,5 +23,11 @@ public abstract class Animation : Animation /// Gets or sets the optional starting value for the animation. /// public T? From { get; set; } + + /// + /// Gets or sets the optional keyframe collection for the current animation. + /// Setting this will overwrite the and values. + /// + public IList> KeyFrames { get; set; } = new List>(); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{T}.cs new file mode 100644 index 00000000000..9896a55b940 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{T}.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable enable + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// A base model representing a typed keyframe that can be used in XAML. + /// + /// The type of values for the keyframe. + public abstract class KeyFrame + { + /// + /// Gets or sets the key time for the current keyframe. This is a normalized + /// value in the [0, 1] range, relative to the total animation duration. + /// + public double Key { get; set; } + + /// + /// Gets or sets the animation value for the current keyframe. + /// + public T? Value { get; set; } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/Vector2KeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ScalarKeyFrame.cs similarity index 65% rename from Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/Vector2KeyFrame.cs rename to Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ScalarKeyFrame.cs index c6286be85ef..5cb49343eae 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/Vector2KeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ScalarKeyFrame.cs @@ -2,14 +2,14 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// of type + /// A type for scalar animations. /// - public class Vector2KeyFrame : TypedKeyFrame + public class ScalarKeyFrame : KeyFrame { } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/ScalarKeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs similarity index 59% rename from Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/ScalarKeyFrame.cs rename to Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs index b27e05b6523..b9860185aac 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/ScalarKeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs @@ -2,12 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; + namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// of type + /// A type for animations. /// - public class ScalarKeyFrame : TypedKeyFrame + public class Vector2KeyFrame : KeyFrame { } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/Vector3KeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs similarity index 64% rename from Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/Vector3KeyFrame.cs rename to Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs index 98bca721815..ff1ed4dd95f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/Vector3KeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs @@ -3,13 +3,14 @@ // See the LICENSE file in the project root for more information. using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// of type + /// A type for animations. /// - public class Vector3KeyFrame : TypedKeyFrame + public class Vector3KeyFrame : KeyFrame { } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/Vector4KeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs similarity index 64% rename from Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/Vector4KeyFrame.cs rename to Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs index f7675638b53..f9509aa0492 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/Vector4KeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs @@ -3,13 +3,14 @@ // See the LICENSE file in the project root for more information. using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// of type + /// A type for animations. /// - public class Vector4KeyFrame : TypedKeyFrame + public class Vector4KeyFrame : KeyFrame { } } From 35b29b391ecc6d5ff25b16dd41b534aab1666085 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 23 Dec 2020 12:53:05 +0100 Subject: [PATCH 076/171] Added support for ObjectAnimationUsingKeyFrames --- .../Builders/Interfaces/IKeyFrameInfo.cs | 3 +-- .../INormalizedKeyFrameAnimationBuilder{T}.cs | 1 - .../Interfaces/IPropertyAnimationBuilder{T}.cs | 1 - .../ITimedKeyFrameAnimationBuilder{T}.cs | 1 - .../NormalizedKeyFrameAnimationBuilder{T}.cs | 1 - .../TimedKeyFrameAnimationBuilder{T}.Xaml.cs | 15 +++++++++++++++ .../Builders/TimedKeyFrameAnimationBuilder{T}.cs | 1 - 7 files changed, 16 insertions(+), 7 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IKeyFrameInfo.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IKeyFrameInfo.cs index 63764ea2299..f4c52dc78f6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IKeyFrameInfo.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IKeyFrameInfo.cs @@ -29,8 +29,7 @@ internal interface IKeyFrameInfo /// The type of values being set by the animation being constructed. /// The value for the current keyframe. [Pure] - T GetValueAs() - where T : unmanaged; + T GetValueAs(); /// /// Gets the normalized progress for the current keyframe. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/INormalizedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/INormalizedKeyFrameAnimationBuilder{T}.cs index 20087a60882..316214a240b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/INormalizedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/INormalizedKeyFrameAnimationBuilder{T}.cs @@ -12,7 +12,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// The type of values being set by the animation being constructed. public interface INormalizedKeyFrameAnimationBuilder - where T : unmanaged { /// /// Adds a new normalized keyframe to the builder in use. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs index e04a5dd6c62..13b45040c43 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs @@ -11,7 +11,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// The type of values being set by the animation being constructed. public interface IPropertyAnimationBuilder - where T : unmanaged { /// /// Adds a custom animation based on normalized keyframes ot the current schedule. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/ITimedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/ITimedKeyFrameAnimationBuilder{T}.cs index 188a154a8fe..9f5c4cde418 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/ITimedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/ITimedKeyFrameAnimationBuilder{T}.cs @@ -13,7 +13,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// The type of values being set by the animation being constructed. public interface ITimedKeyFrameAnimationBuilder - where T : unmanaged { /// /// Adds a new timed keyframe to the builder in use. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs index 46d1cc4eaf8..44b70c1fa40 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs @@ -106,7 +106,6 @@ public KeyFrameInfo( /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public TValue GetValueAs() - where TValue : unmanaged { return Unsafe.As(ref Unsafe.AsRef(in this.value)); } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs index c94da75dc6b..d9775457b2f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -100,6 +100,21 @@ public static Timeline GetAnimation( animation = colorAnimation; } + else if (typeof(T) == typeof(object)) + { + ObjectAnimationUsingKeyFrames objectAnimation = new() { EnableDependentAnimation = true }; + + foreach (var keyFrame in keyFrames) + { + objectAnimation.KeyFrames.Add(new DiscreteObjectKeyFrame() + { + KeyTime = keyFrame.GetTimedProgress(duration), + Value = keyFrame.GetValueAs() + }); + } + + animation = objectAnimation; + } else { return ThrowHelper.ThrowInvalidOperationException("Invalid animation type"); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs index 05319991138..6e1dcfe8fbd 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs @@ -99,7 +99,6 @@ public KeyFrameInfo( /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public TValue GetValueAs() - where TValue : unmanaged { return Unsafe.As(ref Unsafe.AsRef(in this.value)); } From 8d75564f647155d0dba06941f3ac38ab1a07ebc7 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 23 Dec 2020 13:26:37 +0100 Subject: [PATCH 077/171] Switched XAML animation types to strongly typed --- .../Xaml/Default/OffsetAnimation.cs | 8 ++++---- .../Xaml/Default/ScaleAnimation.cs | 13 +++++++++---- .../Xaml/Default/SizeAnimation.cs | 13 +++++++++---- .../Xaml/Default/TranslationAnimation.cs | 13 +++++++++---- .../Xaml/KeyFrames/Vector2KeyFrame.cs | 2 +- .../Xaml/KeyFrames/Vector3KeyFrame.cs | 4 ++-- .../Xaml/KeyFrames/Vector4KeyFrame.cs | 2 +- 7 files changed, 35 insertions(+), 20 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs index 4ab0528c873..5de866dcd70 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using System; -using Microsoft.Toolkit.Uwp.UI.Extensions; +using System.Numerics; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -12,14 +12,14 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// An offset animation working on the composition layer. /// - public class OffsetAnimation : Animation, ITimeline + public class OffsetAnimation : Animation, ITimeline { /// AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { return builder.Translation( - To!.ToVector3(), - From?.ToVector3(), + To.Value, + From, Delay ?? delayHint, Duration ?? durationHint, EasingType ?? easingTypeHint ?? DefaultEasingType, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs index cd4b5a46ef1..c33a951a3c9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using System; -using Microsoft.Toolkit.Uwp.UI.Extensions; +using System.Numerics; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A scale animation working on the composition or XAML layer. /// - public class ScaleAnimation : Animation, ITimeline + public class ScaleAnimation : Animation, ITimeline { /// /// Gets or sets the target framework layer to animate. @@ -22,6 +22,8 @@ public class ScaleAnimation : Animation, ITimeline /// AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { + Vector3 to = To.Value; + Vector3? from = From; TimeSpan? delay = Delay ?? delayHint; TimeSpan? duration = Duration ?? durationHint; EasingType easingType = EasingType ?? easingTypeHint ?? DefaultEasingType; @@ -29,11 +31,14 @@ AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? d if (Layer == FrameworkLayer.Composition) { - return builder.Scale(To!.ToVector3(), From?.ToVector3(), delay, duration, easingType, easingMode); + return builder.Scale(to, from, delay, duration, easingType, easingMode); } else { - return builder.Scale(To!.ToVector2(), From?.ToVector2(), delay, duration, easingType, easingMode, FrameworkLayer.Xaml); + Vector2 to2 = new(to.X, to.Y); + Vector2? from2 = from is null ? null : new(from.Value.X, from.Value.Y); + + return builder.Scale(to2, from2, delay, duration, easingType, easingMode, FrameworkLayer.Xaml); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs index fddbaa03979..593a7adda59 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using System; -using Microsoft.Toolkit.Uwp.UI.Extensions; +using System.Numerics; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A size animation working on the composition or XAML layer. /// - public class SizeAnimation : Animation, ITimeline + public class SizeAnimation : Animation, ITimeline { /// /// Gets or sets the target framework layer to animate. @@ -22,6 +22,8 @@ public class SizeAnimation : Animation, ITimeline /// AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { + Vector3 to = To.Value; + Vector3? from = From; TimeSpan? delay = Delay ?? delayHint; TimeSpan? duration = Duration ?? durationHint; EasingType easingType = EasingType ?? easingTypeHint ?? DefaultEasingType; @@ -29,11 +31,14 @@ AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? d if (Layer == FrameworkLayer.Composition) { - return builder.Size(To!.ToVector3(), From?.ToVector3(), delay, duration, easingType, easingMode); + return builder.Size(to, from, delay, duration, easingType, easingMode); } else { - return builder.Size(To!.ToVector2(), From?.ToVector2(), delay, duration, easingType, easingMode, FrameworkLayer.Xaml); + Vector2 to2 = new(to.X, to.Y); + Vector2? from2 = from is null ? null : new(from.Value.X, from.Value.Y); + + return builder.Size(to2, from2, delay, duration, easingType, easingMode, FrameworkLayer.Xaml); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs index 3b7c5974952..9975c633773 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using System; -using Microsoft.Toolkit.Uwp.UI.Extensions; +using System.Numerics; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A translation animation working on the composition or XAML layer. /// - public class TranslationAnimation : Animation, ITimeline + public class TranslationAnimation : Animation, ITimeline { /// /// Gets or sets the target framework layer to animate. @@ -22,6 +22,8 @@ public class TranslationAnimation : Animation, ITimeline /// AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { + Vector3 to = To.Value; + Vector3? from = From; TimeSpan? delay = Delay ?? delayHint; TimeSpan? duration = Duration ?? durationHint; EasingType easingType = EasingType ?? easingTypeHint ?? DefaultEasingType; @@ -29,11 +31,14 @@ AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? d if (Layer == FrameworkLayer.Composition) { - return builder.Translation(To!.ToVector3(), From?.ToVector3(), delay, duration, easingType, easingMode); + return builder.Translation(to, from, delay, duration, easingType, easingMode); } else { - return builder.Translation(To!.ToVector2(), From?.ToVector2(), delay, duration, easingType, easingMode, FrameworkLayer.Xaml); + Vector2 to2 = new(to.X, to.Y); + Vector2? from2 = from is null ? null : new(from.Value.X, from.Value.Y); + + return builder.Translation(to2, from2, delay, duration, easingType, easingMode, FrameworkLayer.Xaml); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs index b9860185aac..0936a652e63 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs @@ -10,7 +10,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// A type for animations. /// - public class Vector2KeyFrame : KeyFrame + public class Vector2KeyFrame : KeyFrame { } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs index ff1ed4dd95f..10de95b96aa 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs @@ -8,9 +8,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// A type for animations. + /// A type for animations. /// - public class Vector3KeyFrame : KeyFrame + public class Vector3KeyFrame : KeyFrame { } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs index f9509aa0492..29f9c59932a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs @@ -10,7 +10,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// A type for animations. /// - public class Vector4KeyFrame : KeyFrame + public class Vector4KeyFrame : KeyFrame { } } From 1aa8f3aaf4d047ddc8fdaaca5eccd44f261d11fc Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 23 Dec 2020 13:58:05 +0100 Subject: [PATCH 078/171] Minor code tweaks --- .../Xaml/Abstract/Animation.cs | 5 ++++- .../Xaml/Default/ClipAnimation.cs | 4 ++-- .../Xaml/Default/OffsetAnimation.cs | 4 ++-- .../Xaml/Default/OpacityAnimation.cs | 4 ++-- .../Xaml/Default/RotationAnimation.cs | 4 ++-- .../Xaml/Default/RotationInDegreesAnimation.cs | 4 ++-- .../Xaml/Default/ScaleAnimation.cs | 4 ++-- .../Xaml/Default/SizeAnimation.cs | 4 ++-- .../Xaml/Default/TranslationAnimation.cs | 4 ++-- 9 files changed, 20 insertions(+), 17 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs index 2c572c5e2f9..5f79601018b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs @@ -10,7 +10,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A base model representing an animation that can be used in XAML. /// - public abstract class Animation + public abstract class Animation : ITimeline { /// /// Gets or sets the optional initial delay for the animation. @@ -31,5 +31,8 @@ public abstract class Animation /// Gets or sets the optional easing function mode for the animation. /// public EasingMode? EasingMode { get; set; } + + /// + public abstract AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs index 96761a3d469..f8abe56a236 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs @@ -12,10 +12,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A clip animation working on the composition layer. /// - public class ClipAnimation : Animation, ITimeline + public class ClipAnimation : Animation { /// - AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { return builder.Clip( To!.Value, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs index 5de866dcd70..756445341e5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs @@ -12,10 +12,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// An offset animation working on the composition layer. /// - public class OffsetAnimation : Animation, ITimeline + public class OffsetAnimation : Animation { /// - AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { return builder.Translation( To.Value, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs index 5dc950b6061..ebaaa3d487f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs @@ -11,7 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// An opacity animation working on the composition or XAML layer. /// - public class OpacityAnimation : Animation, ITimeline + public class OpacityAnimation : Animation { /// /// Gets or sets the target framework layer to animate. @@ -19,7 +19,7 @@ public class OpacityAnimation : Animation, ITimeline public FrameworkLayer Layer { get; set; } /// - AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { return builder.Opacity( To!.Value, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs index 01967762b81..fbf15c15ea8 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs @@ -11,7 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A rotation animation working on the composition or XAML layer. /// - public class RotationAnimation : Animation, ITimeline + public class RotationAnimation : Animation { /// /// Gets or sets the target framework layer to animate. @@ -19,7 +19,7 @@ public class RotationAnimation : Animation, ITimeline public FrameworkLayer Layer { get; set; } /// - AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { return builder.Rotation( To!.Value, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs index 445480921e6..88ced3ec5b7 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs @@ -11,7 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A rotation in degrees animation working on the composition or XAML layer. /// - public class RotationInDegreesAnimation : Animation, ITimeline + public class RotationInDegreesAnimation : Animation { /// /// Gets or sets the target framework layer to animate. @@ -19,7 +19,7 @@ public class RotationInDegreesAnimation : Animation, ITimeline public FrameworkLayer Layer { get; set; } /// - AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { return builder.RotationInDegrees( To!.Value, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs index c33a951a3c9..285fe8485f9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A scale animation working on the composition or XAML layer. /// - public class ScaleAnimation : Animation, ITimeline + public class ScaleAnimation : Animation { /// /// Gets or sets the target framework layer to animate. @@ -20,7 +20,7 @@ public class ScaleAnimation : Animation, ITimeline public FrameworkLayer Layer { get; set; } /// - AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { Vector3 to = To.Value; Vector3? from = From; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs index 593a7adda59..d1b096fc026 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A size animation working on the composition or XAML layer. /// - public class SizeAnimation : Animation, ITimeline + public class SizeAnimation : Animation { /// /// Gets or sets the target framework layer to animate. @@ -20,7 +20,7 @@ public class SizeAnimation : Animation, ITimeline public FrameworkLayer Layer { get; set; } /// - AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { Vector3 to = To.Value; Vector3? from = From; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs index 9975c633773..590e3429f16 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A translation animation working on the composition or XAML layer. /// - public class TranslationAnimation : Animation, ITimeline + public class TranslationAnimation : Animation { /// /// Gets or sets the target framework layer to animate. @@ -20,7 +20,7 @@ public class TranslationAnimation : Animation, ITimeline public FrameworkLayer Layer { get; set; } /// - AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { Vector3 to = To.Value; Vector3? from = From; From d96413c7c07ba0a892f78732c7b982db0d912bc5 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 23 Dec 2020 13:58:40 +0100 Subject: [PATCH 079/171] Added IKeyFrame interface --- .../Xaml/Abstract/Animation{T}.cs | 4 +++- .../Xaml/Abstract/KeyFrame{T}.cs | 21 ++++++++++++++++++- .../Xaml/Interfaces/IKeyFrame{T}.cs | 20 ++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IKeyFrame{T}.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{T}.cs index 29ee3721a4c..e965c627b31 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{T}.cs @@ -5,6 +5,7 @@ #nullable enable using System.Collections.Generic; +using Windows.UI.Xaml.Markup; namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { @@ -12,6 +13,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// A base model representing a typed animation that can be used in XAML. /// /// The type of values for the animation. + [ContentProperty(Name = nameof(KeyFrames))] public abstract class Animation : Animation { /// @@ -28,6 +30,6 @@ public abstract class Animation : Animation /// Gets or sets the optional keyframe collection for the current animation. /// Setting this will overwrite the and values. /// - public IList> KeyFrames { get; set; } = new List>(); + public IList> KeyFrames { get; set; } = new List>(); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{T}.cs index 9896a55b940..afefb2a3edb 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{T}.cs @@ -4,13 +4,16 @@ #nullable enable +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// /// A base model representing a typed keyframe that can be used in XAML. /// /// The type of values for the keyframe. - public abstract class KeyFrame + public abstract class KeyFrame : IKeyFrame { /// /// Gets or sets the key time for the current keyframe. This is a normalized @@ -22,5 +25,21 @@ public abstract class KeyFrame /// Gets or sets the animation value for the current keyframe. /// public T? Value { get; set; } + + /// + /// Gets or sets the optional easing function type for the keyframe. + /// + public EasingType? EasingType { get; set; } + + /// + /// Gets or sets the optional easing function mode for the keyframe. + /// + public EasingMode? EasingMode { get; set; } + + /// + public INormalizedKeyFrameAnimationBuilder AppentToBuilder(INormalizedKeyFrameAnimationBuilder builder) + { + return builder.KeyFrame(Key, Value!, EasingType ?? DefaultEasingType, EasingMode ?? DefaultEasingMode); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IKeyFrame{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IKeyFrame{T}.cs new file mode 100644 index 00000000000..623e38c09c0 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IKeyFrame{T}.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// An interface representing a XAML model for a custom keyframe. + /// + /// The type of values for the current keyframe. + public interface IKeyFrame + { + /// + /// Appens the current keyframe to a target instance. + /// + /// The target instance to add the keyframe to. + /// The same instance as . + INormalizedKeyFrameAnimationBuilder AppentToBuilder(INormalizedKeyFrameAnimationBuilder builder); + } +} From 0c89f54a4eef3dca93333254ea502ca09299fa8b Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 23 Dec 2020 13:59:46 +0100 Subject: [PATCH 080/171] Added OrientationAnimation type --- .../Xaml/Default/OrientationAnimation.cs | 29 +++++++++++++++++++ .../Xaml/KeyFrames/QuaternionKeyFrame.cs | 16 ++++++++++ 2 files changed, 45 insertions(+) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/QuaternionKeyFrame.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs new file mode 100644 index 00000000000..64b878d2e9e --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Numerics; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// An orientation animation working on the composition layer. + /// + public class OrientationAnimation : Animation + { + /// + public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + { + return builder.Orientation( + To!.Value, + From, + Delay ?? delayHint, + Duration ?? durationHint, + EasingType ?? easingTypeHint ?? DefaultEasingType, + EasingMode ?? easingModeHint ?? DefaultEasingMode); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/QuaternionKeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/QuaternionKeyFrame.cs new file mode 100644 index 00000000000..c297cd2165e --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/QuaternionKeyFrame.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// A type for animations. + /// + public class QuaternionKeyFrame : KeyFrame + { + } +} From d721347607dae4b4d817f5326361c2a3e3d3a565 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 23 Dec 2020 16:05:26 +0100 Subject: [PATCH 081/171] Implemented support for keyframe XAML animations --- .../Xaml/Abstract/Animation{T}.cs | 3 ++- .../Xaml/Abstract/KeyFrame{T}.cs | 19 +++++++++++++++++- .../Xaml/AnimationScope.cs | 4 ++-- .../Xaml/Default/ClipAnimation.cs | 4 ++-- .../Xaml/Default/OffsetAnimation.cs | 14 ++++++++++--- .../Xaml/Default/OpacityAnimation.cs | 12 +++++++++-- .../Xaml/Default/OrientationAnimation.cs | 12 +++++++++-- .../Xaml/Default/RotationAnimation.cs | 20 ++++++++++--------- .../Default/RotationInDegreesAnimation.cs | 12 +++++++++-- .../Xaml/Default/ScaleAnimation.cs | 18 ++++++++++++----- .../Xaml/Default/SizeAnimation.cs | 18 ++++++++++++----- .../Xaml/Default/TranslationAnimation.cs | 20 +++++++++++++------ .../Xaml/Interfaces/IKeyFrame{T}.cs | 4 ++-- .../Animations/EffectDoubleAnimation.cs | 4 ++-- 14 files changed, 120 insertions(+), 44 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{T}.cs index e965c627b31..a6b88cdbfc2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{T}.cs @@ -15,11 +15,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// The type of values for the animation. [ContentProperty(Name = nameof(KeyFrames))] public abstract class Animation : Animation + where T : unmanaged { /// /// Gets or sets the final value for the animation. /// - public T? To { get; set; } + public T To { get; set; } /// /// Gets or sets the optional starting value for the animation. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{T}.cs index afefb2a3edb..a3a36c04574 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{T}.cs @@ -4,6 +4,7 @@ #nullable enable +using System.Collections.Generic; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -36,8 +37,24 @@ public abstract class KeyFrame : IKeyFrame /// public EasingMode? EasingMode { get; set; } + /// + /// Appends a sequence of instances to a target instance. + /// + /// The target instance to add the keyframe to. + /// The keyframes to append. + /// The same instance as . + public static INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder, IEnumerable> keyFrames) + { + foreach (var keyFrame in keyFrames) + { + builder = keyFrame.AppendToBuilder(builder); + } + + return builder; + } + /// - public INormalizedKeyFrameAnimationBuilder AppentToBuilder(INormalizedKeyFrameAnimationBuilder builder) + public INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder) { return builder.KeyFrame(Key, Value!, EasingType ?? DefaultEasingType, EasingMode ?? DefaultEasingMode); } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs index 31dc2ba0aaf..cb9faf8f8c9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs @@ -16,7 +16,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// together and to assign shared properties to be applied to all the contained items automatically. /// [ContentProperty(Name = nameof(Animations))] - public sealed class AnimationScope : Animation, ITimeline + public sealed class AnimationScope : Animation { /// /// Gets or sets the list of animations in the current scope. @@ -24,7 +24,7 @@ public sealed class AnimationScope : Animation, ITimeline public IList Animations { get; set; } = new List(); /// - AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { foreach (ITimeline element in Animations) { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs index f8abe56a236..fc6437466c2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs @@ -12,13 +12,13 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A clip animation working on the composition layer. /// - public class ClipAnimation : Animation + public class ClipAnimation : Animation { /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { return builder.Clip( - To!.Value, + To, From, Delay ?? delayHint, Duration ?? durationHint, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs index 756445341e5..11ccd8c0aac 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs @@ -12,13 +12,21 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// An offset animation working on the composition layer. /// - public class OffsetAnimation : Animation + public class OffsetAnimation : Animation { /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { - return builder.Translation( - To.Value, + if (KeyFrames.Count > 0) + { + return builder.Offset().NormalizedKeyFrames( + delay: Delay ?? delayHint, + duration: Duration ?? durationHint, + build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); + } + + return builder.Offset( + To, From, Delay ?? delayHint, Duration ?? durationHint, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs index ebaaa3d487f..cba2e77a33d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs @@ -11,7 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// An opacity animation working on the composition or XAML layer. /// - public class OpacityAnimation : Animation + public class OpacityAnimation : Animation { /// /// Gets or sets the target framework layer to animate. @@ -21,8 +21,16 @@ public class OpacityAnimation : Animation /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { + if (KeyFrames.Count > 0) + { + return builder.Opacity(Layer).NormalizedKeyFrames( + delay: Delay ?? delayHint, + duration: Duration ?? durationHint, + build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); + } + return builder.Opacity( - To!.Value, + To, From, Delay ?? delayHint, Duration ?? durationHint, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs index 64b878d2e9e..c4d04295bc4 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs @@ -12,13 +12,21 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// An orientation animation working on the composition layer. /// - public class OrientationAnimation : Animation + public class OrientationAnimation : Animation { /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { + if (KeyFrames.Count > 0) + { + return builder.Orientation().NormalizedKeyFrames( + delay: Delay ?? delayHint, + duration: Duration ?? durationHint, + build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); + } + return builder.Orientation( - To!.Value, + To, From, Delay ?? delayHint, Duration ?? durationHint, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs index fbf15c15ea8..417ae34478f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs @@ -11,24 +11,26 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A rotation animation working on the composition or XAML layer. /// - public class RotationAnimation : Animation + public class RotationAnimation : Animation { - /// - /// Gets or sets the target framework layer to animate. - /// - public FrameworkLayer Layer { get; set; } - /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { + if (KeyFrames.Count > 0) + { + return builder.Rotation().NormalizedKeyFrames( + delay: Delay ?? delayHint, + duration: Duration ?? durationHint, + build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); + } + return builder.Rotation( - To!.Value, + To, From, Delay ?? delayHint, Duration ?? durationHint, EasingType ?? easingTypeHint ?? DefaultEasingType, - EasingMode ?? easingModeHint ?? DefaultEasingMode, - Layer); + EasingMode ?? easingModeHint ?? DefaultEasingMode); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs index 88ced3ec5b7..f567d3ea269 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs @@ -11,7 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A rotation in degrees animation working on the composition or XAML layer. /// - public class RotationInDegreesAnimation : Animation + public class RotationInDegreesAnimation : Animation { /// /// Gets or sets the target framework layer to animate. @@ -21,8 +21,16 @@ public class RotationInDegreesAnimation : Animation /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { + if (KeyFrames.Count > 0) + { + return builder.RotationInDegrees(Layer).NormalizedKeyFrames( + delay: Delay ?? delayHint, + duration: Duration ?? durationHint, + build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); + } + return builder.RotationInDegrees( - To!.Value, + To, From, Delay ?? delayHint, Duration ?? durationHint, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs index 285fe8485f9..e57cc406790 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A scale animation working on the composition or XAML layer. /// - public class ScaleAnimation : Animation + public class ScaleAnimation : Animation { /// /// Gets or sets the target framework layer to animate. @@ -22,20 +22,28 @@ public class ScaleAnimation : Animation /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { - Vector3 to = To.Value; - Vector3? from = From; TimeSpan? delay = Delay ?? delayHint; TimeSpan? duration = Duration ?? durationHint; + + if (KeyFrames.Count > 0) + { + return builder.Scale().NormalizedKeyFrames( + delay: Delay ?? delayHint, + duration: Duration ?? durationHint, + build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); + } + + Vector3? from = From; EasingType easingType = EasingType ?? easingTypeHint ?? DefaultEasingType; EasingMode easingMode = EasingMode ?? easingModeHint ?? DefaultEasingMode; if (Layer == FrameworkLayer.Composition) { - return builder.Scale(to, from, delay, duration, easingType, easingMode); + return builder.Scale(To, from, delay, duration, easingType, easingMode); } else { - Vector2 to2 = new(to.X, to.Y); + Vector2 to2 = new(To.X, To.Y); Vector2? from2 = from is null ? null : new(from.Value.X, from.Value.Y); return builder.Scale(to2, from2, delay, duration, easingType, easingMode, FrameworkLayer.Xaml); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs index d1b096fc026..c2035ed0fdf 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A size animation working on the composition or XAML layer. /// - public class SizeAnimation : Animation + public class SizeAnimation : Animation { /// /// Gets or sets the target framework layer to animate. @@ -22,20 +22,28 @@ public class SizeAnimation : Animation /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { - Vector3 to = To.Value; - Vector3? from = From; TimeSpan? delay = Delay ?? delayHint; TimeSpan? duration = Duration ?? durationHint; + + if (KeyFrames.Count > 0) + { + return builder.Size().NormalizedKeyFrames( + delay: Delay ?? delayHint, + duration: Duration ?? durationHint, + build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); + } + + Vector3? from = From; EasingType easingType = EasingType ?? easingTypeHint ?? DefaultEasingType; EasingMode easingMode = EasingMode ?? easingModeHint ?? DefaultEasingMode; if (Layer == FrameworkLayer.Composition) { - return builder.Size(to, from, delay, duration, easingType, easingMode); + return builder.Size(To, from, delay, duration, easingType, easingMode); } else { - Vector2 to2 = new(to.X, to.Y); + Vector2 to2 = new(To.X, To.Y); Vector2? from2 = from is null ? null : new(from.Value.X, from.Value.Y); return builder.Size(to2, from2, delay, duration, easingType, easingMode, FrameworkLayer.Xaml); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs index 590e3429f16..9351ba263a6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using System; -using System.Numerics; +using System.Numerics; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A translation animation working on the composition or XAML layer. /// - public class TranslationAnimation : Animation + public class TranslationAnimation : Animation { /// /// Gets or sets the target framework layer to animate. @@ -22,20 +22,28 @@ public class TranslationAnimation : Animation /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { - Vector3 to = To.Value; - Vector3? from = From; TimeSpan? delay = Delay ?? delayHint; TimeSpan? duration = Duration ?? durationHint; + + if (KeyFrames.Count > 0) + { + return builder.Translation().NormalizedKeyFrames( + delay: Delay ?? delayHint, + duration: Duration ?? durationHint, + build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); + } + + Vector3? from = From; EasingType easingType = EasingType ?? easingTypeHint ?? DefaultEasingType; EasingMode easingMode = EasingMode ?? easingModeHint ?? DefaultEasingMode; if (Layer == FrameworkLayer.Composition) { - return builder.Translation(to, from, delay, duration, easingType, easingMode); + return builder.Translation(To, from, delay, duration, easingType, easingMode); } else { - Vector2 to2 = new(to.X, to.Y); + Vector2 to2 = new(To.X, To.Y); Vector2? from2 = from is null ? null : new(from.Value.X, from.Value.Y); return builder.Translation(to2, from2, delay, duration, easingType, easingMode, FrameworkLayer.Xaml); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IKeyFrame{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IKeyFrame{T}.cs index 623e38c09c0..84cbb65593e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IKeyFrame{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IKeyFrame{T}.cs @@ -11,10 +11,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml public interface IKeyFrame { /// - /// Appens the current keyframe to a target instance. + /// Appends the current keyframe to a target instance. /// /// The target instance to add the keyframe to. /// The same instance as . - INormalizedKeyFrameAnimationBuilder AppentToBuilder(INormalizedKeyFrameAnimationBuilder builder); + INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs index 5816e8fd176..c2085805c2d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs @@ -17,7 +17,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Animations /// /// A set of animations that can be grouped together. /// - public class EffectDoubleAnimation : Animation, ITimeline + public class EffectDoubleAnimation : Animation { /// /// Gets or sets the linked instance to animate. @@ -25,7 +25,7 @@ public class EffectDoubleAnimation : Animation, ITimeline public IPipelineEffect Target { get; set; } /// - AnimationBuilder ITimeline.AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { BlurEffect effect = (BlurEffect)Target; From 2584b8ba60821fabcc5a8307f965bda64aded4ea Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 23 Dec 2020 16:06:14 +0100 Subject: [PATCH 082/171] Removed previous XAML animation/keyframe types --- .../Animations/OffsetAnimation.cs | 27 ------------------ .../Animations/OpacityAnimation.cs | 27 ------------------ .../Animations/RotationAnimation.cs | 27 ------------------ .../Animations/RotationInDegreesAnimation.cs | 22 --------------- .../Animations/ScalarAnimation.cs | 26 ----------------- .../Animations/ScaleAnimation.cs | 22 --------------- .../Animations/TranslationAnimation.cs | 24 ---------------- .../Animations/TypedAnimationBase.cs | 4 +-- .../Animations/Vector2Animation.cs | 28 ------------------- .../Animations/Vector3Animation.cs | 28 ------------------- .../Animations/Vector4Animation.cs | 28 ------------------- .../KeyFrames/ExpressionKeyFrame.cs | 13 --------- 12 files changed, 2 insertions(+), 274 deletions(-) delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/OffsetAnimation.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/OpacityAnimation.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/RotationAnimation.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/RotationInDegreesAnimation.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/ScalarAnimation.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/ScaleAnimation.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/TranslationAnimation.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/Vector2Animation.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/Vector3Animation.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/Vector4Animation.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/ExpressionKeyFrame.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/OffsetAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/OffsetAnimation.cs deleted file mode 100644 index 84bcd413217..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/OffsetAnimation.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Vector3Animation that animates the property - /// - public class OffsetAnimation : Vector3Animation - { - /// - /// Initializes a new instance of the class. - /// - public OffsetAnimation() - { - Target = nameof(Visual.Offset); - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/OpacityAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/OpacityAnimation.cs deleted file mode 100644 index 572fd9fdc48..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/OpacityAnimation.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// ScalarAnimation that animates the property - /// - public class OpacityAnimation : ScalarAnimation - { - /// - /// Initializes a new instance of the class. - /// - public OpacityAnimation() - { - Target = nameof(Visual.Opacity); - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/RotationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/RotationAnimation.cs deleted file mode 100644 index 8f28e9e0474..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/RotationAnimation.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// ScalarAnimation that animates the property - /// - public class RotationAnimation : ScalarAnimation - { - /// - /// Initializes a new instance of the class. - /// - public RotationAnimation() - { - Target = nameof(Visual.RotationAngle); - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/RotationInDegreesAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/RotationInDegreesAnimation.cs deleted file mode 100644 index aa40df2f999..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/RotationInDegreesAnimation.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// ScalarAnimation that animates the property - /// - public class RotationInDegreesAnimation : ScalarAnimation - { - /// - /// Initializes a new instance of the class. - /// - public RotationInDegreesAnimation() - { - Target = nameof(Visual.RotationAngleInDegrees); - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/ScalarAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/ScalarAnimation.cs deleted file mode 100644 index d92c75e5240..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/ScalarAnimation.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Animation that animates a value of type float - /// - public class ScalarAnimation : TypedAnimationBase - { - /// - protected override KeyFrameAnimation GetTypedAnimationFromCompositor(Compositor compositor) - { - return compositor.CreateScalarKeyFrameAnimation(); - } - - /// - protected override void InsertKeyFrameToTypedAnimation(KeyFrameAnimation animation, ScalarKeyFrame keyFrame) - { - (animation as ScalarKeyFrameAnimation).InsertKeyFrame((float)keyFrame.Key, (float)keyFrame.Value); - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/ScaleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/ScaleAnimation.cs deleted file mode 100644 index 29167bd1047..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/ScaleAnimation.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Vector3Animation that animates the property - /// - public class ScaleAnimation : Vector3Animation - { - /// - /// Initializes a new instance of the class. - /// - public ScaleAnimation() - { - Target = nameof(Visual.Scale); - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/TranslationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/TranslationAnimation.cs deleted file mode 100644 index 1ce4a10ee8a..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/TranslationAnimation.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; -using Windows.UI.Xaml.Hosting; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Vector3Animation that animates the Translation property - /// - /// - public class TranslationAnimation : Vector3Animation - { - /// - /// Initializes a new instance of the class. - /// - public TranslationAnimation() - { - Target = "Translation"; - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/TypedAnimationBase.cs b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/TypedAnimationBase.cs index fed3156586c..0fe1a97b538 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/TypedAnimationBase.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/TypedAnimationBase.cs @@ -83,9 +83,9 @@ public override CompositionAnimation GetCompositionAnimation(Compositor composit { InsertKeyFrameToTypedAnimation(animation, typedKeyFrame); } - else if (keyFrame is ExpressionKeyFrame expressionKeyFrame) + //else if (keyFrame is ExpressionKeyFrame expressionKeyFrame) { - animation.InsertExpressionKeyFrame((float)keyFrame.Key, expressionKeyFrame.Value); + //animation.InsertExpressionKeyFrame((float)keyFrame.Key, expressionKeyFrame.Value); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/Vector2Animation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/Vector2Animation.cs deleted file mode 100644 index 21c8d57ea2b..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/Vector2Animation.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Numerics; -using Microsoft.Toolkit.Uwp.UI.Extensions; -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Animation that animates a value of type - /// - public class Vector2Animation : TypedAnimationBase - { - /// - protected override KeyFrameAnimation GetTypedAnimationFromCompositor(Compositor compositor) - { - return compositor.CreateVector2KeyFrameAnimation(); - } - - /// - protected override void InsertKeyFrameToTypedAnimation(KeyFrameAnimation animation, Vector2KeyFrame keyFrame) - { - (animation as Vector2KeyFrameAnimation).InsertKeyFrame((float)keyFrame.Key, keyFrame.Value.ToVector2()); - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/Vector3Animation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/Vector3Animation.cs deleted file mode 100644 index 691aab21bad..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/Vector3Animation.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Numerics; -using Microsoft.Toolkit.Uwp.UI.Extensions; -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Animation that animates a value of type - /// - public class Vector3Animation : TypedAnimationBase - { - /// - protected override KeyFrameAnimation GetTypedAnimationFromCompositor(Compositor compositor) - { - return compositor.CreateVector3KeyFrameAnimation(); - } - - /// - protected override void InsertKeyFrameToTypedAnimation(KeyFrameAnimation animation, Vector3KeyFrame keyFrame) - { - (animation as Vector3KeyFrameAnimation).InsertKeyFrame((float)keyFrame.Key, keyFrame.Value.ToVector3()); - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/Vector4Animation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/Vector4Animation.cs deleted file mode 100644 index f902f20b0cb..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/Vector4Animation.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Numerics; -using Microsoft.Toolkit.Uwp.UI.Extensions; -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Animation that animates a value of type - /// - public class Vector4Animation : TypedAnimationBase - { - /// - protected override KeyFrameAnimation GetTypedAnimationFromCompositor(Compositor compositor) - { - return compositor.CreateVector4KeyFrameAnimation(); - } - - /// - protected override void InsertKeyFrameToTypedAnimation(KeyFrameAnimation animation, Vector4KeyFrame keyFrame) - { - (animation as Vector4KeyFrameAnimation).InsertKeyFrame((float)keyFrame.Key, keyFrame.Value.ToVector4()); - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/ExpressionKeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/ExpressionKeyFrame.cs deleted file mode 100644 index b50c3f4a106..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/ExpressionKeyFrame.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// of type string - /// - public class ExpressionKeyFrame : TypedKeyFrame - { - } -} From f500432cc70f222bedbb73deddb498b91b885fa7 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 23 Dec 2020 16:45:53 +0100 Subject: [PATCH 083/171] Added default values for animation extensions, minor tweaks --- .../Builders/AnimationBuilder.Factories.cs | 4 +- ...KeyFrameAnimationBuilder{T}.Composition.cs | 14 +- .../Extensions/CompositionObjectExtensions.cs | 29 +++ .../Extensions/CompositorExtensions.cs | 217 ++++++++++++------ .../Animations/EffectDoubleAnimation.cs | 2 +- .../Extensions/Visual/VisualExtensions.cs | 2 +- 6 files changed, 183 insertions(+), 85 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs index 09a59be3360..b51eed9026b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs @@ -71,7 +71,7 @@ private sealed record AnimationFactory( /// public CompositionAnimation GetAnimation(CompositionObject targetHint, out CompositionObject? target) { - CompositionEasingFunction easingFunction = targetHint.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); + CompositionEasingFunction easingFunction = targetHint.Compositor.CreateEasingFunction(EasingType, EasingMode); target = null; @@ -274,7 +274,7 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo { Visual visual = (Visual)targetHint; InsetClip clip = visual.Clip as InsetClip ?? (InsetClip)(visual.Clip = visual.Compositor.CreateInsetClip()); - CompositionEasingFunction easingFunction = clip.Compositor.CreateCubicBezierEasingFunction(EasingType, EasingMode); + CompositionEasingFunction easingFunction = clip.Compositor.CreateEasingFunction(EasingType, EasingMode); ScalarKeyFrameAnimation animation = clip.Compositor.CreateScalarKeyFrameAnimation(Property, To, From, Delay, Duration, easingFunction); target = clip; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs index d25869055c1..e9f6f4082f3 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs @@ -58,7 +58,7 @@ public static CompositionAnimation GetAnimation( scalarAnimation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs(), - target.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + target.Compositor.CreateEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); } animation = scalarAnimation; @@ -72,7 +72,7 @@ public static CompositionAnimation GetAnimation( scalarAnimation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), (float)keyFrame.GetValueAs(), - target.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + target.Compositor.CreateEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); } animation = scalarAnimation; @@ -86,7 +86,7 @@ public static CompositionAnimation GetAnimation( vector2Animation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs(), - target.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + target.Compositor.CreateEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); } animation = vector2Animation; @@ -100,7 +100,7 @@ public static CompositionAnimation GetAnimation( vector3Animation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs(), - target.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + target.Compositor.CreateEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); } animation = vector3Animation; @@ -114,7 +114,7 @@ public static CompositionAnimation GetAnimation( vector4Animation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs(), - target.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + target.Compositor.CreateEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); } animation = vector4Animation; @@ -128,7 +128,7 @@ public static CompositionAnimation GetAnimation( colorAnimation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs(), - target.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + target.Compositor.CreateEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); } animation = colorAnimation; @@ -142,7 +142,7 @@ public static CompositionAnimation GetAnimation( quaternionAnimation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs(), - target.Compositor.CreateCubicBezierEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); + target.Compositor.CreateEasingFunction(keyFrame.EasingType, keyFrame.EasingMode)); } animation = quaternionAnimation; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs new file mode 100644 index 00000000000..868bacde220 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositionObjectExtensions.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable enable + +using System.Diagnostics.Contracts; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Extensions +{ + /// + /// An extension for the type. + /// + public static class CompositionObjectExtensions + { + /// + /// Starts a given on a target . + /// + /// The target instance to animate. + /// The instance to run. + /// This method requires to have its property set. + [Pure] + public static void StartAnimation(this CompositionObject compositionObject, CompositionAnimation animation) + { + compositionObject.StartAnimation(animation.Target, animation); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs index 293ec4a81a3..3bf0a28f1af 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs @@ -10,6 +10,7 @@ using Windows.UI; using Windows.UI.Composition; using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations.Extensions { @@ -18,6 +19,26 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Extensions /// public static class CompositorExtensions { + /// + /// Creates the appropriate from the given easing type and mode. + /// + /// The source used to create the easing function. + /// The target easing function to use. + /// The target easing mode to use. + /// A instance with the specified easing. + [Pure] + public static CompositionEasingFunction CreateEasingFunction(this Compositor compositor, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) + { + if (easingType == EasingType.Linear) + { + return compositor.CreateLinearEasingFunction(); + } + + var (a, b) = EasingMaps[(easingType, easingMode)]; + + return compositor.CreateCubicBezierEasingFunction(a, b); + } + /// /// Creates a from the input control points. /// @@ -33,21 +54,6 @@ public static CubicBezierEasingFunction CreateCubicBezierEasingFunction(this Com return compositor.CreateCubicBezierEasingFunction(new(x1, y1), new(x2, y2)); } - /// - /// Creates the appropriate from the given easing type and mode. - /// - /// The source used to create the easing function. - /// The target easing function to use. - /// The target easing mode to use. - /// A instance with the specified easing. - [Pure] - public static CubicBezierEasingFunction CreateCubicBezierEasingFunction(this Compositor compositor, EasingType easingType, EasingMode easingMode) - { - var (a, b) = AnimationExtensions.EasingMaps[(easingType, easingMode)]; - - return compositor.CreateCubicBezierEasingFunction(a, b); - } - /// /// Creates a instance with the given parameters to on a target element. /// @@ -56,24 +62,31 @@ public static CubicBezierEasingFunction CreateCubicBezierEasingFunction(this Com /// The final value for the animation. /// The optional starting value for the animation. /// The optional initial delay for the animation. - /// The animation duration. + /// The optional animation duration. + /// The delay behavior to use for the animation. + /// The iteration behavior to use for the animation. + /// The iteration count to use for the animation. /// A instance with the specified parameters. [Pure] public static BooleanKeyFrameAnimation CreateBooleanKeyFrameAnimation( this Compositor compositor, string? target, bool to, - bool? from, - TimeSpan? delay, - TimeSpan duration) + bool? from = null, + TimeSpan? delay = null, + TimeSpan? duration = null, + AnimationDelayBehavior delayBehavior = AnimationDelayBehavior.SetInitialValueBeforeDelay, + AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count, + int iterationCount = 1) { BooleanKeyFrameAnimation animation = compositor.CreateBooleanKeyFrameAnimation(); - animation.Duration = duration; + animation.Duration = duration ?? DefaultDuration; if (delay.HasValue) { animation.DelayTime = delay.Value; + animation.DelayBehavior = delayBehavior; } animation.InsertKeyFrame(1, to); @@ -84,6 +97,8 @@ public static BooleanKeyFrameAnimation CreateBooleanKeyFrameAnimation( } animation.Target = target; + animation.IterationBehavior = iterationBehavior; + animation.IterationCount = iterationCount; return animation; } @@ -96,35 +111,42 @@ public static BooleanKeyFrameAnimation CreateBooleanKeyFrameAnimation( /// The final value for the animation. /// The optional starting value for the animation. /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function for the animation. + /// The optional animation duration. + /// The optional easing function for the animation. + /// The delay behavior to use for the animation. + /// The iteration behavior to use for the animation. + /// The iteration count to use for the animation. /// A instance with the specified parameters. [Pure] public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation( this Compositor compositor, string? target, float to, - float? from, - TimeSpan? delay, - TimeSpan duration, - CompositionEasingFunction? ease = null) + float? from = null, + TimeSpan? delay = null, + TimeSpan? duration = null, + CompositionEasingFunction? easing = null, + AnimationDelayBehavior delayBehavior = AnimationDelayBehavior.SetInitialValueBeforeDelay, + AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count, + int iterationCount = 1) { ScalarKeyFrameAnimation animation = compositor.CreateScalarKeyFrameAnimation(); - animation.Duration = duration; + animation.Duration = duration ?? DefaultDuration; if (delay.HasValue) { animation.DelayTime = delay.Value; + animation.DelayBehavior = delayBehavior; } - if (ease is null) + if (easing is null) { animation.InsertKeyFrame(1, to); } else { - animation.InsertKeyFrame(1, to, ease); + animation.InsertKeyFrame(1, to, easing); } if (from.HasValue) @@ -133,6 +155,8 @@ public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation( } animation.Target = target; + animation.IterationBehavior = iterationBehavior; + animation.IterationCount = iterationCount; return animation; } @@ -145,35 +169,42 @@ public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation( /// The final value for the animation. /// The optional starting value for the animation. /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function for the animation. + /// The optional animation duration. + /// The optional easing function for the animation. + /// The delay behavior to use for the animation. + /// The iteration behavior to use for the animation. + /// The iteration count to use for the animation. /// A instance with the specified parameters. [Pure] public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation( this Compositor compositor, string? target, Vector2 to, - Vector2? from, - TimeSpan? delay, - TimeSpan duration, - CompositionEasingFunction? ease = null) + Vector2? from = null, + TimeSpan? delay = null, + TimeSpan? duration = null, + CompositionEasingFunction? easing = null, + AnimationDelayBehavior delayBehavior = AnimationDelayBehavior.SetInitialValueBeforeDelay, + AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count, + int iterationCount = 1) { Vector2KeyFrameAnimation animation = compositor.CreateVector2KeyFrameAnimation(); - animation.Duration = duration; + animation.Duration = duration ?? DefaultDuration; if (delay.HasValue) { animation.DelayTime = delay.Value; + animation.DelayBehavior = delayBehavior; } - if (ease is null) + if (easing is null) { animation.InsertKeyFrame(1, to); } else { - animation.InsertKeyFrame(1, to, ease); + animation.InsertKeyFrame(1, to, easing); } if (from.HasValue) @@ -182,6 +213,8 @@ public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation( } animation.Target = target; + animation.IterationBehavior = iterationBehavior; + animation.IterationCount = iterationCount; return animation; } @@ -194,35 +227,42 @@ public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation( /// The final value for the animation. /// The optional starting value for the animation. /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function for the animation. + /// The optional animation duration. + /// The optional easing function for the animation. + /// The delay behavior to use for the animation. + /// The iteration behavior to use for the animation. + /// The iteration count to use for the animation. /// A instance with the specified parameters. [Pure] public static Vector3KeyFrameAnimation CreateVector3KeyFrameAnimation( this Compositor compositor, string? target, Vector3 to, - Vector3? from, - TimeSpan? delay, - TimeSpan duration, - CompositionEasingFunction? ease = null) + Vector3? from = null, + TimeSpan? delay = null, + TimeSpan? duration = null, + CompositionEasingFunction? easing = null, + AnimationDelayBehavior delayBehavior = AnimationDelayBehavior.SetInitialValueBeforeDelay, + AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count, + int iterationCount = 1) { Vector3KeyFrameAnimation animation = compositor.CreateVector3KeyFrameAnimation(); - animation.Duration = duration; + animation.Duration = duration ?? DefaultDuration; if (delay.HasValue) { animation.DelayTime = delay.Value; + animation.DelayBehavior = delayBehavior; } - if (ease is null) + if (easing is null) { animation.InsertKeyFrame(1, to); } else { - animation.InsertKeyFrame(1, to, ease); + animation.InsertKeyFrame(1, to, easing); } if (from.HasValue) @@ -231,6 +271,8 @@ public static Vector3KeyFrameAnimation CreateVector3KeyFrameAnimation( } animation.Target = target; + animation.IterationBehavior = iterationBehavior; + animation.IterationCount = iterationCount; return animation; } @@ -243,35 +285,42 @@ public static Vector3KeyFrameAnimation CreateVector3KeyFrameAnimation( /// The final value for the animation. /// The optional starting value for the animation. /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function for the animation. + /// The optional animation duration. + /// The optional easing function for the animation. + /// The delay behavior to use for the animation. + /// The iteration behavior to use for the animation. + /// The iteration count to use for the animation. /// A instance with the specified parameters. [Pure] public static Vector4KeyFrameAnimation CreateVector4KeyFrameAnimation( this Compositor compositor, string? target, Vector4 to, - Vector4? from, - TimeSpan? delay, - TimeSpan duration, - CompositionEasingFunction? ease = null) + Vector4? from = null, + TimeSpan? delay = null, + TimeSpan? duration = null, + CompositionEasingFunction? easing = null, + AnimationDelayBehavior delayBehavior = AnimationDelayBehavior.SetInitialValueBeforeDelay, + AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count, + int iterationCount = 1) { Vector4KeyFrameAnimation animation = compositor.CreateVector4KeyFrameAnimation(); - animation.Duration = duration; + animation.Duration = duration ?? DefaultDuration; if (delay.HasValue) { animation.DelayTime = delay.Value; + animation.DelayBehavior = delayBehavior; } - if (ease is null) + if (easing is null) { animation.InsertKeyFrame(1, to); } else { - animation.InsertKeyFrame(1, to, ease); + animation.InsertKeyFrame(1, to, easing); } if (from.HasValue) @@ -280,6 +329,8 @@ public static Vector4KeyFrameAnimation CreateVector4KeyFrameAnimation( } animation.Target = target; + animation.IterationBehavior = iterationBehavior; + animation.IterationCount = iterationCount; return animation; } @@ -292,35 +343,42 @@ public static Vector4KeyFrameAnimation CreateVector4KeyFrameAnimation( /// The final value for the animation. /// The optional starting value for the animation. /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function for the animation. + /// The optional animation duration. + /// The optional easing function for the animation. + /// The delay behavior to use for the animation. + /// The iteration behavior to use for the animation. + /// The iteration count to use for the animation. /// A instance with the specified parameters. [Pure] public static ColorKeyFrameAnimation CreateColorKeyFrameAnimation( this Compositor compositor, string? target, Color to, - Color? from, - TimeSpan? delay, - TimeSpan duration, - CompositionEasingFunction? ease = null) + Color? from = null, + TimeSpan? delay = null, + TimeSpan? duration = null, + CompositionEasingFunction? easing = null, + AnimationDelayBehavior delayBehavior = AnimationDelayBehavior.SetInitialValueBeforeDelay, + AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count, + int iterationCount = 1) { ColorKeyFrameAnimation animation = compositor.CreateColorKeyFrameAnimation(); - animation.Duration = duration; + animation.Duration = duration ?? DefaultDuration; if (delay.HasValue) { animation.DelayTime = delay.Value; + animation.DelayBehavior = delayBehavior; } - if (ease is null) + if (easing is null) { animation.InsertKeyFrame(1, to); } else { - animation.InsertKeyFrame(1, to, ease); + animation.InsertKeyFrame(1, to, easing); } if (from.HasValue) @@ -329,6 +387,8 @@ public static ColorKeyFrameAnimation CreateColorKeyFrameAnimation( } animation.Target = target; + animation.IterationBehavior = iterationBehavior; + animation.IterationCount = iterationCount; return animation; } @@ -341,35 +401,42 @@ public static ColorKeyFrameAnimation CreateColorKeyFrameAnimation( /// The final value for the animation. /// The optional starting value for the animation. /// The optional initial delay for the animation. - /// The animation duration. - /// The optional easing function for the animation. + /// The optional animation duration. + /// The optional easing function for the animation. + /// The delay behavior to use for the animation. + /// The iteration behavior to use for the animation. + /// The iteration count to use for the animation. /// A instance with the specified parameters. [Pure] public static QuaternionKeyFrameAnimation CreateQuaternionKeyFrameAnimation( this Compositor compositor, string? target, Quaternion to, - Quaternion? from, - TimeSpan? delay, - TimeSpan duration, - CompositionEasingFunction? ease = null) + Quaternion? from = null, + TimeSpan? delay = null, + TimeSpan? duration = null, + CompositionEasingFunction? easing = null, + AnimationDelayBehavior delayBehavior = AnimationDelayBehavior.SetInitialValueBeforeDelay, + AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count, + int iterationCount = 1) { QuaternionKeyFrameAnimation animation = compositor.CreateQuaternionKeyFrameAnimation(); - animation.Duration = duration; + animation.Duration = duration ?? DefaultDuration; if (delay.HasValue) { animation.DelayTime = delay.Value; + animation.DelayBehavior = delayBehavior; } - if (ease is null) + if (easing is null) { animation.InsertKeyFrame(1, to); } else { - animation.InsertKeyFrame(1, to, ease); + animation.InsertKeyFrame(1, to, easing); } if (from.HasValue) @@ -378,6 +445,8 @@ public static QuaternionKeyFrameAnimation CreateQuaternionKeyFrameAnimation( } animation.Target = target; + animation.IterationBehavior = iterationBehavior; + animation.IterationCount = iterationCount; return animation; } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs index c2085805c2d..7aa745ef77e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs @@ -35,7 +35,7 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS (float?)From, Delay ?? delayHint ?? DefaultDelay, Duration ?? durationHint ?? DefaultDuration, - effect.Brush.Compositor.CreateCubicBezierEasingFunction( + effect.Brush.Compositor.CreateEasingFunction( EasingType ?? easingTypeHint ?? DefaultEasingType, EasingMode ?? easingModeHint ?? DefaultEasingMode)); diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Visual/VisualExtensions.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Visual/VisualExtensions.cs index 1e5cc147912..c5200f829ae 100644 --- a/Microsoft.Toolkit.Uwp.UI/Extensions/Visual/VisualExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Visual/VisualExtensions.cs @@ -164,7 +164,7 @@ public static Vector4 ToVector4(this string str) /// /// The /// The backing the - public static Visual GetVisual(UIElement element) + public static Visual GetVisual(this UIElement element) { return ElementCompositionPreview.GetElementVisual(element); } From 2151b30cdd8897227d31e0b4f34bf9b301e9a97f Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 24 Dec 2020 14:34:55 +0100 Subject: [PATCH 084/171] Added workaround for XAML parsing limitations --- ...n{T}.cs => Animation{TValue,TKeyFrame}.cs} | 15 ++++++++------ ...me{T}.cs => KeyFrame{TValue,TKeyFrame}.cs} | 18 ++++++++--------- .../Xaml/Default/ClipAnimation.cs | 4 ++-- .../Xaml/Default/OffsetAnimation.cs | 9 +++++---- .../Xaml/Default/OpacityAnimation.cs | 6 +++--- .../Xaml/Default/OrientationAnimation.cs | 9 +++++---- .../Xaml/Default/RotationAnimation.cs | 6 +++--- .../Default/RotationInDegreesAnimation.cs | 6 +++--- .../Xaml/Default/ScaleAnimation.cs | 12 ++++++----- .../Xaml/Default/SizeAnimation.cs | 12 ++++++----- .../Xaml/Default/TranslationAnimation.cs | 14 +++++++------ .../Xaml/KeyFrames/QuaternionKeyFrame.cs | 20 +++++++++++++++++-- .../Xaml/KeyFrames/ScalarKeyFrame.cs | 10 ++++++++-- .../Xaml/KeyFrames/Vector2KeyFrame.cs | 13 ++++++++++-- .../Xaml/KeyFrames/Vector3KeyFrame.cs | 13 ++++++++++-- .../Xaml/KeyFrames/Vector4KeyFrame.cs | 13 ++++++++++-- .../Animations/EffectDoubleAnimation.cs | 2 +- .../Extensions/Visual/VisualExtensions.cs | 13 ++++++++++++ 18 files changed, 134 insertions(+), 61 deletions(-) rename Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/{Animation{T}.cs => Animation{TValue,TKeyFrame}.cs} (62%) rename Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/{KeyFrame{T}.cs => KeyFrame{TValue,TKeyFrame}.cs} (72%) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs similarity index 62% rename from Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{T}.cs rename to Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs index a6b88cdbfc2..9020421ed8d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs @@ -12,25 +12,28 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A base model representing a typed animation that can be used in XAML. /// - /// The type of values for the animation. + /// + /// The type to use for the public and properties. + /// This can differ from to facilitate XAML parsing. + /// + /// The actual type of keyframe values in use. [ContentProperty(Name = nameof(KeyFrames))] - public abstract class Animation : Animation - where T : unmanaged + public abstract class Animation : Animation { /// /// Gets or sets the final value for the animation. /// - public T To { get; set; } + public TValue? To { get; set; } /// /// Gets or sets the optional starting value for the animation. /// - public T? From { get; set; } + public TValue? From { get; set; } /// /// Gets or sets the optional keyframe collection for the current animation. /// Setting this will overwrite the and values. /// - public IList> KeyFrames { get; set; } = new List>(); + public IList> KeyFrames { get; set; } = new List>(); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs similarity index 72% rename from Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{T}.cs rename to Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs index a3a36c04574..fa89a76c7eb 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs @@ -6,15 +6,18 @@ using System.Collections.Generic; using Windows.UI.Xaml.Media.Animation; -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml { /// /// A base model representing a typed keyframe that can be used in XAML. /// - /// The type of values for the keyframe. - public abstract class KeyFrame : IKeyFrame + /// + /// The type to use for the public property. + /// This can differ from to facilitate XAML parsing. + /// + /// The actual type of keyframe values in use. + public abstract class KeyFrame : IKeyFrame { /// /// Gets or sets the key time for the current keyframe. This is a normalized @@ -25,7 +28,7 @@ public abstract class KeyFrame : IKeyFrame /// /// Gets or sets the animation value for the current keyframe. /// - public T? Value { get; set; } + public TValue? Value { get; set; } /// /// Gets or sets the optional easing function type for the keyframe. @@ -43,7 +46,7 @@ public abstract class KeyFrame : IKeyFrame /// The target instance to add the keyframe to. /// The keyframes to append. /// The same instance as . - public static INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder, IEnumerable> keyFrames) + public static INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder, IEnumerable> keyFrames) { foreach (var keyFrame in keyFrames) { @@ -54,9 +57,6 @@ public static INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalized } /// - public INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder) - { - return builder.KeyFrame(Key, Value!, EasingType ?? DefaultEasingType, EasingMode ?? DefaultEasingMode); - } + public abstract INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs index fc6437466c2..71b4d943220 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs @@ -12,13 +12,13 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A clip animation working on the composition layer. /// - public class ClipAnimation : Animation + public class ClipAnimation : Animation { /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { return builder.Clip( - To, + To!.Value, From, Delay ?? delayHint, Duration ?? durationHint, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs index 11ccd8c0aac..9f606382a14 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs @@ -4,6 +4,7 @@ using System; using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Extensions; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -12,7 +13,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// An offset animation working on the composition layer. /// - public class OffsetAnimation : Animation + public class OffsetAnimation : Animation { /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) @@ -22,12 +23,12 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS return builder.Offset().NormalizedKeyFrames( delay: Delay ?? delayHint, duration: Duration ?? durationHint, - build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); + build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); } return builder.Offset( - To, - From, + To!.ToVector3(), + From?.ToVector3(), Delay ?? delayHint, Duration ?? durationHint, EasingType ?? easingTypeHint ?? DefaultEasingType, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs index cba2e77a33d..b179070f1db 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs @@ -11,7 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// An opacity animation working on the composition or XAML layer. /// - public class OpacityAnimation : Animation + public class OpacityAnimation : Animation { /// /// Gets or sets the target framework layer to animate. @@ -26,11 +26,11 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS return builder.Opacity(Layer).NormalizedKeyFrames( delay: Delay ?? delayHint, duration: Duration ?? durationHint, - build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); + build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); } return builder.Opacity( - To, + To!.Value, From, Delay ?? delayHint, Duration ?? durationHint, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs index c4d04295bc4..7883b3bb452 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs @@ -4,6 +4,7 @@ using System; using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Extensions; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -12,7 +13,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// An orientation animation working on the composition layer. /// - public class OrientationAnimation : Animation + public class OrientationAnimation : Animation { /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) @@ -22,12 +23,12 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS return builder.Orientation().NormalizedKeyFrames( delay: Delay ?? delayHint, duration: Duration ?? durationHint, - build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); + build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); } return builder.Orientation( - To, - From, + To!.ToQuaternion(), + From?.ToQuaternion(), Delay ?? delayHint, Duration ?? durationHint, EasingType ?? easingTypeHint ?? DefaultEasingType, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs index 417ae34478f..df446ba079f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs @@ -11,7 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A rotation animation working on the composition or XAML layer. /// - public class RotationAnimation : Animation + public class RotationAnimation : Animation { /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) @@ -21,11 +21,11 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS return builder.Rotation().NormalizedKeyFrames( delay: Delay ?? delayHint, duration: Duration ?? durationHint, - build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); + build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); } return builder.Rotation( - To, + To!.Value, From, Delay ?? delayHint, Duration ?? durationHint, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs index f567d3ea269..d1a8df72c99 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs @@ -11,7 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A rotation in degrees animation working on the composition or XAML layer. /// - public class RotationInDegreesAnimation : Animation + public class RotationInDegreesAnimation : Animation { /// /// Gets or sets the target framework layer to animate. @@ -26,11 +26,11 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS return builder.RotationInDegrees(Layer).NormalizedKeyFrames( delay: Delay ?? delayHint, duration: Duration ?? durationHint, - build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); + build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); } return builder.RotationInDegrees( - To, + To!.Value, From, Delay ?? delayHint, Duration ?? durationHint, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs index e57cc406790..43fa6afe8ff 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs @@ -4,6 +4,7 @@ using System; using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Extensions; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -12,7 +13,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A scale animation working on the composition or XAML layer. /// - public class ScaleAnimation : Animation + public class ScaleAnimation : Animation { /// /// Gets or sets the target framework layer to animate. @@ -30,20 +31,21 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS return builder.Scale().NormalizedKeyFrames( delay: Delay ?? delayHint, duration: Duration ?? durationHint, - build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); + build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); } - Vector3? from = From; + Vector3 to = To!.ToVector3(); + Vector3? from = From?.ToVector3(); EasingType easingType = EasingType ?? easingTypeHint ?? DefaultEasingType; EasingMode easingMode = EasingMode ?? easingModeHint ?? DefaultEasingMode; if (Layer == FrameworkLayer.Composition) { - return builder.Scale(To, from, delay, duration, easingType, easingMode); + return builder.Scale(to, from, delay, duration, easingType, easingMode); } else { - Vector2 to2 = new(To.X, To.Y); + Vector2 to2 = new(to.X, to.Y); Vector2? from2 = from is null ? null : new(from.Value.X, from.Value.Y); return builder.Scale(to2, from2, delay, duration, easingType, easingMode, FrameworkLayer.Xaml); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs index c2035ed0fdf..0d4419573f4 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs @@ -4,6 +4,7 @@ using System; using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Extensions; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -12,7 +13,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A size animation working on the composition or XAML layer. /// - public class SizeAnimation : Animation + public class SizeAnimation : Animation { /// /// Gets or sets the target framework layer to animate. @@ -30,20 +31,21 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS return builder.Size().NormalizedKeyFrames( delay: Delay ?? delayHint, duration: Duration ?? durationHint, - build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); + build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); } - Vector3? from = From; + Vector3 to = To!.ToVector3(); + Vector3? from = From?.ToVector3(); EasingType easingType = EasingType ?? easingTypeHint ?? DefaultEasingType; EasingMode easingMode = EasingMode ?? easingModeHint ?? DefaultEasingMode; if (Layer == FrameworkLayer.Composition) { - return builder.Size(To, from, delay, duration, easingType, easingMode); + return builder.Size(to, from, delay, duration, easingType, easingMode); } else { - Vector2 to2 = new(To.X, To.Y); + Vector2 to2 = new(to.X, to.Y); Vector2? from2 = from is null ? null : new(from.Value.X, from.Value.Y); return builder.Size(to2, from2, delay, duration, easingType, easingMode, FrameworkLayer.Xaml); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs index 9351ba263a6..0132f8de89b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs @@ -3,7 +3,8 @@ // See the LICENSE file in the project root for more information. using System; -using System.Numerics; +using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Extensions; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -12,7 +13,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A translation animation working on the composition or XAML layer. /// - public class TranslationAnimation : Animation + public class TranslationAnimation : Animation { /// /// Gets or sets the target framework layer to animate. @@ -30,20 +31,21 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS return builder.Translation().NormalizedKeyFrames( delay: Delay ?? delayHint, duration: Duration ?? durationHint, - build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); + build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); } - Vector3? from = From; + Vector3 to = To!.ToVector3(); + Vector3? from = From?.ToVector3(); EasingType easingType = EasingType ?? easingTypeHint ?? DefaultEasingType; EasingMode easingMode = EasingMode ?? easingModeHint ?? DefaultEasingMode; if (Layer == FrameworkLayer.Composition) { - return builder.Translation(To, from, delay, duration, easingType, easingMode); + return builder.Translation(to, from, delay, duration, easingType, easingMode); } else { - Vector2 to2 = new(To.X, To.Y); + Vector2 to2 = new(to.X, to.Y); Vector2? from2 = from is null ? null : new(from.Value.X, from.Value.Y); return builder.Translation(to2, from2, delay, duration, easingType, easingMode, FrameworkLayer.Xaml); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/QuaternionKeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/QuaternionKeyFrame.cs index c297cd2165e..b8141844571 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/QuaternionKeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/QuaternionKeyFrame.cs @@ -3,14 +3,30 @@ // See the LICENSE file in the project root for more information. using System.Numerics; +using System.Runtime.CompilerServices; using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; +using Microsoft.Toolkit.Uwp.UI.Extensions; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +#nullable enable namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// A type for animations. + /// A type for animations. /// - public class QuaternionKeyFrame : KeyFrame + public class QuaternionKeyFrame : KeyFrame { + /// + public override INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder) + { + Vector4 vector = Value!.ToVector4(); + + return builder.KeyFrame( + Key, + Unsafe.As(ref vector), + EasingType ?? DefaultEasingType, + EasingMode ?? DefaultEasingMode); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ScalarKeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ScalarKeyFrame.cs index 5cb49343eae..b63665165be 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ScalarKeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ScalarKeyFrame.cs @@ -3,13 +3,19 @@ // See the LICENSE file in the project root for more information. using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// A type for scalar animations. + /// A type for scalar animations. /// - public class ScalarKeyFrame : KeyFrame + public class ScalarKeyFrame : KeyFrame { + /// + public override INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder) + { + return builder.KeyFrame(Key, Value!, EasingType ?? DefaultEasingType, EasingMode ?? DefaultEasingMode); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs index 0936a652e63..95ad3d70831 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs @@ -4,13 +4,22 @@ using System.Numerics; using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; +using Microsoft.Toolkit.Uwp.UI.Extensions; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +#nullable enable namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// A type for animations. + /// A type for animations. /// - public class Vector2KeyFrame : KeyFrame + public class Vector2KeyFrame : KeyFrame { + /// + public override INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder) + { + return builder.KeyFrame(Key, Value!.ToVector2(), EasingType ?? DefaultEasingType, EasingMode ?? DefaultEasingMode); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs index 10de95b96aa..75443e0d049 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs @@ -4,13 +4,22 @@ using System.Numerics; using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; +using Microsoft.Toolkit.Uwp.UI.Extensions; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +#nullable enable namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// A type for animations. + /// A type for animations. /// - public class Vector3KeyFrame : KeyFrame + public class Vector3KeyFrame : KeyFrame { + /// + public override INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder) + { + return builder.KeyFrame(Key, Value!.ToVector3(), EasingType ?? DefaultEasingType, EasingMode ?? DefaultEasingMode); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs index 29f9c59932a..a0fdcd3282e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs @@ -4,13 +4,22 @@ using System.Numerics; using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; +using Microsoft.Toolkit.Uwp.UI.Extensions; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +#nullable enable namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// A type for animations. + /// A type for animations. /// - public class Vector4KeyFrame : KeyFrame + public class Vector4KeyFrame : KeyFrame { + /// + public override INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder) + { + return builder.KeyFrame(Key, Value!.ToVector4(), EasingType ?? DefaultEasingType, EasingMode ?? DefaultEasingMode); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs index 7aa745ef77e..8a365c431c0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs @@ -17,7 +17,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Animations /// /// A set of animations that can be grouped together. /// - public class EffectDoubleAnimation : Animation + public class EffectDoubleAnimation : Animation { /// /// Gets or sets the linked instance to animate. diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Visual/VisualExtensions.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Visual/VisualExtensions.cs index c5200f829ae..78293d15e98 100644 --- a/Microsoft.Toolkit.Uwp.UI/Extensions/Visual/VisualExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Visual/VisualExtensions.cs @@ -6,6 +6,7 @@ using System.Globalization; using System.Linq; using System.Numerics; +using System.Runtime.CompilerServices; using Windows.UI.Composition; using Windows.UI.Xaml; using Windows.UI.Xaml.Hosting; @@ -159,6 +160,18 @@ public static Vector4 ToVector4(this string str) } } + /// + /// Converts a to + /// + /// A string in the format of "float, float, float, float" + /// + public static Quaternion ToQuaternion(this string str) + { + Vector4 vector = str.ToVector4(); + + return Unsafe.As(ref vector); + } + /// /// Retrieves the object of a /// From a95d30f8398f1f814f1f2fbef2f50f110fb79860 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 25 Dec 2020 18:07:53 +0100 Subject: [PATCH 085/171] Added expression support to keyframe builders --- .../Builders/Interfaces/IKeyFrameInfo.cs | 9 +++ .../INormalizedKeyFrameAnimationBuilder{T}.cs | 16 +++++ .../ITimedKeyFrameAnimationBuilder{T}.cs | 16 +++++ ...KeyFrameAnimationBuilder{T}.Composition.cs | 53 +++++++++++++++++ ...malizedKeyFrameAnimationBuilder{T}.Xaml.cs | 10 ++++ .../NormalizedKeyFrameAnimationBuilder{T}.cs | 54 +++++++++++++++++ ...KeyFrameAnimationBuilder{T}.Composition.cs | 13 ++++ .../TimedKeyFrameAnimationBuilder{T}.Xaml.cs | 10 ++++ .../TimedKeyFrameAnimationBuilder{T}.cs | 59 ++++++++++++++++++- 9 files changed, 237 insertions(+), 3 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IKeyFrameInfo.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IKeyFrameInfo.cs index f4c52dc78f6..d3f584032bb 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IKeyFrameInfo.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IKeyFrameInfo.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics.Contracts; +using Windows.UI.Composition; using Windows.UI.Xaml.Media.Animation; namespace Microsoft.Toolkit.Uwp.UI.Animations @@ -31,6 +32,14 @@ internal interface IKeyFrameInfo [Pure] T GetValueAs(); + /// + /// Tries to insert an expression keyframe into the target animation, if possible. + /// + /// The target instance. + /// The total duration for the full animation. + /// Whether or not the curreent instance contained an expression. + bool TryInsertExpressionKeyFrame(KeyFrameAnimation animation, TimeSpan duration); + /// /// Gets the normalized progress for the current keyframe. /// diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/INormalizedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/INormalizedKeyFrameAnimationBuilder{T}.cs index 316214a240b..8e9e3719fcd 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/INormalizedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/INormalizedKeyFrameAnimationBuilder{T}.cs @@ -26,5 +26,21 @@ INormalizedKeyFrameAnimationBuilder KeyFrame( T value, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode); + + /// + /// Adds a new normalized expression keyframe to the builder in use. + /// This method can only be used when the animation being built targets the composition layer. + /// + /// The normalized progress for the keyframe (must be in the [0, 1] range). + /// The expression for the new keyframe to add. + /// The easing type to use to reach the new keyframe. + /// The easing mode to use to reach the new keyframe. + /// The same instance that the method was invoked upon. + /// Thrown when the animation being built targets the XAML layer. + INormalizedKeyFrameAnimationBuilder ExpressionKeyFrame( + double progress, + string expression, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/ITimedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/ITimedKeyFrameAnimationBuilder{T}.cs index 9f5c4cde418..c697e52e65c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/ITimedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/ITimedKeyFrameAnimationBuilder{T}.cs @@ -27,5 +27,21 @@ ITimedKeyFrameAnimationBuilder KeyFrame( T value, EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode); + + /// + /// Adds a new timed expressionkeyframe to the builder in use. + /// This method can only be used when the animation being built targets the composition layer. + /// + /// The timed progress for the keyframe, relative to the start of the animation. + /// The expression for the new keyframe to add. + /// The easing type to use to reach the new keyframe. + /// The easing mode to use to reach the new keyframe. + /// The same instance that the method was invoked upon. + /// Thrown when the animation being built targets the XAML layer. + ITimedKeyFrameAnimationBuilder ExpressionKeyFrame( + TimeSpan progress, + string expression, + EasingType easingType = DefaultEasingType, + EasingMode easingMode = DefaultEasingMode); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs index e9f6f4082f3..6fbdcf50961 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs @@ -8,6 +8,7 @@ using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; using Windows.UI; using Windows.UI.Composition; +using Windows.UI.Xaml.Media.Animation; #nullable enable @@ -42,6 +43,11 @@ public static CompositionAnimation GetAnimation( foreach (ref readonly var keyFrame in keyFrames) { + if (keyFrame.TryInsertExpressionKeyFrame(boolAnimation, duration)) + { + continue; + } + boolAnimation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs()); @@ -55,6 +61,11 @@ public static CompositionAnimation GetAnimation( foreach (ref readonly var keyFrame in keyFrames) { + if (keyFrame.TryInsertExpressionKeyFrame(scalarAnimation, duration)) + { + continue; + } + scalarAnimation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs(), @@ -69,6 +80,11 @@ public static CompositionAnimation GetAnimation( foreach (ref readonly var keyFrame in keyFrames) { + if (keyFrame.TryInsertExpressionKeyFrame(scalarAnimation, duration)) + { + continue; + } + scalarAnimation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), (float)keyFrame.GetValueAs(), @@ -83,6 +99,11 @@ public static CompositionAnimation GetAnimation( foreach (ref readonly var keyFrame in keyFrames) { + if (keyFrame.TryInsertExpressionKeyFrame(vector2Animation, duration)) + { + continue; + } + vector2Animation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs(), @@ -97,6 +118,11 @@ public static CompositionAnimation GetAnimation( foreach (ref readonly var keyFrame in keyFrames) { + if (keyFrame.TryInsertExpressionKeyFrame(vector3Animation, duration)) + { + continue; + } + vector3Animation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs(), @@ -111,6 +137,11 @@ public static CompositionAnimation GetAnimation( foreach (ref readonly var keyFrame in keyFrames) { + if (keyFrame.TryInsertExpressionKeyFrame(vector4Animation, duration)) + { + continue; + } + vector4Animation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs(), @@ -125,6 +156,11 @@ public static CompositionAnimation GetAnimation( foreach (ref readonly var keyFrame in keyFrames) { + if (keyFrame.TryInsertExpressionKeyFrame(colorAnimation, duration)) + { + continue; + } + colorAnimation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs(), @@ -139,6 +175,11 @@ public static CompositionAnimation GetAnimation( foreach (ref readonly var keyFrame in keyFrames) { + if (keyFrame.TryInsertExpressionKeyFrame(quaternionAnimation, duration)) + { + continue; + } + quaternionAnimation.InsertKeyFrame( (float)keyFrame.GetNormalizedProgress(duration), keyFrame.GetValueAs(), @@ -178,6 +219,18 @@ public Composition(string property, TimeSpan? delay, TimeSpan duration) { } + /// + public override INormalizedKeyFrameAnimationBuilder ExpressionKeyFrame( + double progress, + string expression, + EasingType easingType, + EasingMode easingMode) + { + this.keyFrames.Append(new(progress, expression, easingType, easingMode)); + + return this; + } + /// public CompositionAnimation GetAnimation(CompositionObject targetHint, out CompositionObject? target) { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs index 4c9479e4b57..2c6baf7195d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -26,6 +26,16 @@ public Xaml(string property, TimeSpan? delay, TimeSpan duration) { } + /// + public override INormalizedKeyFrameAnimationBuilder ExpressionKeyFrame( + double progress, + string expression, + EasingType easingType, + EasingMode easingMode) + { + throw new InvalidOperationException("Expression keyframes can only be used on the composition layer"); + } + /// public Timeline GetAnimation(DependencyObject targetHint) { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs index 44b70c1fa40..c020c4c4b41 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs @@ -5,9 +5,13 @@ using System; using System.Runtime.CompilerServices; using Microsoft.Toolkit.Uwp.UI.Animations.Builders.Helpers; +using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; +using Windows.UI.Composition; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; +#nullable enable + namespace Microsoft.Toolkit.Uwp.UI.Animations { /// @@ -62,6 +66,13 @@ public INormalizedKeyFrameAnimationBuilder KeyFrame( return this; } + /// + public abstract INormalizedKeyFrameAnimationBuilder ExpressionKeyFrame( + double progress, + string expression, + EasingType easingType, + EasingMode easingMode); + /// /// The abstracted info for a normalized animation keyframe. /// @@ -77,6 +88,11 @@ public INormalizedKeyFrameAnimationBuilder KeyFrame( /// private readonly T value; + /// + /// The expression for the current keyframe, if present. + /// + private readonly string? expression; + /// /// Initializes a new instance of the struct. /// @@ -92,6 +108,28 @@ public KeyFrameInfo( { this.progress = progress; this.value = value; + this.expression = null; + + EasingType = easingType; + EasingMode = easingMode; + } + + /// + /// Initializes a new instance of the struct. + /// + /// The normalized progress for the keyframe. + /// The expression for the new keyframe to add. + /// The easing type to use to reach the new keyframe. + /// The easing mode to use to reach the new keyframe. + public KeyFrameInfo( + double progress, + string expression, + EasingType easingType, + EasingMode easingMode) + { + this.progress = progress; + this.value = default; + this.expression = expression; EasingType = easingType; EasingMode = easingMode; @@ -110,6 +148,22 @@ public TValue GetValueAs() return Unsafe.As(ref Unsafe.AsRef(in this.value)); } + /// + public bool TryInsertExpressionKeyFrame(KeyFrameAnimation animation, TimeSpan duration) + { + if (this.expression is null) + { + return false; + } + + animation.InsertExpressionKeyFrame( + (float)this.progress, + this.expression, + animation.Compositor.CreateEasingFunction(EasingType, EasingMode)); + + return true; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public double GetNormalizedProgress(TimeSpan duration) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs index 1f9428a5016..8370acd59b6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs @@ -4,6 +4,7 @@ using System; using Windows.UI.Composition; +using Windows.UI.Xaml.Media.Animation; #nullable enable @@ -27,6 +28,18 @@ public Composition(string property, TimeSpan? delay) { } + /// + public override ITimedKeyFrameAnimationBuilder ExpressionKeyFrame( + TimeSpan progress, + string expression, + EasingType easingType, + EasingMode easingMode) + { + this.keyFrames.Append(new(progress, expression, easingType, easingMode)); + + return this; + } + /// public CompositionAnimation GetAnimation(CompositionObject targetHint, out CompositionObject? target) { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs index d9775457b2f..a3f21a87822 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -142,6 +142,16 @@ public Xaml(string property, TimeSpan? delay) { } + /// + public override ITimedKeyFrameAnimationBuilder ExpressionKeyFrame( + TimeSpan progress, + string expression, + EasingType easingType, + EasingMode easingMode) + { + throw new InvalidOperationException("Expression keyframes can only be used on the composition layer"); + } + /// public Timeline GetAnimation(DependencyObject targetHint) { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs index 6e1dcfe8fbd..d64fc852439 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs @@ -5,8 +5,11 @@ using System; using System.Runtime.CompilerServices; using Microsoft.Toolkit.Uwp.UI.Animations.Builders.Helpers; +using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; +using Windows.UI.Composition; using Windows.UI.Xaml.Media.Animation; -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +#nullable enable namespace Microsoft.Toolkit.Uwp.UI.Animations { @@ -47,14 +50,21 @@ protected TimedKeyFrameAnimationBuilder(string property, TimeSpan? delay) public ITimedKeyFrameAnimationBuilder KeyFrame( TimeSpan progress, T value, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode) + EasingType easingType, + EasingMode easingMode) { this.keyFrames.Append(new(progress, value, easingType, easingMode)); return this; } + /// + public abstract ITimedKeyFrameAnimationBuilder ExpressionKeyFrame( + TimeSpan progress, + string expression, + EasingType easingType, + EasingMode easingMode); + /// /// The abstracted info for a timed animation keyframe. /// @@ -70,6 +80,11 @@ public ITimedKeyFrameAnimationBuilder KeyFrame( /// private readonly T value; + /// + /// The expression for the current keyframe, if present. + /// + private readonly string? expression; + /// /// Initializes a new instance of the struct. /// @@ -85,6 +100,28 @@ public KeyFrameInfo( { this.progress = progress; this.value = value; + this.expression = null; + + EasingType = easingType; + EasingMode = easingMode; + } + + /// + /// Initializes a new instance of the struct. + /// + /// The progress for the keyframe. + /// The expression for the new keyframe to add. + /// The easing type to use to reach the new keyframe. + /// The easing mode to use to reach the new keyframe. + public KeyFrameInfo( + TimeSpan progress, + string expression, + EasingType easingType, + EasingMode easingMode) + { + this.progress = progress; + this.value = default; + this.expression = expression; EasingType = easingType; EasingMode = easingMode; @@ -103,6 +140,22 @@ public TValue GetValueAs() return Unsafe.As(ref Unsafe.AsRef(in this.value)); } + /// + public bool TryInsertExpressionKeyFrame(KeyFrameAnimation animation, TimeSpan duration) + { + if (this.expression is null) + { + return false; + } + + animation.InsertExpressionKeyFrame( + (float)GetNormalizedProgress(duration), + this.expression, + animation.Compositor.CreateEasingFunction(EasingType, EasingMode)); + + return true; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public double GetNormalizedProgress(TimeSpan duration) From ff288be01d3946e1a8c55a5b3a4a87494c386a38 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 25 Dec 2020 18:43:17 +0100 Subject: [PATCH 086/171] Added infrastructure to support implicit animations --- .../Abstract/Animation{TValue,TKeyFrame}.cs | 1 + .../ImplicitAnimation{TValue,TKeyFrame}.cs | 81 ++++++++++++++++++ .../Xaml/AnimationCollection2.cs | 82 +++++++++++++++++++ .../Xaml/Interfaces/IImplicitTimeline.cs | 29 +++++++ .../Xaml/Interfaces/ITimeline.cs | 1 + 5 files changed, 194 insertions(+) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IImplicitTimeline.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs index 9020421ed8d..e1e76baa7fe 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs @@ -19,6 +19,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// The actual type of keyframe values in use. [ContentProperty(Name = nameof(KeyFrames))] public abstract class Animation : Animation + where TKeyFrame : unmanaged { /// /// Gets or sets the final value for the animation. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs new file mode 100644 index 00000000000..1d69a3be31c --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs @@ -0,0 +1,81 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable enable + +using Microsoft.Toolkit.Uwp.UI.Extensions; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// A base model representing a typed animation that can be used as an implicit composition animation. + /// + /// + public abstract class ImplicitAnimation : Animation, IImplicitTimeline + where TKeyFrame : unmanaged + { + /// + /// Gets or sets the optional implicit target for the animation. + /// + public string? ImplicitTarget { get; set; } + + /// + /// Gets the target for the animation. + /// + protected abstract string Target { get; } + + /// + public CompositionAnimation GetAnimation(UIElement element, out string? target) + { + NormalizedKeyFrameAnimationBuilder.Composition builder = new( + Target, + Delay ?? DefaultDuration, + Duration ?? DefaultDuration); + + var (to, from) = GetParsedValues(); + + // If there are no values set for the animation at all (no initial/target values, nor + // keyframes), we just manually insert a single expression keyframe pointing to the final + // value for the current animation. This is often the case with implicit animations, as + // it is used to smoothly transition between two discrete property changes for a visual. + if (to is null && from is null && KeyFrames.Count == 0) + { + builder.ExpressionKeyFrame(1.0, "this.FinalValue", DefaultEasingType, DefaultEasingMode); + } + else + { + // Otherwise, we just insert the keyframes for the initial/target values, as well as the + // other keyframes that might be present into the current animation. The order is not + // important when inserting keyframes, as each one stores the normalized progress value. + if (to is not null) + { + builder.KeyFrame(1.0, to.Value, EasingType ?? DefaultEasingType, EasingMode ?? DefaultEasingMode); + } + + if (from is not null) + { + builder.KeyFrame(0.0, from.Value, default, default); + } + + foreach (var keyFrame in KeyFrames) + { + keyFrame.AppendToBuilder(builder); + } + } + + target = ImplicitTarget; + + return builder.GetAnimation(element.GetVisual(), out _); + } + + /// + /// Gets the parsed values from . + /// + /// The parsed animation values as . + protected abstract (TKeyFrame? To, TKeyFrame? From) GetParsedValues(); + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs index cbbd62b0235..2d253cde7d0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs @@ -6,9 +6,12 @@ using System; using System.Collections.Generic; +using System.Diagnostics.Contracts; using System.Threading.Tasks; using Microsoft.Toolkit.Diagnostics; +using Windows.UI.Composition; using Windows.UI.Xaml; +using Windows.UI.Xaml.Hosting; using Windows.UI.Xaml.Markup; namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml @@ -118,5 +121,84 @@ public async Task StartAsync(UIElement element) Ended?.Invoke(this, EventArgs.Empty); } + + /// + /// Creates a for the current collection. + /// This can be used to be assigned to show/hide implicit composition animations. + /// + /// The target to animate. + /// The instance to use. + [Pure] + internal CompositionAnimationGroup GetCompositionAnimationGroup(UIElement element) + { + Compositor compositor = ElementCompositionPreview.GetElementVisual(element).Compositor; + CompositionAnimationGroup animations = compositor.CreateAnimationGroup(); + + static void GatherAnimations(UIElement element, CompositionAnimationGroup animations, ITimeline timeline) + { + if (timeline is AnimationScope scope) + { + foreach (ITimeline child in scope.Animations) + { + GatherAnimations(element, animations, child); + } + } + else if (timeline is IImplicitTimeline animation) + { + animations.Add(animation.GetAnimation(element, out _)); + } + } + + foreach (ITimeline timeline in Animations) + { + GatherAnimations(element, animations, timeline); + } + + return animations; + } + + /// + /// Creates an for the current collection. + /// This can be used to be assigned to implicit composition animations. + /// + /// The target to animate. + /// The instance to use. + [Pure] + internal ImplicitAnimationCollection GetImplicitAnimationCollection(UIElement element) + { + Compositor compositor = ElementCompositionPreview.GetElementVisual(element).Compositor; + ImplicitAnimationCollection animations = compositor.CreateImplicitAnimationCollection(); + + static void GatherAnimations(UIElement element, ImplicitAnimationCollection animations, ITimeline timeline) + { + if (timeline is AnimationScope scope) + { + foreach (ITimeline child in scope.Animations) + { + GatherAnimations(element, animations, child); + } + } + else if (timeline is IImplicitTimeline implicitTimeline) + { + CompositionAnimation animation = implicitTimeline.GetAnimation(element, out string? target); + + target ??= animation.Target; + + if (!animations.ContainsKey(target)) + { + animations[target] = animations.Compositor.CreateAnimationGroup(); + } + + ((CompositionAnimationGroup)animations[target]).Add(animation); + } + } + + foreach (ITimeline timeline in Animations) + { + GatherAnimations(element, animations, timeline); + } + + return animations; + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IImplicitTimeline.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IImplicitTimeline.cs new file mode 100644 index 00000000000..66fa0e13d8a --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IImplicitTimeline.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Composition; +using Windows.UI.Xaml; + +#nullable enable + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// An interface representing a XAML model for a custom implicit composition animation. + /// + internal interface IImplicitTimeline + { + /// + /// Gets a from the currnet node. This animation might + /// be used either as an implicit show/hide animation, or as a direct implicit animation. + /// + /// The target the animation will be applied to. + /// + /// The optional target property for the animation. This might be used for direct implicit + /// animations that target a property but want to be triggered according to a separate property. + /// + /// A new instance. + CompositionAnimation GetAnimation(UIElement element, out string? target); + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITimeline.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITimeline.cs index 24d15209d0f..ca3ebcaccb7 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITimeline.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITimeline.cs @@ -14,6 +14,7 @@ public interface ITimeline { /// /// Appens the current animation to a target instance. + /// This method is used when the current instance is explicitly triggered. /// /// The target instance to schedule the animation on. /// A hint for the animation delay, if present. From 4c7c1af61154c1ea4aa922cdb46870ab8b95cd1d Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 25 Dec 2020 18:43:34 +0100 Subject: [PATCH 087/171] Updated default animation XAML types --- .../Xaml/Default/OffsetAnimation.cs | 12 +++++++++++- .../Xaml/Default/OpacityAnimation.cs | 12 +++++++++++- .../Xaml/Default/OrientationAnimation.cs | 12 +++++++++++- .../Xaml/Default/RotationAnimation.cs | 12 +++++++++++- .../Xaml/Default/RotationInDegreesAnimation.cs | 12 +++++++++++- .../Xaml/Default/ScaleAnimation.cs | 12 +++++++++++- .../Xaml/Default/SizeAnimation.cs | 12 +++++++++++- .../Xaml/Default/TranslationAnimation.cs | 11 ++++++++++- 8 files changed, 87 insertions(+), 8 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs index 9f606382a14..f991d2e3ae6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs @@ -5,6 +5,7 @@ using System; using System.Numerics; using Microsoft.Toolkit.Uwp.UI.Extensions; +using Windows.UI.Composition; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -13,8 +14,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// An offset animation working on the composition layer. /// - public class OffsetAnimation : Animation + public class OffsetAnimation : ImplicitAnimation { + /// + protected override string Target => nameof(Visual.Offset); + /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { @@ -34,5 +38,11 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS EasingType ?? easingTypeHint ?? DefaultEasingType, EasingMode ?? easingModeHint ?? DefaultEasingMode); } + + /// + protected override (Vector3? To, Vector3? From) GetParsedValues() + { + return (To?.ToVector3(), From?.ToVector3()); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs index b179070f1db..0dbab219e22 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using Windows.UI.Composition; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -11,13 +12,16 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// An opacity animation working on the composition or XAML layer. /// - public class OpacityAnimation : Animation + public class OpacityAnimation : ImplicitAnimation { /// /// Gets or sets the target framework layer to animate. /// public FrameworkLayer Layer { get; set; } + /// + protected override string Target => nameof(Visual.Opacity); + /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { @@ -38,5 +42,11 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS EasingMode ?? easingModeHint ?? DefaultEasingMode, Layer); } + + /// + protected override (double? To, double? From) GetParsedValues() + { + return (To, From); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs index 7883b3bb452..1bdb825c796 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs @@ -5,6 +5,7 @@ using System; using System.Numerics; using Microsoft.Toolkit.Uwp.UI.Extensions; +using Windows.UI.Composition; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -13,8 +14,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// An orientation animation working on the composition layer. /// - public class OrientationAnimation : Animation + public class OrientationAnimation : ImplicitAnimation { + /// + protected override string Target => nameof(Visual.Orientation); + /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { @@ -34,5 +38,11 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS EasingType ?? easingTypeHint ?? DefaultEasingType, EasingMode ?? easingModeHint ?? DefaultEasingMode); } + + /// + protected override (Quaternion? To, Quaternion? From) GetParsedValues() + { + return (To?.ToQuaternion(), From?.ToQuaternion()); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs index df446ba079f..1f5df37c47c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using Windows.UI.Composition; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -11,8 +12,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A rotation animation working on the composition or XAML layer. /// - public class RotationAnimation : Animation + public class RotationAnimation : ImplicitAnimation { + /// + protected override string Target => nameof(Visual.RotationAngle); + /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { @@ -32,5 +36,11 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS EasingType ?? easingTypeHint ?? DefaultEasingType, EasingMode ?? easingModeHint ?? DefaultEasingMode); } + + /// + protected override (double? To, double? From) GetParsedValues() + { + return (To, From); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs index d1a8df72c99..b512766fa2c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using Windows.UI.Composition; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -11,13 +12,16 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A rotation in degrees animation working on the composition or XAML layer. /// - public class RotationInDegreesAnimation : Animation + public class RotationInDegreesAnimation : ImplicitAnimation { /// /// Gets or sets the target framework layer to animate. /// public FrameworkLayer Layer { get; set; } + /// + protected override string Target => nameof(Visual.RotationAngleInDegrees); + /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { @@ -38,5 +42,11 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS EasingMode ?? easingModeHint ?? DefaultEasingMode, Layer); } + + /// + protected override (double? To, double? From) GetParsedValues() + { + return (To, From); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs index 43fa6afe8ff..70ffef08d76 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs @@ -5,6 +5,7 @@ using System; using System.Numerics; using Microsoft.Toolkit.Uwp.UI.Extensions; +using Windows.UI.Composition; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -13,13 +14,16 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A scale animation working on the composition or XAML layer. /// - public class ScaleAnimation : Animation + public class ScaleAnimation : ImplicitAnimation { /// /// Gets or sets the target framework layer to animate. /// public FrameworkLayer Layer { get; set; } + /// + protected override string Target => nameof(Visual.Scale); + /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { @@ -51,5 +55,11 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS return builder.Scale(to2, from2, delay, duration, easingType, easingMode, FrameworkLayer.Xaml); } } + + /// + protected override (Vector3? To, Vector3? From) GetParsedValues() + { + return (To?.ToVector3(), From?.ToVector3()); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs index 0d4419573f4..2e648421dbf 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs @@ -5,6 +5,7 @@ using System; using System.Numerics; using Microsoft.Toolkit.Uwp.UI.Extensions; +using Windows.UI.Composition; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -13,13 +14,16 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A size animation working on the composition or XAML layer. /// - public class SizeAnimation : Animation + public class SizeAnimation : ImplicitAnimation { /// /// Gets or sets the target framework layer to animate. /// public FrameworkLayer Layer { get; set; } + /// + protected override string Target => nameof(Visual.Size); + /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { @@ -51,5 +55,11 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS return builder.Size(to2, from2, delay, duration, easingType, easingMode, FrameworkLayer.Xaml); } } + + /// + protected override (Vector3? To, Vector3? From) GetParsedValues() + { + return (To?.ToVector3(), From?.ToVector3()); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs index 0132f8de89b..027e3b08b7b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs @@ -13,13 +13,16 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// A translation animation working on the composition or XAML layer. /// - public class TranslationAnimation : Animation + public class TranslationAnimation : ImplicitAnimation { /// /// Gets or sets the target framework layer to animate. /// public FrameworkLayer Layer { get; set; } + /// + protected override string Target => "Translation"; + /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { @@ -51,5 +54,11 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS return builder.Translation(to2, from2, delay, duration, easingType, easingMode, FrameworkLayer.Xaml); } } + + /// + protected override (Vector3? To, Vector3? From) GetParsedValues() + { + return (To?.ToVector3(), From?.ToVector3()); + } } } From de3b5b9fdb7f056bf6418a08ed456ad717fd340c Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 25 Dec 2020 20:33:10 +0100 Subject: [PATCH 088/171] Implemented implicit animations with new backend --- .../NormalizedKeyFrameAnimationBuilder{T}.cs | 5 +- .../Explicit.cs | 2 +- .../Extensions/CompositorExtensions.cs | 5 + .../Implicit2.cs | 228 ++++++++++++++++++ .../Xaml/AnimationCollection2.cs | 88 +------ .../ImplicitCompositionAnimationCollection.cs | 132 ++++++++++ .../Xaml/Interfaces/IImplicitTimeline.cs | 2 +- 7 files changed, 378 insertions(+), 84 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Implicit2.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitCompositionAnimationCollection.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs index c020c4c4b41..5caac007aa9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs @@ -8,7 +8,6 @@ using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; using Windows.UI.Composition; using Windows.UI.Xaml.Media.Animation; -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; #nullable enable @@ -58,8 +57,8 @@ protected NormalizedKeyFrameAnimationBuilder(string property, TimeSpan? delay, T public INormalizedKeyFrameAnimationBuilder KeyFrame( double progress, T value, - EasingType easingType = DefaultEasingType, - EasingMode easingMode = DefaultEasingMode) + EasingType easingType, + EasingMode easingMode) { this.keyFrames.Append(new(progress, value, easingType, easingMode)); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs index 863e5c4fa2c..123a95e13ff 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs @@ -13,7 +13,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations public static class Explicit { /// - /// Identifies the property for the attached instance. + /// The attached "Animations" property. /// public static readonly DependencyProperty AnimationsProperty = DependencyProperty.RegisterAttached( "Animations", diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs index 3bf0a28f1af..6aafc14fbb2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs @@ -34,6 +34,11 @@ public static CompositionEasingFunction CreateEasingFunction(this Compositor com return compositor.CreateLinearEasingFunction(); } + if (easingType == EasingType.Default) + { + easingType = DefaultEasingType; + } + var (a, b) = EasingMaps[(easingType, easingMode)]; return compositor.CreateCubicBezierEasingFunction(a, b); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Implicit2.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Implicit2.cs new file mode 100644 index 00000000000..730381f00c5 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Implicit2.cs @@ -0,0 +1,228 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Hosting; + +#nullable enable + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// Attached properties to support implicitly triggered animations for instances. + /// + public static class Implicit2 + { + /// + /// The attached "ShowAnimations" property. + /// + public static readonly DependencyProperty ShowAnimationsProperty = DependencyProperty.RegisterAttached( + "ShowAnimations", + typeof(ImplicitCompositionAnimationCollection), + typeof(Implicit2), + new PropertyMetadata(null, OnShowAnimationsPropertyChanged)); + + /// + /// The attached "HideAnimations" property. + /// + public static readonly DependencyProperty HideAnimationsProperty = DependencyProperty.RegisterAttached( + "HideAnimations", + typeof(ImplicitCompositionAnimationCollection), + typeof(Implicit2), + new PropertyMetadata(null, OnHideAnimationsPropertyChanged)); + + /// + /// The attached "Animations" property. + /// + public static readonly DependencyProperty AnimationsProperty = DependencyProperty.RegisterAttached( + "Animations", + typeof(ImplicitCompositionAnimationCollection), + typeof(Implicit2), + new PropertyMetadata(null, OnAnimationsPropertyChanged)); + + /// + /// Gets the value of the property. + /// + /// The to get the value for. + /// The retrieved value. + public static ImplicitCompositionAnimationCollection GetShowAnimations(UIElement element) + { + var collection = (ImplicitCompositionAnimationCollection)element.GetValue(ShowAnimationsProperty); + + if (collection is null) + { + element.SetValue(ShowAnimationsProperty, collection = new()); + } + + return collection; + } + + /// + /// Sets the value of the property. + /// + /// The to set the value for. + /// The value to set. + public static void SetShowAnimations(UIElement element, ImplicitCompositionAnimationCollection value) + { + element.SetValue(ShowAnimationsProperty, value); + } + + /// + /// Gets the value of the property. + /// + /// The to get the value for. + /// The retrieved value. + public static ImplicitCompositionAnimationCollection GetHideAnimations(UIElement element) + { + var collection = (ImplicitCompositionAnimationCollection)element.GetValue(HideAnimationsProperty); + + if (collection is null) + { + element.SetValue(HideAnimationsProperty, collection = new()); + } + + return collection; + } + + /// + /// Sets the value of the property. + /// + /// The to set the value for. + /// The value to set. + public static void SetHideAnimations(UIElement element, ImplicitCompositionAnimationCollection value) + { + element.SetValue(HideAnimationsProperty, value); + } + + /// + /// Gets the value of the property. + /// + /// The to get the value for. + /// The retrieved value. + public static ImplicitCompositionAnimationCollection GetAnimations(UIElement element) + { + var collection = (ImplicitCompositionAnimationCollection)element.GetValue(AnimationsProperty); + + if (collection is null) + { + element.SetValue(AnimationsProperty, collection = new()); + } + + return collection; + } + + /// + /// Sets the value of the property. + /// + /// The to set the value for. + /// The value to set. + public static void SetAnimations(UIElement element, ImplicitCompositionAnimationCollection value) + { + element.SetValue(AnimationsProperty, value); + } + + /// + /// Callback to keep the attached parent in sync for animations linked to the property. + /// + /// The target object the property was changed for. + /// The instance for the current event. + private static void OnShowAnimationsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + static void OnAnimationsChanged(object sender, EventArgs e) + { + var collection = (ImplicitCompositionAnimationCollection)sender; + + if (collection.ParentReference!.TryGetTarget(out UIElement element)) + { + ElementCompositionPreview.SetImplicitShowAnimation(element, collection.GetCompositionAnimationGroup()); + } + } + + if (e.OldValue is ImplicitCompositionAnimationCollection oldCollection) + { + oldCollection.AnimationsChanged -= OnAnimationsChanged; + } + + if (d is UIElement element && + e.NewValue is ImplicitCompositionAnimationCollection collection) + { + collection.ParentReference = new(element); + collection.AnimationsChanged -= OnAnimationsChanged; + collection.AnimationsChanged += OnAnimationsChanged; + + ElementCompositionPreview.SetImplicitShowAnimation(element, collection.GetCompositionAnimationGroup()); + } + } + + /// + /// Callback to keep the attached parent in sync for animations linked to the property. + /// + /// The target object the property was changed for. + /// The instance for the current event. + private static void OnHideAnimationsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + static void OnAnimationsChanged(object sender, EventArgs e) + { + var collection = (ImplicitCompositionAnimationCollection)sender; + + if (collection.ParentReference!.TryGetTarget(out UIElement element)) + { + ElementCompositionPreview.SetImplicitHideAnimation(element, collection.GetCompositionAnimationGroup()); + } + } + + if (e.OldValue is ImplicitCompositionAnimationCollection oldCollection) + { + oldCollection.AnimationsChanged -= OnAnimationsChanged; + } + + if (d is UIElement element && + e.NewValue is ImplicitCompositionAnimationCollection collection) + { + collection.ParentReference = new(element); + collection.AnimationsChanged -= OnAnimationsChanged; + collection.AnimationsChanged += OnAnimationsChanged; + + ElementCompositionPreview.SetImplicitHideAnimation(element, collection.GetCompositionAnimationGroup()); + } + } + + /// + /// Callback to keep the attached parent in sync for animations linked to the property. + /// + /// The target object the property was changed for. + /// The instance for the current event. + private static void OnAnimationsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + static void OnAnimationsChanged(object sender, EventArgs e) + { + var collection = (ImplicitCompositionAnimationCollection)sender; + + if (collection.ParentReference!.TryGetTarget(out UIElement element)) + { + ElementCompositionPreview.GetElementVisual(element).ImplicitAnimations = collection.GetImplicitAnimationCollection(); + } + } + + if (e.OldValue is ImplicitCompositionAnimationCollection oldCollection) + { + oldCollection.AnimationsChanged -= OnAnimationsChanged; + } + + if (d is UIElement element && + e.NewValue is ImplicitCompositionAnimationCollection collection) + { + collection.ParentReference = new(element); + collection.AnimationsChanged -= OnAnimationsChanged; + collection.AnimationsChanged += OnAnimationsChanged; + + ElementCompositionPreview.GetElementVisual(element).ImplicitAnimations = collection.GetImplicitAnimationCollection(); + } + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs index 2d253cde7d0..69e4080009b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs @@ -9,9 +9,7 @@ using System.Diagnostics.Contracts; using System.Threading.Tasks; using Microsoft.Toolkit.Diagnostics; -using Windows.UI.Composition; using Windows.UI.Xaml; -using Windows.UI.Xaml.Hosting; using Windows.UI.Xaml.Markup; namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml @@ -75,14 +73,7 @@ public async void Start() /// public Task StartAsync() { - UIElement? parent = null; - - if (ParentReference?.TryGetTarget(out parent) != true) - { - ThrowHelper.ThrowInvalidOperationException("The current animation collection isn't bound to a parent UIElement instance."); - } - - return StartAsync(parent!); + return StartAsync(GetParent()); } /// @@ -123,82 +114,21 @@ public async Task StartAsync(UIElement element) } /// - /// Creates a for the current collection. - /// This can be used to be assigned to show/hide implicit composition animations. + /// Gets the current parent instance. /// - /// The target to animate. - /// The instance to use. + /// The reference from . + /// Thrown if there is no parent available. [Pure] - internal CompositionAnimationGroup GetCompositionAnimationGroup(UIElement element) + private UIElement GetParent() { - Compositor compositor = ElementCompositionPreview.GetElementVisual(element).Compositor; - CompositionAnimationGroup animations = compositor.CreateAnimationGroup(); - - static void GatherAnimations(UIElement element, CompositionAnimationGroup animations, ITimeline timeline) - { - if (timeline is AnimationScope scope) - { - foreach (ITimeline child in scope.Animations) - { - GatherAnimations(element, animations, child); - } - } - else if (timeline is IImplicitTimeline animation) - { - animations.Add(animation.GetAnimation(element, out _)); - } - } - - foreach (ITimeline timeline in Animations) - { - GatherAnimations(element, animations, timeline); - } - - return animations; - } - - /// - /// Creates an for the current collection. - /// This can be used to be assigned to implicit composition animations. - /// - /// The target to animate. - /// The instance to use. - [Pure] - internal ImplicitAnimationCollection GetImplicitAnimationCollection(UIElement element) - { - Compositor compositor = ElementCompositionPreview.GetElementVisual(element).Compositor; - ImplicitAnimationCollection animations = compositor.CreateImplicitAnimationCollection(); - - static void GatherAnimations(UIElement element, ImplicitAnimationCollection animations, ITimeline timeline) - { - if (timeline is AnimationScope scope) - { - foreach (ITimeline child in scope.Animations) - { - GatherAnimations(element, animations, child); - } - } - else if (timeline is IImplicitTimeline implicitTimeline) - { - CompositionAnimation animation = implicitTimeline.GetAnimation(element, out string? target); - - target ??= animation.Target; - - if (!animations.ContainsKey(target)) - { - animations[target] = animations.Compositor.CreateAnimationGroup(); - } - - ((CompositionAnimationGroup)animations[target]).Add(animation); - } - } + UIElement? parent = null; - foreach (ITimeline timeline in Animations) + if (ParentReference?.TryGetTarget(out parent) != true) { - GatherAnimations(element, animations, timeline); + ThrowHelper.ThrowInvalidOperationException("The current animation collection isn't bound to a parent UIElement instance."); } - return animations; + return parent!; } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitCompositionAnimationCollection.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitCompositionAnimationCollection.cs new file mode 100644 index 00000000000..cfb97489242 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitCompositionAnimationCollection.cs @@ -0,0 +1,132 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable enable + +using System; +using System.Collections.ObjectModel; +using System.Diagnostics.Contracts; +using Microsoft.Toolkit.Diagnostics; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Hosting; + +namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +{ + /// + /// A collection of implicit animations that can be grouped together. This type represents a composite animation + /// (such as ) that is executed on a given element. + /// + public sealed class ImplicitCompositionAnimationCollection : Collection + { + /// + /// Raised whenever the contained animations are changed. + /// + internal event EventHandler? AnimationsChanged; + + /// + /// Gets or sets the weak reference to the parent that owns the current implicit animation collection. + /// + internal WeakReference? ParentReference { get; set; } + + /// + /// Creates a for the current collection. + /// This can be used to be assigned to show/hide implicit composition animations. + /// + /// The instance to use. + [Pure] + internal CompositionAnimationGroup GetCompositionAnimationGroup() + { + UIElement parent = GetParent(); + Compositor compositor = ElementCompositionPreview.GetElementVisual(parent).Compositor; + CompositionAnimationGroup animations = compositor.CreateAnimationGroup(); + + foreach (IImplicitTimeline timeline in this) + { + animations.Add(timeline.GetAnimation(parent, out _)); + } + + return animations; + } + + /// + /// Creates an for the current collection. + /// This can be used to be assigned to implicit composition animations. + /// + /// The instance to use. + [Pure] + internal ImplicitAnimationCollection GetImplicitAnimationCollection() + { + UIElement parent = GetParent(); + Compositor compositor = ElementCompositionPreview.GetElementVisual(parent).Compositor; + ImplicitAnimationCollection animations = compositor.CreateImplicitAnimationCollection(); + + foreach (IImplicitTimeline timeline in this) + { + CompositionAnimation animation = timeline.GetAnimation(parent, out string? target); + + target ??= animation.Target; + + if (!animations.ContainsKey(target)) + { + animations[target] = animations.Compositor.CreateAnimationGroup(); + } + + ((CompositionAnimationGroup)animations[target]).Add(animation); + } + + return animations; + } + + /// + protected override void ClearItems() + { + base.ClearItems(); + + AnimationsChanged?.Invoke(this, EventArgs.Empty); + } + + /// + protected override void InsertItem(int index, IImplicitTimeline item) + { + base.InsertItem(index, item); + + AnimationsChanged?.Invoke(this, EventArgs.Empty); + } + + /// + protected override void RemoveItem(int index) + { + base.RemoveItem(index); + + AnimationsChanged?.Invoke(this, EventArgs.Empty); + } + + /// + protected override void SetItem(int index, IImplicitTimeline item) + { + base.SetItem(index, item); + + AnimationsChanged?.Invoke(this, EventArgs.Empty); + } + + /// + /// Gets the current parent instance. + /// + /// The reference from . + /// Thrown if there is no parent available. + [Pure] + private UIElement GetParent() + { + UIElement? parent = null; + + if (ParentReference?.TryGetTarget(out parent) != true) + { + ThrowHelper.ThrowInvalidOperationException("The current animation collection isn't bound to a parent UIElement instance."); + } + + return parent!; + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IImplicitTimeline.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IImplicitTimeline.cs index 66fa0e13d8a..6d6f6ac1277 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IImplicitTimeline.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IImplicitTimeline.cs @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml /// /// An interface representing a XAML model for a custom implicit composition animation. /// - internal interface IImplicitTimeline + public interface IImplicitTimeline { /// /// Gets a from the currnet node. This animation might From 0acfbad6a46aa44e20374ffa855bdad120cfe01f Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 25 Dec 2020 23:53:09 +0100 Subject: [PATCH 089/171] Removed .Xaml namespace --- Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs | 1 - Microsoft.Toolkit.Uwp.UI.Animations/Implicit2.cs | 3 --- Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs | 2 +- .../Xaml/Abstract/Animation{TValue,TKeyFrame}.cs | 2 +- .../Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs | 2 +- .../Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs | 2 +- .../Xaml/AnimationCollection2.cs | 2 +- .../Xaml/AnimationDictionary.cs | 2 +- Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs | 2 +- .../Xaml/Default/ClipAnimation.cs | 2 +- .../Xaml/Default/OffsetAnimation.cs | 2 +- .../Xaml/Default/OpacityAnimation.cs | 2 +- .../Xaml/Default/OrientationAnimation.cs | 2 +- .../Xaml/Default/RotationAnimation.cs | 2 +- .../Xaml/Default/RotationInDegreesAnimation.cs | 2 +- .../Xaml/Default/ScaleAnimation.cs | 2 +- .../Xaml/Default/SizeAnimation.cs | 2 +- .../Xaml/Default/TranslationAnimation.cs | 2 +- .../Xaml/ImplicitCompositionAnimationCollection.cs | 2 +- .../Xaml/Interfaces/IImplicitTimeline.cs | 2 +- .../Xaml/Interfaces/IKeyFrame{T}.cs | 2 +- .../Xaml/Interfaces/ITimeline.cs | 2 +- .../Xaml/KeyFrames/QuaternionKeyFrame.cs | 1 - .../Xaml/KeyFrames/ScalarKeyFrame.cs | 1 - .../Xaml/KeyFrames/Vector2KeyFrame.cs | 1 - .../Xaml/KeyFrames/Vector3KeyFrame.cs | 1 - .../Xaml/KeyFrames/Vector4KeyFrame.cs | 1 - 27 files changed, 20 insertions(+), 29 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs index 123a95e13ff..022d8490178 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Explicit.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Animations diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Implicit2.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Implicit2.cs index 730381f00c5..2db8e2bb457 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Implicit2.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Implicit2.cs @@ -3,9 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; -using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; -using Windows.UI.Composition; using Windows.UI.Xaml; using Windows.UI.Xaml.Hosting; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs index 5f79601018b..e932e8f428f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs @@ -5,7 +5,7 @@ using System; using Windows.UI.Xaml.Media.Animation; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// A base model representing an animation that can be used in XAML. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs index e1e76baa7fe..80e1cdba87b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs @@ -7,7 +7,7 @@ using System.Collections.Generic; using Windows.UI.Xaml.Markup; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// A base model representing a typed animation that can be used in XAML. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs index 1d69a3be31c..63271b5c848 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs @@ -9,7 +9,7 @@ using Windows.UI.Xaml; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// A base model representing a typed animation that can be used as an implicit composition animation. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs index fa89a76c7eb..d5588e6c1d9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs @@ -7,7 +7,7 @@ using System.Collections.Generic; using Windows.UI.Xaml.Media.Animation; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// A base model representing a typed keyframe that can be used in XAML. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs index 69e4080009b..55b33b25e25 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs @@ -12,7 +12,7 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Markup; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// A collection of animations that can be grouped together. This type represents a composite animation diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationDictionary.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationDictionary.cs index 58135c86021..cabd7e1829a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationDictionary.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationDictionary.cs @@ -9,7 +9,7 @@ using System.Collections.Generic; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// A collection of animations that can be defined from XAML. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs index cb9faf8f8c9..c229d8bda4c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs @@ -9,7 +9,7 @@ using Windows.UI.Xaml.Markup; using Windows.UI.Xaml.Media.Animation; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// A container of elements that can be used to conceptually group animations diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs index 71b4d943220..c36551a140d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs @@ -7,7 +7,7 @@ using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// A clip animation working on the composition layer. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs index f991d2e3ae6..5ac35e56777 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs @@ -9,7 +9,7 @@ using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// An offset animation working on the composition layer. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs index 0dbab219e22..32c88837bc1 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs @@ -7,7 +7,7 @@ using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// An opacity animation working on the composition or XAML layer. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs index 1bdb825c796..88b7c242dcd 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs @@ -9,7 +9,7 @@ using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// An orientation animation working on the composition layer. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs index 1f5df37c47c..03acef75aec 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs @@ -7,7 +7,7 @@ using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// A rotation animation working on the composition or XAML layer. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs index b512766fa2c..67ad2d5e4e6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs @@ -7,7 +7,7 @@ using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// A rotation in degrees animation working on the composition or XAML layer. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs index 70ffef08d76..85c4d03cdbb 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs @@ -9,7 +9,7 @@ using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// A scale animation working on the composition or XAML layer. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs index 2e648421dbf..67f38b71174 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs @@ -9,7 +9,7 @@ using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// A size animation working on the composition or XAML layer. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs index 027e3b08b7b..8469f78e0d0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs @@ -8,7 +8,7 @@ using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// A translation animation working on the composition or XAML layer. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitCompositionAnimationCollection.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitCompositionAnimationCollection.cs index cfb97489242..104ad954920 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitCompositionAnimationCollection.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitCompositionAnimationCollection.cs @@ -12,7 +12,7 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Hosting; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// A collection of implicit animations that can be grouped together. This type represents a composite animation diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IImplicitTimeline.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IImplicitTimeline.cs index 6d6f6ac1277..6ad4ac7025e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IImplicitTimeline.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IImplicitTimeline.cs @@ -7,7 +7,7 @@ #nullable enable -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// An interface representing a XAML model for a custom implicit composition animation. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IKeyFrame{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IKeyFrame{T}.cs index 84cbb65593e..267d1bc7e17 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IKeyFrame{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IKeyFrame{T}.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// An interface representing a XAML model for a custom keyframe. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITimeline.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITimeline.cs index ca3ebcaccb7..6f3ad7d93d7 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITimeline.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITimeline.cs @@ -5,7 +5,7 @@ using System; using Windows.UI.Xaml.Media.Animation; -namespace Microsoft.Toolkit.Uwp.UI.Animations.Xaml +namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// An interface representing a XAML model for a custom animation. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/QuaternionKeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/QuaternionKeyFrame.cs index b8141844571..fb6954198c9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/QuaternionKeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/QuaternionKeyFrame.cs @@ -4,7 +4,6 @@ using System.Numerics; using System.Runtime.CompilerServices; -using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; using Microsoft.Toolkit.Uwp.UI.Extensions; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ScalarKeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ScalarKeyFrame.cs index b63665165be..d947d835e19 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ScalarKeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ScalarKeyFrame.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs index 95ad3d70831..9a4fc96b393 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Numerics; -using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; using Microsoft.Toolkit.Uwp.UI.Extensions; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs index 75443e0d049..6da3d2ff917 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Numerics; -using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; using Microsoft.Toolkit.Uwp.UI.Extensions; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs index a0fdcd3282e..b05bad728f3 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Numerics; -using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; using Microsoft.Toolkit.Uwp.UI.Extensions; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; From cc7b0a0fd2440c72b107ab4e6b2b8ef5ce5724c9 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 26 Dec 2020 00:02:45 +0100 Subject: [PATCH 090/171] Removed legacy code, fully migrated to new backend --- .../AnimationSet.cs | 634 ------------------ .../AnimationSetCompletedEventArgs.cs | 19 - .../AnimationSetState.cs | 32 - .../AnimationTask.cs | 40 -- .../ApiInformationHelper.cs | 13 - .../AnimationCollection.cs | 218 ------ .../Animations/AnimationBase.cs | 173 ----- .../Animations/TypedAnimationBase.cs | 164 ----- .../KeyFrames/KeyFrame.cs | 30 - .../KeyFrames/KeyFrameCollection.cs | 15 - .../KeyFrames/TypedKeyFrame.cs | 30 - .../EffectAnimationDefinition.cs | 30 - .../EffectDirectPropertyChangeDefinition.cs | 30 - .../Implicit.cs | 240 +++---- .../Implicit2.cs | 225 ------- .../Xaml/AnimationDictionary.cs | 20 +- ...nimationCollection2.cs => AnimationSet.cs} | 2 +- ...nCollection.cs => ImplicitAnimationSet.cs} | 2 +- .../Animations/AnimationEndBehavior.cs | 18 +- .../Animations/AnimationStartBehavior.cs | 18 +- .../Animations/StartAnimationAction.cs | 12 +- .../Animations/EffectDoubleAnimation.cs | 1 - 22 files changed, 158 insertions(+), 1808 deletions(-) delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/AnimationSet.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/AnimationSetCompletedEventArgs.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/AnimationSetState.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/AnimationTask.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/ApiInformationHelper.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/AnimationCollection.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/AnimationBase.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/TypedAnimationBase.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/KeyFrame.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/KeyFrameCollection.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/TypedKeyFrame.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/EffectAnimationDefinition.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/EffectDirectPropertyChangeDefinition.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Implicit2.cs rename Microsoft.Toolkit.Uwp.UI.Animations/Xaml/{AnimationCollection2.cs => AnimationSet.cs} (98%) rename Microsoft.Toolkit.Uwp.UI.Animations/Xaml/{ImplicitCompositionAnimationCollection.cs => ImplicitAnimationSet.cs} (98%) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationSet.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationSet.cs deleted file mode 100644 index fa8632942f2..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationSet.cs +++ /dev/null @@ -1,634 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Threading.Tasks; -using Windows.UI.Composition; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Hosting; -using Windows.UI.Xaml.Media.Animation; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Defines an object for storing and managing CompositionAnimations for an element - /// - public class AnimationSet : IDisposable - { - private List _animationSets; - - private Compositor _compositor; - private CompositionScopedBatch _batch; - private Dictionary _compositionAnimations; - private List _compositionEffectAnimations; - private Dictionary _directCompositionPropertyChanges; - private List _directCompositionEffectPropertyChanges; - - private Storyboard _storyboard; - private Dictionary _storyboardAnimations; - - private List _animationTasks; - - private TaskCompletionSource _animationTCS; - - private bool _storyboardCompleted; - private bool _compositionCompleted; - - /// - /// Gets or sets a value indicating whether composition must be use even on SDK > 10586 - /// - public static bool UseComposition { get; set; } - - /// - /// Gets the object that backs the XAML element - /// - public Visual Visual { get; private set; } - - /// - /// Gets the - /// - public UIElement Element { get; private set; } - - /// - /// Gets the current state of the AnimationSet - /// - public AnimationSetState State { get; private set; } - - /// - /// Initializes a new instance of the class. - /// - /// The associated element - public AnimationSet(UIElement element) - { - if (element == null) - { - throw new NullReferenceException("Element must not be null"); - } - - var visual = ElementCompositionPreview.GetElementVisual(element); - - if (visual == null) - { - throw new NullReferenceException("Visual must not be null"); - } - - Visual = visual; - if (Visual.Compositor == null) - { - throw new NullReferenceException("Visual must have a compositor"); - } - - Element = element; - State = AnimationSetState.NotStarted; - _compositor = Visual.Compositor; - - _compositionAnimations = new Dictionary(); - _compositionEffectAnimations = new List(); - _directCompositionPropertyChanges = new Dictionary(); - _directCompositionEffectPropertyChanges = new List(); - _animationSets = new List(); - _storyboard = new Storyboard(); - _storyboardAnimations = new Dictionary(); - _animationTasks = new List(); - } - - /// - /// Occurs when all animations have completed - /// - public event EventHandler Completed; - - /// - /// Stats all animations. This method is not awaitable. - /// - public async void Start() - { - await StartAsync(); - } - - /// - /// Starts all animations and returns an awaitable task. - /// - /// A that can be awaited until all animations have completed - public async Task StartAsync() - { - if (_animationTCS == null || _animationTCS.Task.IsCompleted) - { - if (_animationTCS != null && _animationTCS.Task.IsCompleted) - { - foreach (var set in _animationSets) - { - set.State = AnimationSetState.NotStarted; - set._animationTCS = null; - } - } - - State = AnimationSetState.Running; - _animationTCS = new TaskCompletionSource(); - } - else - { - return await _animationTCS.Task; - } - - foreach (var set in _animationSets) - { - if (set.State != AnimationSetState.Completed) - { - var completed = await set.StartAsync(); - - if (!completed) - { - // the animation was stopped - return await _animationTCS.Task; - } - } - } - - foreach (var task in _animationTasks) - { - if (task.Task != null && !task.Task.IsCompleted) - { - await task.Task; - } - - // if _animationSet is stopped while task was running - if (State == AnimationSetState.Stopped) - { - return await _animationTCS.Task; - } - } - - _animationTasks.Clear(); - - foreach (var property in _directCompositionPropertyChanges) - { - typeof(Visual).GetProperty(property.Key).SetValue(Visual, property.Value); - } - - foreach (var definition in _directCompositionEffectPropertyChanges) - { - definition.EffectBrush.Properties.InsertScalar(definition.PropertyName, definition.Value); - } - - if (_compositionAnimations.Count > 0 || _compositionEffectAnimations.Count > 0) - { - if (_batch != null) - { - if (!_batch.IsEnded) - { - _batch.End(); - } - - _batch.Completed -= Batch_Completed; - } - - _batch = _compositor.CreateScopedBatch(CompositionBatchTypes.Animation); - _batch.Completed += Batch_Completed; - - foreach (var anim in _compositionAnimations) - { - Visual.StartAnimation(anim.Key, anim.Value); - } - - foreach (var effect in _compositionEffectAnimations) - { - effect.EffectBrush.StartAnimation(effect.PropertyName, effect.Animation); - } - - _compositionCompleted = false; - _batch.End(); - } - else - { - _compositionCompleted = true; - } - - if (_storyboardAnimations.Count > 0) - { - _storyboardCompleted = false; - - _storyboard.Completed -= Storyboard_Completed; - _storyboard.Completed += Storyboard_Completed; - - _storyboard.Begin(); - } - else - { - _storyboardCompleted = true; - } - - HandleCompleted(); - - return await _animationTCS.Task; - } - - /// - /// Stops all animations. - /// - public void Stop() - { - foreach (var set in _animationSets) - { - if (set.State != AnimationSetState.Completed) - { - set.Stop(); - } - } - - if (_batch != null) - { - if (!_batch.IsEnded) - { - _batch.End(); - } - - _batch.Completed -= Batch_Completed; - } - - foreach (var anim in _compositionAnimations) - { - Visual.StopAnimation(anim.Key); - } - - foreach (var effect in _compositionEffectAnimations) - { - effect.EffectBrush.StopAnimation(effect.PropertyName); - } - - _storyboard.Pause(); - - HandleCompleted(true); - _animationTCS = null; - } - - /// - /// Wait for existing animations to complete before running new animations - /// - /// AnimationSet to allow chaining - public AnimationSet Then() - { - var savedAnimationSet = new AnimationSet(Element); - savedAnimationSet._compositionAnimations = _compositionAnimations; - savedAnimationSet._compositionEffectAnimations = _compositionEffectAnimations; - savedAnimationSet._directCompositionPropertyChanges = _directCompositionPropertyChanges; - savedAnimationSet._directCompositionEffectPropertyChanges = _directCompositionEffectPropertyChanges; - savedAnimationSet._storyboard = _storyboard; - savedAnimationSet._storyboardAnimations = _storyboardAnimations; - - _animationTasks.ForEach(t => t.AnimationSet = savedAnimationSet); - savedAnimationSet._animationTasks = _animationTasks; - - _animationSets.Add(savedAnimationSet); - - _compositionAnimations = new Dictionary(); - _compositionEffectAnimations = new List(); - _directCompositionPropertyChanges = new Dictionary(); - _directCompositionEffectPropertyChanges = new List(); - _storyboard = new Storyboard(); - _storyboardAnimations = new Dictionary(); - _animationTasks = new List(); - - return this; - } - - /// - /// Overwrites the duration on all animations after last Then() - /// to the specified value - /// - /// The duration in milliseconds - /// AnimationSet to allow chaining - public AnimationSet SetDuration(double duration) - { - if (duration <= 0) - { - duration = 1; - } - - return SetDuration(TimeSpan.FromMilliseconds(duration)); - } - - /// - /// Overwrites the duration on all animations after last Then() - /// to the specified value - /// - /// for the duration - /// AnimationSet to allow chaining - public AnimationSet SetDuration(TimeSpan duration) - { - foreach (var task in _animationTasks) - { - task.Duration = duration; - } - - foreach (var anim in _compositionAnimations) - { - var animation = anim.Value as KeyFrameAnimation; - if (animation != null) - { - animation.Duration = duration; - } - } - - foreach (var effect in _compositionEffectAnimations) - { - var animation = effect.Animation as KeyFrameAnimation; - if (animation != null) - { - animation.Duration = duration; - } - } - - foreach (var timeline in _storyboardAnimations) - { - var animation = timeline.Value as DoubleAnimation; - if (animation != null) - { - animation.Duration = duration; - } - } - - return this; - } - - /// - /// Overwrites the duration on all animations to the specified value - /// - /// The duration in milliseconds - /// AnimationSet to allow chaining - public AnimationSet SetDurationForAll(double duration) - { - foreach (var set in _animationSets) - { - set.SetDuration(duration); - } - - return SetDuration(duration); - } - - /// - /// Overwrites the duration on all animations to the specified value - /// - /// for the duration - /// AnimationSet to allow chaining - public AnimationSet SetDurationForAll(TimeSpan duration) - { - foreach (var set in _animationSets) - { - set.SetDuration(duration); - } - - return SetDuration(duration); - } - - /// - /// Overwrites the delay time on all animations after last Then() - /// to the specified value - /// - /// The delay time in milliseconds - /// AnimationSet to allow chaining - public AnimationSet SetDelay(double delayTime) - { - if (delayTime < 0) - { - delayTime = 0; - } - - return SetDelay(TimeSpan.FromMilliseconds(delayTime)); - } - - /// - /// Overwrites the delay time on all animations after last Then() - /// to the specified value - /// - /// for how much to delay - /// AnimationSet to allow chaining - public AnimationSet SetDelay(TimeSpan delayTime) - { - foreach (var task in _animationTasks) - { - task.Delay = delayTime; - } - - foreach (var anim in _compositionAnimations) - { - var animation = anim.Value as KeyFrameAnimation; - if (animation != null) - { - animation.DelayTime = delayTime; - } - } - - foreach (var effect in _compositionEffectAnimations) - { - var animation = effect.Animation as KeyFrameAnimation; - if (animation != null) - { - animation.DelayTime = delayTime; - } - } - - foreach (var timeline in _storyboardAnimations) - { - var animation = timeline.Value as DoubleAnimation; - if (animation != null) - { - animation.BeginTime = delayTime; - } - } - - return this; - } - - /// - /// Overwrites the delay time on all animations to the specified value - /// - /// The delay time in milliseconds - /// AnimationSet to allow chaining - public AnimationSet SetDelayForAll(double delayTime) - { - foreach (var set in _animationSets) - { - set.SetDelay(delayTime); - } - - return SetDelay(delayTime); - } - - /// - /// Overwrites the delay time on all animations to the specified value - /// - /// for how much to delay - /// AnimationSet to allow chaining - public AnimationSet SetDelayForAll(TimeSpan delayTime) - { - foreach (var set in _animationSets) - { - set.SetDelay(delayTime); - } - - return SetDelay(delayTime); - } - - /// - /// Adds a composition animation to be run on - /// - /// The property to be animated on the backing Visual - /// The to be applied - public void AddCompositionAnimation(string propertyName, CompositionAnimation animation) - { - _compositionAnimations[propertyName] = animation; - } - - /// - /// Removes a composition animation from being run on property - /// - /// The property that no longer needs to be animated - public void RemoveCompositionAnimation(string propertyName) - { - if (_compositionAnimations.ContainsKey(propertyName)) - { - _compositionAnimations.Remove(propertyName); - } - } - - /// - /// Adds a composition effect animation to be run on backing - /// - /// The that will have a property animated - /// The animation to be applied - /// The property of the effect to be animated - public void AddCompositionEffectAnimation(CompositionObject effectBrush, CompositionAnimation animation, string propertyName) - { - var effect = new EffectAnimationDefinition() - { - EffectBrush = effectBrush, - Animation = animation, - PropertyName = propertyName - }; - - _compositionEffectAnimations.Add(effect); - } - - /// - /// Adds a composition property that will change instantaneously - /// - /// The property to be animated on the backing Visual - /// The value to be applied - public void AddCompositionDirectPropertyChange(string propertyName, object value) - { - _directCompositionPropertyChanges[propertyName] = value; - } - - /// - /// Removes a composition property change - /// - /// The property that no longer needs to be changed - public void RemoveCompositionDirectPropertyChange(string propertyName) - { - if (_directCompositionPropertyChanges.ContainsKey(propertyName)) - { - _directCompositionPropertyChanges.Remove(propertyName); - } - } - - /// - /// Adds a storyboard animation to be run - /// - /// The property to be animated with Storyboards - /// The timeline object to be added to storyboard - public void AddStoryboardAnimation(string propertyPath, Timeline timeline) - { - if (_storyboardAnimations.ContainsKey(propertyPath)) - { - var previousAnimation = _storyboardAnimations[propertyPath]; - _storyboard.Children.Remove(previousAnimation); - _storyboardAnimations.Remove(propertyPath); - } - - _storyboardAnimations.Add(propertyPath, timeline); - _storyboard.Children.Add(timeline); - - Storyboard.SetTarget(timeline, Element); - Storyboard.SetTargetProperty(timeline, propertyPath); - } - - /// - /// Dispose resources. - /// - public void Dispose() - { - _animationTCS = null; - } - - /// - /// Adds a to the AnimationSet that - /// will run add an animation once completed. Useful when an animation - /// needs to do asynchronous initialization before running - /// - /// The to be added - internal void AddAnimationThroughTask(AnimationTask animationTask) - { - _animationTasks.Add(animationTask); - } - - /// - /// Adds an effect property change to be run on - /// - /// The that will have a property changed - /// The value to be applied - /// The property of the effect to be animated - internal void AddEffectDirectPropertyChange(CompositionObject effectBrush, float value, string propertyName) - { - var definition = new EffectDirectPropertyChangeDefinition() - { - EffectBrush = effectBrush, - Value = value, - PropertyName = propertyName - }; - - _directCompositionEffectPropertyChanges.Add(definition); - } - - private void Storyboard_Completed(object sender, object e) - { - _storyboardCompleted = true; - _storyboard.Completed -= Storyboard_Completed; - HandleCompleted(); - } - - private void Batch_Completed(object sender, CompositionBatchCompletedEventArgs args) - { - _compositionCompleted = true; - _batch.Completed -= Batch_Completed; - HandleCompleted(); - } - - private void HandleCompleted(bool stopped = false) - { - var completed = _storyboardCompleted && _compositionCompleted; - - if (!completed && !stopped) - { - return; - } - - if (_storyboardCompleted && _compositionCompleted) - { - State = AnimationSetState.Completed; - } - else - { - State = AnimationSetState.Stopped; - } - - if (_animationTCS != null && !_animationTCS.Task.IsCompleted) - { - _animationTCS.SetResult(State == AnimationSetState.Completed); - Completed?.Invoke(this, new AnimationSetCompletedEventArgs() { Completed = _storyboardCompleted && _compositionCompleted }); - } - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationSetCompletedEventArgs.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationSetCompletedEventArgs.cs deleted file mode 100644 index 3bad5d6cb13..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationSetCompletedEventArgs.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// AnimationSet Completed EventArgs. - /// - public class AnimationSetCompletedEventArgs : EventArgs - { - /// - /// Gets a value indicating whether the animation completed - /// - public bool Completed { get; internal set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationSetState.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationSetState.cs deleted file mode 100644 index 9157c72c0f2..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationSetState.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// States of AnimationSet. - /// - public enum AnimationSetState - { - /// - /// The animation has not been started - /// - NotStarted, - - /// - /// The animation has been started and is in progress - /// - Running, - - /// - /// The animation has been started and is stopped - /// - Stopped, - - /// - /// The animation had completed - /// - Completed - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationTask.cs b/Microsoft.Toolkit.Uwp.UI.Animations/AnimationTask.cs deleted file mode 100644 index d9aefee2beb..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/AnimationTask.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Threading.Tasks; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Defines which is used by - /// to run animations that require - /// asynchronous initialization - /// - internal class AnimationTask - { - /// - /// Gets or sets that will run before any animation - /// and it will add the animation to the AnimationSet once complete - /// - public Task Task { get; set; } - - /// - /// Gets or sets that will run the animation - /// - public AnimationSet AnimationSet { get; set; } - - /// - /// Gets or sets Duration to be applied to the animation once the task is completed - /// Used when Duration is changed before Task completes - /// - public TimeSpan? Duration { get; set; } - - /// - /// Gets or sets Delay to be applied to the animation once the task is completed - /// Used when Duration is changed before Task completes - /// - public TimeSpan? Delay { get; set; } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/ApiInformationHelper.cs b/Microsoft.Toolkit.Uwp.UI.Animations/ApiInformationHelper.cs deleted file mode 100644 index a81b7a5d8fe..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/ApiInformationHelper.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.Foundation.Metadata; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - internal class ApiInformationHelper - { - public static bool IsXamlRootAvailable { get; } = ApiInformation.IsPropertyPresent("Windows.UI.Xaml.UIElement", "XamlRoot"); - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/AnimationCollection.cs b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/AnimationCollection.cs deleted file mode 100644 index 11d387e30be..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/AnimationCollection.cs +++ /dev/null @@ -1,218 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using Windows.UI.Composition; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Hosting; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// An ObservableCollection of - /// - public class AnimationCollection : IList - { - private readonly List _internalList = new List(); - - // needed in order to be able to update animations when a animations are added/removed or - // animation properties change (for example in binding) - private WeakReference _parent; - - internal UIElement Parent - { - get - { - _parent.TryGetTarget(out var element); - return element; - } - - set => _parent = new WeakReference(value); - } - - /// - /// Gets a value indicating whether the collection contains an animation that targets the Translation property - /// - public bool ContainsTranslationAnimation => this.Count(anim => !string.IsNullOrWhiteSpace(anim.Target) && anim.Target.StartsWith("Translation")) > 0; - - /// - public int Count => _internalList.Count; - - /// - public bool IsReadOnly => false; - - /// - public AnimationBase this[int index] { get => _internalList[index]; set => Insert(index, value); } - - /// - /// Raised when an animation has been added/removed or modified - /// - public event EventHandler AnimationCollectionChanged; - - /// - /// Starts the animations in the collection - /// - /// The to be animated - public void StartAnimation(UIElement element) - { - foreach (var animation in this) - { - animation.StartAnimation(element); - } - } - - /// - /// Creates a that can be used to animate a visual on the - /// Composition layer - /// - /// The element used to get the - /// - internal CompositionAnimationGroup GetCompositionAnimationGroup(UIElement element) - { - var visual = ElementCompositionPreview.GetElementVisual(element); - var compositor = visual.Compositor; - var animationGroup = compositor.CreateAnimationGroup(); - - foreach (var cAnim in this) - { - var compositionAnimation = cAnim.GetCompositionAnimation(compositor); - if (compositionAnimation != null) - { - animationGroup.Add(compositionAnimation); - } - } - - return animationGroup; - } - - /// - /// Creates a that can be used to apply implicit animation on a - /// visual on the Composition layer - /// - /// The element used to get the - /// - internal ImplicitAnimationCollection GetImplicitAnimationCollection(UIElement element) - { - var visual = ElementCompositionPreview.GetElementVisual(element); - var compositor = visual.Compositor; - var implicitAnimations = compositor.CreateImplicitAnimationCollection(); - - var animations = new Dictionary(); - - foreach (var cAnim in this) - { - CompositionAnimation animation; - if (!string.IsNullOrWhiteSpace(cAnim.Target) - && (animation = cAnim.GetCompositionAnimation(compositor)) != null) - { - var target = cAnim.ImplicitTarget ?? cAnim.Target; - if (!animations.ContainsKey(target)) - { - animations[target] = compositor.CreateAnimationGroup(); - } - - animations[target].Add(animation); - } - } - - foreach (var kv in animations) - { - implicitAnimations[kv.Key] = kv.Value; - } - - return implicitAnimations; - } - - private void AnimationChanged(object sender, EventArgs e) - { - AnimationCollectionChanged?.Invoke(this, EventArgs.Empty); - } - - /// - public int IndexOf(AnimationBase item) - { - return _internalList.IndexOf(item); - } - - /// - public void Insert(int index, AnimationBase item) - { - item.AnimationChanged += AnimationChanged; - _internalList.Insert(index, item); - AnimationCollectionChanged?.Invoke(this, EventArgs.Empty); - } - - /// - public void RemoveAt(int index) - { - if (index >= 0 && index < _internalList.Count) - { - var animation = _internalList[index]; - animation.AnimationChanged -= AnimationChanged; - } - - _internalList.RemoveAt(index); - AnimationCollectionChanged?.Invoke(this, EventArgs.Empty); - } - - /// - public void Add(AnimationBase item) - { - item.AnimationChanged += AnimationChanged; - _internalList.Add(item); - AnimationCollectionChanged?.Invoke(this, EventArgs.Empty); - } - - /// - public void Clear() - { - foreach (var animation in _internalList) - { - animation.AnimationChanged -= AnimationChanged; - } - - _internalList.Clear(); - AnimationCollectionChanged?.Invoke(this, EventArgs.Empty); - } - - /// - public bool Contains(AnimationBase item) - { - return _internalList.Contains(item); - } - - /// - public void CopyTo(AnimationBase[] array, int arrayIndex) - { - _internalList.CopyTo(array, arrayIndex); - } - - /// - public bool Remove(AnimationBase item) - { - var result = _internalList.Remove(item); - if (result) - { - item.AnimationChanged -= AnimationChanged; - AnimationCollectionChanged?.Invoke(this, EventArgs.Empty); - } - - return result; - } - - /// - public IEnumerator GetEnumerator() - { - return _internalList.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _internalList.GetEnumerator(); - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/AnimationBase.cs b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/AnimationBase.cs deleted file mode 100644 index 0c7fbd5180f..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/AnimationBase.cs +++ /dev/null @@ -1,173 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using Windows.UI.Composition; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Hosting; -using Windows.UI.Xaml.Markup; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Abstract class providing common dependency properties for composition animations - /// - [ContentProperty(Name = nameof(KeyFrames))] - public abstract class AnimationBase : DependencyObject - { - /// - /// Identifies the property - /// - public static readonly DependencyProperty TargetProperty = - DependencyProperty.Register(nameof(Target), typeof(string), typeof(AnimationBase), new PropertyMetadata(null, OnAnimationPropertyChanged)); - - /// - /// Identifies the property - /// - public static readonly DependencyProperty DurationProperty = - DependencyProperty.Register(nameof(Duration), typeof(TimeSpan), typeof(AnimationBase), new PropertyMetadata(TimeSpan.FromMilliseconds(400), OnAnimationPropertyChanged)); - - /// - /// Identifies the property - /// - public static readonly DependencyProperty KeyFramesProperty = - DependencyProperty.Register(nameof(KeyFrames), typeof(KeyFrameCollection), typeof(AnimationBase), new PropertyMetadata(null, OnAnimationPropertyChanged)); - - /// - /// Identifies the property - /// - public static readonly DependencyProperty ImplicitTargetProperty = - DependencyProperty.Register(nameof(ImplicitTarget), typeof(string), typeof(AnimationBase), new PropertyMetadata(null, OnAnimationPropertyChanged)); - - /// - /// Identifies the property - /// - public static readonly DependencyProperty DelayProperty = - DependencyProperty.Register(nameof(Delay), typeof(TimeSpan), typeof(AnimationBase), new PropertyMetadata(TimeSpan.Zero, OnAnimationPropertyChanged)); - - /// - /// Identifies the property - /// - public static readonly DependencyProperty SetInitialValueBeforeDelayProperty = - DependencyProperty.Register(nameof(SetInitialValueBeforeDelay), typeof(bool), typeof(AnimationBase), new PropertyMetadata(false, OnAnimationPropertyChanged)); - - /// - /// Initializes a new instance of the class. - /// - public AnimationBase() - { - if (KeyFrames == null) - { - KeyFrames = new KeyFrameCollection(); - } - } - - /// - /// Raised when a property changes - /// - public event EventHandler AnimationChanged; - - /// - /// Gets or sets the duration of the animation - /// - public TimeSpan Duration - { - get { return (TimeSpan)GetValue(DurationProperty); } - set { SetValue(DurationProperty, value); } - } - - /// - /// Gets or sets the of the animations - /// - public KeyFrameCollection KeyFrames - { - get { return (KeyFrameCollection)GetValue(KeyFramesProperty); } - set { SetValue(KeyFramesProperty, value); } - } - - /// - /// Gets or sets the target property to be animated - /// - public string Target - { - get { return (string)GetValue(TargetProperty); } - set { SetValue(TargetProperty, value); } - } - - /// - /// Gets or sets the property that should start the implicit animation - /// - public string ImplicitTarget - { - get { return (string)GetValue(ImplicitTargetProperty); } - set { SetValue(ImplicitTargetProperty, value); } - } - - /// - /// Gets or sets the delay of the animation - /// - public TimeSpan Delay - { - get { return (TimeSpan)GetValue(DelayProperty); } - set { SetValue(DelayProperty, value); } - } - - /// - /// Gets or sets a value indicating whether the value at keyframe 0 should be set before the delay - /// - public bool SetInitialValueBeforeDelay - { - get { return (bool)GetValue(SetInitialValueBeforeDelayProperty); } - set { SetValue(SetInitialValueBeforeDelayProperty, value); } - } - - /// - /// Starts the animation on the specified element - /// - /// The to be animated - public void StartAnimation(UIElement element) - { - if (element == null) - { - return; - } - - var visual = ElementCompositionPreview.GetElementVisual(element); - var compositor = visual.Compositor; - - if (Target.Contains("Translation")) - { - ElementCompositionPreview.SetIsTranslationEnabled(element, true); - } - - var compositionAnimation = GetCompositionAnimation(compositor); - visual.StartAnimation(Target, compositionAnimation); - } - - /// - /// Gets a that can be used on the Composition layer - /// - /// The to use to create the animation - /// - public abstract CompositionAnimation GetCompositionAnimation(Compositor compositor); - - /// - /// Called when any property of the animation changes - /// - protected void OnAnimationChanged() - { - AnimationChanged?.Invoke(this, EventArgs.Empty); - } - - /// - /// Called when any property of the animation changes - /// - /// The animation where a property has changed - /// The details about the property change - private static void OnAnimationPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - (d as AnimationBase).OnAnimationChanged(); - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/TypedAnimationBase.cs b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/TypedAnimationBase.cs deleted file mode 100644 index 0fe1a97b538..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/Animations/TypedAnimationBase.cs +++ /dev/null @@ -1,164 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using Windows.UI.Composition; -using Windows.UI.Xaml; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// A generic class extending to provide common implementation for most animations - /// - /// Type of to use - /// Type of value being animated. - public abstract class TypedAnimationBase : AnimationBase - where TKeyFrame : TypedKeyFrame, new() - { - private TKeyFrame _fromKeyFrame; - private TKeyFrame _toKeyFrame; - - /// - /// Identifies the dependency property. - /// - public static readonly DependencyProperty FromProperty = - DependencyProperty.Register(nameof(From), typeof(U), typeof(TypedAnimationBase), new PropertyMetadata(GetDefaultValue(), OnAnimationPropertyChanged)); - - /// - /// Identifies the dependency property. - /// - public static readonly DependencyProperty ToProperty = - DependencyProperty.Register(nameof(To), typeof(U), typeof(TypedAnimationBase), new PropertyMetadata(GetDefaultValue(), OnAnimationPropertyChanged)); - - /// - /// Gets or sets the value at the beginning. - /// Setting this value adds a new where the Key = 0 - /// - public U From - { - get { return (U)GetValue(FromProperty); } - set { SetValue(FromProperty, value); } - } - - /// - /// Gets or sets the value at the end. - /// Setting this value generates a new where the Key = 1 - /// - public U To - { - get { return (U)GetValue(ToProperty); } - set { SetValue(ToProperty, value); } - } - - /// - public override CompositionAnimation GetCompositionAnimation(Compositor compositor) - { - if (DesignTimeHelpers.IsRunningInLegacyDesignerMode) - { - return null; - } - - if (string.IsNullOrWhiteSpace(Target)) - { - return null; - } - - PrepareKeyFrames(); - var animation = GetTypedAnimationFromCompositor(compositor); - animation.Target = Target; - animation.Duration = Duration; - animation.DelayTime = Delay; - animation.DelayBehavior = SetInitialValueBeforeDelay ? AnimationDelayBehavior.SetInitialValueBeforeDelay : AnimationDelayBehavior.SetInitialValueAfterDelay; - - if (KeyFrames.Count == 0) - { - animation.InsertExpressionKeyFrame(1.0f, "this.FinalValue"); - return animation; - } - - foreach (var keyFrame in KeyFrames) - { - if (keyFrame is TKeyFrame typedKeyFrame) - { - InsertKeyFrameToTypedAnimation(animation, typedKeyFrame); - } - //else if (keyFrame is ExpressionKeyFrame expressionKeyFrame) - { - //animation.InsertExpressionKeyFrame((float)keyFrame.Key, expressionKeyFrame.Value); - } - } - - return animation; - } - - /// - /// Creates a composition animation for the property to be animated - /// - /// used to create the animation - /// - protected abstract KeyFrameAnimation GetTypedAnimationFromCompositor(Compositor compositor); - - /// - /// Inserts the value and a specified key in the typed - /// - /// The animation where the key frame will be inserted - /// The key frame that will be inserted - protected abstract void InsertKeyFrameToTypedAnimation(KeyFrameAnimation animation, TKeyFrame keyFrame); - - private static void OnAnimationPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((TypedAnimationBase)d).OnAnimationChanged(); - } - - // these two methods are required to support double (non nullable type) - private static object GetDefaultValue() - { - if (typeof(U) == typeof(double)) - { - return double.NaN; - } - - return default(U); - } - - private static bool IsValueNull(U value) - { - if (typeof(U) == typeof(double)) - { - return double.IsNaN((double)(object)value); - } - - return value == null; - } - - private void PrepareKeyFrames() - { - if (_fromKeyFrame != null) - { - KeyFrames.Remove(_fromKeyFrame); - } - - if (_toKeyFrame != null) - { - KeyFrames.Remove(_toKeyFrame); - } - - if (!IsValueNull(From)) - { - _fromKeyFrame = new TKeyFrame(); - _fromKeyFrame.Key = 0f; - _fromKeyFrame.Value = From; - KeyFrames.Add(_fromKeyFrame); - } - - if (!IsValueNull(To)) - { - _toKeyFrame = new TKeyFrame(); - _toKeyFrame.Key = 1f; - _toKeyFrame.Value = To; - KeyFrames.Add(_toKeyFrame); - } - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/KeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/KeyFrame.cs deleted file mode 100644 index 4d08d472610..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/KeyFrame.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Xaml; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Provides common Dependency properties for KeyFrames - /// - public abstract class KeyFrame : DependencyObject - { - /// - /// Identifies the dependency property - /// - public static readonly DependencyProperty KeyProperty = - DependencyProperty.Register(nameof(Key), typeof(double), typeof(KeyFrame), new PropertyMetadata(0.0)); - - /// - /// Gets or sets the key of the key frame - /// Value should be between 0.0 and 1.0 - /// - public double Key - { - get { return (double)GetValue(KeyProperty); } - set { SetValue(KeyProperty, value); } - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/KeyFrameCollection.cs b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/KeyFrameCollection.cs deleted file mode 100644 index ebee73c4e47..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/KeyFrameCollection.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// A collection of - /// - public class KeyFrameCollection : List - { - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/TypedKeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/TypedKeyFrame.cs deleted file mode 100644 index 1d2c7cd2722..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/CompositionAnimations/KeyFrames/TypedKeyFrame.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Xaml; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Provides type implementation of - /// - /// The type of property being animated - public abstract class TypedKeyFrame : KeyFrame - { - /// - /// Gets or sets the value at the specific key - /// - public T Value - { - get { return (T)GetValue(ValueProperty); } - set { SetValue(ValueProperty, value); } - } - - /// - /// Identifies the dependency property - /// - public static readonly DependencyProperty ValueProperty = - DependencyProperty.Register(nameof(Value), typeof(T), typeof(TypedKeyFrame), new PropertyMetadata(default(T))); - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/EffectAnimationDefinition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/EffectAnimationDefinition.cs deleted file mode 100644 index 5c00ac95b2a..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/EffectAnimationDefinition.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Defines an which is used by - /// to link effect animations to Visuals - /// - internal class EffectAnimationDefinition - { - /// - /// Gets or sets that will be animated - /// - public CompositionObject EffectBrush { get; set; } - - /// - /// Gets or sets the - /// - public CompositionAnimation Animation { get; set; } - - /// - /// Gets or sets the property name that will be animated on the - /// - public string PropertyName { get; set; } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/EffectDirectPropertyChangeDefinition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/EffectDirectPropertyChangeDefinition.cs deleted file mode 100644 index 04ccef0e94f..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/EffectDirectPropertyChangeDefinition.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.UI.Composition; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Defines an which is used by - /// to link effect property Changes to Visuals - /// - internal class EffectDirectPropertyChangeDefinition - { - /// - /// Gets or sets that will be animated - /// - public CompositionObject EffectBrush { get; set; } - - /// - /// Gets or sets the value for the property - /// - public float Value { get; set; } - - /// - /// Gets or sets the property name that will be animated on the - /// - public string PropertyName { get; set; } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs index a8a28187eba..827491ed400 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs @@ -3,219 +3,223 @@ // See the LICENSE file in the project root for more information. using System; -using Windows.UI.Composition; using Windows.UI.Xaml; using Windows.UI.Xaml.Hosting; +#nullable enable + namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// Attached Properties to enable Implicit Animations through XAML + /// Attached properties to support implicitly triggered animations for instances. /// - public class Implicit + public static class Implicit { /// - /// Identifies the Implicit.ShowAnimations XAML attached property + /// The attached "ShowAnimations" property. /// - public static readonly DependencyProperty ShowAnimationsProperty = - DependencyProperty.RegisterAttached("ShowAnimations", typeof(AnimationCollection), typeof(Implicit), new PropertyMetadata(null, ShowAnimationsChanged)); + public static readonly DependencyProperty ShowAnimationsProperty = DependencyProperty.RegisterAttached( + "ShowAnimations", + typeof(ImplicitAnimationSet), + typeof(Implicit), + new PropertyMetadata(null, OnShowAnimationsPropertyChanged)); /// - /// Identifies the Implicit.HideAnimations XAML attached property + /// The attached "HideAnimations" property. /// - public static readonly DependencyProperty HideAnimationsProperty = - DependencyProperty.RegisterAttached("HideAnimations", typeof(AnimationCollection), typeof(Implicit), new PropertyMetadata(null, HideAnimationsChanged)); + public static readonly DependencyProperty HideAnimationsProperty = DependencyProperty.RegisterAttached( + "HideAnimations", + typeof(ImplicitAnimationSet), + typeof(Implicit), + new PropertyMetadata(null, OnHideAnimationsPropertyChanged)); /// - /// Identifies the Implicit.Animations XAML attached property + /// The attached "Animations" property. /// - public static readonly DependencyProperty AnimationsProperty = - DependencyProperty.RegisterAttached("Animations", typeof(AnimationCollection), typeof(Implicit), new PropertyMetadata(null, AnimationsChanged)); + public static readonly DependencyProperty AnimationsProperty = DependencyProperty.RegisterAttached( + "Animations", + typeof(ImplicitAnimationSet), + typeof(Implicit), + new PropertyMetadata(null, OnAnimationsPropertyChanged)); /// - /// Gets the value of the Implicit.ShowAnimations XAML attached property. + /// Gets the value of the property. /// - /// The to get the value from - /// - public static AnimationCollection GetShowAnimations(DependencyObject obj) + /// The to get the value for. + /// The retrieved value. + public static ImplicitAnimationSet GetShowAnimations(UIElement element) { - var collection = (AnimationCollection)obj.GetValue(ShowAnimationsProperty); + var collection = (ImplicitAnimationSet)element.GetValue(ShowAnimationsProperty); - if (collection == null) + if (collection is null) { - collection = new AnimationCollection(); - obj.SetValue(ShowAnimationsProperty, collection); + element.SetValue(ShowAnimationsProperty, collection = new()); } return collection; } /// - /// Sets the value of the Implicit.ShowAnimations XAML attached property. + /// Sets the value of the property. /// - /// The to set the value - /// The to set - public static void SetShowAnimations(DependencyObject obj, AnimationCollection value) + /// The to set the value for. + /// The value to set. + public static void SetShowAnimations(UIElement element, ImplicitAnimationSet value) { - obj.SetValue(ShowAnimationsProperty, value); + element.SetValue(ShowAnimationsProperty, value); } /// - /// Gets the value of the Implicit.HideAnimations XAML attached property. + /// Gets the value of the property. /// - /// The to get the value from - /// - public static AnimationCollection GetHideAnimations(DependencyObject obj) + /// The to get the value for. + /// The retrieved value. + public static ImplicitAnimationSet GetHideAnimations(UIElement element) { - var collection = (AnimationCollection)obj.GetValue(HideAnimationsProperty); + var collection = (ImplicitAnimationSet)element.GetValue(HideAnimationsProperty); - if (collection == null) + if (collection is null) { - collection = new AnimationCollection(); - obj.SetValue(HideAnimationsProperty, collection); + element.SetValue(HideAnimationsProperty, collection = new()); } return collection; } /// - /// Sets the value of the Implicit.HideAnimations XAML attached property. + /// Sets the value of the property. /// - /// The to set the value - /// The to set - public static void SetHideAnimations(DependencyObject obj, AnimationCollection value) + /// The to set the value for. + /// The value to set. + public static void SetHideAnimations(UIElement element, ImplicitAnimationSet value) { - obj.SetValue(HideAnimationsProperty, value); + element.SetValue(HideAnimationsProperty, value); } /// - /// Gets the value of the Implicit.Animations XAML attached property. + /// Gets the value of the property. /// - /// The to get the value from - /// - public static AnimationCollection GetAnimations(DependencyObject obj) + /// The to get the value for. + /// The retrieved value. + public static ImplicitAnimationSet GetAnimations(UIElement element) { - var collection = (AnimationCollection)obj.GetValue(AnimationsProperty); + var collection = (ImplicitAnimationSet)element.GetValue(AnimationsProperty); - if (collection == null) + if (collection is null) { - collection = new AnimationCollection(); - obj.SetValue(AnimationsProperty, collection); + element.SetValue(AnimationsProperty, collection = new()); } return collection; } /// - /// Sets the value of the Implicit.Animations XAML attached property. + /// Sets the value of the property. /// - /// The to set the value - /// The to set - public static void SetAnimations(DependencyObject obj, AnimationCollection value) + /// The to set the value for. + /// The value to set. + public static void SetAnimations(UIElement element, ImplicitAnimationSet value) { - obj.SetValue(AnimationsProperty, value); + element.SetValue(AnimationsProperty, value); } - private static void ShowAnimationsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + /// + /// Callback to keep the attached parent in sync for animations linked to the property. + /// + /// The target object the property was changed for. + /// The instance for the current event. + private static void OnShowAnimationsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - if (e.OldValue is AnimationCollection oldCollection) + static void OnAnimationsChanged(object sender, EventArgs e) { - oldCollection.AnimationCollectionChanged -= ShowCollectionChanged; - } + var collection = (ImplicitAnimationSet)sender; - if (e.NewValue is AnimationCollection animationCollection && d is UIElement element) - { - animationCollection.Parent = element; - animationCollection.AnimationCollectionChanged -= ShowCollectionChanged; - animationCollection.AnimationCollectionChanged += ShowCollectionChanged; - ElementCompositionPreview.SetImplicitShowAnimation(element, GetCompositionAnimationGroup(animationCollection, element)); + if (collection.ParentReference!.TryGetTarget(out UIElement element)) + { + ElementCompositionPreview.SetImplicitShowAnimation(element, collection.GetCompositionAnimationGroup()); + } } - } - private static void HideAnimationsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - if (e.OldValue is AnimationCollection oldCollection) + if (e.OldValue is ImplicitAnimationSet oldCollection) { - oldCollection.AnimationCollectionChanged -= HideCollectionChanged; + oldCollection.AnimationsChanged -= OnAnimationsChanged; } - if (e.NewValue is AnimationCollection animationCollection && d is UIElement element) + if (d is UIElement element && + e.NewValue is ImplicitAnimationSet collection) { - animationCollection.Parent = element; - animationCollection.AnimationCollectionChanged -= HideCollectionChanged; - animationCollection.AnimationCollectionChanged += HideCollectionChanged; - ElementCompositionPreview.SetImplicitHideAnimation(element, GetCompositionAnimationGroup(animationCollection, element)); + collection.ParentReference = new(element); + collection.AnimationsChanged -= OnAnimationsChanged; + collection.AnimationsChanged += OnAnimationsChanged; + + ElementCompositionPreview.SetImplicitShowAnimation(element, collection.GetCompositionAnimationGroup()); } } - private static void AnimationsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + /// + /// Callback to keep the attached parent in sync for animations linked to the property. + /// + /// The target object the property was changed for. + /// The instance for the current event. + private static void OnHideAnimationsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - if (e.OldValue is AnimationCollection oldCollection) + static void OnAnimationsChanged(object sender, EventArgs e) { - oldCollection.AnimationCollectionChanged -= AnimationsCollectionChanged; - } + var collection = (ImplicitAnimationSet)sender; - if (e.NewValue is AnimationCollection animationCollection && d is UIElement element) - { - animationCollection.Parent = element; - animationCollection.AnimationCollectionChanged -= AnimationsCollectionChanged; - animationCollection.AnimationCollectionChanged += AnimationsCollectionChanged; - ElementCompositionPreview.GetElementVisual(element).ImplicitAnimations = GetImplicitAnimationCollection(animationCollection, element); + if (collection.ParentReference!.TryGetTarget(out UIElement element)) + { + ElementCompositionPreview.SetImplicitHideAnimation(element, collection.GetCompositionAnimationGroup()); + } } - } - private static void ShowCollectionChanged(object sender, EventArgs e) - { - var collection = (AnimationCollection)sender; - if (collection.Parent == null) + if (e.OldValue is ImplicitAnimationSet oldCollection) { - return; + oldCollection.AnimationsChanged -= OnAnimationsChanged; } - ElementCompositionPreview.SetImplicitShowAnimation(collection.Parent, GetCompositionAnimationGroup(collection, collection.Parent)); - } - - private static void HideCollectionChanged(object sender, EventArgs e) - { - var collection = (AnimationCollection)sender; - if (collection.Parent == null) + if (d is UIElement element && + e.NewValue is ImplicitAnimationSet collection) { - return; - } + collection.ParentReference = new(element); + collection.AnimationsChanged -= OnAnimationsChanged; + collection.AnimationsChanged += OnAnimationsChanged; - ElementCompositionPreview.SetImplicitHideAnimation(collection.Parent, GetCompositionAnimationGroup(collection, collection.Parent)); + ElementCompositionPreview.SetImplicitHideAnimation(element, collection.GetCompositionAnimationGroup()); + } } - private static void AnimationsCollectionChanged(object sender, EventArgs e) + /// + /// Callback to keep the attached parent in sync for animations linked to the property. + /// + /// The target object the property was changed for. + /// The instance for the current event. + private static void OnAnimationsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - var collection = (AnimationCollection)sender; - if (collection.Parent == null) + static void OnAnimationsChanged(object sender, EventArgs e) { - return; - } + var collection = (ImplicitAnimationSet)sender; - ElementCompositionPreview.GetElementVisual(collection.Parent).ImplicitAnimations = - GetImplicitAnimationCollection(collection, collection.Parent); - } + if (collection.ParentReference!.TryGetTarget(out UIElement element)) + { + ElementCompositionPreview.GetElementVisual(element).ImplicitAnimations = collection.GetImplicitAnimationCollection(); + } + } - private static CompositionAnimationGroup GetCompositionAnimationGroup(AnimationCollection collection, UIElement element) - { - if (collection.ContainsTranslationAnimation) + if (e.OldValue is ImplicitAnimationSet oldCollection) { - ElementCompositionPreview.SetIsTranslationEnabled(element, true); + oldCollection.AnimationsChanged -= OnAnimationsChanged; } - return collection.GetCompositionAnimationGroup(element); - } - - private static ImplicitAnimationCollection GetImplicitAnimationCollection(AnimationCollection collection, UIElement element) - { - if (collection.ContainsTranslationAnimation) + if (d is UIElement element && + e.NewValue is ImplicitAnimationSet collection) { - ElementCompositionPreview.SetIsTranslationEnabled(element, true); - } + collection.ParentReference = new(element); + collection.AnimationsChanged -= OnAnimationsChanged; + collection.AnimationsChanged += OnAnimationsChanged; - return collection.GetImplicitAnimationCollection(element); + ElementCompositionPreview.GetElementVisual(element).ImplicitAnimations = collection.GetImplicitAnimationCollection(); + } } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Implicit2.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Implicit2.cs deleted file mode 100644 index 2db8e2bb457..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Implicit2.cs +++ /dev/null @@ -1,225 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Hosting; - -#nullable enable - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Attached properties to support implicitly triggered animations for instances. - /// - public static class Implicit2 - { - /// - /// The attached "ShowAnimations" property. - /// - public static readonly DependencyProperty ShowAnimationsProperty = DependencyProperty.RegisterAttached( - "ShowAnimations", - typeof(ImplicitCompositionAnimationCollection), - typeof(Implicit2), - new PropertyMetadata(null, OnShowAnimationsPropertyChanged)); - - /// - /// The attached "HideAnimations" property. - /// - public static readonly DependencyProperty HideAnimationsProperty = DependencyProperty.RegisterAttached( - "HideAnimations", - typeof(ImplicitCompositionAnimationCollection), - typeof(Implicit2), - new PropertyMetadata(null, OnHideAnimationsPropertyChanged)); - - /// - /// The attached "Animations" property. - /// - public static readonly DependencyProperty AnimationsProperty = DependencyProperty.RegisterAttached( - "Animations", - typeof(ImplicitCompositionAnimationCollection), - typeof(Implicit2), - new PropertyMetadata(null, OnAnimationsPropertyChanged)); - - /// - /// Gets the value of the property. - /// - /// The to get the value for. - /// The retrieved value. - public static ImplicitCompositionAnimationCollection GetShowAnimations(UIElement element) - { - var collection = (ImplicitCompositionAnimationCollection)element.GetValue(ShowAnimationsProperty); - - if (collection is null) - { - element.SetValue(ShowAnimationsProperty, collection = new()); - } - - return collection; - } - - /// - /// Sets the value of the property. - /// - /// The to set the value for. - /// The value to set. - public static void SetShowAnimations(UIElement element, ImplicitCompositionAnimationCollection value) - { - element.SetValue(ShowAnimationsProperty, value); - } - - /// - /// Gets the value of the property. - /// - /// The to get the value for. - /// The retrieved value. - public static ImplicitCompositionAnimationCollection GetHideAnimations(UIElement element) - { - var collection = (ImplicitCompositionAnimationCollection)element.GetValue(HideAnimationsProperty); - - if (collection is null) - { - element.SetValue(HideAnimationsProperty, collection = new()); - } - - return collection; - } - - /// - /// Sets the value of the property. - /// - /// The to set the value for. - /// The value to set. - public static void SetHideAnimations(UIElement element, ImplicitCompositionAnimationCollection value) - { - element.SetValue(HideAnimationsProperty, value); - } - - /// - /// Gets the value of the property. - /// - /// The to get the value for. - /// The retrieved value. - public static ImplicitCompositionAnimationCollection GetAnimations(UIElement element) - { - var collection = (ImplicitCompositionAnimationCollection)element.GetValue(AnimationsProperty); - - if (collection is null) - { - element.SetValue(AnimationsProperty, collection = new()); - } - - return collection; - } - - /// - /// Sets the value of the property. - /// - /// The to set the value for. - /// The value to set. - public static void SetAnimations(UIElement element, ImplicitCompositionAnimationCollection value) - { - element.SetValue(AnimationsProperty, value); - } - - /// - /// Callback to keep the attached parent in sync for animations linked to the property. - /// - /// The target object the property was changed for. - /// The instance for the current event. - private static void OnShowAnimationsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - static void OnAnimationsChanged(object sender, EventArgs e) - { - var collection = (ImplicitCompositionAnimationCollection)sender; - - if (collection.ParentReference!.TryGetTarget(out UIElement element)) - { - ElementCompositionPreview.SetImplicitShowAnimation(element, collection.GetCompositionAnimationGroup()); - } - } - - if (e.OldValue is ImplicitCompositionAnimationCollection oldCollection) - { - oldCollection.AnimationsChanged -= OnAnimationsChanged; - } - - if (d is UIElement element && - e.NewValue is ImplicitCompositionAnimationCollection collection) - { - collection.ParentReference = new(element); - collection.AnimationsChanged -= OnAnimationsChanged; - collection.AnimationsChanged += OnAnimationsChanged; - - ElementCompositionPreview.SetImplicitShowAnimation(element, collection.GetCompositionAnimationGroup()); - } - } - - /// - /// Callback to keep the attached parent in sync for animations linked to the property. - /// - /// The target object the property was changed for. - /// The instance for the current event. - private static void OnHideAnimationsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - static void OnAnimationsChanged(object sender, EventArgs e) - { - var collection = (ImplicitCompositionAnimationCollection)sender; - - if (collection.ParentReference!.TryGetTarget(out UIElement element)) - { - ElementCompositionPreview.SetImplicitHideAnimation(element, collection.GetCompositionAnimationGroup()); - } - } - - if (e.OldValue is ImplicitCompositionAnimationCollection oldCollection) - { - oldCollection.AnimationsChanged -= OnAnimationsChanged; - } - - if (d is UIElement element && - e.NewValue is ImplicitCompositionAnimationCollection collection) - { - collection.ParentReference = new(element); - collection.AnimationsChanged -= OnAnimationsChanged; - collection.AnimationsChanged += OnAnimationsChanged; - - ElementCompositionPreview.SetImplicitHideAnimation(element, collection.GetCompositionAnimationGroup()); - } - } - - /// - /// Callback to keep the attached parent in sync for animations linked to the property. - /// - /// The target object the property was changed for. - /// The instance for the current event. - private static void OnAnimationsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - static void OnAnimationsChanged(object sender, EventArgs e) - { - var collection = (ImplicitCompositionAnimationCollection)sender; - - if (collection.ParentReference!.TryGetTarget(out UIElement element)) - { - ElementCompositionPreview.GetElementVisual(element).ImplicitAnimations = collection.GetImplicitAnimationCollection(); - } - } - - if (e.OldValue is ImplicitCompositionAnimationCollection oldCollection) - { - oldCollection.AnimationsChanged -= OnAnimationsChanged; - } - - if (d is UIElement element && - e.NewValue is ImplicitCompositionAnimationCollection collection) - { - collection.ParentReference = new(element); - collection.AnimationsChanged -= OnAnimationsChanged; - collection.AnimationsChanged += OnAnimationsChanged; - - ElementCompositionPreview.GetElementVisual(element).ImplicitAnimations = collection.GetImplicitAnimationCollection(); - } - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationDictionary.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationDictionary.cs index cabd7e1829a..cf1483c933a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationDictionary.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationDictionary.cs @@ -14,12 +14,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// A collection of animations that can be defined from XAML. /// - public sealed class AnimationDictionary : DependencyObject, IList + public sealed class AnimationDictionary : DependencyObject, IList { /// /// The underlying list of animations. /// - private readonly List list = new(); + private readonly List list = new(); /// /// The reference to the parent that owns the current animation dictionary. @@ -49,7 +49,7 @@ internal UIElement? Parent public bool IsReadOnly => false; /// - public AnimationCollection2 this[int index] + public AnimationSet this[int index] { get => this.list[index]; set @@ -62,7 +62,7 @@ public AnimationCollection2 this[int index] } /// - public void Add(AnimationCollection2 item) + public void Add(AnimationSet item) { this.list.Add(item); @@ -81,19 +81,19 @@ public void Clear() } /// - public bool Contains(AnimationCollection2 item) + public bool Contains(AnimationSet item) { return this.list.Contains(item); } /// - public void CopyTo(AnimationCollection2[] array, int arrayIndex) + public void CopyTo(AnimationSet[] array, int arrayIndex) { this.list.CopyTo(array, arrayIndex); } /// - public IEnumerator GetEnumerator() + public IEnumerator GetEnumerator() { return this.list.GetEnumerator(); } @@ -105,13 +105,13 @@ IEnumerator IEnumerable.GetEnumerator() } /// - public int IndexOf(AnimationCollection2 item) + public int IndexOf(AnimationSet item) { return this.list.IndexOf(item); } /// - public void Insert(int index, AnimationCollection2 item) + public void Insert(int index, AnimationSet item) { this.list.Insert(index, item); @@ -119,7 +119,7 @@ public void Insert(int index, AnimationCollection2 item) } /// - public bool Remove(AnimationCollection2 item) + public bool Remove(AnimationSet item) { bool removed = this.list.Remove(item); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs similarity index 98% rename from Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs rename to Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs index 55b33b25e25..d4832b69479 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationCollection2.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs @@ -19,7 +19,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// (such as ) that can be executed on a given element. /// [ContentProperty(Name = nameof(Animations))] - public sealed class AnimationCollection2 : DependencyObject + public sealed class AnimationSet : DependencyObject { /// /// Raised whenever the current animation is started. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitCompositionAnimationCollection.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs similarity index 98% rename from Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitCompositionAnimationCollection.cs rename to Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs index 104ad954920..1d428c74e84 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitCompositionAnimationCollection.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs @@ -18,7 +18,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// A collection of implicit animations that can be grouped together. This type represents a composite animation /// (such as ) that is executed on a given element. /// - public sealed class ImplicitCompositionAnimationCollection : Collection + public sealed class ImplicitAnimationSet : Collection { /// /// Raised whenever the contained animations are changed. diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs index 3f96634f6a4..546630afd72 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs @@ -4,20 +4,20 @@ #nullable enable -using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; +using Microsoft.Toolkit.Uwp.UI.Animations; using Microsoft.Xaml.Interactivity; namespace Microsoft.Toolkit.Uwp.UI.Behaviors.Animations { /// - /// A custom that fires whenever a linked ends. + /// A custom that fires whenever a linked ends. /// - public sealed class AnimationEndBehavior : Trigger + public sealed class AnimationEndBehavior : Trigger { /// - /// The current instance in use. + /// The current instance in use. /// - private AnimationCollection2? animationCollection; + private AnimationSet? animationCollection; /// protected override void OnAttached() @@ -36,10 +36,10 @@ protected override void OnDetaching() } /// - /// Sets the current instance in use. + /// Sets the current instance in use. /// - /// The instance in use. - private void SetResolvedCollection(AnimationCollection2? animationCollection) + /// The instance in use. + private void SetResolvedCollection(AnimationSet? animationCollection) { if (this.animationCollection == animationCollection) { @@ -62,7 +62,7 @@ private void SetResolvedCollection(AnimationCollection2? animationCollection) /// /// Invokes the current actions when the linked animations completes. /// - /// The source instance. + /// The source instance. /// The arguments for the event (unused). private void AnimationCollection_Ended(object sender, System.EventArgs e) { diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs index fd49c019068..ceb6e6e6cf8 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs @@ -4,20 +4,20 @@ #nullable enable -using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; +using Microsoft.Toolkit.Uwp.UI.Animations; using Microsoft.Xaml.Interactivity; namespace Microsoft.Toolkit.Uwp.UI.Behaviors.Animations { /// - /// A custom that fires whenever a linked starts. + /// A custom that fires whenever a linked starts. /// - public sealed class AnimationStartBehavior : Trigger + public sealed class AnimationStartBehavior : Trigger { /// - /// The current instance in use. + /// The current instance in use. /// - private AnimationCollection2? animationCollection; + private AnimationSet? animationCollection; /// protected override void OnAttached() @@ -36,10 +36,10 @@ protected override void OnDetaching() } /// - /// Sets the current instance in use. + /// Sets the current instance in use. /// - /// The instance in use. - private void SetResolvedCollection(AnimationCollection2? animationCollection) + /// The instance in use. + private void SetResolvedCollection(AnimationSet? animationCollection) { if (this.animationCollection == animationCollection) { @@ -62,7 +62,7 @@ private void SetResolvedCollection(AnimationCollection2? animationCollection) /// /// Invokes the current actions when the linked animations starts. /// - /// The source instance. + /// The source instance. /// The arguments for the event (unused). private void AnimationCollection_Started(object sender, System.EventArgs e) { diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs index 41608115529..9908ae0a120 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs @@ -3,23 +3,23 @@ // See the LICENSE file in the project root for more information. using Microsoft.Toolkit.Diagnostics; -using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; +using Microsoft.Toolkit.Uwp.UI.Animations; using Microsoft.Xaml.Interactivity; using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Behaviors.Animations { /// - /// An implementation that can trigger a target instance. + /// An implementation that can trigger a target instance. /// public sealed class StartAnimationAction : DependencyObject, IAction { /// - /// Gets or sets the linked instance to invoke. + /// Gets or sets the linked instance to invoke. /// - public AnimationCollection2 Animation + public AnimationSet Animation { - get => (AnimationCollection2)GetValue(AnimationProperty); + get => (AnimationSet)GetValue(AnimationProperty); set => SetValue(AnimationProperty, value); } @@ -28,7 +28,7 @@ public AnimationCollection2 Animation /// public static readonly DependencyProperty AnimationProperty = DependencyProperty.Register( "Animation", - typeof(AnimationCollection2), + typeof(AnimationSet), typeof(StartAnimationAction), new PropertyMetadata(null)); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs index 8a365c431c0..72e0f770274 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs @@ -6,7 +6,6 @@ using Microsoft.Graphics.Canvas.Effects; using Microsoft.Toolkit.Uwp.UI.Animations; using Microsoft.Toolkit.Uwp.UI.Animations.Extensions; -using Microsoft.Toolkit.Uwp.UI.Animations.Xaml; using Microsoft.Toolkit.Uwp.UI.Media.Effects; using Windows.UI.Composition; using Windows.UI.Xaml.Media.Animation; From d103248e533698b8844c5af68610725dff3320ce Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 26 Dec 2020 00:13:29 +0100 Subject: [PATCH 091/171] Minor code tweaks --- .../Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs | 12 +++++++++++- .../Xaml/KeyFrames/QuaternionKeyFrame.cs | 14 +++----------- .../Xaml/KeyFrames/ScalarKeyFrame.cs | 8 +++----- .../Xaml/KeyFrames/Vector2KeyFrame.cs | 7 +++---- .../Xaml/KeyFrames/Vector3KeyFrame.cs | 7 +++---- .../Xaml/KeyFrames/Vector4KeyFrame.cs | 7 +++---- 6 files changed, 26 insertions(+), 29 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs index d5588e6c1d9..feaf0757b6b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations { @@ -57,6 +58,15 @@ public static INormalizedKeyFrameAnimationBuilder AppendToBuilder(INo } /// - public abstract INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder); + public INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder) + { + return builder.KeyFrame(Key, GetParsedValue()!, EasingType ?? DefaultEasingType, EasingMode ?? DefaultEasingMode); + } + + /// + /// Gets the parsed values for . + /// + /// The parsed keyframe values a . + protected abstract TKeyFrame? GetParsedValue(); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/QuaternionKeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/QuaternionKeyFrame.cs index fb6954198c9..97ad030e566 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/QuaternionKeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/QuaternionKeyFrame.cs @@ -3,9 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Numerics; -using System.Runtime.CompilerServices; using Microsoft.Toolkit.Uwp.UI.Extensions; -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; #nullable enable @@ -14,18 +12,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// A type for animations. /// - public class QuaternionKeyFrame : KeyFrame + public sealed class QuaternionKeyFrame : KeyFrame { /// - public override INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder) + protected override Quaternion GetParsedValue() { - Vector4 vector = Value!.ToVector4(); - - return builder.KeyFrame( - Key, - Unsafe.As(ref vector), - EasingType ?? DefaultEasingType, - EasingMode ?? DefaultEasingMode); + return Value!.ToQuaternion(); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ScalarKeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ScalarKeyFrame.cs index d947d835e19..61fbb8fbfc2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ScalarKeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ScalarKeyFrame.cs @@ -2,19 +2,17 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; - namespace Microsoft.Toolkit.Uwp.UI.Animations { /// /// A type for scalar animations. /// - public class ScalarKeyFrame : KeyFrame + public sealed class ScalarKeyFrame : KeyFrame { /// - public override INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder) + protected override double GetParsedValue() { - return builder.KeyFrame(Key, Value!, EasingType ?? DefaultEasingType, EasingMode ?? DefaultEasingMode); + return Value!.Value; } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs index 9a4fc96b393..dd62fca4577 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector2KeyFrame.cs @@ -4,7 +4,6 @@ using System.Numerics; using Microsoft.Toolkit.Uwp.UI.Extensions; -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; #nullable enable @@ -13,12 +12,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// A type for animations. /// - public class Vector2KeyFrame : KeyFrame + public sealed class Vector2KeyFrame : KeyFrame { /// - public override INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder) + protected override Vector2 GetParsedValue() { - return builder.KeyFrame(Key, Value!.ToVector2(), EasingType ?? DefaultEasingType, EasingMode ?? DefaultEasingMode); + return Value!.ToVector2(); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs index 6da3d2ff917..7db405372ef 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector3KeyFrame.cs @@ -4,7 +4,6 @@ using System.Numerics; using Microsoft.Toolkit.Uwp.UI.Extensions; -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; #nullable enable @@ -13,12 +12,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// A type for animations. /// - public class Vector3KeyFrame : KeyFrame + public sealed class Vector3KeyFrame : KeyFrame { /// - public override INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder) + protected override Vector3 GetParsedValue() { - return builder.KeyFrame(Key, Value!.ToVector3(), EasingType ?? DefaultEasingType, EasingMode ?? DefaultEasingMode); + return Value!.ToVector3(); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs index b05bad728f3..cba7c1b197b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/Vector4KeyFrame.cs @@ -4,7 +4,6 @@ using System.Numerics; using Microsoft.Toolkit.Uwp.UI.Extensions; -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; #nullable enable @@ -13,12 +12,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// A type for animations. /// - public class Vector4KeyFrame : KeyFrame + public sealed class Vector4KeyFrame : KeyFrame { /// - public override INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder) + protected override Vector4 GetParsedValue() { - return builder.KeyFrame(Key, Value!.ToVector4(), EasingType ?? DefaultEasingType, EasingMode ?? DefaultEasingMode); + return Value!.ToVector4(); } } } From b3bdfd150a5cf5f4502938cab80fce7971cab298 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 26 Dec 2020 00:16:34 +0100 Subject: [PATCH 092/171] Added expression support to keyframes --- .../Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs index feaf0757b6b..2546e5714e9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs @@ -31,6 +31,12 @@ public abstract class KeyFrame : IKeyFrame /// public TValue? Value { get; set; } + /// + /// Gets or sets the optional expression for the current keyframe. + /// If this is set, will be ignored. + /// + public string? Expression { get; set; } + /// /// Gets or sets the optional easing function type for the keyframe. /// @@ -60,6 +66,11 @@ public static INormalizedKeyFrameAnimationBuilder AppendToBuilder(INo /// public INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder) { + if (Expression is not null) + { + return builder.ExpressionKeyFrame(Key, Expression, EasingType ?? DefaultEasingType, EasingMode ?? DefaultEasingMode); + } + return builder.KeyFrame(Key, GetParsedValue()!, EasingType ?? DefaultEasingType, EasingMode ?? DefaultEasingMode); } From 060b154a1ae1c3a3e807a08d96b82f781bbe6db9 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 26 Dec 2020 01:26:04 +0100 Subject: [PATCH 093/171] Fixed an incorrect XML summary cref reference --- .../Builders/AnimationBuilder.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs index 87d85875906..b63c68ccca5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs @@ -34,8 +34,8 @@ private AnimationBuilder() /// For instance: /// /// AnimationBuilder.Create()
- /// .Opacity(from: 0, to: 1, duration: 400)
- /// .Translation(Axis.X, from: -40, to: 0, duration: 400)
+ /// .Opacity(from: 0, to: 1)
+ /// .Translation(Axis.X, from: -40, to: 0)
/// .Start(MyButton); ///
/// @@ -44,13 +44,13 @@ private AnimationBuilder() /// /// For instance: /// - /// var animation = AnimationBuilder.Create().Opacity(0, 1, duration: 400).Size(1.2, 1, duration: 400);
+ /// var animation = AnimationBuilder.Create().Opacity(0, 1).Size(1.2, 1);
///
/// animation.Start(MyButton);
/// animation.Start(MyGrid); ///
- /// Alternatively, the type can be used to configure animations directly - /// from XAML. The same APIs will still be used behind the scenes to handle animations. + /// Alternatively, the type can be used to configure animations directly from XAML. + /// The same APIs will still be used behind the scenes to handle animations. ///
/// An empty instance to use to construct an animation sequence. [Pure] From d963d11cef7136150810771288069ba3dd7b1d2d Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 26 Dec 2020 02:09:02 +0100 Subject: [PATCH 094/171] Updated default easing parameters --- .../Enums/EasingType.cs | 4 +++- .../Extensions/AnimationExtensions.cs | 8 ++++++-- .../Extensions/CompositorExtensions.cs | 5 ----- .../Extensions/EasingTypeExtensions.cs | 14 +++++++++----- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Enums/EasingType.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Enums/EasingType.cs index b0c1b5a1f42..7ffaa901aca 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Enums/EasingType.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Enums/EasingType.cs @@ -10,7 +10,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations public enum EasingType { /// - /// The default easing type, which is specified in which is by default . + /// The default easing type, which is specified in . + /// Animations using this easing type follow the guidelines mentioned in the "Timing and easing" section of the docs. + /// For more info, see: . /// Default, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs index d115669f336..2e6b3ae853c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/AnimationExtensions.cs @@ -27,18 +27,22 @@ public static class AnimationExtensions /// /// The default value used for animations. /// - public const EasingType DefaultEasingType = EasingType.Cubic; + public const EasingType DefaultEasingType = EasingType.Default; /// /// The default value used for animations. /// - public const EasingMode DefaultEasingMode = EasingMode.EaseOut; + public const EasingMode DefaultEasingMode = EasingMode.EaseInOut; /// /// The reusable mapping of control points for easing curves for combinations of and values. /// internal static readonly Dictionary<(EasingType Type, EasingMode Mode), (Vector2 A, Vector2 B)> EasingMaps = new() { + [(EasingType.Default, EasingMode.EaseOut)] = (new(0.1f, 0.9f), new(0.2f, 1.0f)), + [(EasingType.Default, EasingMode.EaseIn)] = (new(0.7f, 0.0f), new(1.0f, 0.5f)), + [(EasingType.Default, EasingMode.EaseInOut)] = (new(0.8f, 0.0f), new(0.2f, 1.0f)), + [(EasingType.Cubic, EasingMode.EaseOut)] = (new(0.215f, 0.61f), new(0.355f, 1f)), [(EasingType.Cubic, EasingMode.EaseIn)] = (new(0.55f, 0.055f), new(0.675f, 0.19f)), [(EasingType.Cubic, EasingMode.EaseInOut)] = (new(0.645f, 0.045f), new(0.355f, 1f)), diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs index 6aafc14fbb2..3bf0a28f1af 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs @@ -34,11 +34,6 @@ public static CompositionEasingFunction CreateEasingFunction(this Compositor com return compositor.CreateLinearEasingFunction(); } - if (easingType == EasingType.Default) - { - easingType = DefaultEasingType; - } - var (a, b) = EasingMaps[(easingType, easingMode)]; return compositor.CreateCubicBezierEasingFunction(a, b); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/EasingTypeExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/EasingTypeExtensions.cs index 57fb05749b5..96580c8d000 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/EasingTypeExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/EasingTypeExtensions.cs @@ -24,14 +24,17 @@ public static class EasingTypeExtensions [Pure] public static EasingFunctionBase? ToEasingFunction(this EasingType easingType, EasingMode easingMode) { - if (easingType == EasingType.Default) - { - easingType = AnimationExtensions.DefaultEasingType; - } - return easingType switch { EasingType.Linear => null, + + EasingType.Default when easingMode == EasingMode.EaseIn + => new ExponentialEase { Exponent = 4.5, EasingMode = EasingMode.EaseIn }, + EasingType.Default when easingMode == EasingMode.EaseOut + => new ExponentialEase { Exponent = 7, EasingMode = EasingMode.EaseOut }, + EasingType.Default when easingMode == EasingMode.EaseInOut + => new CircleEase { EasingMode = EasingMode.EaseInOut }, + EasingType.Cubic => new CubicEase { EasingMode = easingMode }, EasingType.Back => new BackEase { EasingMode = easingMode }, EasingType.Bounce => new BounceEase { EasingMode = easingMode }, @@ -41,6 +44,7 @@ public static class EasingTypeExtensions EasingType.Quartic => new QuarticEase { EasingMode = easingMode }, EasingType.Quintic => new QuinticEase { EasingMode = easingMode }, EasingType.Sine => new SineEase { EasingMode = easingMode }, + _ => ThrowHelper.ThrowArgumentException("Invalid easing type") }; } From 9b5f4d2a1de24f8c0a9e4a9544d5c03bafef8d57 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 26 Dec 2020 02:30:32 +0100 Subject: [PATCH 095/171] Updated ReorderGridAnimation type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✅ Lowered target type to just ListViewBase ✅ Switched property type to TimeSpan ✅ Renamed owner type to ItemsReorderAnimation --- .../ItemsReorderAnimation.cs | 165 ++++++++++++++++++ .../ReorderGridAnimation.cs | 130 -------------- 2 files changed, 165 insertions(+), 130 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/ItemsReorderAnimation.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/ReorderGridAnimation.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/ItemsReorderAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/ItemsReorderAnimation.cs new file mode 100644 index 00000000000..efb1ff1880a --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/ItemsReorderAnimation.cs @@ -0,0 +1,165 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Windows.ApplicationModel; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Hosting; + +#nullable enable + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// Provides the ability to assign a reorder animation to a . + /// + public static class ItemsReorderAnimation + { + /// + /// Identifies the attached "Duration" . + /// + public static readonly DependencyProperty DurationProperty = DependencyProperty.RegisterAttached( + "Duration", + typeof(TimeSpan), + typeof(ItemsReorderAnimation), + new PropertyMetadata(TimeSpan.Zero, OnDurationChanged)); + + /// + /// Identifies the attached "ReorderAnimation" . + /// + private static readonly DependencyProperty ReorderAnimationProperty = DependencyProperty.RegisterAttached( + "ReorderAnimation", + typeof(ImplicitAnimationCollection), + typeof(ItemsReorderAnimation), + new PropertyMetadata(null)); + + /// + /// Gets the value of the property. + /// + /// The to get the value for. + /// The retrieved value. + public static TimeSpan GetDuration(ListViewBase listView) + { + return (TimeSpan)listView.GetValue(DurationProperty); + } + + /// + /// Sets a value for the duration, in milliseconds, the animation should take. + /// + /// the object to set the value on. + /// The duration. + public static void SetDuration(ListViewBase listView, TimeSpan value) + { + listView.SetValue(DurationProperty, value); + } + + /// + /// Callback to apply the reorder animation when changes. + /// + /// The target object the property was changed for. + /// The instance for the current event. + private static void OnDurationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (DesignMode.DesignModeEnabled) + { + return; + } + + if (d is ListViewBase listView && e.NewValue is TimeSpan duration) + { + AssignReorderAnimation(listView, duration); + + listView.ContainerContentChanging -= OnContainerContentChanging; + listView.ContainerContentChanging += OnContainerContentChanging; + + listView.ChoosingItemContainer -= OnChoosingItemContainer; + listView.ChoosingItemContainer += OnChoosingItemContainer; + } + } + + /// + /// Updates the reorder animation for a target instance. + /// + /// The target instance. + /// The duration of the animation. + private static void AssignReorderAnimation(ListViewBase listView, TimeSpan duration) + { + Compositor compositor = ElementCompositionPreview.GetElementVisual(listView).Compositor; + ImplicitAnimationCollection animationCollection = (ImplicitAnimationCollection)listView.GetValue(ReorderAnimationProperty); + + if (animationCollection is null) + { + animationCollection = compositor.CreateImplicitAnimationCollection(); + + listView.SetValue(ReorderAnimationProperty, animationCollection); + } + + if (duration == TimeSpan.Zero) + { + animationCollection.Remove(nameof(Visual.Offset)); + } + else + { + Vector3KeyFrameAnimation offsetAnimation = compositor.CreateVector3KeyFrameAnimation(); + + offsetAnimation.InsertExpressionKeyFrame(1.0f, "this.FinalValue"); + offsetAnimation.Duration = duration; + offsetAnimation.Target = nameof(Visual.Offset); + + CompositionAnimationGroup animationGroup = compositor.CreateAnimationGroup(); + + animationGroup.Add(offsetAnimation); + + animationCollection[nameof(Visual.Offset)] = animationGroup; + } + } + + /// + /// Updates the reorder animation to each container, whenever one changes. + /// + /// The sender instance. + /// The instance for the current container change. + private static void OnContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args) + { + if (args.InRecycleQueue) + { + PokeUIElementZIndex(args.ItemContainer); + } + else + { + Visual visual = ElementCompositionPreview.GetElementVisual(args.ItemContainer); + ImplicitAnimationCollection? animationCollection = sender.GetValue(ReorderAnimationProperty) as ImplicitAnimationCollection; + + visual.ImplicitAnimations = animationCollection; + } + } + + /// + /// Pokes the Z index of each container when one is chosen, to ensure animations are displayed correctly. + /// + /// The sender instance. + /// The instance for the current container event. + private static void OnChoosingItemContainer(ListViewBase sender, ChoosingItemContainerEventArgs args) + { + if (args.ItemContainer is not null) + { + PokeUIElementZIndex(args.ItemContainer); + } + } + + /// + /// Pokes the Z index of a target . + /// + /// The target to poke the Z index for. + private static void PokeUIElementZIndex(UIElement element) + { + int oldZIndex = Canvas.GetZIndex(element); + + Canvas.SetZIndex(element, oldZIndex + 1); + Canvas.SetZIndex(element, oldZIndex); + } + } +} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/ReorderGridAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/ReorderGridAnimation.cs deleted file mode 100644 index f05d5b1d46c..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Animations/ReorderGridAnimation.cs +++ /dev/null @@ -1,130 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using Windows.UI.Composition; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Hosting; - -namespace Microsoft.Toolkit.Uwp.UI.Animations -{ - /// - /// Provides the ability to assign a reorder animation to a GridView. - /// - public class ReorderGridAnimation - { - private static readonly DependencyProperty ReorderAnimationProperty = - DependencyProperty.RegisterAttached("ReorderAnimation", typeof(bool), typeof(ImplicitAnimationCollection), new PropertyMetadata(null)); - - /// - /// Identifies the Duration attached dependency property. - /// - /// The identifier for the Duration attached dependency property. - public static readonly DependencyProperty DurationProperty = DependencyProperty.RegisterAttached("Duration", typeof(double), typeof(ReorderGridAnimation), new PropertyMetadata(double.NaN, OnDurationChanged)); - - /// - /// Gets a value indicating the duration, in milliseconds, the animation should take. - /// - /// The object to get the value from. - /// A value indicating the duration for the animation. - public static double GetDuration(DependencyObject obj) - { - return (double)obj.GetValue(DurationProperty); - } - - /// - /// Sets a value for the duration, in milliseconds, the animation should take. - /// - /// the object to set the value on. - /// The duration in milliseconds. - public static void SetDuration(DependencyObject obj, double value) - { - obj.SetValue(DurationProperty, value); - } - - private static void OnDurationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - if (Windows.ApplicationModel.DesignMode.DesignModeEnabled) - { - return; - } - - GridView view = d as GridView; - if (view != null) - { - AssignReorderAnimation(view); - - view.ContainerContentChanging -= OnContainerContentChanging; - view.ContainerContentChanging += OnContainerContentChanging; - - view.ChoosingItemContainer -= OnChoosingItemContainer; - view.ChoosingItemContainer += OnChoosingItemContainer; - } - } - - private static void AssignReorderAnimation(GridView view) - { - var compositor = ElementCompositionPreview.GetElementVisual(view).Compositor; - var elementImplicitAnimation = view.GetValue(ReorderAnimationProperty) as ImplicitAnimationCollection; - if (elementImplicitAnimation == null) - { - elementImplicitAnimation = compositor.CreateImplicitAnimationCollection(); - view.SetValue(ReorderAnimationProperty, elementImplicitAnimation); - } - - double duration = (double)view.GetValue(DurationProperty); - if (double.IsNaN(duration)) - { - elementImplicitAnimation.Remove(nameof(Visual.Offset)); - } - else - { - elementImplicitAnimation[nameof(Visual.Offset)] = CreateOffsetAnimation(compositor, duration); - } - } - - private static void OnContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args) - { - var elementVisual = ElementCompositionPreview.GetElementVisual(args.ItemContainer); - if (args.InRecycleQueue) - { - PokeUIElementZIndex(args.ItemContainer); - } - else - { - var elementImplicitAnimation = sender.GetValue(ReorderAnimationProperty) as ImplicitAnimationCollection; - elementVisual.ImplicitAnimations = elementImplicitAnimation; - } - } - - private static void OnChoosingItemContainer(ListViewBase sender, ChoosingItemContainerEventArgs args) - { - if (args.ItemContainer != null) - { - PokeUIElementZIndex(args.ItemContainer); - } - } - - private static CompositionAnimationGroup CreateOffsetAnimation(Compositor compositor, double duration) - { - Vector3KeyFrameAnimation offsetAnimation = compositor.CreateVector3KeyFrameAnimation(); - offsetAnimation.InsertExpressionKeyFrame(1.0f, "this.FinalValue"); - offsetAnimation.Duration = TimeSpan.FromMilliseconds(duration); - offsetAnimation.Target = nameof(Visual.Offset); - - CompositionAnimationGroup animationGroup = compositor.CreateAnimationGroup(); - animationGroup.Add(offsetAnimation); - - return animationGroup; - } - - private static void PokeUIElementZIndex(UIElement element) - { - var oldZIndex = Canvas.GetZIndex(element); - Canvas.SetZIndex(element, oldZIndex + 1); - Canvas.SetZIndex(element, oldZIndex); - } - } -} \ No newline at end of file From d05027d547d3fde1c2f088e8a71570f391232873 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 26 Dec 2020 19:35:17 +0100 Subject: [PATCH 096/171] Minor code tweaks --- .../Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs | 10 +++++----- .../Xaml/Default/ClipAnimation.cs | 2 +- .../Xaml/Default/OffsetAnimation.cs | 4 ++-- .../Xaml/Default/OpacityAnimation.cs | 4 ++-- .../Xaml/Default/OrientationAnimation.cs | 4 ++-- .../Xaml/Default/RotationAnimation.cs | 4 ++-- .../Xaml/Default/RotationInDegreesAnimation.cs | 4 ++-- .../Xaml/Default/ScaleAnimation.cs | 4 ++-- .../Xaml/Default/SizeAnimation.cs | 4 ++-- .../Xaml/Default/TranslationAnimation.cs | 4 ++-- 10 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs index 63271b5c848..7555438d0b3 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs @@ -19,20 +19,20 @@ public abstract class ImplicitAnimation : Animation - /// Gets or sets the optional implicit target for the animation. + /// Gets the explicit target for the animation. This is the primary target property that is animated. ///
- public string? ImplicitTarget { get; set; } + protected abstract string ExplicitTarget { get; } /// - /// Gets the target for the animation. + /// Gets or sets the optional implicit target for the animation. This can act as a trigger property for the animation. /// - protected abstract string Target { get; } + public string? ImplicitTarget { get; set; } /// public CompositionAnimation GetAnimation(UIElement element, out string? target) { NormalizedKeyFrameAnimationBuilder.Composition builder = new( - Target, + ExplicitTarget, Delay ?? DefaultDuration, Duration ?? DefaultDuration); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs index c36551a140d..075f4bed04c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// A clip animation working on the composition layer. /// - public class ClipAnimation : Animation + public sealed class ClipAnimation : Animation { /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs index 5ac35e56777..229071fbf79 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs @@ -14,10 +14,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// An offset animation working on the composition layer. /// - public class OffsetAnimation : ImplicitAnimation + public sealed class OffsetAnimation : ImplicitAnimation { /// - protected override string Target => nameof(Visual.Offset); + protected override string ExplicitTarget => nameof(Visual.Offset); /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs index 32c88837bc1..ea7c2eec4c3 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// An opacity animation working on the composition or XAML layer. /// - public class OpacityAnimation : ImplicitAnimation + public sealed class OpacityAnimation : ImplicitAnimation { /// /// Gets or sets the target framework layer to animate. @@ -20,7 +20,7 @@ public class OpacityAnimation : ImplicitAnimation public FrameworkLayer Layer { get; set; } /// - protected override string Target => nameof(Visual.Opacity); + protected override string ExplicitTarget => nameof(Visual.Opacity); /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs index 88b7c242dcd..76bd1dca1ba 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs @@ -14,10 +14,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// An orientation animation working on the composition layer. /// - public class OrientationAnimation : ImplicitAnimation + public sealed class OrientationAnimation : ImplicitAnimation { /// - protected override string Target => nameof(Visual.Orientation); + protected override string ExplicitTarget => nameof(Visual.Orientation); /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs index 03acef75aec..fa900a99791 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs @@ -12,10 +12,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// A rotation animation working on the composition or XAML layer. /// - public class RotationAnimation : ImplicitAnimation + public sealed class RotationAnimation : ImplicitAnimation { /// - protected override string Target => nameof(Visual.RotationAngle); + protected override string ExplicitTarget => nameof(Visual.RotationAngle); /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs index 67ad2d5e4e6..5eaeca174e9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// A rotation in degrees animation working on the composition or XAML layer. /// - public class RotationInDegreesAnimation : ImplicitAnimation + public sealed class RotationInDegreesAnimation : ImplicitAnimation { /// /// Gets or sets the target framework layer to animate. @@ -20,7 +20,7 @@ public class RotationInDegreesAnimation : ImplicitAnimation public FrameworkLayer Layer { get; set; } /// - protected override string Target => nameof(Visual.RotationAngleInDegrees); + protected override string ExplicitTarget => nameof(Visual.RotationAngleInDegrees); /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs index 85c4d03cdbb..1c5ceb3d5bb 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs @@ -14,7 +14,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// A scale animation working on the composition or XAML layer. /// - public class ScaleAnimation : ImplicitAnimation + public sealed class ScaleAnimation : ImplicitAnimation { /// /// Gets or sets the target framework layer to animate. @@ -22,7 +22,7 @@ public class ScaleAnimation : ImplicitAnimation public FrameworkLayer Layer { get; set; } /// - protected override string Target => nameof(Visual.Scale); + protected override string ExplicitTarget => nameof(Visual.Scale); /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs index 67f38b71174..dba609b9584 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs @@ -14,7 +14,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// A size animation working on the composition or XAML layer. /// - public class SizeAnimation : ImplicitAnimation + public sealed class SizeAnimation : ImplicitAnimation { /// /// Gets or sets the target framework layer to animate. @@ -22,7 +22,7 @@ public class SizeAnimation : ImplicitAnimation public FrameworkLayer Layer { get; set; } /// - protected override string Target => nameof(Visual.Size); + protected override string ExplicitTarget => nameof(Visual.Size); /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs index 8469f78e0d0..23f709ee0f6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs @@ -13,7 +13,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// A translation animation working on the composition or XAML layer. /// - public class TranslationAnimation : ImplicitAnimation + public sealed class TranslationAnimation : ImplicitAnimation { /// /// Gets or sets the target framework layer to animate. @@ -21,7 +21,7 @@ public class TranslationAnimation : ImplicitAnimation public FrameworkLayer Layer { get; set; } /// - protected override string Target => "Translation"; + protected override string ExplicitTarget => "Translation"; /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) From 7adb7c8bdb9db2278798515885c55a33547488a8 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 26 Dec 2020 20:30:48 +0100 Subject: [PATCH 097/171] Code refactoring, simplified default XAML animations --- .../Abstract/Animation{TValue,TKeyFrame}.cs | 58 +++++++++++++++++++ .../ImplicitAnimation{TValue,TKeyFrame}.cs | 11 ---- .../Abstract/KeyFrame{TValue,TKeyFrame}.cs | 17 ------ .../Xaml/Default/ClipAnimation.cs | 9 +++ .../Xaml/Default/OffsetAnimation.cs | 23 -------- .../Xaml/Default/OpacityAnimation.cs | 29 ---------- .../Xaml/Default/OrientationAnimation.cs | 23 -------- .../Xaml/Default/RotationAnimation.cs | 23 -------- .../Default/RotationInDegreesAnimation.cs | 29 ---------- .../Xaml/Default/ScaleAnimation.cs | 40 ------------- .../Xaml/Default/SizeAnimation.cs | 40 ------------- .../Xaml/Default/TranslationAnimation.cs | 40 ------------- .../Animations/EffectDoubleAnimation.cs | 11 +++- 13 files changed, 77 insertions(+), 276 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs index 80e1cdba87b..ce5260fd0d2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs @@ -4,8 +4,11 @@ #nullable enable +using System; using System.Collections.Generic; using Windows.UI.Xaml.Markup; +using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations { @@ -36,5 +39,60 @@ public abstract class Animation : Animation /// Setting this will overwrite the and values. /// public IList> KeyFrames { get; set; } = new List>(); + + /// + /// Gets the explicit target for the animation. This is the primary target property that is animated. + /// + protected abstract string ExplicitTarget { get; } + + /// + public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + { + return builder.NormalizedKeyFrames( + property: ExplicitTarget, + delay: Delay ?? delayHint, + duration: Duration ?? durationHint, + build: b => AppendToBuilder(b, easingTypeHint, easingModeHint)); + } + + /// + /// Gets the parsed values from . + /// + /// The parsed animation values as . + protected abstract (TKeyFrame? To, TKeyFrame? From) GetParsedValues(); + + /// + /// Appends the current keyframe values to a target instance. + /// This method will also automatically generate keyframes for and . + /// + /// The target instance to add the keyframe to. + /// A hint for the easing type, if present. + /// A hint for the easing mode, if present. + /// The same instance as . + protected INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder, EasingType? easingTypeHint, EasingMode? easingModeHint) + { + foreach (var keyFrame in KeyFrames) + { + builder = keyFrame.AppendToBuilder(builder); + } + + var (to, from) = GetParsedValues(); + + if (to is not null) + { + builder.KeyFrame( + 1.0, + to.Value, + EasingType ?? easingTypeHint ?? DefaultEasingType, + EasingMode ?? easingModeHint ?? DefaultEasingMode); + } + + if (from is not null) + { + builder.KeyFrame(0.0, from.Value, default, default); + } + + return builder; + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs index 7555438d0b3..49d9a88fb0b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs @@ -18,11 +18,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations public abstract class ImplicitAnimation : Animation, IImplicitTimeline where TKeyFrame : unmanaged { - /// - /// Gets the explicit target for the animation. This is the primary target property that is animated. - /// - protected abstract string ExplicitTarget { get; } - /// /// Gets or sets the optional implicit target for the animation. This can act as a trigger property for the animation. /// @@ -71,11 +66,5 @@ public CompositionAnimation GetAnimation(UIElement element, out string? target) return builder.GetAnimation(element.GetVisual(), out _); } - - /// - /// Gets the parsed values from . - /// - /// The parsed animation values as . - protected abstract (TKeyFrame? To, TKeyFrame? From) GetParsedValues(); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs index 2546e5714e9..dfe37ce58a4 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs @@ -4,7 +4,6 @@ #nullable enable -using System.Collections.Generic; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -47,22 +46,6 @@ public abstract class KeyFrame : IKeyFrame /// public EasingMode? EasingMode { get; set; } - /// - /// Appends a sequence of instances to a target instance. - /// - /// The target instance to add the keyframe to. - /// The keyframes to append. - /// The same instance as . - public static INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder, IEnumerable> keyFrames) - { - foreach (var keyFrame in keyFrames) - { - builder = keyFrame.AppendToBuilder(builder); - } - - return builder; - } - /// public INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder) { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs index 075f4bed04c..8ca15c90a21 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs @@ -14,6 +14,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// public sealed class ClipAnimation : Animation { + /// + protected override string ExplicitTarget => throw new NotImplementedException(); + /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { @@ -25,5 +28,11 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS EasingType ?? easingTypeHint ?? DefaultEasingType, EasingMode ?? easingModeHint ?? DefaultEasingMode); } + + /// + protected override (Thickness? To, Thickness? From) GetParsedValues() + { + throw new NotImplementedException(); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs index 229071fbf79..da1e3a30bf9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs @@ -2,12 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Numerics; using Microsoft.Toolkit.Uwp.UI.Extensions; using Windows.UI.Composition; -using Windows.UI.Xaml.Media.Animation; -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations { @@ -19,26 +16,6 @@ public sealed class OffsetAnimation : ImplicitAnimation /// protected override string ExplicitTarget => nameof(Visual.Offset); - /// - public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) - { - if (KeyFrames.Count > 0) - { - return builder.Offset().NormalizedKeyFrames( - delay: Delay ?? delayHint, - duration: Duration ?? durationHint, - build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); - } - - return builder.Offset( - To!.ToVector3(), - From?.ToVector3(), - Delay ?? delayHint, - Duration ?? durationHint, - EasingType ?? easingTypeHint ?? DefaultEasingType, - EasingMode ?? easingModeHint ?? DefaultEasingMode); - } - /// protected override (Vector3? To, Vector3? From) GetParsedValues() { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs index ea7c2eec4c3..bbcee97c36b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs @@ -2,10 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using Windows.UI.Composition; -using Windows.UI.Xaml.Media.Animation; -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations { @@ -14,35 +11,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// public sealed class OpacityAnimation : ImplicitAnimation { - /// - /// Gets or sets the target framework layer to animate. - /// - public FrameworkLayer Layer { get; set; } - /// protected override string ExplicitTarget => nameof(Visual.Opacity); - /// - public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) - { - if (KeyFrames.Count > 0) - { - return builder.Opacity(Layer).NormalizedKeyFrames( - delay: Delay ?? delayHint, - duration: Duration ?? durationHint, - build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); - } - - return builder.Opacity( - To!.Value, - From, - Delay ?? delayHint, - Duration ?? durationHint, - EasingType ?? easingTypeHint ?? DefaultEasingType, - EasingMode ?? easingModeHint ?? DefaultEasingMode, - Layer); - } - /// protected override (double? To, double? From) GetParsedValues() { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs index 76bd1dca1ba..f50270adfbc 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs @@ -2,12 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Numerics; using Microsoft.Toolkit.Uwp.UI.Extensions; using Windows.UI.Composition; -using Windows.UI.Xaml.Media.Animation; -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations { @@ -19,26 +16,6 @@ public sealed class OrientationAnimation : ImplicitAnimation /// protected override string ExplicitTarget => nameof(Visual.Orientation); - /// - public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) - { - if (KeyFrames.Count > 0) - { - return builder.Orientation().NormalizedKeyFrames( - delay: Delay ?? delayHint, - duration: Duration ?? durationHint, - build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); - } - - return builder.Orientation( - To!.ToQuaternion(), - From?.ToQuaternion(), - Delay ?? delayHint, - Duration ?? durationHint, - EasingType ?? easingTypeHint ?? DefaultEasingType, - EasingMode ?? easingModeHint ?? DefaultEasingMode); - } - /// protected override (Quaternion? To, Quaternion? From) GetParsedValues() { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs index fa900a99791..fcbb3a403e1 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs @@ -2,10 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using Windows.UI.Composition; -using Windows.UI.Xaml.Media.Animation; -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations { @@ -17,26 +14,6 @@ public sealed class RotationAnimation : ImplicitAnimation /// protected override string ExplicitTarget => nameof(Visual.RotationAngle); - /// - public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) - { - if (KeyFrames.Count > 0) - { - return builder.Rotation().NormalizedKeyFrames( - delay: Delay ?? delayHint, - duration: Duration ?? durationHint, - build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); - } - - return builder.Rotation( - To!.Value, - From, - Delay ?? delayHint, - Duration ?? durationHint, - EasingType ?? easingTypeHint ?? DefaultEasingType, - EasingMode ?? easingModeHint ?? DefaultEasingMode); - } - /// protected override (double? To, double? From) GetParsedValues() { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs index 5eaeca174e9..be8357ed26d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs @@ -2,10 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using Windows.UI.Composition; -using Windows.UI.Xaml.Media.Animation; -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations { @@ -14,35 +11,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// public sealed class RotationInDegreesAnimation : ImplicitAnimation { - /// - /// Gets or sets the target framework layer to animate. - /// - public FrameworkLayer Layer { get; set; } - /// protected override string ExplicitTarget => nameof(Visual.RotationAngleInDegrees); - /// - public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) - { - if (KeyFrames.Count > 0) - { - return builder.RotationInDegrees(Layer).NormalizedKeyFrames( - delay: Delay ?? delayHint, - duration: Duration ?? durationHint, - build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); - } - - return builder.RotationInDegrees( - To!.Value, - From, - Delay ?? delayHint, - Duration ?? durationHint, - EasingType ?? easingTypeHint ?? DefaultEasingType, - EasingMode ?? easingModeHint ?? DefaultEasingMode, - Layer); - } - /// protected override (double? To, double? From) GetParsedValues() { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs index 1c5ceb3d5bb..1dc5879a836 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs @@ -2,12 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Numerics; using Microsoft.Toolkit.Uwp.UI.Extensions; using Windows.UI.Composition; -using Windows.UI.Xaml.Media.Animation; -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations { @@ -16,46 +13,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations ///
public sealed class ScaleAnimation : ImplicitAnimation { - /// - /// Gets or sets the target framework layer to animate. - /// - public FrameworkLayer Layer { get; set; } - /// protected override string ExplicitTarget => nameof(Visual.Scale); - /// - public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) - { - TimeSpan? delay = Delay ?? delayHint; - TimeSpan? duration = Duration ?? durationHint; - - if (KeyFrames.Count > 0) - { - return builder.Scale().NormalizedKeyFrames( - delay: Delay ?? delayHint, - duration: Duration ?? durationHint, - build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); - } - - Vector3 to = To!.ToVector3(); - Vector3? from = From?.ToVector3(); - EasingType easingType = EasingType ?? easingTypeHint ?? DefaultEasingType; - EasingMode easingMode = EasingMode ?? easingModeHint ?? DefaultEasingMode; - - if (Layer == FrameworkLayer.Composition) - { - return builder.Scale(to, from, delay, duration, easingType, easingMode); - } - else - { - Vector2 to2 = new(to.X, to.Y); - Vector2? from2 = from is null ? null : new(from.Value.X, from.Value.Y); - - return builder.Scale(to2, from2, delay, duration, easingType, easingMode, FrameworkLayer.Xaml); - } - } - /// protected override (Vector3? To, Vector3? From) GetParsedValues() { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs index dba609b9584..0e2cdc2802c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs @@ -2,12 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Numerics; using Microsoft.Toolkit.Uwp.UI.Extensions; using Windows.UI.Composition; -using Windows.UI.Xaml.Media.Animation; -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations { @@ -16,46 +13,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations ///
public sealed class SizeAnimation : ImplicitAnimation { - /// - /// Gets or sets the target framework layer to animate. - /// - public FrameworkLayer Layer { get; set; } - /// protected override string ExplicitTarget => nameof(Visual.Size); - /// - public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) - { - TimeSpan? delay = Delay ?? delayHint; - TimeSpan? duration = Duration ?? durationHint; - - if (KeyFrames.Count > 0) - { - return builder.Size().NormalizedKeyFrames( - delay: Delay ?? delayHint, - duration: Duration ?? durationHint, - build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); - } - - Vector3 to = To!.ToVector3(); - Vector3? from = From?.ToVector3(); - EasingType easingType = EasingType ?? easingTypeHint ?? DefaultEasingType; - EasingMode easingMode = EasingMode ?? easingModeHint ?? DefaultEasingMode; - - if (Layer == FrameworkLayer.Composition) - { - return builder.Size(to, from, delay, duration, easingType, easingMode); - } - else - { - Vector2 to2 = new(to.X, to.Y); - Vector2? from2 = from is null ? null : new(from.Value.X, from.Value.Y); - - return builder.Size(to2, from2, delay, duration, easingType, easingMode, FrameworkLayer.Xaml); - } - } - /// protected override (Vector3? To, Vector3? From) GetParsedValues() { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs index 23f709ee0f6..8f579ce7593 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs @@ -2,11 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Numerics; using Microsoft.Toolkit.Uwp.UI.Extensions; -using Windows.UI.Xaml.Media.Animation; -using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations { @@ -15,46 +12,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations ///
public sealed class TranslationAnimation : ImplicitAnimation { - /// - /// Gets or sets the target framework layer to animate. - /// - public FrameworkLayer Layer { get; set; } - /// protected override string ExplicitTarget => "Translation"; - /// - public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) - { - TimeSpan? delay = Delay ?? delayHint; - TimeSpan? duration = Duration ?? durationHint; - - if (KeyFrames.Count > 0) - { - return builder.Translation().NormalizedKeyFrames( - delay: Delay ?? delayHint, - duration: Duration ?? durationHint, - build: b => KeyFrame.AppendToBuilder(b, KeyFrames)); - } - - Vector3 to = To!.ToVector3(); - Vector3? from = From?.ToVector3(); - EasingType easingType = EasingType ?? easingTypeHint ?? DefaultEasingType; - EasingMode easingMode = EasingMode ?? easingModeHint ?? DefaultEasingMode; - - if (Layer == FrameworkLayer.Composition) - { - return builder.Translation(to, from, delay, duration, easingType, easingMode); - } - else - { - Vector2 to2 = new(to.X, to.Y); - Vector2? from2 = from is null ? null : new(from.Value.X, from.Value.Y); - - return builder.Translation(to2, from2, delay, duration, easingType, easingMode, FrameworkLayer.Xaml); - } - } - /// protected override (Vector3? To, Vector3? From) GetParsedValues() { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs index 72e0f770274..99b179e3ce2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/EffectDoubleAnimation.cs @@ -16,13 +16,16 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Animations /// /// A set of animations that can be grouped together. /// - public class EffectDoubleAnimation : Animation + public sealed class EffectDoubleAnimation : Animation { /// /// Gets or sets the linked instance to animate. /// public IPipelineEffect Target { get; set; } + /// + protected override string ExplicitTarget => throw new NotImplementedException(); + /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { @@ -40,5 +43,11 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS return builder.ExternalAnimation(effect.Brush, animation); } + + /// + protected override (double? To, double? From) GetParsedValues() + { + throw new NotImplementedException(); + } } } From dae4b0a469580325ed50f835cacdf138137f0932 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 26 Dec 2020 20:39:26 +0100 Subject: [PATCH 098/171] Minor code tweaks --- .../Xaml/Default/ClipAnimation.cs | 2 +- .../Xaml/Default/OffsetAnimation.cs | 2 +- .../Xaml/Default/OpacityAnimation.cs | 4 ++-- .../Xaml/Default/OrientationAnimation.cs | 2 +- .../Xaml/Default/RotationAnimation.cs | 4 ++-- .../Xaml/Default/RotationInDegreesAnimation.cs | 4 ++-- .../Xaml/Default/ScaleAnimation.cs | 4 ++-- .../Xaml/Default/SizeAnimation.cs | 4 ++-- .../Xaml/Default/TranslationAnimation.cs | 4 ++-- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs index 8ca15c90a21..d86006e6673 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ClipAnimation.cs @@ -30,7 +30,7 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS } /// - protected override (Thickness? To, Thickness? From) GetParsedValues() + protected override (Thickness?, Thickness?) GetParsedValues() { throw new NotImplementedException(); } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs index da1e3a30bf9..d5e24649ea4 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OffsetAnimation.cs @@ -17,7 +17,7 @@ public sealed class OffsetAnimation : ImplicitAnimation protected override string ExplicitTarget => nameof(Visual.Offset); /// - protected override (Vector3? To, Vector3? From) GetParsedValues() + protected override (Vector3?, Vector3?) GetParsedValues() { return (To?.ToVector3(), From?.ToVector3()); } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs index bbcee97c36b..16d477dd806 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OpacityAnimation.cs @@ -7,7 +7,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// An opacity animation working on the composition or XAML layer. + /// An opacity animation working on the composition or layer. /// public sealed class OpacityAnimation : ImplicitAnimation { @@ -15,7 +15,7 @@ public sealed class OpacityAnimation : ImplicitAnimation protected override string ExplicitTarget => nameof(Visual.Opacity); /// - protected override (double? To, double? From) GetParsedValues() + protected override (double?, double?) GetParsedValues() { return (To, From); } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs index f50270adfbc..6b5918971fe 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/OrientationAnimation.cs @@ -17,7 +17,7 @@ public sealed class OrientationAnimation : ImplicitAnimation protected override string ExplicitTarget => nameof(Visual.Orientation); /// - protected override (Quaternion? To, Quaternion? From) GetParsedValues() + protected override (Quaternion?, Quaternion?) GetParsedValues() { return (To?.ToQuaternion(), From?.ToQuaternion()); } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs index fcbb3a403e1..b542db91b8c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationAnimation.cs @@ -7,7 +7,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// A rotation animation working on the composition or XAML layer. + /// A rotation animation working on the composition or layer. /// public sealed class RotationAnimation : ImplicitAnimation { @@ -15,7 +15,7 @@ public sealed class RotationAnimation : ImplicitAnimation protected override string ExplicitTarget => nameof(Visual.RotationAngle); /// - protected override (double? To, double? From) GetParsedValues() + protected override (double?, double?) GetParsedValues() { return (To, From); } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs index be8357ed26d..946b3f318aa 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/RotationInDegreesAnimation.cs @@ -7,7 +7,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// A rotation in degrees animation working on the composition or XAML layer. + /// A rotation in degrees animation working on the composition or layer. /// public sealed class RotationInDegreesAnimation : ImplicitAnimation { @@ -15,7 +15,7 @@ public sealed class RotationInDegreesAnimation : ImplicitAnimation nameof(Visual.RotationAngleInDegrees); /// - protected override (double? To, double? From) GetParsedValues() + protected override (double?, double?) GetParsedValues() { return (To, From); } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs index 1dc5879a836..0ec6660364f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/ScaleAnimation.cs @@ -9,7 +9,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// A scale animation working on the composition or XAML layer. + /// A scale animation working on the composition or layer. /// public sealed class ScaleAnimation : ImplicitAnimation { @@ -17,7 +17,7 @@ public sealed class ScaleAnimation : ImplicitAnimation protected override string ExplicitTarget => nameof(Visual.Scale); /// - protected override (Vector3? To, Vector3? From) GetParsedValues() + protected override (Vector3?, Vector3?) GetParsedValues() { return (To?.ToVector3(), From?.ToVector3()); } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs index 0e2cdc2802c..3e75b3626a4 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/SizeAnimation.cs @@ -9,7 +9,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// A size animation working on the composition or XAML layer. + /// A size animation working on the composition or layer. /// public sealed class SizeAnimation : ImplicitAnimation { @@ -17,7 +17,7 @@ public sealed class SizeAnimation : ImplicitAnimation protected override string ExplicitTarget => nameof(Visual.Size); /// - protected override (Vector3? To, Vector3? From) GetParsedValues() + protected override (Vector3?, Vector3?) GetParsedValues() { return (To?.ToVector3(), From?.ToVector3()); } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs index 8f579ce7593..80626f63b7f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Default/TranslationAnimation.cs @@ -8,7 +8,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// A translation animation working on the composition or XAML layer. + /// A translation animation working on the composition or layer. /// public sealed class TranslationAnimation : ImplicitAnimation { @@ -16,7 +16,7 @@ public sealed class TranslationAnimation : ImplicitAnimation protected override string ExplicitTarget => "Translation"; /// - protected override (Vector3? To, Vector3? From) GetParsedValues() + protected override (Vector3?, Vector3?) GetParsedValues() { return (To?.ToVector3(), From?.ToVector3()); } From 2009eb6234b4d9e8f78ba787ef2e3d6fad077b77 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 26 Dec 2020 20:47:15 +0100 Subject: [PATCH 099/171] Added custom animation types --- .../CustomAnimation{TValue,TKeyFrame}.cs | 47 +++++++++++++++++++ .../Xaml/Custom/ColorAnimation.cs | 22 +++++++++ .../Xaml/Custom/QuaternionAnimation.cs | 21 +++++++++ .../Xaml/Custom/ScalarAnimation.cs | 18 +++++++ .../Xaml/Custom/Vector2Animation.cs | 21 +++++++++ .../Xaml/Custom/Vector3Animation.cs | 21 +++++++++ .../Xaml/Custom/Vector4Animation.cs | 21 +++++++++ 7 files changed, 171 insertions(+) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/CustomAnimation{TValue,TKeyFrame}.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/ColorAnimation.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/QuaternionAnimation.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/ScalarAnimation.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/Vector2Animation.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/Vector3Animation.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/Vector4Animation.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/CustomAnimation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/CustomAnimation{TValue,TKeyFrame}.cs new file mode 100644 index 00000000000..3e9f8415e97 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/CustomAnimation{TValue,TKeyFrame}.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable enable + +using System; +using Windows.UI.Xaml.Media.Animation; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// A custom animation types, that can target both the composition and the XAML layer, and that + /// can adapt based on the context it is being used from (eg. explicit or implicit animation). + /// + /// + public abstract class CustomAnimation : ImplicitAnimation + where TKeyFrame : unmanaged + { + /// + /// Gets or sets the target property for the animation. + /// + public string? Target { get; set; } + + /// + /// Gets or sets the target framework layer for the animation. This is only supported + /// for a set of animation types (see the docs for more on this). Furthermore, this is + /// ignored when the animation is being used as an implicit composition animation. + /// The default value is . + /// + public FrameworkLayer Layer { get; set; } + + /// + protected override string ExplicitTarget => Target!; + + /// + public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + { + return builder.NormalizedKeyFrames( + property: ExplicitTarget, + delay: Delay ?? delayHint, + duration: Duration ?? durationHint, + layer: Layer, + build: b => AppendToBuilder(b, easingTypeHint, easingModeHint)); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/ColorAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/ColorAnimation.cs new file mode 100644 index 00000000000..56a35de9aae --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/ColorAnimation.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Toolkit.Uwp.Helpers; +using Microsoft.Toolkit.Uwp.UI.Extensions; +using Windows.UI; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// A custom animation. + /// + public sealed class ColorAnimation : CustomAnimation + { + /// + protected override (Color?, Color?) GetParsedValues() + { + return (To, From); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/QuaternionAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/QuaternionAnimation.cs new file mode 100644 index 00000000000..dcd29250b9f --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/QuaternionAnimation.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Extensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// A custom animation. + /// + public sealed class QuaternionAnimation : CustomAnimation + { + /// + protected override (Quaternion?, Quaternion?) GetParsedValues() + { + return (To?.ToQuaternion(), From?.ToQuaternion()); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/ScalarAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/ScalarAnimation.cs new file mode 100644 index 00000000000..65eea298f0d --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/ScalarAnimation.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// A custom scalar animation. + /// + public sealed class ScalarAnimation : CustomAnimation + { + /// + protected override (double?, double?) GetParsedValues() + { + return (To, From); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/Vector2Animation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/Vector2Animation.cs new file mode 100644 index 00000000000..5c080094181 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/Vector2Animation.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Extensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// A custom animation. + /// + public sealed class Vector2Animation : CustomAnimation + { + /// + protected override (Vector2?, Vector2?) GetParsedValues() + { + return (To?.ToVector2(), From?.ToVector2()); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/Vector3Animation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/Vector3Animation.cs new file mode 100644 index 00000000000..ed1be8c4bbe --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/Vector3Animation.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Extensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// A custom animation. + /// + public sealed class Vector3Animation : CustomAnimation + { + /// + protected override (Vector3?, Vector3?) GetParsedValues() + { + return (To?.ToVector3(), From?.ToVector3()); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/Vector4Animation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/Vector4Animation.cs new file mode 100644 index 00000000000..818343e55c5 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/Vector4Animation.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Extensions; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// A custom animation. + /// + public sealed class Vector4Animation : CustomAnimation + { + /// + protected override (Vector4?, Vector4?) GetParsedValues() + { + return (To?.ToVector4(), From?.ToVector4()); + } + } +} From 0ae8c4dfdd05be7aa9e4447b3c3c5aa506fe97e7 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 26 Dec 2020 20:51:50 +0100 Subject: [PATCH 100/171] Fixed a build error --- .../Extensions/DependencyObjectExtensions.cs | 13 +++++++------ .../Xaml/Custom/ColorAnimation.cs | 2 -- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs index 642dde9b8f7..a572b7a68a0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs @@ -10,6 +10,7 @@ using Windows.UI; using Windows.UI.Xaml; using Windows.UI.Xaml.Media.Animation; +using XamlColorAnimation = Windows.UI.Xaml.Media.Animation.ColorAnimation; namespace Microsoft.Toolkit.Uwp.UI.Animations.Extensions { @@ -97,18 +98,18 @@ public static PointAnimation CreatePointAnimation( } /// - /// Prepares a with the given info. + /// Prepares a with the given info. /// /// The target to animate. /// The property to animate inside the target . /// The final property value. /// The optional initial property value. /// The optional delay for the animation. - /// The duration of the . - /// The easing function to use inside the . - /// A instance with the specified parameters. + /// The duration of the . + /// The easing function to use inside the . + /// A instance with the specified parameters. [Pure] - public static ColorAnimation CreateColorAnimation( + public static XamlColorAnimation CreateColorAnimation( this DependencyObject target, string property, Color to, @@ -117,7 +118,7 @@ public static ColorAnimation CreateColorAnimation( TimeSpan duration, EasingFunctionBase? easing = null) { - ColorAnimation animation = new() + XamlColorAnimation animation = new() { To = to, From = from, diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/ColorAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/ColorAnimation.cs index 56a35de9aae..0ec13fd775e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/ColorAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/ColorAnimation.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.Toolkit.Uwp.Helpers; -using Microsoft.Toolkit.Uwp.UI.Extensions; using Windows.UI; namespace Microsoft.Toolkit.Uwp.UI.Animations From 7a53d9c216e52a8ca44fe106129ca2a38d26cfc2 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 26 Dec 2020 20:53:18 +0100 Subject: [PATCH 101/171] Suppressed an incorrect IntelliSense warning --- .../Xaml/Custom/ColorAnimation.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/ColorAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/ColorAnimation.cs index 0ec13fd775e..386748ba93a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/ColorAnimation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Custom/ColorAnimation.cs @@ -4,6 +4,8 @@ using Windows.UI; +#pragma warning disable CS0419 + namespace Microsoft.Toolkit.Uwp.UI.Animations { /// From 76fa6b20e857799798fbec8c1aed3f6517bf69a7 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 26 Dec 2020 22:58:52 +0100 Subject: [PATCH 102/171] Added stateful keyframe animation builder APIs --- .../Builders/AnimationBuilder.KeyFrames.cs | 80 +++++++++++++++ .../AnimationBuilder.PropertyBuilders.cs | 99 +++++++++++++++++-- .../IPropertyAnimationBuilder{T}.cs | 28 ++++++ 3 files changed, 198 insertions(+), 9 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.KeyFrames.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.KeyFrames.cs index db8195f96d2..ed2199e8aed 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.KeyFrames.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.KeyFrames.cs @@ -283,6 +283,47 @@ public AnimationBuilder NormalizedKeyFrames( return this; } + /// + /// Adds a custom animation based on normalized keyframes to the current schedule. + /// + /// The type of values to animate. + /// The type of state to pass to the builder. + /// The target property to animate. + /// The state to pass to the builder. + /// The callback to use to construct the custom animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder NormalizedKeyFrames( + string property, + TState state, + Action, TState> build, + TimeSpan? delay = null, + TimeSpan? duration = null, + FrameworkLayer layer = FrameworkLayer.Composition) + where T : unmanaged + { + if (layer == FrameworkLayer.Composition) + { + NormalizedKeyFrameAnimationBuilder.Composition builder = new(property, delay, duration ?? DefaultDuration); + + build(builder, state); + + this.compositionAnimationFactories.Add(builder); + } + else + { + NormalizedKeyFrameAnimationBuilder.Xaml builder = new(property, delay, duration ?? DefaultDuration); + + build(builder, state); + + this.xamlAnimationFactories.Add(builder); + } + + return this; + } + /// /// Adds a custom animation based on timed keyframes to the current schedule. /// @@ -318,5 +359,44 @@ public AnimationBuilder TimedKeyFrames( return this; } + + /// + /// Adds a custom animation based on timed keyframes to the current schedule. + /// + /// The type of values to animate. + /// The type of state to pass to the builder. + /// The target property to animate. + /// The state to pass to the builder. + /// The callback to use to construct the custom animation. + /// The optional initial delay for the animation. + /// The target framework layer to animate. + /// The current instance. + public AnimationBuilder TimedKeyFrames( + string property, + TState state, + Action, TState> build, + TimeSpan? delay = null, + FrameworkLayer layer = FrameworkLayer.Composition) + where T : unmanaged + { + if (layer == FrameworkLayer.Composition) + { + TimedKeyFrameAnimationBuilder.Composition builder = new(property, delay); + + build(builder, state); + + this.compositionAnimationFactories.Add(builder); + } + else + { + TimedKeyFrameAnimationBuilder.Xaml builder = new(property, delay); + + build(builder, state); + + this.xamlAnimationFactories.Add(builder); + } + + return this; + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs index 43660ec787c..02f91ca880b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs @@ -30,19 +30,38 @@ private sealed record PropertyAnimationBuilder( /// public AnimationBuilder NormalizedKeyFrames( Action> build, - TimeSpan? delay = null, - TimeSpan? duration = null) + TimeSpan? delay, + TimeSpan? duration) { return Builder.NormalizedKeyFrames(Property, build, delay, duration, Layer); } + /// + public AnimationBuilder NormalizedKeyFrames( + TState state, + Action, TState> build, + TimeSpan? delay, + TimeSpan? duration) + { + return Builder.NormalizedKeyFrames(Property, state, build, delay, duration, Layer); + } + /// public AnimationBuilder TimedKeyFrames( Action> build, - TimeSpan? delay = null) + TimeSpan? delay) { return Builder.TimedKeyFrames(Property, build, delay, Layer); } + + /// + public AnimationBuilder TimedKeyFrames( + TState state, + Action, TState> build, + TimeSpan? delay) + { + return Builder.TimedKeyFrames(Property, state, build, delay, Layer); + } } /// @@ -56,8 +75,8 @@ private sealed record CompositionClipAnimationBuilder( /// public AnimationBuilder NormalizedKeyFrames( Action> build, - TimeSpan? delay = null, - TimeSpan? duration = null) + TimeSpan? delay, + TimeSpan? duration) { NormalizedKeyFrameAnimationBuilder.Composition builder = new(Property, delay, duration ?? DefaultDuration); @@ -68,10 +87,26 @@ public AnimationBuilder NormalizedKeyFrames( return Builder; } + /// + public AnimationBuilder NormalizedKeyFrames( + TState state, + Action, TState> build, + TimeSpan? delay, + TimeSpan? duration) + { + NormalizedKeyFrameAnimationBuilder.Composition builder = new(Property, delay, duration ?? DefaultDuration); + + build(builder, state); + + Builder.compositionAnimationFactories.Add(new Factory(builder)); + + return Builder; + } + /// public AnimationBuilder TimedKeyFrames( Action> build, - TimeSpan? delay = null) + TimeSpan? delay) { TimedKeyFrameAnimationBuilder.Composition builder = new(Property, delay); @@ -82,6 +117,21 @@ public AnimationBuilder TimedKeyFrames( return Builder; } + /// + public AnimationBuilder TimedKeyFrames( + TState state, + Action, TState> build, + TimeSpan? delay) + { + TimedKeyFrameAnimationBuilder.Composition builder = new(Property, delay); + + build(builder, state); + + Builder.compositionAnimationFactories.Add(new Factory(builder)); + + return Builder; + } + /// /// A private factory implementing . /// @@ -112,8 +162,8 @@ private sealed record XamlTransformPropertyAnimationBuilder( /// public AnimationBuilder NormalizedKeyFrames( Action> build, - TimeSpan? delay = null, - TimeSpan? duration = null) + TimeSpan? delay, + TimeSpan? duration) { NormalizedKeyFrameAnimationBuilder.Xaml builder = new(Property, delay, duration ?? DefaultDuration); @@ -124,10 +174,26 @@ public AnimationBuilder NormalizedKeyFrames( return Builder; } + /// + public AnimationBuilder NormalizedKeyFrames( + TState state, + Action, TState> build, + TimeSpan? delay, + TimeSpan? duration) + { + NormalizedKeyFrameAnimationBuilder.Xaml builder = new(Property, delay, duration ?? DefaultDuration); + + build(builder, state); + + Builder.xamlAnimationFactories.Add(new Factory(builder)); + + return Builder; + } + /// public AnimationBuilder TimedKeyFrames( Action> build, - TimeSpan? delay = null) + TimeSpan? delay) { TimedKeyFrameAnimationBuilder.Xaml builder = new(Property, delay); @@ -138,6 +204,21 @@ public AnimationBuilder TimedKeyFrames( return Builder; } + /// + public AnimationBuilder TimedKeyFrames( + TState state, + Action, TState> build, + TimeSpan? delay) + { + TimedKeyFrameAnimationBuilder.Xaml builder = new(Property, delay); + + build(builder, state); + + Builder.xamlAnimationFactories.Add(new Factory(builder)); + + return Builder; + } + /// /// A private factory implementing . /// diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs index 13b45040c43..f2a3668894f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs @@ -24,6 +24,21 @@ AnimationBuilder NormalizedKeyFrames( TimeSpan? delay = null, TimeSpan? duration = null); + /// + /// Adds a custom animation based on normalized keyframes ot the current schedule. + /// + /// The type of state to pass to the builder. + /// The state to pass to the builder. + /// The callback to use to construct the custom animation. + /// The optional initial delay for the animation. + /// The animation duration. + /// The current instance. + AnimationBuilder NormalizedKeyFrames( + TState state, + Action, TState> build, + TimeSpan? delay = null, + TimeSpan? duration = null); + /// /// Adds a custom animation based on timed keyframes to the current schedule. /// @@ -33,5 +48,18 @@ AnimationBuilder NormalizedKeyFrames( AnimationBuilder TimedKeyFrames( Action> build, TimeSpan? delay = null); + + /// + /// Adds a custom animation based on timed keyframes to the current schedule. + /// + /// The type of state to pass to the builder. + /// The state to pass to the builder. + /// The callback to use to construct the custom animation. + /// The optional initial delay for the animation. + /// The current instance. + AnimationBuilder TimedKeyFrames( + TState state, + Action, TState> build, + TimeSpan? delay = null); } } From e90958431fd1d82f65a1dc071f3e15eba6ff2c5e Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 26 Dec 2020 23:08:56 +0100 Subject: [PATCH 103/171] Removed some closure/delegate allocations --- .../Xaml/Abstract/Animation{TValue,TKeyFrame}.cs | 5 +++-- .../Xaml/Abstract/CustomAnimation{TValue,TKeyFrame}.cs | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs index ce5260fd0d2..3ddab46f0e1 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs @@ -48,11 +48,12 @@ public abstract class Animation : Animation /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { - return builder.NormalizedKeyFrames( + return builder.NormalizedKeyFrames This, EasingType? EasingTypeHint, EasingMode? EasingModeHint)>( property: ExplicitTarget, + state: (this, easingTypeHint, easingModeHint), delay: Delay ?? delayHint, duration: Duration ?? durationHint, - build: b => AppendToBuilder(b, easingTypeHint, easingModeHint)); + build: static (b, s) => s.This.AppendToBuilder(b, s.EasingTypeHint, s.EasingModeHint)); } /// diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/CustomAnimation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/CustomAnimation{TValue,TKeyFrame}.cs index 3e9f8415e97..b15443237de 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/CustomAnimation{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/CustomAnimation{TValue,TKeyFrame}.cs @@ -36,12 +36,13 @@ public abstract class CustomAnimation : ImplicitAnimation public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { - return builder.NormalizedKeyFrames( + return builder.NormalizedKeyFrames This, EasingType? EasingTypeHint, EasingMode? EasingModeHint)>( property: ExplicitTarget, + state: (this, easingTypeHint, easingModeHint), delay: Delay ?? delayHint, duration: Duration ?? durationHint, layer: Layer, - build: b => AppendToBuilder(b, easingTypeHint, easingModeHint)); + build: static (b, s) => s.This.AppendToBuilder(b, s.EasingTypeHint, s.EasingModeHint)); } } } From 2f01c600e9f43d353b2212f1bddf6d53bfdcdc58 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 27 Dec 2020 00:04:44 +0100 Subject: [PATCH 104/171] Improved dispatching for Vector2 composition animations --- .../Builders/AnimationBuilder.Default.cs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs index 3c85424851c..e983d14530b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Default.cs @@ -156,8 +156,7 @@ public AnimationBuilder Translation( { if (layer == FrameworkLayer.Composition) { - AddCompositionAnimationFactory("Translation.X", to.X, from?.X, delay, duration, easingType, easingMode); - AddCompositionAnimationFactory("Translation.Y", to.Y, from?.Y, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory("Translation.XY", to, from, delay, duration, easingType, easingMode); } else { @@ -233,8 +232,7 @@ public AnimationBuilder Offset( EasingType easingType = DefaultEasingType, EasingMode easingMode = DefaultEasingMode) { - AddCompositionAnimationFactory($"{nameof(Visual.Offset)}.X", to.X, from?.X, delay, duration, easingType, easingMode); - AddCompositionAnimationFactory($"{nameof(Visual.Offset)}.Y", to.Y, from?.Y, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory($"{nameof(Visual.Offset)}.XY", to, from, delay, duration, easingType, easingMode); return this; } @@ -353,8 +351,7 @@ public AnimationBuilder Scale( { if (layer == FrameworkLayer.Composition) { - AddCompositionAnimationFactory($"{nameof(Visual.Scale)}.X", to.X, from?.X, delay, duration, easingType, easingMode); - AddCompositionAnimationFactory($"{nameof(Visual.Scale)}.Y", to.Y, from?.Y, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory($"{nameof(Visual.Scale)}.XY", to, from, delay, duration, easingType, easingMode); } else { @@ -443,8 +440,7 @@ public AnimationBuilder CenterPoint( { if (layer == FrameworkLayer.Composition) { - AddCompositionAnimationFactory($"{nameof(Visual.CenterPoint)}.X", to.X, from?.X, delay, duration, easingType, easingMode); - AddCompositionAnimationFactory($"{nameof(Visual.CenterPoint)}.Y", to.Y, from?.Y, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory($"{nameof(Visual.CenterPoint)}.XY", to, from, delay, duration, easingType, easingMode); } else { @@ -800,8 +796,7 @@ public AnimationBuilder Size( { if (layer == FrameworkLayer.Composition) { - AddCompositionAnimationFactory($"{nameof(Visual.Size)}.X", to.X, from?.X, delay, duration, easingType, easingMode); - AddCompositionAnimationFactory($"{nameof(Visual.Size)}.Y", to.Y, from?.Y, delay, duration, easingType, easingMode); + AddCompositionAnimationFactory($"{nameof(Visual.Size)}.XY", to, from, delay, duration, easingType, easingMode); } else { From 38a489607bac2a01ec365722c896be05bf34607a Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 27 Dec 2020 01:14:51 +0100 Subject: [PATCH 105/171] Added missing translation settings for implicit animations --- Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs index 827491ed400..bc78c955b01 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs @@ -152,6 +152,7 @@ static void OnAnimationsChanged(object sender, EventArgs e) collection.AnimationsChanged -= OnAnimationsChanged; collection.AnimationsChanged += OnAnimationsChanged; + ElementCompositionPreview.SetIsTranslationEnabled(element, true); ElementCompositionPreview.SetImplicitShowAnimation(element, collection.GetCompositionAnimationGroup()); } } @@ -185,6 +186,7 @@ static void OnAnimationsChanged(object sender, EventArgs e) collection.AnimationsChanged -= OnAnimationsChanged; collection.AnimationsChanged += OnAnimationsChanged; + ElementCompositionPreview.SetIsTranslationEnabled(element, true); ElementCompositionPreview.SetImplicitHideAnimation(element, collection.GetCompositionAnimationGroup()); } } @@ -218,6 +220,7 @@ static void OnAnimationsChanged(object sender, EventArgs e) collection.AnimationsChanged -= OnAnimationsChanged; collection.AnimationsChanged += OnAnimationsChanged; + ElementCompositionPreview.SetIsTranslationEnabled(element, true); ElementCompositionPreview.GetElementVisual(element).ImplicitAnimations = collection.GetImplicitAnimationCollection(); } } From 3d1b97652412447a7f2b00b1380e40cb50c98c99 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 27 Dec 2020 01:40:12 +0100 Subject: [PATCH 106/171] Fixed incorrect delay for implicit animations --- .../Xaml/Abstract/Animation{TValue,TKeyFrame}.cs | 4 ++-- .../Xaml/Abstract/CustomAnimation{TValue,TKeyFrame}.cs | 5 +++-- .../Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs index 3ddab46f0e1..843163de68e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs @@ -51,8 +51,8 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS return builder.NormalizedKeyFrames This, EasingType? EasingTypeHint, EasingMode? EasingModeHint)>( property: ExplicitTarget, state: (this, easingTypeHint, easingModeHint), - delay: Delay ?? delayHint, - duration: Duration ?? durationHint, + delay: Delay ?? delayHint ?? DefaultDelay, + duration: Duration ?? durationHint ?? DefaultDuration, build: static (b, s) => s.This.AppendToBuilder(b, s.EasingTypeHint, s.EasingModeHint)); } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/CustomAnimation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/CustomAnimation{TValue,TKeyFrame}.cs index b15443237de..7d8f0012180 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/CustomAnimation{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/CustomAnimation{TValue,TKeyFrame}.cs @@ -6,6 +6,7 @@ using System; using Windows.UI.Xaml.Media.Animation; +using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; namespace Microsoft.Toolkit.Uwp.UI.Animations { @@ -39,8 +40,8 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS return builder.NormalizedKeyFrames This, EasingType? EasingTypeHint, EasingMode? EasingModeHint)>( property: ExplicitTarget, state: (this, easingTypeHint, easingModeHint), - delay: Delay ?? delayHint, - duration: Duration ?? durationHint, + delay: Delay ?? delayHint ?? DefaultDelay, + duration: Duration ?? durationHint ?? DefaultDuration, layer: Layer, build: static (b, s) => s.This.AppendToBuilder(b, s.EasingTypeHint, s.EasingModeHint)); } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs index 49d9a88fb0b..65116e596cc 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs @@ -28,7 +28,7 @@ public CompositionAnimation GetAnimation(UIElement element, out string? target) { NormalizedKeyFrameAnimationBuilder.Composition builder = new( ExplicitTarget, - Delay ?? DefaultDuration, + Delay ?? DefaultDelay, Duration ?? DefaultDuration); var (to, from) = GetParsedValues(); From 8bad1409ce24ea81a7ad466b9b501727ae14d451 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 27 Dec 2020 01:44:54 +0100 Subject: [PATCH 107/171] =?UTF-8?q?Updated=20sample=20app=20to=20use=20the?= =?UTF-8?q?=20updated=20APIs=20=F0=9F=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Pages/About.xaml | 18 ++--- .../Pages/About.xaml.cs | 3 +- .../ImplicitAnimationsCode.bind | 10 +-- .../ImplicitAnimationsPage.xaml | 43 ++++++----- .../ReorderGridAnimation/ReorderGridPage.xaml | 2 +- .../Shell.SamplePicker.cs | 24 ++---- Microsoft.Toolkit.Uwp.SampleApp/Shell.xaml | 75 +++++-------------- .../Styles/Generic.xaml | 11 +-- 8 files changed, 69 insertions(+), 117 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Pages/About.xaml b/Microsoft.Toolkit.Uwp.SampleApp/Pages/About.xaml index 0607623cd30..08d00dde167 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Pages/About.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/Pages/About.xaml @@ -13,9 +13,9 @@ - - - + + + - + - + Click="RecentSample_Click" + Style="{StaticResource AboutHyperlinkButtonStyle}"> + - - - + + + - - + - + + Text="{x:Bind Published.ToString('MMM d', {x:Null})}" /> - - + - + Style="{StaticResource AboutHyperlinkButtonStyle}"> + - + - + + ShadowOpacity="0" + Color="Black"> - - + + - + - + - + - + - + - - + + - - - - - - + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - + + + + - + Recent Activity - + - + ItemsPanel="{StaticResource ItemsWrapGridHorizontalTemplate}" + ItemsSource="{x:Bind RecentSamples, Mode=OneWay}" /> @@ -161,36 +179,49 @@ Grid.Row="3" Grid.RowSpan="3" Grid.Column="4" - ItemsPanel="{StaticResource ItemsWrapGridHorizontalTemplate}" - animations:Implicit.Animations="{StaticResource ImplicitOffset}"> - - - - + animations:Implicit.Animations="{StaticResource ImplicitOffset}" + ItemsPanel="{StaticResource ItemsWrapGridHorizontalTemplate}"> + + + + - + Release Notes - + + ItemsSource="{x:Bind LandingPageLinks.Resources, Mode=OneWay}"> - - - + + + - + @@ -204,18 +235,25 @@ + animations:Implicit.Animations="{StaticResource ImplicitOffset}" + BorderBrush="{ThemeResource Border-AboutPage-Horizontal}" + BorderThickness="0,1,0,0" /> - - + animations:Implicit.Animations="{StaticResource ImplicitOffset}" + BorderBrush="{ThemeResource Border-AboutPage-Horizontal}" + BorderThickness="0,1,0,0" /> + + Privacy statement @@ -224,12 +262,20 @@ - - + + - - + + @@ -267,7 +313,7 @@ - + @@ -303,7 +349,7 @@ - + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind index 86c93142b10..ad9490e7528 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind @@ -9,34 +9,28 @@ xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors.Animations" xmlns:core="using:Microsoft.Xaml.Interactions.Core" mc:Ignorable="d"> - - - + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PipelineBrush/PipelineBrushPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PipelineBrush/PipelineBrushPage.xaml index 7a934c95530..b191e57511f 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PipelineBrush/PipelineBrushPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PipelineBrush/PipelineBrushPage.xaml @@ -1,57 +1,60 @@ - + - + - + - + - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - + + + + + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml index 50e209df3c7..b93c0b8cd66 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml @@ -4,8 +4,6 @@ xmlns:ani="using:Microsoft.Toolkit.Uwp.UI.Animations" xmlns:anibehaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors.Animations" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:effects="using:Microsoft.Toolkit.Uwp.UI.Media.Effects" - xmlns:mani="using:Microsoft.Toolkit.Uwp.UI.Media.Animations" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:media="using:Microsoft.Toolkit.Uwp.UI.Media" xmlns:triggers="using:Microsoft.Toolkit.Uwp.UI.Triggers" @@ -30,12 +28,12 @@ - + - + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Shell.xaml b/Microsoft.Toolkit.Uwp.SampleApp/Shell.xaml index 247a91b1340..d878d82ed0c 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Shell.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/Shell.xaml @@ -7,9 +7,8 @@ xmlns:extensions="using:Microsoft.Toolkit.Uwp.UI.Extensions" xmlns:local="using:Microsoft.Toolkit.Uwp.SampleApp" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:winui="using:Microsoft.UI.Xaml.Controls" xmlns:media="using:Microsoft.Toolkit.Uwp.UI.Media" - xmlns:effects="using:Microsoft.Toolkit.Uwp.UI.Media.Effects" + xmlns:winui="using:Microsoft.UI.Xaml.Controls" extensions:TitleBarExtensions.BackgroundColor="{StaticResource Brand-Color}" extensions:TitleBarExtensions.ButtonBackgroundColor="{StaticResource Brand-Color}" extensions:TitleBarExtensions.ButtonForegroundColor="{StaticResource Titlebar-Foreground}" @@ -58,15 +57,19 @@ Tapped="ContentShadow_Tapped" Visibility="{Binding Visibility, ElementName=SamplePickerGrid}"> - - + + - + - + @@ -106,16 +109,27 @@ - + - - + + - - + + @@ -142,8 +156,8 @@ - - + + @@ -186,29 +200,50 @@ Foreground="{ThemeResource Brush-Main}" Text="{Binding BadgeUpdateVersionRequired}" /> - + - - + + - - + + - - + + - - + + From acd7d87dba5469cef962a6d7cee32cf872abc0af Mon Sep 17 00:00:00 2001 From: michael-hawker <24302614+michael-hawker@users.noreply.github.com> Date: Sat, 2 Jan 2021 15:13:15 -0800 Subject: [PATCH 129/171] Add Activity and StartAnimationActivity --- .../Microsoft.Toolkit.Uwp.SampleApp.csproj | 1 + .../Activities/StartAnimationActivity.bind | 50 +++++++++++++ .../SamplePages/XamlOnlyPage.xaml | 3 +- .../SamplePages/samples.json | 8 ++ .../Xaml/Activities/Activity.cs | 32 ++++++++ .../Xaml/Activities/StartAnimationActivity.cs | 73 +++++++++++++++++++ .../Xaml/AnimationSet.cs | 8 +- .../Interfaces/{ITrigger.cs => IActivity.cs} | 11 +-- .../Xaml/Interfaces/IImplicitTimeline.cs | 2 +- .../Animations/StartAnimationAction.cs | 19 ++++- 10 files changed, 194 insertions(+), 13 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Activities/StartAnimationActivity.bind create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/Activity.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs rename Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/{ITrigger.cs => IActivity.cs} (56%) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index 36ea971938b..3b0396ef582 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -590,6 +590,7 @@ + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Activities/StartAnimationActivity.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Activities/StartAnimationActivity.bind new file mode 100644 index 00000000000..616214e3eee --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Activities/StartAnimationActivity.bind @@ -0,0 +1,50 @@ + + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml index b93c0b8cd66..6753d0f8971 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml @@ -27,8 +27,9 @@ - + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json index 529ecec9c52..5c9aae295d4 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json @@ -460,6 +460,14 @@ "Name": "Animations", "Icon": "Icons/Animations.png", "Samples": [ + { + "Name": "StartAnimationActivity", + "Subcategory": "Activities", + "About": "Activity for Animations to Start another Animation", + "CodeUrl": "https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities", + "XamlCodeFile": "/SamplePages/Animations/Activities/StartAnimationActivity.bind", + "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/animations/Fade.md" + }, { "Name": "Fade", "Subcategory": "Effect", diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/Activity.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/Activity.cs new file mode 100644 index 00000000000..4747c16f984 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/Activity.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Threading.Tasks; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// Base class to use when creating activities which accept a . + /// + public abstract class Activity : DependencyObject, IActivity + { + /// + /// Gets or sets the to wait before running the activity. + /// + public TimeSpan? Delay { get; set; } + + /// + public virtual Task InvokeAsync(UIElement element) + { + if (Delay is not null) + { + return Task.Delay(Delay.Value); + } + + return Task.CompletedTask; + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs new file mode 100644 index 00000000000..4393cf1b495 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs @@ -0,0 +1,73 @@ +using Microsoft.Toolkit.Diagnostics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// which Starts the provided when invoked. + /// + public class StartAnimationActivity : Activity + { + /// + /// Gets or sets the linked instance to invoke. + /// + public AnimationSet Animation + { + get => (AnimationSet)GetValue(AnimationProperty); + set => SetValue(AnimationProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty AnimationProperty = DependencyProperty.Register( + "Animation", + typeof(AnimationSet), + typeof(StartAnimationActivity), + new PropertyMetadata(null)); + + /// + /// Gets or sets the object to start the specified animation on. If not specified, will use the current object the parent animation is running on. + /// + public UIElement TargetObject + { + get { return (UIElement)GetValue(TargetObjectProperty); } + set { SetValue(TargetObjectProperty, value); } + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty TargetObjectProperty = + DependencyProperty.Register(nameof(TargetObject), typeof(UIElement), typeof(StartAnimationActivity), new PropertyMetadata(null)); + + /// + public override async Task InvokeAsync(UIElement element) + { + Guard.IsNotNull(Animation, nameof(Animation)); + + await base.InvokeAsync(element); + + // If we've specified an explicit target for the Animation, use that + if (TargetObject is not null) + { + await Animation.StartAsync(TargetObject); + } + //// Otherwise see if the Animation has any context, and if not, we'll run it in our own context + else if (Animation.ParentReference is null) + { + await Animation.StartAsync(element); + } + //// Otherwise use the Animation's context (usually parent) + else + { + await Animation.StartAsync(); + } + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs index 5e24d720e86..5b4a29ef4a3 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs @@ -106,9 +106,9 @@ public async Task StartAsync(UIElement element) await builder.StartAsync(element); } - else if (node is ITrigger trigger) + else if (node is IActivity trigger) { - await trigger.InvokeAsync(); + await trigger.InvokeAsync(element); } } } @@ -123,8 +123,8 @@ public async Task StartAsync(UIElement element) case ITimeline timeline: builder = timeline.AppendToBuilder(builder); break; - case ITrigger trigger: - _ = trigger.InvokeAsync(); + case IActivity trigger: + _ = trigger.InvokeAsync(element); break; } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITrigger.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IActivity.cs similarity index 56% rename from Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITrigger.cs rename to Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IActivity.cs index c5402b405f3..b3a4fc20a87 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/ITrigger.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IActivity.cs @@ -3,18 +3,19 @@ // See the LICENSE file in the project root for more information. using System.Threading.Tasks; +using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// An interface representing a XAML model for a custom trigger or action. + /// An interface representing a XAML model for a custom activity or action within an 'Timeline'. /// - public interface ITrigger : AnimationSet.INode + public interface IActivity : AnimationSet.INode { /// - /// Invokes the current trigger. + /// Invokes the current activity. /// - /// A that indicates when the trigger has completed its execution. - Task InvokeAsync(); + /// A that indicates when the activity has completed its execution. + Task InvokeAsync(UIElement element); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IImplicitTimeline.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IImplicitTimeline.cs index 6ad4ac7025e..963e07bd19e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IImplicitTimeline.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IImplicitTimeline.cs @@ -15,7 +15,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations public interface IImplicitTimeline { /// - /// Gets a from the currnet node. This animation might + /// Gets a from the current node. This animation might /// be used either as an implicit show/hide animation, or as a direct implicit animation. /// /// The target the animation will be applied to. diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs index 62936eea684..cb7b7c04a21 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs @@ -32,14 +32,29 @@ public AnimationSet Animation typeof(StartAnimationAction), new PropertyMetadata(null)); + /// + /// Gets or sets the object to start the specified animation on. If not specified, will use the current object the parent animation is running on. + /// + public UIElement TargetObject + { + get { return (UIElement)GetValue(TargetObjectProperty); } + set { SetValue(TargetObjectProperty, value); } + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty TargetObjectProperty = + DependencyProperty.Register(nameof(TargetObject), typeof(UIElement), typeof(StartAnimationActivity), new PropertyMetadata(null)); + /// public object Execute(object sender, object parameter) { Guard.IsNotNull(Animation, nameof(Animation)); - if (sender is UIElement element) + if (TargetObject is not null) { - Animation.Start(element); + Animation.Start(TargetObject); } else { From 5a6dc189d3897207dd149d2a4f6b6091aaed691b Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 3 Jan 2021 17:52:15 +0100 Subject: [PATCH 130/171] Fixed StyleCop warnings, minor code style tweaks --- .../Xaml/Activities/StartAnimationActivity.cs | 25 +++++++++++-------- .../Xaml/AnimationSet.cs | 8 +++--- .../Xaml/Interfaces/IActivity.cs | 2 +- .../Animations/StartAnimationAction.cs | 13 ++++++---- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs index 4393cf1b495..460de41faa6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs @@ -1,9 +1,9 @@ -using Microsoft.Toolkit.Diagnostics; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using System.Threading.Tasks; +using Microsoft.Toolkit.Diagnostics; using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Animations @@ -26,7 +26,7 @@ public AnimationSet Animation /// Identifies the dependency property. /// public static readonly DependencyProperty AnimationProperty = DependencyProperty.Register( - "Animation", + nameof(Animation), typeof(AnimationSet), typeof(StartAnimationActivity), new PropertyMetadata(null)); @@ -43,8 +43,11 @@ public UIElement TargetObject /// /// Identifies the dependency property. /// - public static readonly DependencyProperty TargetObjectProperty = - DependencyProperty.Register(nameof(TargetObject), typeof(UIElement), typeof(StartAnimationActivity), new PropertyMetadata(null)); + public static readonly DependencyProperty TargetObjectProperty = DependencyProperty.Register( + nameof(TargetObject), + typeof(UIElement), + typeof(StartAnimationActivity), + new PropertyMetadata(null)); /// public override async Task InvokeAsync(UIElement element) @@ -53,17 +56,17 @@ public override async Task InvokeAsync(UIElement element) await base.InvokeAsync(element); - // If we've specified an explicit target for the Animation, use that + // If we've specified an explicit target for the animation, we can use that. Otherwise, we can + // check whether the target animation has an implicit parent. If that's the case, we will use + // that to invoke the animation, or just use the input (usually the parent) as fallback. if (TargetObject is not null) { await Animation.StartAsync(TargetObject); } - //// Otherwise see if the Animation has any context, and if not, we'll run it in our own context else if (Animation.ParentReference is null) { await Animation.StartAsync(element); } - //// Otherwise use the Animation's context (usually parent) else { await Animation.StartAsync(); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs index 5b4a29ef4a3..aaaab8a497f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs @@ -106,9 +106,9 @@ public async Task StartAsync(UIElement element) await builder.StartAsync(element); } - else if (node is IActivity trigger) + else if (node is IActivity activity) { - await trigger.InvokeAsync(element); + await activity.InvokeAsync(element); } } } @@ -123,8 +123,8 @@ public async Task StartAsync(UIElement element) case ITimeline timeline: builder = timeline.AppendToBuilder(builder); break; - case IActivity trigger: - _ = trigger.InvokeAsync(element); + case IActivity activity: + _ = activity.InvokeAsync(element); break; } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IActivity.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IActivity.cs index b3a4fc20a87..d5aaed5f024 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IActivity.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IActivity.cs @@ -8,7 +8,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// An interface representing a XAML model for a custom activity or action within an 'Timeline'. + /// An interface representing a XAML model for a custom activity or action within an . /// public interface IActivity : AnimationSet.INode { diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs index cb7b7c04a21..5f714192825 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs @@ -27,7 +27,7 @@ public AnimationSet Animation /// Identifies the dependency property. /// public static readonly DependencyProperty AnimationProperty = DependencyProperty.Register( - "Animation", + nameof(Animation), typeof(AnimationSet), typeof(StartAnimationAction), new PropertyMetadata(null)); @@ -37,15 +37,18 @@ public AnimationSet Animation /// public UIElement TargetObject { - get { return (UIElement)GetValue(TargetObjectProperty); } - set { SetValue(TargetObjectProperty, value); } + get => (UIElement)GetValue(TargetObjectProperty); + set => SetValue(TargetObjectProperty, value); } /// /// Identifies the dependency property. /// - public static readonly DependencyProperty TargetObjectProperty = - DependencyProperty.Register(nameof(TargetObject), typeof(UIElement), typeof(StartAnimationActivity), new PropertyMetadata(null)); + public static readonly DependencyProperty TargetObjectProperty = DependencyProperty.Register( + nameof(TargetObject), + typeof(UIElement), + typeof(StartAnimationActivity), + new PropertyMetadata(null)); /// public object Execute(object sender, object parameter) From f4a2a4b1ec23febe4e50962282ee28ef5f6d153e Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Mon, 4 Jan 2021 02:05:47 +0100 Subject: [PATCH 131/171] Added ColorKeyFrame type --- .../Xaml/KeyFrames/ColorKeyFrame.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ColorKeyFrame.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ColorKeyFrame.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ColorKeyFrame.cs new file mode 100644 index 00000000000..4d2f59d1bb7 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/KeyFrames/ColorKeyFrame.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// A type for color animations. + /// + public sealed class ColorKeyFrame : KeyFrame + { + /// + protected override Color GetParsedValue() + { + return Value!.Value; + } + } +} From 91c856badea9b49d4c22f76cbdeb2caf84ea1f4d Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 5 Jan 2021 00:53:17 +0100 Subject: [PATCH 132/171] Added cancellation support to AnimationBuilder --- .../Builders/AnimationBuilder.cs | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs index b63c68ccca5..c139e01a288 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.cs @@ -4,7 +4,9 @@ #nullable enable +using System.Collections.Generic; using System.Diagnostics.Contracts; +using System.Threading; using System.Threading.Tasks; using Windows.UI.Composition; using Windows.UI.Xaml; @@ -96,6 +98,73 @@ public void Start(UIElement element) } } + /// + /// Starts the animations present in the current instance, and + /// registers a given cancellation token to stop running animations before they complete. + /// + /// The target to animate. + /// The cancellation token to stop animations while they're running. + public void Start(UIElement element, CancellationToken token) + { + List<(CompositionObject Target, string Path)>? compositionAnimations = null; + + if (this.compositionAnimationFactories.Count > 0) + { + compositionAnimations = new List<(CompositionObject Target, string Path)>(this.compositionAnimationFactories.Count); + + ElementCompositionPreview.SetIsTranslationEnabled(element, true); + + Visual visual = ElementCompositionPreview.GetElementVisual(element); + + foreach (var factory in this.compositionAnimationFactories) + { + var animation = factory.GetAnimation(visual, out var target); + + if (target is null) + { + visual.StartAnimation(animation.Target, animation); + } + else + { + target.StartAnimation(animation.Target, animation); + } + + compositionAnimations.Add((target ?? visual, animation.Target)); + } + } + + Storyboard? storyboard = null; + + if (this.xamlAnimationFactories.Count > 0) + { + storyboard = new Storyboard(); + + foreach (var factory in this.xamlAnimationFactories) + { + storyboard.Children.Add(factory.GetAnimation(element)); + } + + storyboard.Begin(); + } + + static void Stop(object state) + { + (List<(CompositionObject Target, string Path)>? animations, Storyboard? storyboard) = ((List<(CompositionObject, string)>?, Storyboard?))state; + + if (animations is not null) + { + foreach (var (target, path) in animations) + { + target.StopAnimation(path); + } + } + + storyboard?.Stop(); + } + + token.Register(static obj => Stop(obj), (compositionAnimations, storyboard)); + } + /// /// Starts the animations present in the current instance. /// @@ -154,5 +223,91 @@ public Task StartAsync(UIElement element) return Task.WhenAll(compositionTask, xamlTask); } + + /// + /// Starts the animations present in the current instance, and + /// registers a given cancellation token to stop running animations before they complete. + /// + /// The target to animate. + /// The cancellation token to stop animations while they're running. + /// A that completes when all animations have completed. + public Task StartAsync(UIElement element, CancellationToken token) + { + Task + compositionTask = Task.CompletedTask, + xamlTask = Task.CompletedTask; + List<(CompositionObject Target, string Path)>? compositionAnimations = null; + + if (this.compositionAnimationFactories.Count > 0) + { + compositionAnimations = new List<(CompositionObject Target, string Path)>(this.compositionAnimationFactories.Count); + + ElementCompositionPreview.SetIsTranslationEnabled(element, true); + + Visual visual = ElementCompositionPreview.GetElementVisual(element); + CompositionScopedBatch batch = visual.Compositor.CreateScopedBatch(CompositionBatchTypes.Animation); + TaskCompletionSource taskCompletionSource = new(); + + batch.Completed += (_, _) => taskCompletionSource.SetResult(null); + + foreach (var factory in this.compositionAnimationFactories) + { + var animation = factory.GetAnimation(visual, out var target); + + if (target is null) + { + visual.StartAnimation(animation.Target, animation); + } + else + { + target.StartAnimation(animation.Target, animation); + } + + compositionAnimations.Add((target ?? visual, animation.Target)); + } + + batch.End(); + + compositionTask = taskCompletionSource.Task; + } + + Storyboard? storyboard = null; + + if (this.xamlAnimationFactories.Count > 0) + { + storyboard = new Storyboard(); + + TaskCompletionSource taskCompletionSource = new(); + + foreach (var factory in this.xamlAnimationFactories) + { + storyboard.Children.Add(factory.GetAnimation(element)); + } + + storyboard.Completed += (_, _) => taskCompletionSource.SetResult(null); + storyboard.Begin(); + + xamlTask = taskCompletionSource.Task; + } + + static void Stop(object state) + { + (List<(CompositionObject Target, string Path)>? animations, Storyboard? storyboard) = ((List<(CompositionObject, string)>?, Storyboard?))state; + + if (animations is not null) + { + foreach (var (target, path) in animations) + { + target.StopAnimation(path); + } + } + + storyboard?.Stop(); + } + + token.Register(static obj => Stop(obj), (compositionAnimations, storyboard)); + + return Task.WhenAll(compositionTask, xamlTask); + } } } From b22b356424098a66900469a3da341a4cff534fde Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 6 Jan 2021 02:20:03 +0100 Subject: [PATCH 133/171] Added cancellation support to AnimationSet --- .../Xaml/Activities/Activity.cs | 5 +- .../Xaml/Activities/StartAnimationActivity.cs | 15 ++-- .../Xaml/AnimationSet.cs | 78 ++++++++++++++++--- .../Xaml/Interfaces/IActivity.cs | 5 +- 4 files changed, 82 insertions(+), 21 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/Activity.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/Activity.cs index 4747c16f984..7abc9a772f9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/Activity.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/Activity.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Threading; using System.Threading.Tasks; using Windows.UI.Xaml; @@ -19,11 +20,11 @@ public abstract class Activity : DependencyObject, IActivity public TimeSpan? Delay { get; set; } /// - public virtual Task InvokeAsync(UIElement element) + public virtual Task InvokeAsync(UIElement element, CancellationToken token) { if (Delay is not null) { - return Task.Delay(Delay.Value); + return Task.Delay(Delay.Value, token); } return Task.CompletedTask; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs index 460de41faa6..bdb0fe6edae 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Threading; using System.Threading.Tasks; using Microsoft.Toolkit.Diagnostics; using Windows.UI.Xaml; @@ -36,8 +37,8 @@ public AnimationSet Animation ///
public UIElement TargetObject { - get { return (UIElement)GetValue(TargetObjectProperty); } - set { SetValue(TargetObjectProperty, value); } + get => (UIElement)GetValue(TargetObjectProperty); + set => SetValue(TargetObjectProperty, value); } /// @@ -50,26 +51,26 @@ public UIElement TargetObject new PropertyMetadata(null)); /// - public override async Task InvokeAsync(UIElement element) + public override async Task InvokeAsync(UIElement element, CancellationToken token) { Guard.IsNotNull(Animation, nameof(Animation)); - await base.InvokeAsync(element); + await base.InvokeAsync(element, token); // If we've specified an explicit target for the animation, we can use that. Otherwise, we can // check whether the target animation has an implicit parent. If that's the case, we will use // that to invoke the animation, or just use the input (usually the parent) as fallback. if (TargetObject is not null) { - await Animation.StartAsync(TargetObject); + await Animation.StartAsync(TargetObject, token); } else if (Animation.ParentReference is null) { - await Animation.StartAsync(element); + await Animation.StartAsync(element, token); } else { - await Animation.StartAsync(); + await Animation.StartAsync(token); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs index aaaab8a497f..f24cbab9c40 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs @@ -7,6 +7,8 @@ using System; using System.Collections.Generic; using System.Diagnostics.Contracts; +using System.Runtime.CompilerServices; +using System.Threading; using System.Threading.Tasks; using Microsoft.Toolkit.Diagnostics; using Windows.UI.Xaml; @@ -22,11 +24,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations public sealed class AnimationSet : DependencyObject { /// - /// An interface representing a node in an instance. + /// A conditional weak table storing instances associated with animations + /// that have been started from the current set. This can be used to defer stopping running animations for any + /// target instance that originated from the current . /// - public interface INode - { - } + private readonly ConditionalWeakTable cancellationTokenMap = new(); /// /// Raised whenever the current animation is started. @@ -38,6 +40,13 @@ public interface INode /// public event EventHandler? Ended; + /// + /// An interface representing a node in an instance. + /// + public interface INode + { + } + /// /// Gets or sets the list of nodes in the current collection. /// @@ -67,6 +76,7 @@ public interface INode internal WeakReference? ParentReference { get; set; } /// + /// Thrown when there is no attached instance. public async void Start() { // Here we're using an async void method on purpose, in order to be able to await @@ -78,19 +88,44 @@ public async void Start() } /// + public async void Start(UIElement element) + { + await StartAsync(element); + } + + /// + /// Thrown when there is no attached instance. + public async void Start(CancellationToken token) + { + await StartAsync(token); + } + + /// + /// Thrown when there is no attached instance. public Task StartAsync() { return StartAsync(GetParent()); } /// - public async void Start(UIElement element) + public Task StartAsync(UIElement element) { - await StartAsync(element); + CancellationTokenSource cancellationTokenSource = new(); + + this.cancellationTokenMap.AddOrUpdate(element, cancellationTokenSource); + + return StartAsync(element, cancellationTokenSource.Token); + } + + /// + /// Thrown when there is no attached instance. + public Task StartAsync(CancellationToken token) + { + return StartAsync(GetParent(), token); } /// - public async Task StartAsync(UIElement element) + public async Task StartAsync(UIElement element, CancellationToken token) { Started?.Invoke(this, EventArgs.Empty); @@ -104,11 +139,11 @@ public async Task StartAsync(UIElement element) timeline.AppendToBuilder(builder); - await builder.StartAsync(element); + await builder.StartAsync(element, token); } else if (node is IActivity activity) { - await activity.InvokeAsync(element); + await activity.InvokeAsync(element, token); } } } @@ -124,17 +159,38 @@ public async Task StartAsync(UIElement element) builder = timeline.AppendToBuilder(builder); break; case IActivity activity: - _ = activity.InvokeAsync(element); + _ = activity.InvokeAsync(element, token); break; } } - await builder.StartAsync(element); + await builder.StartAsync(element, token); } Ended?.Invoke(this, EventArgs.Empty); } + /// + /// Cancels the current animation on the attached instance. + /// + /// Thrown when there is no attached instance. + public void Stop() + { + Stop(GetParent()); + } + + /// + /// Cancels the current animation for a target instance. + /// + /// The target instance to stop the animation for. + public void Stop(UIElement element) + { + if (this.cancellationTokenMap.TryGetValue(element, out CancellationTokenSource value)) + { + value.Cancel(); + } + } + /// /// Gets the current parent instance. /// diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IActivity.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IActivity.cs index d5aaed5f024..7baa9a47d77 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IActivity.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Interfaces/IActivity.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Threading; using System.Threading.Tasks; using Windows.UI.Xaml; @@ -15,7 +16,9 @@ public interface IActivity : AnimationSet.INode /// /// Invokes the current activity. /// + /// The target to invoke the activity for. + /// A cancellation token to cancel the activity before it completes. /// A that indicates when the activity has completed its execution. - Task InvokeAsync(UIElement element); + Task InvokeAsync(UIElement element, CancellationToken token); } } From 5ef29ba1fb1d3b35338548a9b61f4ae548c7aff0 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 6 Jan 2021 02:26:00 +0100 Subject: [PATCH 134/171] Added OperationCanceledException-s handling --- .../Xaml/Activities/StartAnimationActivity.cs | 1 + .../Xaml/AnimationSet.cs | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs index bdb0fe6edae..a2694ba6695 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Threading; using System.Threading.Tasks; using Microsoft.Toolkit.Diagnostics; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs index f24cbab9c40..d24272c627c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs @@ -143,7 +143,20 @@ public async Task StartAsync(UIElement element, CancellationToken token) } else if (node is IActivity activity) { - await activity.InvokeAsync(element, token); + try + { + // Unlike with animations, activities can potentially throw if they execute + // an await operation on a task that was linked to a cancellation token. For + // instance, this is the case for the await operation for the initial delay, + // and the same can apply to 3rd party activities that would just integrate + // the input token into their logic. We can just catch these exceptions and + // stop the sequential execution immediately from the handler. + await activity.InvokeAsync(element, token); + } + catch (OperationCanceledException) + { + break; + } } } } From b1cc8db1c37f63995e3aae3556934ba417fdd445 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 8 Jan 2021 13:24:59 +0100 Subject: [PATCH 135/171] Added cancellation check in sequential mode --- .../Xaml/Activities/StartAnimationActivity.cs | 1 - Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs | 8 ++++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs index a2694ba6695..bdb0fe6edae 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Threading; using System.Threading.Tasks; using Microsoft.Toolkit.Diagnostics; diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs index d24272c627c..bcdecc051b7 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs @@ -158,6 +158,14 @@ public async Task StartAsync(UIElement element, CancellationToken token) break; } } + + // This should in theory only be necessary in the timeline branch, but doing this check + // after running activities too help guard against 3rd party activities that might not + // properly monitor the token being in use, and still run fine after a cancellation. + if (token.IsCancellationRequested) + { + break; + } } } else From 59d1a03e0574783cbc8825f3d94c0a61f63d67a0 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 8 Jan 2021 13:37:13 +0100 Subject: [PATCH 136/171] Added StopAnimationActivity type --- .../Xaml/Activities/StartAnimationActivity.cs | 6 +- .../Xaml/Activities/StopAnimationActivity.cs | 74 +++++++++++++++++++ 2 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StopAnimationActivity.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs index bdb0fe6edae..3abc6a08e84 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StartAnimationActivity.cs @@ -10,12 +10,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations { /// - /// which Starts the provided when invoked. + /// An which starts the provided when invoked. /// public class StartAnimationActivity : Activity { /// - /// Gets or sets the linked instance to invoke. + /// Gets or sets the linked instance to start. /// public AnimationSet Animation { @@ -59,7 +59,7 @@ public override async Task InvokeAsync(UIElement element, CancellationToken toke // If we've specified an explicit target for the animation, we can use that. Otherwise, we can // check whether the target animation has an implicit parent. If that's the case, we will use - // that to invoke the animation, or just use the input (usually the parent) as fallback. + // that to start the animation, or just use the input (usually the parent) as fallback. if (TargetObject is not null) { await Animation.StartAsync(TargetObject, token); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StopAnimationActivity.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StopAnimationActivity.cs new file mode 100644 index 00000000000..58a174ea7f2 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/StopAnimationActivity.cs @@ -0,0 +1,74 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Toolkit.Diagnostics; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// An which stops the provided when invoked. + /// + public class StopAnimationActivity : Activity + { + /// + /// Gets or sets the linked instance to stop. + /// + public AnimationSet Animation + { + get => (AnimationSet)GetValue(AnimationProperty); + set => SetValue(AnimationProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty AnimationProperty = DependencyProperty.Register( + nameof(Animation), + typeof(AnimationSet), + typeof(StartAnimationActivity), + new PropertyMetadata(null)); + + /// + /// Gets or sets the object to stop the specified animation for. If not specified, will use the current object the parent animation is running on. + /// + public UIElement TargetObject + { + get => (UIElement)GetValue(TargetObjectProperty); + set => SetValue(TargetObjectProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty TargetObjectProperty = DependencyProperty.Register( + nameof(TargetObject), + typeof(UIElement), + typeof(StartAnimationActivity), + new PropertyMetadata(null)); + + /// + public override async Task InvokeAsync(UIElement element, CancellationToken token) + { + Guard.IsNotNull(Animation, nameof(Animation)); + + await base.InvokeAsync(element, token); + + if (TargetObject is not null) + { + Animation.Stop(TargetObject); + } + else if (Animation.ParentReference is null) + { + Animation.Stop(element); + } + else + { + Animation.Stop(); + } + } + } +} From fa67d9d8de53426f8ba9c83a072a173b55a2a5d2 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 8 Jan 2021 18:39:43 +0100 Subject: [PATCH 137/171] Switched animation properties to DependencyProperty This is needed to enable using {Binding ElementName} to target animations, as well as to property use {Binding} to set animation properties --- .../Implicit.cs | 26 +++---- .../Xaml/Abstract/Animation.cs | 63 +++++++++++++-- .../Abstract/Animation{TValue,TKeyFrame}.cs | 56 ++++++++++++- .../Abstract/KeyFrame{TValue,TKeyFrame}.cs | 78 +++++++++++++++++-- .../Xaml/Activities/Activity.cs | 15 +++- .../Xaml/AnimationScope.cs | 26 ++++++- .../Xaml/AnimationSet.cs | 14 +--- .../Xaml/ImplicitAnimationSet.cs | 40 +--------- ...fectAnimation{TEffect,TValue,TKeyFrame}.cs | 16 +++- 9 files changed, 254 insertions(+), 80 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs index bc78c955b01..93c799013e8 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Implicit.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; +using Windows.Foundation.Collections; using Windows.UI.Xaml; using Windows.UI.Xaml.Hosting; @@ -130,7 +130,7 @@ public static void SetAnimations(UIElement element, ImplicitAnimationSet value) /// The instance for the current event. private static void OnShowAnimationsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - static void OnAnimationsChanged(object sender, EventArgs e) + static void OnAnimationsChanged(IObservableVector sender, IVectorChangedEventArgs args) { var collection = (ImplicitAnimationSet)sender; @@ -142,15 +142,15 @@ static void OnAnimationsChanged(object sender, EventArgs e) if (e.OldValue is ImplicitAnimationSet oldCollection) { - oldCollection.AnimationsChanged -= OnAnimationsChanged; + oldCollection.VectorChanged -= OnAnimationsChanged; } if (d is UIElement element && e.NewValue is ImplicitAnimationSet collection) { collection.ParentReference = new(element); - collection.AnimationsChanged -= OnAnimationsChanged; - collection.AnimationsChanged += OnAnimationsChanged; + collection.VectorChanged -= OnAnimationsChanged; + collection.VectorChanged += OnAnimationsChanged; ElementCompositionPreview.SetIsTranslationEnabled(element, true); ElementCompositionPreview.SetImplicitShowAnimation(element, collection.GetCompositionAnimationGroup()); @@ -164,7 +164,7 @@ static void OnAnimationsChanged(object sender, EventArgs e) /// The instance for the current event. private static void OnHideAnimationsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - static void OnAnimationsChanged(object sender, EventArgs e) + static void OnAnimationsChanged(IObservableVector sender, IVectorChangedEventArgs args) { var collection = (ImplicitAnimationSet)sender; @@ -176,15 +176,15 @@ static void OnAnimationsChanged(object sender, EventArgs e) if (e.OldValue is ImplicitAnimationSet oldCollection) { - oldCollection.AnimationsChanged -= OnAnimationsChanged; + oldCollection.VectorChanged -= OnAnimationsChanged; } if (d is UIElement element && e.NewValue is ImplicitAnimationSet collection) { collection.ParentReference = new(element); - collection.AnimationsChanged -= OnAnimationsChanged; - collection.AnimationsChanged += OnAnimationsChanged; + collection.VectorChanged -= OnAnimationsChanged; + collection.VectorChanged += OnAnimationsChanged; ElementCompositionPreview.SetIsTranslationEnabled(element, true); ElementCompositionPreview.SetImplicitHideAnimation(element, collection.GetCompositionAnimationGroup()); @@ -198,7 +198,7 @@ static void OnAnimationsChanged(object sender, EventArgs e) /// The instance for the current event. private static void OnAnimationsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - static void OnAnimationsChanged(object sender, EventArgs e) + static void OnAnimationsChanged(IObservableVector sender, IVectorChangedEventArgs args) { var collection = (ImplicitAnimationSet)sender; @@ -210,15 +210,15 @@ static void OnAnimationsChanged(object sender, EventArgs e) if (e.OldValue is ImplicitAnimationSet oldCollection) { - oldCollection.AnimationsChanged -= OnAnimationsChanged; + oldCollection.VectorChanged -= OnAnimationsChanged; } if (d is UIElement element && e.NewValue is ImplicitAnimationSet collection) { collection.ParentReference = new(element); - collection.AnimationsChanged -= OnAnimationsChanged; - collection.AnimationsChanged += OnAnimationsChanged; + collection.VectorChanged -= OnAnimationsChanged; + collection.VectorChanged += OnAnimationsChanged; ElementCompositionPreview.SetIsTranslationEnabled(element, true); ElementCompositionPreview.GetElementVisual(element).ImplicitAnimations = collection.GetImplicitAnimationCollection(); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs index e932e8f428f..591341b652b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using Windows.UI.Xaml; using Windows.UI.Xaml.Media.Animation; namespace Microsoft.Toolkit.Uwp.UI.Animations @@ -10,27 +11,79 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// A base model representing an animation that can be used in XAML. /// - public abstract class Animation : ITimeline + public abstract class Animation : DependencyObject, ITimeline { /// /// Gets or sets the optional initial delay for the animation. /// - public TimeSpan? Delay { get; set; } + public TimeSpan? Delay + { + get => (TimeSpan?)GetValue(DelayProperty); + set => SetValue(DelayProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty DelayProperty = DependencyProperty.Register( + nameof(Delay), + typeof(TimeSpan?), + typeof(Animation), + new PropertyMetadata(null)); /// /// Gets or sets the animation duration. /// - public TimeSpan? Duration { get; set; } + public TimeSpan? Duration + { + get => (TimeSpan?)GetValue(DurationProperty); + set => SetValue(DurationProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty DurationProperty = DependencyProperty.Register( + nameof(Duration), + typeof(TimeSpan?), + typeof(Animation), + new PropertyMetadata(null)); /// /// Gets or sets the optional easing function type for the animation. /// - public EasingType? EasingType { get; set; } + public EasingType? EasingType + { + get => (EasingType?)GetValue(EasingTypeProperty); + set => SetValue(EasingTypeProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty EasingTypeProperty = DependencyProperty.Register( + nameof(EasingType), + typeof(EasingType?), + typeof(Animation), + new PropertyMetadata(null)); /// /// Gets or sets the optional easing function mode for the animation. /// - public EasingMode? EasingMode { get; set; } + public EasingMode? EasingMode + { + get => (EasingMode?)GetValue(EasingModeProperty); + set => SetValue(EasingModeProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty EasingModeProperty = DependencyProperty.Register( + nameof(EasingMode), + typeof(EasingMode?), + typeof(Animation), + new PropertyMetadata(null)); /// public abstract AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs index 843163de68e..d2206ff15b0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; +using Windows.UI.Xaml; using Windows.UI.Xaml.Markup; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -27,18 +28,67 @@ public abstract class Animation : Animation /// /// Gets or sets the final value for the animation. /// - public TValue? To { get; set; } + public TValue? To + { + get => (TValue?)GetValue(ToProperty); + set => SetValue(ToProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty ToProperty = DependencyProperty.Register( + nameof(To), + typeof(TValue?), + typeof(Animation), + new PropertyMetadata(null)); /// /// Gets or sets the optional starting value for the animation. /// - public TValue? From { get; set; } + public TValue? From + { + get => (TValue?)GetValue(FromProperty); + set => SetValue(FromProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty FromProperty = DependencyProperty.Register( + nameof(From), + typeof(TValue?), + typeof(Animation), + new PropertyMetadata(null)); /// /// Gets or sets the optional keyframe collection for the current animation. /// Setting this will overwrite the and values. /// - public IList> KeyFrames { get; set; } = new List>(); + public IList> KeyFrames + { + get + { + if (GetValue(KeyFramesProperty) is not IList> keyFrames) + { + keyFrames = new List>(); + + SetValue(KeyFramesProperty, keyFrames); + } + + return keyFrames; + } + set => SetValue(KeyFramesProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty KeyFramesProperty = DependencyProperty.Register( + nameof(KeyFrames), + typeof(IList>), + typeof(Animation), + new PropertyMetadata(null)); /// /// Gets the explicit target for the animation. This is the primary target property that is animated. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs index dfe37ce58a4..ac24e21a9de 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs @@ -4,6 +4,7 @@ #nullable enable +using Windows.UI.Xaml; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -17,34 +18,99 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// This can differ from to facilitate XAML parsing. /// /// The actual type of keyframe values in use. - public abstract class KeyFrame : IKeyFrame + public abstract class KeyFrame : DependencyObject, IKeyFrame { /// /// Gets or sets the key time for the current keyframe. This is a normalized /// value in the [0, 1] range, relative to the total animation duration. /// - public double Key { get; set; } + public double Key + { + get => (double)GetValue(KeyProperty); + set => SetValue(KeyProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty KeyProperty = DependencyProperty.Register( + nameof(Key), + typeof(double), + typeof(KeyFrame), + new PropertyMetadata(0.0)); /// /// Gets or sets the animation value for the current keyframe. /// - public TValue? Value { get; set; } + public TValue? Value + { + get => (TValue?)GetValue(ValueProperty); + set => SetValue(ValueProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( + nameof(Value), + typeof(TValue?), + typeof(KeyFrame), + new PropertyMetadata(null)); /// /// Gets or sets the optional expression for the current keyframe. /// If this is set, will be ignored. /// - public string? Expression { get; set; } + public string? Expression + { + get => (string?)GetValue(ExpressionProperty); + set => SetValue(ExpressionProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty ExpressionProperty = DependencyProperty.Register( + nameof(Expression), + typeof(string), + typeof(KeyFrame), + new PropertyMetadata(null)); /// /// Gets or sets the optional easing function type for the keyframe. /// - public EasingType? EasingType { get; set; } + public EasingType? EasingType + { + get => (EasingType?)GetValue(EasingTypeProperty); + set => SetValue(EasingTypeProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty EasingTypeProperty = DependencyProperty.Register( + nameof(EasingType), + typeof(EasingType?), + typeof(KeyFrame), + new PropertyMetadata(null)); /// /// Gets or sets the optional easing function mode for the keyframe. /// - public EasingMode? EasingMode { get; set; } + public EasingMode? EasingMode + { + get => (EasingMode?)GetValue(EasingModeProperty); + set => SetValue(EasingModeProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty EasingModeProperty = DependencyProperty.Register( + nameof(EasingMode), + typeof(EasingMode?), + typeof(KeyFrame), + new PropertyMetadata(null)); /// public INormalizedKeyFrameAnimationBuilder AppendToBuilder(INormalizedKeyFrameAnimationBuilder builder) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/Activity.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/Activity.cs index 7abc9a772f9..88ad912ab2f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/Activity.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Activities/Activity.cs @@ -17,7 +17,20 @@ public abstract class Activity : DependencyObject, IActivity /// /// Gets or sets the to wait before running the activity. /// - public TimeSpan? Delay { get; set; } + public TimeSpan? Delay + { + get => (TimeSpan?)GetValue(DelayProperty); + set => SetValue(DelayProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty DelayProperty = DependencyProperty.Register( + nameof(Delay), + typeof(TimeSpan?), + typeof(Activity), + new PropertyMetadata(null)); /// public virtual Task InvokeAsync(UIElement element, CancellationToken token) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs index c229d8bda4c..afcf8619885 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; +using Windows.UI.Xaml; using Windows.UI.Xaml.Markup; using Windows.UI.Xaml.Media.Animation; @@ -21,7 +22,30 @@ public sealed class AnimationScope : Animation /// /// Gets or sets the list of animations in the current scope. /// - public IList Animations { get; set; } = new List(); + public IList Animations + { + get + { + if (GetValue(AnimationsProperty) is not IList animations) + { + animations = new List(); + + SetValue(AnimationsProperty, animations); + } + + return animations; + } + set => SetValue(AnimationsProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty AnimationsProperty = DependencyProperty.Register( + nameof(Animations), + typeof(IList), + typeof(AnimationScope), + new PropertyMetadata(null)); /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs index bcdecc051b7..20d76ab0333 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs @@ -5,14 +5,12 @@ #nullable enable using System; -using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; using Microsoft.Toolkit.Diagnostics; using Windows.UI.Xaml; -using Windows.UI.Xaml.Markup; namespace Microsoft.Toolkit.Uwp.UI.Animations { @@ -20,8 +18,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// A collection of animations that can be grouped together. This type represents a composite animation /// (such as ) that can be executed on a given element. /// - [ContentProperty(Name = nameof(Nodes))] - public sealed class AnimationSet : DependencyObject + public sealed class AnimationSet : DependencyObjectCollection { /// /// A conditional weak table storing instances associated with animations @@ -47,11 +44,6 @@ public interface INode { } - /// - /// Gets or sets the list of nodes in the current collection. - /// - public IList Nodes { get; set; } = new List(); - /// /// Gets or sets a value indicating whether top level animation nodes in this collection are invoked /// sequentially. This applies to both nodes (which will still trigger @@ -131,7 +123,7 @@ public async Task StartAsync(UIElement element, CancellationToken token) if (IsSequential) { - foreach (INode node in Nodes) + foreach (INode node in this) { if (node is ITimeline timeline) { @@ -172,7 +164,7 @@ public async Task StartAsync(UIElement element, CancellationToken token) { var builder = AnimationBuilder.Create(); - foreach (INode node in Nodes) + foreach (INode node in this) { switch (node) { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs index 1d428c74e84..2cbf0da37c2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/ImplicitAnimationSet.cs @@ -5,7 +5,6 @@ #nullable enable using System; -using System.Collections.ObjectModel; using System.Diagnostics.Contracts; using Microsoft.Toolkit.Diagnostics; using Windows.UI.Composition; @@ -18,13 +17,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// A collection of implicit animations that can be grouped together. This type represents a composite animation /// (such as ) that is executed on a given element. /// - public sealed class ImplicitAnimationSet : Collection + public sealed class ImplicitAnimationSet : DependencyObjectCollection { - /// - /// Raised whenever the contained animations are changed. - /// - internal event EventHandler? AnimationsChanged; - /// /// Gets or sets the weak reference to the parent that owns the current implicit animation collection. /// @@ -79,38 +73,6 @@ internal ImplicitAnimationCollection GetImplicitAnimationCollection() return animations; } - /// - protected override void ClearItems() - { - base.ClearItems(); - - AnimationsChanged?.Invoke(this, EventArgs.Empty); - } - - /// - protected override void InsertItem(int index, IImplicitTimeline item) - { - base.InsertItem(index, item); - - AnimationsChanged?.Invoke(this, EventArgs.Empty); - } - - /// - protected override void RemoveItem(int index) - { - base.RemoveItem(index); - - AnimationsChanged?.Invoke(this, EventArgs.Empty); - } - - /// - protected override void SetItem(int index, IImplicitTimeline item) - { - base.SetItem(index, item); - - AnimationsChanged?.Invoke(this, EventArgs.Empty); - } - /// /// Gets the current parent instance. /// diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/Abstract/EffectAnimation{TEffect,TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Abstract/EffectAnimation{TEffect,TValue,TKeyFrame}.cs index 9aee4327817..7cea88d7936 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Animations/Abstract/EffectAnimation{TEffect,TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Abstract/EffectAnimation{TEffect,TValue,TKeyFrame}.cs @@ -5,6 +5,7 @@ using System; using Microsoft.Toolkit.Uwp.UI.Media; using Windows.UI.Composition; +using Windows.UI.Xaml; using Windows.UI.Xaml.Media.Animation; using static Microsoft.Toolkit.Uwp.UI.Animations.Extensions.AnimationExtensions; @@ -28,7 +29,20 @@ public abstract class EffectAnimation : Animation /// Gets or sets the linked instance to animate. /// - public TEffect? Target { get; set; } + public TEffect? Target + { + get => (TEffect?)GetValue(TargetProperty); + set => SetValue(TargetProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty TargetProperty = DependencyProperty.Register( + nameof(Target), + typeof(TEffect), + typeof(EffectAnimation), + new PropertyMetadata(null)); /// public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) From af409dfec6c860c2ec486778504dad98b7b32daa Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 8 Jan 2021 18:51:53 +0100 Subject: [PATCH 138/171] Fixed {Binding ElementName} for effect animations --- .../Brushes/PipelineBrush.cs | 26 ++++++++++++++++++- .../Effects/Abstract/PipelineEffect.cs | 3 ++- .../Visuals/AttachedVisualFactoryBase.cs | 2 +- .../Visuals/PipelineVisualFactory.cs | 25 +++++++++++++++++- 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/PipelineBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/PipelineBrush.cs index 4a33e40357d..44c37fa38f6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/PipelineBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/PipelineBrush.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Xaml; using Windows.UI.Xaml.Markup; using Windows.UI.Xaml.Media; @@ -23,7 +24,30 @@ public sealed class PipelineBrush : XamlCompositionEffectBrushBase /// /// Gets or sets the collection of effects to use in the current pipeline. /// - public IList Effects { get; set; } = new List(); + public IList Effects + { + get + { + if (GetValue(EffectsProperty) is not IList effects) + { + effects = new List(); + + SetValue(EffectsProperty, effects); + } + + return effects; + } + set => SetValue(EffectsProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty EffectsProperty = DependencyProperty.Register( + nameof(Effects), + typeof(IList), + typeof(PipelineBrush), + new PropertyMetadata(null)); /// protected override PipelineBuilder OnPipelineRequested() diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/Abstract/PipelineEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/Abstract/PipelineEffect.cs index 7800130b038..3d3639f3223 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/Abstract/PipelineEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/Abstract/PipelineEffect.cs @@ -7,6 +7,7 @@ // See the LICENSE file in the project root for more information. using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; using Windows.UI.Composition; +using Windows.UI.Xaml; #nullable enable @@ -15,7 +16,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media /// /// A base pipeline effect. /// - public abstract class PipelineEffect : IPipelineEffect + public abstract class PipelineEffect : DependencyObject, IPipelineEffect { /// public CompositionBrush? Brush { get; private set; } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Visuals/AttachedVisualFactoryBase.cs b/Microsoft.Toolkit.Uwp.UI.Media/Visuals/AttachedVisualFactoryBase.cs index d6ce1661ef3..1badf68d02f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Visuals/AttachedVisualFactoryBase.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Visuals/AttachedVisualFactoryBase.cs @@ -11,7 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media /// /// A type responsible for creating instances to attach to target elements. /// - public abstract class AttachedVisualFactoryBase + public abstract class AttachedVisualFactoryBase : DependencyObject { /// /// Creates a to attach to the target element. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Visuals/PipelineVisualFactory.cs b/Microsoft.Toolkit.Uwp.UI.Media/Visuals/PipelineVisualFactory.cs index e04c5f157cc..694c9a859da 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Visuals/PipelineVisualFactory.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Visuals/PipelineVisualFactory.cs @@ -26,7 +26,30 @@ public sealed class PipelineVisualFactory : PipelineVisualFactoryBase /// /// Gets or sets the collection of effects to use in the current pipeline. /// - public IList Effects { get; set; } = new List(); + public IList Effects + { + get + { + if (GetValue(EffectsProperty) is not IList effects) + { + effects = new List(); + + SetValue(EffectsProperty, effects); + } + + return effects; + } + set => SetValue(EffectsProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty EffectsProperty = DependencyProperty.Register( + nameof(Effects), + typeof(IList), + typeof(PipelineVisualFactory), + new PropertyMetadata(null)); /// public override async ValueTask GetAttachedVisualAsync(UIElement element) From 04939b5c42de236c2cb2e48936e4f48572f5cb3b Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 8 Jan 2021 20:05:57 +0100 Subject: [PATCH 139/171] Fixed overlapping animations in AnimationSet --- Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs index 20d76ab0333..22441c8409f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationSet.cs @@ -102,6 +102,8 @@ public Task StartAsync() /// public Task StartAsync(UIElement element) { + Stop(element); + CancellationTokenSource cancellationTokenSource = new(); this.cancellationTokenMap.AddOrUpdate(element, cancellationTokenSource); From 9e4f4bc3b9f669efd6e955d04222a796005990e3 Mon Sep 17 00:00:00 2001 From: michael-hawker <24302614+michael-hawker@users.noreply.github.com> Date: Fri, 8 Jan 2021 12:18:35 -0800 Subject: [PATCH 140/171] Add InvokeActionsActivity to Behaviors Package and Sample --- .../Assets/Llama.mp3 | Bin 0 -> 24013 bytes .../Microsoft.Toolkit.Uwp.SampleApp.csproj | 2 + .../Activities/InvokeActionsActivity.bind | 54 +++++++++++++++++ .../SamplePages/XamlOnlyPage.xaml | 12 ++++ .../SamplePages/samples.json | 8 +++ .../Animations/InvokeActionsActivity.cs | 56 ++++++++++++++++++ 6 files changed, 132 insertions(+) create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/Assets/Llama.mp3 create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Activities/InvokeActionsActivity.bind create mode 100644 Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/InvokeActionsActivity.cs diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Assets/Llama.mp3 b/Microsoft.Toolkit.Uwp.SampleApp/Assets/Llama.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..20fa5514349b2ccf4cfab5fa487ecd696a13df32 GIT binary patch literal 24013 zcmdSA@JX5-Ny$;rF_J z5AQ$VKA+4vbIi=1^L`!kInLSn3|vtF1Mt|;6!eXajUPM2006p&jjNZhm94Lhr#-;K zTaX{{|6)Y{VlJMKu|Nl3KNl}g0Pp`ow2vV>FAr}Ue-~SKhyQ!5-@k+TT>QK|0Qv|e z{>PIOKJI1cR?^78Y0_TmK+85tX!n3$TG znVVZ!Qc_V<)6me;(b3h_)89WlJpTFf+|tt8+UD-=;o<4!<<-^C`+L;C!90%H?%$Y2 z|E>J5G5xP&0a*QBU-`ea|GzFD`P%~kzy$-@1Tdv7i}f!AJ_`U(M~5*cR~rozW|6m1gO z{Mgbz-t_a+oZ{jC@Rj~``M3W~&Z~`*_6#!hqfULYS57iNAL*dLx6_U^L zaF7O%{e_}4G)A>lA(Ec@wYzwmrfFvMd&~RFt|i(ALax90FIL`(fq!~t3e1>kE{p=2 zX+0{YXhrcHsEvy`e4mIE;F&iDwJo~!-exB3x0vm@eK>w7v>Fs8!YfsM|K+Bn1Ha7k zQX}SQ74?w0h__6O*b)SUP!DDb$`^Bh(|(YPgJLt#lY}ZGw;(@MMkf&q?<23-3Gxb$ zuPCa$!2TAJ#Pb{7~b^Ym{? zobTN^Jh!9Mdv&7ZmAiZ2p!R}DGXMgAJ5|FO$FJJL{PYxH;*0H5&2#7d5;tEii@XSS zdO#q*mH?BGH(1$~U#Y^K&O!s8QRrk@;50wE!J`-A`?x{h+VD9bP;YHG(LcQ%rL*Z= zrI^^oJ|G%S!}LJyTuaPOrdw2$ZuGs6($x@Y=bfl(!leLhvXq0Ow38*?0B4k6{#IbESdQSGdYq!cwz z<%2q&=Bhr;o@D6b0uIK6k~~dUIDKsd+v67-A9(*cmblM{J%+dW+x&X`i@S@z)23n+ zR~{m2=zj@<&(QEU%?rZTUe!i{%u{G zN8F4U^fO&I{dEIb+frVIPAhv32OCHJrO`9h7&OJ2)f{*#3?@3`Hkb5o-bCYC9t0{)eRx~8TlY- zDv3aGbJgtdad9N|p?adyz_H)9wet7|>7+)*0yYr|w$aNA`>1*~y7QuOs?kx)Yjpx^ z1LB?JHIwYwpS3lxF>Z4n%SG8t9Qg z7b|S=8^9ZQGFJQ*&gO5jj~6{qL3V`Wna&&f3GE;WsABCbDpC}seSH1r_-sPyoUnkp zDuXu6fu@D6Gk~d1rl$=VxRR9pY~9PlYeqGRw{cu&X%2v~%ElDU_m95-0QinY-40C6 zE2{wiB*~bGM;O8#)9lm-#H#eZWy-Z;5)k!D4Y$=ghF1;mo=6&t*Xng0=QX_Ze5jX}BHNX(c#KISRZhQxe{*hUP?4WlsCkT8@Rp06y<+kHF^wSF^_SV~pMh(zMb?NLXVv;vH2rO1S8bp9A08+#r z?P+^XrokGTa)SDe<@vYW02I(7tDdG;E@7g3>zjtdriB}Msz=X+=wXHOA4ns}eygVC z5-W{eNBKev3UO#1CEb5Jy#Y-`B!FLaO37RYJ|+xc z#{k^uWNx8QN8}?fxYugK1Tf%sgg0UQW~>|v;7#SSgjU+pNCeD|U{ryX+S|Fo_U!Q{ zF7B<<=#xX=6olDem{ZEOkf?XwSytsi^0HENKT|W-ajM;LI=*nT!r#pQs|vdPWe}i- zNk!lo`Rw&))mC1Y;+dt$s$A)fzv+j0Mv&rbb#u@jjPPp>&r$gbYA;8U&1THNrH&ptUkFcRT|Af1g+gA{<<@z z_lFW+M)DFrn+0<9mO%0MlvSWpsCA!^K&)}UmR%!akBcon@q>bc!Oox$+uV;N^Q2N) z*P@{5RNeCURF*l=i&ZTjieV${iS)0(1HzPIjQlX2Kkh$&#_U&>_9L6Lcs`j2IkcRi zBP-fVxreCmbV50yN`$sPRKXO}fxb_O`fVNRpyPpW4o~P?wQ%`s|M9m*0@rEOZO*89 z)$CS3+3XU46m9tGB?rR92${d#g1;*D$eF{0xcIf!HR~d1=6f;{IBvQ;>;3f8Pvx_F zhr&1Ei+s#O4Q8DBr_`2W-fE{0B+}}Lw*@sewPDt zw((CkE)x;jK}&cZ`$8$VO35C!QCoV0P!&@q}y9?gG*o_kHs zx+IGAJqq&>oDqENShAaKF$VI<-MINg7lkqQgqoLYxqFIFcE>CiW5*XcwyTa)pY`cg zMQ8wop(BmM7(iij%5*rpGa!0T5MbL=li082g}(N`6?whY z_QnURyOi`Fe>VWIkx|{|n7UcDjD1=vLK*Ze>tFp1lO}c)icEqK@jYKxH{@w=6W?Gq zS-Aug5G*Z-4@jgky3JGwT*eU6-aFW(mBRt%e1@wiiyxTlTy~k{IG9VO-mPTt%HbNK zx`Xhs=U-P%REv4bu9FRhHK|{1I2dIoEgIF%KN1PPtM3 z77ae-lvrH>T=MBfq6um5@gu~<-PoU8oz)Y&t&TtSRp*}3tRCC~Mt^(DDmmeh zBg2iRnGxp;$3&v7WtPtUNJdgJu9D(&*>v4->F)`=uI$3b*845V^A?}auIlHeYg@-O z_j^9{WHP}XzO@kZv53ahYvNnKF{b#S(7*C0_+p)U!R=yRao;_eWJi|&;boXTb`;(^1vEYe9srt>>|gN zP1FV5MTP5mGC0d#k#xio`aTy%#UmC9Xy@DfQ-V)WIEsBvG7J*XLX&#ev0L zk~J7`h@NM>sNV~lC%dm(Z7r{eYT#_G>i%husqJ;}YI)k|d<{UI4mU3bRAX6tL!Dc0 z?J2V5yv%9iW4^sc^XUVNT|J+@aRvou?;;a-hxRaLKYL?yr9WNKE6K+bO%w z{edwTP>eE#dpy)3o6^oP|d4FkTksWiys>3n>B& z@x5kclo)1_7ljW9^ULAjq`6Z9&=}||@?>XlFmMPk^msK8@wuaL*T#}(d$BejK-qfa z$DXOcSbY+hC)2E4V_i@rMolW>4;_}%Y-IZBa~Xw(D~#Sj=E-_{`EMq-wSw*-XP0}UbA(aM5;AFcsRihW%|>8fk&Sc-zqDy6c+ z;LND_Q{a;8tg%JJ^uJ={NS#Bz(%n~JjV9=>4%&;kmm zyaaQU=)LhV6lI$dW1~Bt?>7u62(~DeYoiH}#M%{XUAky;{~ag$jPq zuH#A0r|?DfL4A+>bJ5vJgVch~F@TVmjKma9m=^7gO^i+I(rQS3Xlr+*Og2o^S;9y| z6-h}dLFpjSTRDnJRqB{6ur@K zuj$hk9#QUp{C$zYPUyr07j?150DFT&xG=uPkVpfs587nvQAmA>q)`*8;;W(-^&JNF zU)gP+9PZ*A6b5po1!?WQZ`q8$wLJ~iynprL)y*{yI_JQY%DQO22ZV!{(i{OnaNi@8~on;n|Go=xrgu~T@B=?tX~?7%Ey=~MA!F-%y1taPjc0O#L3V=-(u{2YOIBA z29zRzGsKSd9Ph z(7-1ty}`1HV3qYRuWz2LvU|kdF7E~u|2O}%LIO{DKhI;4^jZz$cDpb>$I}>)si*Xk z)2FN!%EnJcdmpi8Warms!1kr)L0wSWN$0@1hsEheojqu04~@{*kve#DRN;PupO7!p zEKd0Kc~3?8w_+-Tix8>SsaDW!MUjM14HuG`#ui-R0jO4>h1Bd;Db#yQI#E+l{#t+a35OVGt(B}S_j z_{mek4;hq>Ns6k@8%9k10b?z`x_Q!>HDN_Oj^#qNms-?q7(24e%8&2R`Yz|WawwSvn zrflKA@3&6^UN^s@kbVdUSwY<`JBHj|BGEbCKQC|I zKTD`(;{hTCuGb~X7}ZNTHu7RsI*VH)H4|8|3r6H+;bFZR^q`6-JtDtJ56UlcL^d<) zWVfgH*f`UwQJS|{2QLaa#IX`ez-xSUdK>P$kNg#xW6{mzbtK>OOaydJpu;%!FKo*7ob8!QC-lul-Fw!cvwnOD_<1i@~*6&bF6ej!5>=tS|bd8M4 zRw0f0!aj0ZJ}}B;@VyG$P|W73Kd<#l;5roHuH#+ z12wqbaY4rW;lNuZ&DuPmG@|Zgrj`AcTQ4KGA-yP^)ow)TxfddD4<|EuN? zBv%G4A>7EEF=#ng=H2~nRv=qJ@cJH3IjJ2}wL>)z6Gqo0>;vvll_eig`d|LzA%TSg zi}Sc7?xt*JbdviC@z>Lu8ui*}R#dfgQCYPSM2IL6LK~F_E8;Ob0qE)~yUk2c$Vw06 zt5+Yt+`S*9xbP$J9)_zeDZPE?Z(FDz!68vtrvwcQ@of9sj>9B6tGTjXfbG5y6oaza z4Y7R*`)!AE#k}!z%M@YfY%#w6KqaY50(s_E_QLc?@oSMjOeK`%r1r+}ZheWHniown zzCOlK301LYTR4DKbm?^&81(*aWp(-En<>Vjfide?-CwR6V{(*?@`MzOqUssY;kGC5 z&>`|&p^Ftf#&Wy{`8pENF9MyD;Tb=bU3n8CXirBQ4N$1x6=H+zm^_8bF$v9eUoKIJ zlGb^Z?dbqsoTc?5_~M{|1C%El+y1%3UIF!WWV)^$6)}snR(ai!Qk{}WFh0~qW`lk+ zInf9$25gT>@Zkt@kxgV-#2LiODNvki`u*A82}Rkw%d$T;o#b}b70L4C&m+s(yT{%( zY;aKK@iIh^-cu9d{>L8xjFMl`*(IAaI#Ro{u?>meo6@X*)E~FJQ~#^voda{p(5vZ# zA(?b%bz()V6K<_t2NbI71ECjg1*d>%i-{=@Ts4{8<3sKE7V7@|S7nE;gk}t(8TW=e zlA?Hs3ch8-5z_BE?;oXLo}jL`#DI9{D+pYXY;O~&J+%yaT67Th+sQPuqU=xKRDNLC z44=9+AgZ+7>jkT!`d`BibCXx7>+vKq2+8F&g~-HIZY$5qV-=Fc2zg4L$seR5Uh5yh z!j2)VC`Ul36P?(OJNPP`ML`T}hdq-cCwfLP%M9z7Xn9!XFQ4vH226H}qRFHCt)A&_-WG5?ztjAwT_yA5OA=%ipC@ikAZ zRK6ZvB-O1ZCiYou>7lnaSY; z??Y++8qR+64s7c#{$X1A#zkB5&TL0jKJ-RbTwpB)8rS=SWozTV3eV%ys({Kp>v ze6O@JyDxEO059N{+<6xN+rqCZ5z%5p$0c}^P4A?&Vr?v*hNh~>eZ{*R=shKKOvfHM zX-rC-A9Q$fWM;PJ;UbYO@081-SLE(kSaXSTaw`d7IV=&EnO3o4@WUj+XrWb>1{kf{*7Ou;~n!u(aA=2&gUwb0?W_L`cU4Lwn@|E7ap! z1bHy4Gn1S2nkfBHg)b)?Ka$9m$KQBNx+%V)_`cwnnK(h!jpwtwrMSh z=^1Nm@h}cj@`_#Go@BL&Fyj=xKK|ShP5ta9jbDy4bhge_ZE*+ru$a6R_lrWy&$%jI%UCW-b>oYD@&7a2+RElLnp`a7}emq*F79!=;^lL{NX^1!Ru^yKUBr*pvhV9_6pR|vITRw z;(O+-R=MwU%t5WyV7ib^eg?~0f5gloMn_kT#&FhUWKW!B6)j}v!OUj%78i-hgTm?~ z^3Kn#t)q2vYB*n^mS-#DMgNeeW}zOKO*C+j&TG3Oy~P%xKTtn^e+qs5%jE>Zgq}n^ zo&=REM|wy%`s0OLkj-hO=@3@f)|BtRK7VaGON!1(xqA=}+W0$Hon@`4j5;F94_mnL9q$;?V! zwWi@V{m%F#8<#7j;4)r+uL*Ai8<>+R?u&o-vRR7EO)MoJbR=)x=OAWHq_D-dSn$x)+%00m%G8ntd!qjoyEXaw7!8SepUw9 zrG42c{R9jBH!R7Hbb?lVb{tRKLveDy7r=!U(@~Z%Sw=+0IQ{wKDLwkjQZ<(+mE9|r zHqSC#Cn~%gXa#4FhdYM{dtSj~F-ZjVHP+aLXN! zaSjl`B%9@)fFqwbR_ls0*gN*^lWxo7XRG4W%CfNSWdgC~>|f&FP5P>*LSDxtTFLy4 zZ7lA`f%K|u)N{T3W$Xl%U--Di!{=an7)R%dGw}7%1eOXDFlWz16w7mx_JK^-KQOYxGDu=2@&`LBoszJSa>&i@e_jCUS3 zQT8Bfloc0mgO5=*XGb*Mc!(?s?qBqmuZLgG&wX5gW($4Sx5qo>DNFQ}pS2DgpuupC zAAcr&Av@tp!2ZYd*`esUVespC7woB3Bd2TOrr2c5M$1-}GR1+CH??cyT(I1+-yh!_ zw!P{h&e=8QBIerl#o1l?CJ%T=46bwdge5ZO-as|3Zun#9TLd!%kj4$%v^^(@zO~CS zj3n(w($cz>H&8L2qxScR4p>o1;YTi?C--wX0SlTK5}||q;~3h!4Yl&GoO?`^DuhU7 zFG^1yzNfY=$zaTr;o|d0$(qV_k>cUfL8{~4%^Ajjyj)u4z~pu;qsfVaxeH9FFVuCRNe=%7 z#V}q~nHY+FzzaDvh$1KFe7ZQB7AYs6=kRHWQ0w*+idV@zAmv%yW|Nh?p{)XOn$2w~ zkN@|HfBX>uV2*&%1X%o~?mmr$ltWaU^^_TFq0e_27I)rTy6oVy&Doz^NT7XkW|tGK z5x%QD-gd5XDZwwMO3JN?O zvAM#QVNy|Z5qS0@coD4_nSeQ1;P>){yGwpoD1mO_YZ70)(xMq7or#IiVVRp3q_J2A z^8q%ugzP9UrNlbMx-x&0Ya3mOOvk{Y2mO5u8Z{K^0o9US)wv%b@n9JRk4#H{yO7p3 zmE(Z67i|AiQuB9O5>7sr&<~dOkOCpZWs~LW41;ir3v^}F`&NR$Ou}|IGnEO?Mz6DV z-nMh4B(V={&BOsq9n}VGC=>z*2tA5zaTU~^m5_o}^P3sz%ve=A* zsLSE6>US%SVPA{T!5dD$PL@8Q7R1!XKi!WuUzf4EZuJ~5oFp3Ed)nK3*ew}9+7WY6 z(>pLedH+^Wb}UD#D<`8y4Z2Kw#LPeb7D!-#fSJoN@tF>Le35nka}Z92fvWXxm^f*@ z;C0+vf5*Bjh>s)`luk5f4q1 znGE$KUXHj|Cw0s@uRm|5Fv6l0@QNP2yMp04M>9Ece!lOB&#J%7)cDoq;M?2R21(PW z%cG@k{O?eR-O|D9tC~p(w^v^8J&#c*@@JGkvBr6_02mD{o{d)S+!h`}1fQW{vYR*` z7=!Get^!WS>z_GF2;ARokghLBWl|kNl2FR;n=@jv-?ZYDP*U1lGlW!mFQ}uMbJSA4 zn9A0Mu9@9%MJ82!H(Cxm%craSD5yOs>zUO0B16-GHTxI-I`f+)3wR-3ih#;{3XUa| zzOQ_8vXny5#^NajzJH6;GdfI_wjvjaurV-p*AW{KwxN2N=bk@dAYg*__N>jaEDYe>Hn+^7l!vT_fs@f!>Ef85p& zZ#sz=nHjj{qp+y%2<+tcQ)!r+n@Jt8FJdA!C&y;A_rEk0npEL-8$V?qt}c}kK^-J_ z{3RnINsxw@H!6n5rZZ)Duy_g#e>-soIacX5ce2yFQdHh-P7{3+jD2$nr#L%!TU6ces zAubF$8zTS5ABhASv8}osb4Y4MyKzgF#>IDF8`N{Dm&h}ocVB_X=P$;}vnb4znEAtz z=Wgg1Ctv3EP$Xe@hGuX2uY)%hBEZq#v!W-gl*ZLZKQ=RNqWMls~dOsk9xE zgURV6FGT73#rqnsdUIgS<_nY2w7YUJt%;;1bBjJ03jR6xD`o8P#fkJ=0Qhx}SSbN$ zHw|%8*T%NXQRDdZj<+kC#5EMPcn?+n@!|$Bh$$SY1hWMHkgQ=W?xVyI)-~^qFt2CI z@)Zo-1!>vZB-vEOE$8cYGx>4c9EGzn*gOMHAKMZalwVO^TU*fffS!kFB zeoA0C%6)z$ycc5^r0zg6aiJWh&EHzthly0OkLJZN)fRu!McXL%Ik%y`kzl`g)R~jq zt<^8lJ}oMNuNF>(s7~DeiTC9grfqe!h*s)o{HL9uyd3Qgx{|H6j8(vHY?;|o%au+5 zge{xFvn_-9$%Y5|Sic5hDB)we)M*iYRmFx!0`7OBK>q?WqbFDFB`Z?wBa8Hfh1n z`O(%sr^iej$GY&bU8z7Rx81%sHN#g-v1fT%BWvRA`JrvNULi`R=32_>B%V*waR!P3 z`qq~je$r{;j%rQ#urMaad;T*}Fs*X!sWI?<=7#u9!-eul=FlP2o*vHCHwKO)Y)js2 z4OdWSsX!fbTmH}|)1N1cIixl@_gy=au71uqIeK|bcX9L{1x+tLEm7*2ZtkbKr%ILI zyKaOdx{?^3x46SK7-(rh`p@^)g2EVt2)21E%}WEM)&Lo^)-kbGcaAZfuTR*Zqu$iR z#5HP`{?GFxCQ+uKvpdw?!x8|;nu@}eIJ2g`HK8Gdmx+vl5}QN4cl49qAPqT>n0b%! zGecwF!W2Ci3iY)LS8JEeRsO)~ec7D)Y%|7!qnk!|)A zi)KbO3e+G4gX1FebgG)2plna7TcW}40HN}QToFvjB&h;Z9^!h+&|5dt+}KFDn;jEN zl`H6XsjKU{?$*lHVULJ2x|6J4mHoa|UOZMmYacX#PxekL6MjDD05}5GGsyg%Tu%xN zXrcdHjLjwwRB3$&Wn>Bn%da(J--s!RjRo2Bgef&w%h3D~w{_$VlWoFPFy5Pfcrz^_ z%H>AzR;O4`MD1dpxasdmNMUngZE0Mq5G)C5Ix$|Ws!fD%$i$`{M|H=GZ@|GuhK=)- z`i(;Uk9kvS9YM$F%NLm`Pkq9ohI-NGl6q~OUuH#_xF{97t~AAqIGk&kc^0|*0B}>? za{W>bd@!+6;eBc`ag=WngISOr3TomRqFLAOJ%8c(+$O0uzH_Zr+6n@l!Pk8T;ev_S zV@&b5!sR7rD8HT@pXsxwM*x3d2^f}SG4f3{I(mHJt9RVsU6cQ~V;x|oD(eDfSjd$4 zDov`eEneZj=iep(upOd(3Z}M}XQH;UVN}5VWu3*Z7joeyKyF6KCnqWy z=c}NCB?k!qvZ2E`k*?=rm?YzdWw@Z{|LrI0qp&Z}2DK+KP*ph6LlNnHWX>3V`Y~Y` z3*Vxunv1MUPeBd9^vlzL7W#8~Py1FlhLKA;Xp7A~_!mr;7^S@>q+^YN8PQvdMOqi; zz!@9TL&o=vM({tNEk0@5lE3;%1Hf zLC4AJJR-SR*_#NH#F?sk^IAmFv_oG5R$%CD`Rz(Y))*@ag3)h09%lRv4qha|5Qcd# zM0U(Nr|vd!v40<}yR2G$_B8W$Ob>$~K8&zf;(_iq*uWK1n%2JSLHtr$y+|o6EpgtM zBQE*LS*-k7$l#KI&}g=b&Vp@ujRlLAi=KiMMzJ{5j?#Ih>l-_)i3G};T%&r{G*K z*>yr!-eIsXt2Pt-mCCkvi%DS686k5OUEJK7-3W1uuP4urB1TEOVEp9F*OlQ^a*KLW zb$5BedkK74VYE!v{o{)nMhuPEBD`OWiVGI(@|pTM-*wC7n-wvKIs!Nj8b=C9zO^QD zGD1063Sb<>*y;0Oglx(-+r6>~29S8ECJvO-W1(V=_&lbeh?lb*Ce5;TLNoWlJ60El zOa*kWtZQPC_A{dI*I!BH;Sa=x8GcYcBIn0KuBQLU?yFm_!QX{Cn%w+O6P2~qv1UW8 zfNGu*^_Rx84A_4m3r^oAyS?zs(IgQwN=eS_-m!WXOrQ)KYZxyVt-Of;O^|<1{sYHW zD37f~xALhIXQeQx5gjX#01jm7Dy60de0jru@Q0%xf0eRxVvACm!TN^_i;bF&t76BH zf^#OB-%JL`bmh4)(@o%Q-X|jt*h%)>MXf3!CeA8`0*+-EOi2Bt&?OG^ul{ZVfNu1f z$B+Iu^_|s6-;3A*@HJ~ z!m-o~xhWKP4y&Jn+=qHIC>yj6ih;pqW6<-&Pug>Z)bbw zHzOrGp^@&zo%hr#$Ln>lh|fUL@;CyCX-T0!vVN5p&y`%DsG0&)8tI!0P?VaT(zs^{m7|qS)?ZYO8|AyG6e-NoLe`VEf*_twy{9R?bGRL+H~c6CNzB{ z;S3?EkM=&>x)%nYbF_wMhBL4Bv&4Fe+oE^`&{s@r6U)_ngVGo8tQ#p&`s{DC!#0tJSCME^w@W$92j-WbP8`4g{MMlsMhpJ4rgj>z=>O4$ zER&cQ3nQ^9bdTp>{vRTN%gh>fPpA;Oeego5V* zF^M(j?Ct7LQ^Oc(i22z*)Ahj8h<3xx6|o4-PfHmmDWAo-(6~x$ZpN5=8a6I$9YH~W zrT#hbKuV!$wQLLroiK0fmL<9?E+wJ7CEd)SWq$UlyDk}4GK`2?5CH8va=mTn)RfSz z+U>o4cHOc80#OA}S-_EqP54d~gc^D{85_=@694f(Mnh-ife$>P{GlpeQ)sgb0%tj~ zvqlER;iVjXj|Nv>lR^c@p}Y`N${^L)oh~ua!|wzxhamK9Q5*4MB{qGC#pzSTAB$lc zvI4T!kz3=f38hqSAp z?C^CC_v*>64^t{Im6-6Gwn~3ZIFy5?A>l_N61_T(ER7@{dyuh^5+4-S*E(4C`8^>T zbkhT@ygaV&P<~`K1n=Q!0578+teQ$5EpV~rNVHKqCWi*Oh>g(P-r|qatW?RBk;_^X zuSK_izo>6|mU`ja;YaYzvre>4Hto8)QW`C(g|vEfH>C?T=V=$eugJGyx#5C|M;JU zp&Lkz4S=cVlpVHR|5BIWj*g~ z8PtysSidN%FP%q4M8r--CO7(vjmQs8PIucH2%JwzQA1o?R9jrh+Dp+#?Cb~$&w z&2Owsy?}9B1U7Tsc$P^bpHSCvt0FO6i3CTtUB7<~OQksF(G+IO&wn!VYh(?P+?6OE zzd|hKzJ^_;Fxhj&f5MI5$OnzsuF16UZZm%OeD-HWu!IJ*#!n@CAp%pcr_L3vaxGF` z?(wri*-93N(dXohOl5+qeQ=_y?}X`H-+rCvdE)qA6N(aou(3QxxCMBZng4d{vq;Aa zw%Ya|%47F>lFBX3i}tVJ#!xjlfRhTH72j7-wV4oqo(+KADkQ^+vyDfWYmvBOqWFup z=R9%-Ln=tb+brwUpfKlu{4dbZ$>_)Jz*IZh=y45v5d@$?C(cAB*D$N}ik7G(RnIu5 zB1?+oBnmo~HVm-(t``YSzyP_bAhK_Evd3|Zz%X?hzJ&n`;zqK6=38uFv3o4$>IpUHn0d0LPl~ddbmgZbgn6j z$^6}A;`-}kE)1+nPz4?22@+6=92A8I$%cZ_&`8SyI_17{(R;WNvPF)u3wVFKBk+UY z_NU=UC6k>MCsMUq^~FN&$v*RAGle-xZJkv8DUwc>>iWr;8*uG^zw{T?Xm{^`{RcUD z9jChS(Apsq`gLvsJWF`7G`c2>Yn_>MZJkY9wo$GI7?v~f2_aF2w>c9izbvFNRMIai8dEoi5j~ZSxiIRx~&(RAtTCF!787x&1 zx%qmGm1{ zUNP|c+q^w(PIx0BxoOB zlgQ2zpF!t}|(yaw0|MQ=m zA<;#c)oc!EVcPQXZ=??J$D3dL_x+a{?tb&nMBX{F>d|(7ha1wL=OuE;Sn=UB8--Dh z;~k`)+Y4Z|J3Y%j_zlz`Ii2b#=wZaOhwa&nm{FjNaeh-%tKb|HFg18A?u%-Fr?3Dy zuh|Tbq@uZboaUr+Zy_52&kw3ZPp7#LdG^1BUb1z9WlnNuTb?JEotM}N=^3-N{ z8M3vFf1(r{$3LmU;g2TdN1-4j2tzx!uRefWFZ7X<<8?E z0EV*jFwh!Z*Ysl;tLr|llo*-I?nA@Ql(~~4$?TM-s2OQeE4yN?2*|kRR*73om}2_% zDbWwBDXM9y1kPU&z=utY1T?FH6bkt%vHAWrdq%#lug94zy(bq~F;0HM!Y9@aBz0{5 z)%HvjFo&TaJ8#lZj>r60JO%)}$tNED|HTHd@34zN%&iIcu;(`!Iy~koa?>XuGj5tC4E0etg}Sr(Tm7<;#gcisaT6*IWSQwgOCj z6l{ZvR`S*_%a~!)MvGKyRhpr!bXj}`)>tLNo2GW=m`S~YU_`<8ekf3sOAfDVW_Vod zn{i0|%zKd7seZkXREt}F9`_9Z^ob)1P@|TBTTj`H`(p06h2`!*v(>|w^yGomV+5SW z&Yirvky4*SplbBaXA5q$KY(?Sp!LCMww_IUsF zpVzrh2xtG>b(}FauidGQ=2d%aIaKDX};TgGmKF@-l_h| zCe8`5D&v~Kkr@9Hf51SgUhaW35g$V`bMlUs*T> zX(ZFA`67#wRtx%AZhTSJToG&=AEhenh%bKONH7p}uc9~e(M0IyWEtHxb7tki_97Ag zfXUx;9M`&;=kp%en=_Xdngu~m9ncLosEOy0#Awo@k-yD@2l(@g*|3_wiskir!M@Qs4V4{^%loNWNna%-qop@+-*l%jp+8 z#|>K%)fb0kA)33&yTbRzJ^)VOkwZPVNeXc@pFd{ySDh=KiypATU71Wof&!<5QYJV0qO3Rc7OpHau`BN zq+1##MCtDC?oJT|3F&T-Qo7^;5in5s4ey`v-e1nAbAMRZx%S>??X{Lpy%~`_R|aeS zzCk5G6zQQP`|bnll$e+*%rynQXla-%P}n(GozG6J`p{E$EsG(k>C0{zlP9ST_ALWe zc`$7I%&LE9B-fMP-q_+xZ50t|dYZ7C!!kN1hJQOFD8rNXCrImXAI(<@EKnUQJE4{t z#1X~HAb6XUy~PV~D~GWr=CU;L`SXAN>#uOlJCZ>x1sdm-6@pZWT<hCX`*?f*JoMsam%xxnNq)Q z?{UEgh=q7VTw7Ej(^7WbS@c4g7{6s_=LdLaPjas?h1#gdm;RU!w2WkbAr5#%GgRGH zXN!u>JZ8#}x!@y4RUkyaRxYYknhQmZM+;>yg4~Cgbn_kwEa!CZOnlbOF<_SMNnt4c zu$=6%eJruL`HLbem(T5NiFb8ksqw#yc}U#S8j?jy#31Dnn#hdQJ?nkfe?#|v1rZCSRgFX;eLPKX9gsHQ$W zr6y%{s#XXaem-Mc#{E!a14Gz5I_8W*jmej6*FQ~QKbSj=MMkR z08sRObt{N4Qum_~uKr6xWV3MdzYR{&wEs6W&S)m8B+4Qp7a&P%Bu1#j^m|E_C9qGp zpC-hPxSE~;BA>>J9k|ccGDZrSf8%sxAj;jG)MP)Sfs40exp8>anbbL*CtfP?O_Cd(v-zBd8{jdWKW|0p}`b8v*Kt0rf^4^%EuON zX8+#8m38?=_+lvzw(aC1o`KRl_My)bo8YA~F8V^_h<$yvXq|VD1JMd4?Ft{co zU%XdjAd(RNHias*{to|L0H_Rx^PkcQX$3{a-sL}B3iHOw1qNa6*)(3pR?bck$AwD7 z!m_irHC9~f8o!?#P!7D+acWcfm&>eLg0w1!TO^0zyKzbPAJL1vth4#gcOX0Nh4W!n z-ose4!xqDCqvfXe%uL1TZ1O_GL-)AGH3(j0iFOgEE|<^fpU4$rUL~)NgqObvSYc5l z|6VjON3nzDmG%AG#-6A0ZFvo$y(c!CUKe=Vd{RC?_;>ldeXXHkx@7vc;xFsi>g!D# zM$Haai~shPhpnEMg5D_wPrObA+@|0~Gcr3FHA414v;Qg&7o%zM`{wqPl)^$)ea@vU zm5vb_bWVu5h-k|0sS5RmIxhAdjA+SU$A*CJx?VIY@a2d?k`qxdF#!?!oQ$=Jg(~!b z>D8m1-bBl}=JI1chox1QILThmMhm4$f3;k(b8ff=XEHPg(;s`^?HhupydeIiTz10Z zUgxpW@t75+{=1;a;nF8ldqV0>(~?2s@i3F#{+PS{qxEqh9!7t32SSTA2thl`g$R(2 zwD8)MIz}->l($~PF(o?F9_x{*9Ybe zg+>5K5fj^Tk25yf(WdFW+VDhw!L`E5v4PjdfrPfQF@rbTpVw!M1l81G;qB7LkXN0V z{13&(zg5I7j)mU*B`?wQYEu{&eL1Z&o^IgZFgrAg0@%|H9uj@DC@y2#9wHStUtCTl zQ7IP%M925j^IDEl%{uQvi`+%$aQfT1ef6N&m<*1XAcI)J`iYkBB!dHn2lz=idN59-DF;F- zeSqfS1U8_1|F-#PqGO;LWs`n5rKClk<(%cOG$+NXTi2W3n5A!m048k(ay@YdLXvm~ zDz{4jS!AC{Zn&E0J!9fgB4XzN=NBN9jw%GH(np;BedYn)w9!<9T+VKSv8(N=4 z`+PS{JI&wU!ds+adX$p4?EdmY{&0?oZ?^PB5d>ik$@x|`p@uG(`x+zYr5i}19e8KcqVdWheN%32({RIQ;UVcT`^E_5fXQiP!D`TF# zpN|+cR#gNiMvh#R$8{mC^yCl_6T&BwtFPtV=~x{9cKdzJswSrnk0sN@j2<=tm%5u( z9kx-xADS7Wa4f<@oPlNI4*%^y&__m%Z(k9}$J<7^a;z#4Aq!mpwI6+wQ05*Qdl;z$ zg_ok>ROQG;8L6xv$7*aPr(oG4rnPF8nbD$jbS8Rm{r6{&=1<9Thn@9j6?07iN;;+uW?r>_^~i(25tkq)RBzy|9%iE_a>pqSiH)U5=vWpdrKn|snO5?%^EBVTfXg(4qEe1+`$QEB_&1m_<-H6g%0y!QX+VRaTta( zr~{IsjevsY8ycJLof>L|sN0cAqG)cm`YU3wY=UBS9qz^}X-#pT3%9sn$_gxzgmCF5 zA)QXKfG$LoX^lcqYonVx{if}&r&eCM|7|%20B|K${V5;rP5~!iVP{Z?0a&1!d>gU* zWCIp?1y7{P_P=ib+1e6uf|;z~Nz7urFjOoaNqQ4iGbd_24xIe4aF3G(2PcGHbu0ko z$UnY*(1Z2HXp+d~)iDGCC}+AQ)qifGD4LjP+~*1LhAVYYEx{su-FRFx;kDoMut zl9Q;>D(Z1;+2u7Yu^XcNQ4mkW+W=&vuP3Fb)r>91ZT;{)u)G z&_X}e3tJiD6i>9usNWi!s}l;L>hd{HHYklz)#vf!3w0#i?)3^CF&BJD2ZgemU2x>S zOvlZyR+<^oBX;)4XP72pudL*Qnw2oV74sAtT7)8BdbdlV&Ay2i77gNh(blV3H@!Yb zEfJM%h9_Sfm2(=5?-e$87X5?Vh=!a@efiWs(p1kcN6fF z9h44FdSia{Xb^rb*orIv`{s=>-Sk1vts{_=z7GRXCYf2+$=KueFrnU66kCKs2ABsH z?CI}4c_jtDCTBd~pWZ;M@p!#_W%~IC#P^rMl*kA2Lf_K)n{tUgDG$>3!!m1QMwvDu zbHAVJ*n!w27Nv%Si*M%yZ);OJM?!(`U-)u|A|J&EVcfYrPE+}LQ-dT3i6l&)+~L0u z1g+gy8$A+X(q+NTpCOW@m@M4?msKAngxl*HQczjcO|begwht&7W3mbx0h8v*drlj; zV8ZAn^)%AE9(Z7BG4GR^WHT@+k5gHiX(u%Q7{2J=cpv6;M}Tyw*WYQASwEWg_g{OMJi0O zLQhyJ!hD|b>!O8@HGbbIx^(ht$O$3rN! zgQ@NXpkqe4f(^+pjc50}_|yuIr3lMsmB<16&MGsFnAn7+@}$_vu}43?t|m4C&3#rL zs;dal0AcSO?98`P(+QVqrY6NX7LqW!O`djN$03Iucn$cH8zcC7JdY3;?nIt>`cL|b;C=bBR|E{fVWIR2e zu7ZBKT)29b9o6#Xg88Gs)ge+xb0dv(_LEb%Tn(B7mtQ6C=ij(ql(bVlx7603zrDR# z@6JEnSbNj`@na`yO&^0sZ!t;7LmfRbsL=7fG$?yY6$)@=>IBc`i}z*4NBcdIeImt6 zK_URlad&sDlbcc#jIw)Jbm$DO>p^AL9b+liWtEy7ZW{W^oU*x=m01Rg43y(sZOnpI z%^4Puut0rQc-a~|)TV+CC6mY~K{kmBC&5Z&QAiKVe(zCPHcq@0zma#@-~>qLeT~*2py?9;OiK6fJL}wN45sIUDoZHRn`i7uRC#_Jl0hbTf5VB3Yct$4Ze z$Xpk2<)t7+zg}Eb=}U56`cvaNaCShLpJwfZRgFnT+jR%{J*~?EAGnge-h!}7pl=Zb1Tl2ae6C)p^mYZePZO|F!1EGGzTXE(y@#k3=WhhSh@TDPlE6S zSVz}L5LjdUDreb`wqT(Y{)ke?K28WO|BZ|*Ecz#nG!G4}G^LnoORu6^YXZITH-xBu zp$7#fGP1}#>kFKR8pcN&)(1GulworNx#=@!i0Ko$*F5si4`?;~x>V35bZz{pg1<*` zUfT&P&I0HpPr=WjMLGMV40uY(yUSKsz=<842525KVtX@AoLR($&#dxHuSk-uLz=Y}|DN{W_A&MUuPcPrkzv_)@z<9zb3 zr=bkUVWofsRWmT1vrKv9etg;tU5d(1QVR|Qz(HwZPgVcMIPvg1RUR4p2do6gE;TmR z5h~qYNvbrZJ~9@S4hZY2m#W=NnmqFtavr>zbon=A^QOFM^xWxC=4fjwmz%e_DaZ)N|D(X`xcsY3=RStSa&KJz50?f7l2smY zU#yyX?_Hgh??+5pzU6}-%KYE2XRX^;x#d6p5={O^5%8!W=iTSe|2#I+-{6a_`qC|l zXn&_>7@ZV+et;1D+c5vFB+L~~C$JaO723?i zH4SerF>rK(s+s8{8c<;Gw$Qm>S&mQc>p?J2)^3NEo<`E_q$1hSTkeYL%4YfnY(j}d z?fG|#|E^D1R2hR&T)?;JPm1+cSF$ynhsj=*5~{51Q^B3Hmco1;SBDMT4;SA`v!HbQ zM5?gN<{#tWAm%b8UOou_^Ywe$8$>m%0^D#}O&DQogL-U&20+|_#4J#bVte(NzCzQ~ zXxP+B$QU5-mFdT^Y(c}CO29MTeG>MVGOKV1rrEq{2yYyULF&f}sB$$;ovjoc0#0gY zm*&vWI1ccfh9q6YC*Q}iG>WMcpU6uBcP|EN@9^Ib1pP-jW^zvmYmT3#F2|~-Rw{?v zzYGEu$Q=J%W`*-~bM={jlwcMZpzlp63BdB^O-M|*B$%_f>DUg(v@Uv11BKchf=P+l zhg+Ft9DstCn?aM!#~A`;Q|eaNFu)NB7yV=JEf21|FUdEt+g*UzP}Av<*PJgvzSEW#n4d6DO4J1`#`eD@akqd=yv=Dd1v;NV{Q!F z_sH;5l0_WRfXtDp{_)U8ij1R?z+&+{L%rg`_p?Iu=9kt~3|8#KoNP{uPf3eJWs3Nc zd4vXLjf^r+6tfUNl$D_*2~Ve}g9cac)zOS{%a4{8Z)H@)dyW`kojA7BS(cqYwDmBy zD1)nzmKrIUTth%O3mfu;fE-!^u~CCi+WxnG-{Tp)FQgCRE39x}0+i$r%W|WgENy)a z@d;bNvpTmg3+pfsNib~ZR3b=Xn8>iysTeWI6i?6tKx9|m(<>$KP?0R^h@7sZo~k>5c|MpANeS9JGk?=i@$$-vSicLE`GZY zhjiUC>P=skY9DRO%bQoY3W#_9nWuT{a>1FOeQD#<^{R$aw`;NI^G(Gq?Nm4SnIAH8 zn(<(^0jsh8>z}^KE$#%bp4!c$KYcrFf`L)MWNSY@+9;ML&?n*Zwv17%#sC{YoFAiHqkNy-@4=dHbACJSxFhDO;i`6rf!}{PN$w1aukG{uqRLgETw9`M zK?rBwyWL-Ln}|IOCr~72&Mif&7L8sM$t7f#9&V`SgzN4~1eph7Ba}mp%c%KkulNUT zMYz07QDePAS^vksZ3hyHn$7*^@CAQ3W>s#Y3lL}IuJq?3kR+Lz%OAH})5pd;w(w7> zCMAiDJw|o8CyxAZSaif@`mz3QZr9u#5-zy8z5Vx{gjQ)}Xr;?9$=y4HWw-UZcC!2FTIpoaQ?R=FUW>`_=r*p?fMMeN zYyZ;pz*)_oZ%+CxFe#mS!7%l!owO>260KR@bnRnad=)kVj;4C2R{h6@FKnS)7=SG5 zl?$R6uGasDc9_e9^up9NkBF9nt#cfq+@@Ntxd==RRe&WX2@E2k1diyM9q$tHLm! z@U4jfs*en>wt^St%s^!Sw2sbl1=gA={-kyXo^7b0NR)bHo3|_S zyFmPU`TI32rEQ$|+2fv@*RIL+HxROAGUdn|i}M-xW|N-#_fNid4`9Mb9e6c*0eDnz z=msT-*sb5IInG#A<`RMX*3-3Kos#q0-A}7o39fPV4~VPvDd@3%OS_Th9Xs_at-T;Z zf~PH z^Eyyo|G|Lyp#3Am=_Ca;R=s|W&=<90A36^-$C5K%GZ;uLG?9%X70@$=V3(9T{I!Gd z7)&&*2w`qoN=H4i9}P)`(u603Z2HWhwn8}m=dr5^Ru;c~$;q;qyZX&h$-gxL!k{O% zVloOyXn$fmfCETAvXTqvqZ}OrROZ6ssU27a^Q^=J3JgLO^ny$Y=UiONOfJWzeWx&O z{h82+U6t@b^nPy{Aq@$se8qapaQMkd1jyGf(KUJ~ zWKVGh+{(=i=Of>WpBR*Qpi6-5wL!FNO#Qn~&Z6SH$|jNcWyK>WotP3Kr8q*6DK~?6 zW~J`?l4{<#?G$TNT=v+kjbx<6*$fbD#b(DLkQSKu)iV_WQmfVHDTN~lloWL+_vGxf z(n0B8X2cK!g)IZf`7f0`;2Of_zV&#M5fbwmF>vSpz_VI0#PNfx2YrQKbe1hSP|84M z#_eq%(e$Mdw3{aa)sej!F9xDYm|{y>#@&Lu44nQ-tiJN+|CJrEQC8MO#UQ0OUi@X_vriAp73D@3XSE@BcRh2sHlqD+0%_HPNx z(!pucAa0&bqR8n*iX7TVNty8Z`1o9JXFxPGG!JiY z2g4G#ENpLYsi`xm@qsmb%}LE|Y4o9u7-XNc46l*StdUK8@F1waAL)jBk^inK(9o1A k_7CLp@y$EZIMU-D?zVqcnl%(Ol|==lqy)sP|Nor-0lof=5C8xG literal 0 HcmV?d00001 diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index 55fdcfb3ebe..95766942540 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -132,6 +132,7 @@ + @@ -588,6 +589,7 @@ + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Activities/InvokeActionsActivity.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Activities/InvokeActionsActivity.bind new file mode 100644 index 00000000000..ac325ddb2f7 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Activities/InvokeActionsActivity.bind @@ -0,0 +1,54 @@ + + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml index 6753d0f8971..cb97cca1945 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml @@ -4,8 +4,11 @@ xmlns:ani="using:Microsoft.Toolkit.Uwp.UI.Animations" xmlns:anibehaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors.Animations" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:interactions="using:Microsoft.Xaml.Interactions.Core" + xmlns:interactivity="using:Microsoft.Xaml.Interactivity" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:media="using:Microsoft.Toolkit.Uwp.UI.Media" + xmlns:mediaactions="using:Microsoft.Xaml.Interactions.Media" xmlns:triggers="using:Microsoft.Toolkit.Uwp.UI.Triggers" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" mc:Ignorable="d"> @@ -30,6 +33,7 @@ + @@ -37,5 +41,13 @@ + + + + + + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json index 5c9aae295d4..7eb708f0190 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json @@ -468,6 +468,14 @@ "XamlCodeFile": "/SamplePages/Animations/Activities/StartAnimationActivity.bind", "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/animations/Fade.md" }, + { + "Name": "InvokeActionsActivity", + "Subcategory": "Activities", + "About": "Activity chaining Actions from the Behaviors package into an Animation schedule.", + "CodeUrl": "https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations", + "XamlCodeFile": "/SamplePages/Animations/Activities/InvokeActionsActivity.bind", + "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/animations/Fade.md" + }, { "Name": "Fade", "Subcategory": "Effect", diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/InvokeActionsActivity.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/InvokeActionsActivity.cs new file mode 100644 index 00000000000..1d8ea52bd55 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/InvokeActionsActivity.cs @@ -0,0 +1,56 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Toolkit.Uwp.UI.Animations; +using Microsoft.Xaml.Interactivity; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Markup; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// The is an which allows bridging to performing any behavior based within the schedule. + /// + [ContentProperty(Name = nameof(Actions))] + public class InvokeActionsActivity : Activity + { + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty ActionsProperty = DependencyProperty.Register( + nameof(Actions), + typeof(ActionCollection), + typeof(InvokeActionsActivity), + new PropertyMetadata(null)); + + /// + /// Gets the collection of actions associated with the behavior. This is a dependency property. + /// + public ActionCollection Actions + { + get + { + if (GetValue(ActionsProperty) is not ActionCollection actionCollection) + { + actionCollection = new ActionCollection(); + + SetValue(ActionsProperty, actionCollection); + } + + return actionCollection; + } + } + + /// + public override async Task InvokeAsync(UIElement element, CancellationToken token) + { + await base.InvokeAsync(element, token); + + Interaction.ExecuteActions(element, Actions, EventArgs.Empty); + } + } +} From 93c8244c5e661d5c9a176ad9d4e4253edc8afc5e Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 8 Jan 2021 23:14:20 +0100 Subject: [PATCH 141/171] Added direction parameter to compositor extensions --- .../Extensions/CompositorExtensions.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs index da2450c9d3b..a12a165367f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/CompositorExtensions.cs @@ -72,6 +72,7 @@ public static CubicBezierEasingFunction CreateCubicBezierEasingFunction(this Com /// The optional initial delay for the animation. /// The optional animation duration. /// The delay behavior to use for the animation. + /// The direction to use when playing the animation. /// The iteration behavior to use for the animation. /// The iteration count to use for the animation. /// A instance with the specified parameters. @@ -84,6 +85,7 @@ public static BooleanKeyFrameAnimation CreateBooleanKeyFrameAnimation( TimeSpan? delay = null, TimeSpan? duration = null, AnimationDelayBehavior delayBehavior = AnimationDelayBehavior.SetInitialValueBeforeDelay, + AnimationDirection direction = AnimationDirection.Normal, AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count, int iterationCount = 1) { @@ -105,6 +107,7 @@ public static BooleanKeyFrameAnimation CreateBooleanKeyFrameAnimation( } animation.Target = target; + animation.Direction = direction; animation.IterationBehavior = iterationBehavior; animation.IterationCount = iterationCount; @@ -122,6 +125,7 @@ public static BooleanKeyFrameAnimation CreateBooleanKeyFrameAnimation( /// The optional animation duration. /// The optional easing function for the animation. /// The delay behavior to use for the animation. + /// The direction to use when playing the animation. /// The iteration behavior to use for the animation. /// The iteration count to use for the animation. /// A instance with the specified parameters. @@ -135,6 +139,7 @@ public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation( TimeSpan? duration = null, CompositionEasingFunction? easing = null, AnimationDelayBehavior delayBehavior = AnimationDelayBehavior.SetInitialValueBeforeDelay, + AnimationDirection direction = AnimationDirection.Normal, AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count, int iterationCount = 1) { @@ -163,6 +168,7 @@ public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation( } animation.Target = target; + animation.Direction = direction; animation.IterationBehavior = iterationBehavior; animation.IterationCount = iterationCount; @@ -180,6 +186,7 @@ public static ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation( /// The optional animation duration. /// The optional easing function for the animation. /// The delay behavior to use for the animation. + /// The direction to use when playing the animation. /// The iteration behavior to use for the animation. /// The iteration count to use for the animation. /// A instance with the specified parameters. @@ -193,6 +200,7 @@ public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation( TimeSpan? duration = null, CompositionEasingFunction? easing = null, AnimationDelayBehavior delayBehavior = AnimationDelayBehavior.SetInitialValueBeforeDelay, + AnimationDirection direction = AnimationDirection.Normal, AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count, int iterationCount = 1) { @@ -221,6 +229,7 @@ public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation( } animation.Target = target; + animation.Direction = direction; animation.IterationBehavior = iterationBehavior; animation.IterationCount = iterationCount; @@ -238,6 +247,7 @@ public static Vector2KeyFrameAnimation CreateVector2KeyFrameAnimation( /// The optional animation duration. /// The optional easing function for the animation. /// The delay behavior to use for the animation. + /// The direction to use when playing the animation. /// The iteration behavior to use for the animation. /// The iteration count to use for the animation. /// A instance with the specified parameters. @@ -251,6 +261,7 @@ public static Vector3KeyFrameAnimation CreateVector3KeyFrameAnimation( TimeSpan? duration = null, CompositionEasingFunction? easing = null, AnimationDelayBehavior delayBehavior = AnimationDelayBehavior.SetInitialValueBeforeDelay, + AnimationDirection direction = AnimationDirection.Normal, AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count, int iterationCount = 1) { @@ -279,6 +290,7 @@ public static Vector3KeyFrameAnimation CreateVector3KeyFrameAnimation( } animation.Target = target; + animation.Direction = direction; animation.IterationBehavior = iterationBehavior; animation.IterationCount = iterationCount; @@ -296,6 +308,7 @@ public static Vector3KeyFrameAnimation CreateVector3KeyFrameAnimation( /// The optional animation duration. /// The optional easing function for the animation. /// The delay behavior to use for the animation. + /// The direction to use when playing the animation. /// The iteration behavior to use for the animation. /// The iteration count to use for the animation. /// A instance with the specified parameters. @@ -309,6 +322,7 @@ public static Vector4KeyFrameAnimation CreateVector4KeyFrameAnimation( TimeSpan? duration = null, CompositionEasingFunction? easing = null, AnimationDelayBehavior delayBehavior = AnimationDelayBehavior.SetInitialValueBeforeDelay, + AnimationDirection direction = AnimationDirection.Normal, AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count, int iterationCount = 1) { @@ -337,6 +351,7 @@ public static Vector4KeyFrameAnimation CreateVector4KeyFrameAnimation( } animation.Target = target; + animation.Direction = direction; animation.IterationBehavior = iterationBehavior; animation.IterationCount = iterationCount; @@ -354,6 +369,7 @@ public static Vector4KeyFrameAnimation CreateVector4KeyFrameAnimation( /// The optional animation duration. /// The optional easing function for the animation. /// The delay behavior to use for the animation. + /// The direction to use when playing the animation. /// The iteration behavior to use for the animation. /// The iteration count to use for the animation. /// A instance with the specified parameters. @@ -367,6 +383,7 @@ public static ColorKeyFrameAnimation CreateColorKeyFrameAnimation( TimeSpan? duration = null, CompositionEasingFunction? easing = null, AnimationDelayBehavior delayBehavior = AnimationDelayBehavior.SetInitialValueBeforeDelay, + AnimationDirection direction = AnimationDirection.Normal, AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count, int iterationCount = 1) { @@ -395,6 +412,7 @@ public static ColorKeyFrameAnimation CreateColorKeyFrameAnimation( } animation.Target = target; + animation.Direction = direction; animation.IterationBehavior = iterationBehavior; animation.IterationCount = iterationCount; @@ -412,6 +430,7 @@ public static ColorKeyFrameAnimation CreateColorKeyFrameAnimation( /// The optional animation duration. /// The optional easing function for the animation. /// The delay behavior to use for the animation. + /// The direction to use when playing the animation. /// The iteration behavior to use for the animation. /// The iteration count to use for the animation. /// A instance with the specified parameters. @@ -425,6 +444,7 @@ public static QuaternionKeyFrameAnimation CreateQuaternionKeyFrameAnimation( TimeSpan? duration = null, CompositionEasingFunction? easing = null, AnimationDelayBehavior delayBehavior = AnimationDelayBehavior.SetInitialValueBeforeDelay, + AnimationDirection direction = AnimationDirection.Normal, AnimationIterationBehavior iterationBehavior = AnimationIterationBehavior.Count, int iterationCount = 1) { @@ -453,6 +473,7 @@ public static QuaternionKeyFrameAnimation CreateQuaternionKeyFrameAnimation( } animation.Target = target; + animation.Direction = direction; animation.IterationBehavior = iterationBehavior; animation.IterationCount = iterationCount; From aaa6b0d73d25f6e9d9431806047fb737ec83e2e6 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 12 Jan 2021 21:46:47 +0100 Subject: [PATCH 142/171] Added more options to XAML animation extensions --- .../Builders/AnimationBuilder.Factories.cs | 6 ++-- .../Extensions/DependencyObjectExtensions.cs | 31 +++++++++++++++++-- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs index 4cf58b95856..7468cbf5dfd 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.Factories.cs @@ -179,7 +179,7 @@ public Timeline GetAnimation(DependencyObject targetHint) Delay, Duration, easingFunction, - true); + enableDependecyAnimations: true); } if (typeof(T) == typeof(double)) @@ -191,7 +191,7 @@ public Timeline GetAnimation(DependencyObject targetHint) Delay, Duration, easingFunction, - true); + enableDependecyAnimations: true); } if (typeof(T) == typeof(Point)) @@ -203,7 +203,7 @@ public Timeline GetAnimation(DependencyObject targetHint) Delay, Duration, easingFunction, - true); + enableDependecyAnimations: true); } if (typeof(T) == typeof(Color)) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs index a572b7a68a0..dbaa79c384b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Extensions/DependencyObjectExtensions.cs @@ -29,6 +29,9 @@ public static class DependencyObjectExtensions /// The optional delay for the animation. /// The duration of the . /// The easing function to use inside the . + /// The repeat behavior for the animation (defaults to one iteration). + /// The behavior to use when the animation reaches the end of its schedule. + /// Indicates whether the animation plays in reverse after each forward iteration. /// Indicates whether or not to apply this animation to elements that need the visual tree to be rearranged. /// A instance with the specified parameters. [Pure] @@ -40,6 +43,9 @@ public static DoubleAnimation CreateDoubleAnimation( TimeSpan? delay, TimeSpan duration, EasingFunctionBase? easing = null, + RepeatBehavior? repeatBehavior = null, + FillBehavior fillBehavior = FillBehavior.HoldEnd, + bool autoReverse = false, bool enableDependecyAnimations = false) { DoubleAnimation animation = new() @@ -49,6 +55,9 @@ public static DoubleAnimation CreateDoubleAnimation( BeginTime = delay, Duration = duration, EasingFunction = easing, + RepeatBehavior = repeatBehavior ?? new RepeatBehavior(1), + FillBehavior = fillBehavior, + AutoReverse = autoReverse, EnableDependentAnimation = enableDependecyAnimations }; @@ -68,6 +77,9 @@ public static DoubleAnimation CreateDoubleAnimation( /// The optional delay for the animation. /// The duration of the . /// The easing function to use inside the . + /// The repeat behavior for the animation (defaults to one iteration). + /// The behavior to use when the animation reaches the end of its schedule. + /// Indicates whether the animation plays in reverse after each forward iteration. /// Indicates whether or not to apply this animation to elements that need the visual tree to be rearranged. /// A instance with the specified parameters. [Pure] @@ -79,6 +91,9 @@ public static PointAnimation CreatePointAnimation( TimeSpan? delay, TimeSpan duration, EasingFunctionBase? easing = null, + RepeatBehavior? repeatBehavior = null, + FillBehavior fillBehavior = FillBehavior.HoldEnd, + bool autoReverse = false, bool enableDependecyAnimations = false) { PointAnimation animation = new() @@ -88,6 +103,9 @@ public static PointAnimation CreatePointAnimation( BeginTime = delay, Duration = duration, EasingFunction = easing, + RepeatBehavior = repeatBehavior ?? new RepeatBehavior(1), + FillBehavior = fillBehavior, + AutoReverse = autoReverse, EnableDependentAnimation = enableDependecyAnimations }; @@ -107,6 +125,9 @@ public static PointAnimation CreatePointAnimation( /// The optional delay for the animation. /// The duration of the . /// The easing function to use inside the . + /// The repeat behavior for the animation (defaults to one iteration). + /// The behavior to use when the animation reaches the end of its schedule. + /// Indicates whether the animation plays in reverse after each forward iteration. /// A instance with the specified parameters. [Pure] public static XamlColorAnimation CreateColorAnimation( @@ -116,7 +137,10 @@ public static XamlColorAnimation CreateColorAnimation( Color? from, TimeSpan? delay, TimeSpan duration, - EasingFunctionBase? easing = null) + EasingFunctionBase? easing = null, + RepeatBehavior? repeatBehavior = null, + FillBehavior fillBehavior = FillBehavior.HoldEnd, + bool autoReverse = false) { XamlColorAnimation animation = new() { @@ -124,7 +148,10 @@ public static XamlColorAnimation CreateColorAnimation( From = from, BeginTime = delay, Duration = duration, - EasingFunction = easing + EasingFunction = easing, + RepeatBehavior = repeatBehavior ?? new RepeatBehavior(1), + FillBehavior = fillBehavior, + AutoReverse = autoReverse }; Storyboard.SetTarget(animation, target); From 8bac49cb777fe8e92115251fcd88979417ae49f6 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 12 Jan 2021 22:37:03 +0100 Subject: [PATCH 143/171] Added RepeatOption type --- .../Options/RepeatOption.cs | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs new file mode 100644 index 00000000000..1bf7469b5c4 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs @@ -0,0 +1,110 @@ +using System; +using System.Diagnostics.Contracts; +using System.Linq; +using Microsoft.Toolkit.Diagnostics; +using Windows.Foundation.Metadata; +using Windows.UI.Composition; +using Windows.UI.Xaml.Media.Animation; + +#pragma warning disable CS0419 + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// A type describing the repeat behavior for a custom animation. + /// + [CreateFromString(MethodName = "Microsoft.Toolkit.Uwp.UI.Animations.RepeatOption.Parse")] + public readonly struct RepeatOption + { + /// + /// The number of iterations for the animation. + /// + private readonly int value; + + /// + /// Initializes a new instance of the struct. + /// + /// The number of iterations for the animation. + private RepeatOption(int value) + { + this.value = value; + } + + /// + /// Gets a value representing a single iteration. + /// + public static RepeatOption One => new(1); + + /// + /// Gets a value indicating an animation that repeats forever. + /// + public static RepeatOption Forever => new(-1); + + /// + /// Creates a value with the specified number of iterations. + /// + /// The number of iterations for the animation. + /// A value with the specified number of iterations. + /// Thrown when is negative. + [Pure] + public static RepeatOption Count(int count) + { + Guard.IsGreaterThanOrEqualTo(count, 0, nameof(count)); + + return new(count); + } + + /// + /// Parses a value from a . + /// The allowed values are either non-negative integers, or "Forever". + /// + /// The input text to parse. + /// The parsed value. + [Pure] + public static RepeatOption Parse(string text) + { + if (int.TryParse(text, out int count)) + { + return Count(count); + } + + if (text.AsSpan().Trim().SequenceEqual("Forever".AsSpan())) + { + return Forever; + } + + return ThrowHelper.ThrowArgumentException("Invalid input text"); + } + + /// + /// Gets a value corresponding to the current value. + /// + /// A value matching the current value. + [Pure] + public RepeatBehavior ToRepeatBehavior() + { + if (this.value < 0) + { + return RepeatBehavior.Forever; + } + + return new(this.value); + } + + /// + /// Gets the and count values matching the current value. + /// If the current value represents an infinitely repeating animation, the returned count will be set to 1. + /// + /// The and count values matching the current value. + [Pure] + public (AnimationIterationBehavior Behavior, int Count) ToBehaviorAndCount() + { + if (this.value < 0) + { + return (AnimationIterationBehavior.Forever, 1); + } + + return (AnimationIterationBehavior.Count, this.value); + } + } +} From cf76265892ce9cb83a94356a4d42b10d46c4493f Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 12 Jan 2021 22:55:46 +0100 Subject: [PATCH 144/171] Added RepeatOption support to AnimationBuilder --- .../Builders/AnimationBuilder.KeyFrames.cs | 40 ++++++++-- .../AnimationBuilder.PropertyBuilders.cs | 76 +++++++++++++------ .../IPropertyAnimationBuilder{T}.cs | 16 +++- ...KeyFrameAnimationBuilder{T}.Composition.cs | 8 +- ...malizedKeyFrameAnimationBuilder{T}.Xaml.cs | 5 +- .../NormalizedKeyFrameAnimationBuilder{T}.cs | 9 ++- ...KeyFrameAnimationBuilder{T}.Composition.cs | 5 +- .../TimedKeyFrameAnimationBuilder{T}.Xaml.cs | 8 +- .../TimedKeyFrameAnimationBuilder{T}.cs | 9 ++- 9 files changed, 130 insertions(+), 46 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.KeyFrames.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.KeyFrames.cs index 2f786ad6d03..da124833948 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.KeyFrames.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.KeyFrames.cs @@ -235,6 +235,7 @@ public IPropertyAnimationBuilder Size() /// The callback to use to construct the custom animation. /// The optional initial delay for the animation. /// The animation duration. + /// The repeat option for the animation (defaults to one iteration). /// The target framework layer to animate. /// The current instance. public AnimationBuilder NormalizedKeyFrames( @@ -242,12 +243,17 @@ public AnimationBuilder NormalizedKeyFrames( Action> build, TimeSpan? delay = null, TimeSpan? duration = null, + RepeatOption? repeatOption = null, FrameworkLayer layer = FrameworkLayer.Composition) where T : unmanaged { if (layer == FrameworkLayer.Composition) { - NormalizedKeyFrameAnimationBuilder.Composition builder = new(property, delay, duration ?? DefaultDuration); + NormalizedKeyFrameAnimationBuilder.Composition builder = new( + property, + delay, + duration ?? DefaultDuration, + repeatOption ?? RepeatOption.One); build(builder); @@ -255,7 +261,11 @@ public AnimationBuilder NormalizedKeyFrames( } else { - NormalizedKeyFrameAnimationBuilder.Xaml builder = new(property, delay, duration ?? DefaultDuration); + NormalizedKeyFrameAnimationBuilder.Xaml builder = new( + property, + delay, + duration ?? DefaultDuration, + repeatOption ?? RepeatOption.One); build(builder); @@ -275,6 +285,7 @@ public AnimationBuilder NormalizedKeyFrames( /// The callback to use to construct the custom animation. /// The optional initial delay for the animation. /// The animation duration. + /// The repeat option for the animation (defaults to one iteration). /// The target framework layer to animate. /// The current instance. public AnimationBuilder NormalizedKeyFrames( @@ -283,12 +294,17 @@ public AnimationBuilder NormalizedKeyFrames( Action, TState> build, TimeSpan? delay = null, TimeSpan? duration = null, + RepeatOption? repeatOption = null, FrameworkLayer layer = FrameworkLayer.Composition) where T : unmanaged { if (layer == FrameworkLayer.Composition) { - NormalizedKeyFrameAnimationBuilder.Composition builder = new(property, delay, duration ?? DefaultDuration); + NormalizedKeyFrameAnimationBuilder.Composition builder = new( + property, + delay, + duration ?? DefaultDuration, + repeatOption ?? RepeatOption.One); build(builder, state); @@ -296,7 +312,11 @@ public AnimationBuilder NormalizedKeyFrames( } else { - NormalizedKeyFrameAnimationBuilder.Xaml builder = new(property, delay, duration ?? DefaultDuration); + NormalizedKeyFrameAnimationBuilder.Xaml builder = new( + property, + delay, + duration ?? DefaultDuration, + repeatOption ?? RepeatOption.One); build(builder, state); @@ -313,18 +333,20 @@ public AnimationBuilder NormalizedKeyFrames( /// The target property to animate. /// The callback to use to construct the custom animation. /// The optional initial delay for the animation. + /// The repeat option for the animation (defaults to one iteration). /// The target framework layer to animate. /// The current instance. public AnimationBuilder TimedKeyFrames( string property, Action> build, TimeSpan? delay = null, + RepeatOption? repeatOption = null, FrameworkLayer layer = FrameworkLayer.Composition) where T : unmanaged { if (layer == FrameworkLayer.Composition) { - TimedKeyFrameAnimationBuilder.Composition builder = new(property, delay); + TimedKeyFrameAnimationBuilder.Composition builder = new(property, delay, repeatOption ?? RepeatOption.One); build(builder); @@ -332,7 +354,7 @@ public AnimationBuilder TimedKeyFrames( } else { - TimedKeyFrameAnimationBuilder.Xaml builder = new(property, delay); + TimedKeyFrameAnimationBuilder.Xaml builder = new(property, delay, repeatOption ?? RepeatOption.One); build(builder); @@ -351,6 +373,7 @@ public AnimationBuilder TimedKeyFrames( /// The state to pass to the builder. /// The callback to use to construct the custom animation. /// The optional initial delay for the animation. + /// The repeat option for the animation (defaults to one iteration). /// The target framework layer to animate. /// The current instance. public AnimationBuilder TimedKeyFrames( @@ -358,12 +381,13 @@ public AnimationBuilder TimedKeyFrames( TState state, Action, TState> build, TimeSpan? delay = null, + RepeatOption? repeatOption = null, FrameworkLayer layer = FrameworkLayer.Composition) where T : unmanaged { if (layer == FrameworkLayer.Composition) { - TimedKeyFrameAnimationBuilder.Composition builder = new(property, delay); + TimedKeyFrameAnimationBuilder.Composition builder = new(property, delay, repeatOption ?? RepeatOption.One); build(builder, state); @@ -371,7 +395,7 @@ public AnimationBuilder TimedKeyFrames( } else { - TimedKeyFrameAnimationBuilder.Xaml builder = new(property, delay); + TimedKeyFrameAnimationBuilder.Xaml builder = new(property, delay, repeatOption ?? RepeatOption.One); build(builder, state); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs index 02f91ca880b..0a3d47d9f69 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs @@ -31,9 +31,10 @@ private sealed record PropertyAnimationBuilder( public AnimationBuilder NormalizedKeyFrames( Action> build, TimeSpan? delay, - TimeSpan? duration) + TimeSpan? duration, + RepeatOption? repeatOption) { - return Builder.NormalizedKeyFrames(Property, build, delay, duration, Layer); + return Builder.NormalizedKeyFrames(Property, build, delay, duration, repeatOption, Layer); } /// @@ -41,26 +42,29 @@ public AnimationBuilder NormalizedKeyFrames( TState state, Action, TState> build, TimeSpan? delay, - TimeSpan? duration) + TimeSpan? duration, + RepeatOption? repeatOption) { - return Builder.NormalizedKeyFrames(Property, state, build, delay, duration, Layer); + return Builder.NormalizedKeyFrames(Property, state, build, delay, duration, repeatOption, Layer); } /// public AnimationBuilder TimedKeyFrames( Action> build, - TimeSpan? delay) + TimeSpan? delay, + RepeatOption? repeatOption) { - return Builder.TimedKeyFrames(Property, build, delay, Layer); + return Builder.TimedKeyFrames(Property, build, delay, repeatOption, Layer); } /// public AnimationBuilder TimedKeyFrames( TState state, Action, TState> build, - TimeSpan? delay) + TimeSpan? delay, + RepeatOption? repeatOption) { - return Builder.TimedKeyFrames(Property, state, build, delay, Layer); + return Builder.TimedKeyFrames(Property, state, build, delay, repeatOption, Layer); } } @@ -76,9 +80,14 @@ private sealed record CompositionClipAnimationBuilder( public AnimationBuilder NormalizedKeyFrames( Action> build, TimeSpan? delay, - TimeSpan? duration) + TimeSpan? duration, + RepeatOption? repeatOption) { - NormalizedKeyFrameAnimationBuilder.Composition builder = new(Property, delay, duration ?? DefaultDuration); + NormalizedKeyFrameAnimationBuilder.Composition builder = new( + Property, + delay, + duration ?? DefaultDuration, + repeatOption ?? RepeatOption.One); build(builder); @@ -92,9 +101,14 @@ public AnimationBuilder NormalizedKeyFrames( TState state, Action, TState> build, TimeSpan? delay, - TimeSpan? duration) + TimeSpan? duration, + RepeatOption? repeatOption) { - NormalizedKeyFrameAnimationBuilder.Composition builder = new(Property, delay, duration ?? DefaultDuration); + NormalizedKeyFrameAnimationBuilder.Composition builder = new( + Property, + delay, + duration ?? DefaultDuration, + repeatOption ?? RepeatOption.One); build(builder, state); @@ -106,9 +120,10 @@ public AnimationBuilder NormalizedKeyFrames( /// public AnimationBuilder TimedKeyFrames( Action> build, - TimeSpan? delay) + TimeSpan? delay, + RepeatOption? repeatOption) { - TimedKeyFrameAnimationBuilder.Composition builder = new(Property, delay); + TimedKeyFrameAnimationBuilder.Composition builder = new(Property, delay, repeatOption ?? RepeatOption.One); build(builder); @@ -121,9 +136,10 @@ public AnimationBuilder TimedKeyFrames( public AnimationBuilder TimedKeyFrames( TState state, Action, TState> build, - TimeSpan? delay) + TimeSpan? delay, + RepeatOption? repeatOption) { - TimedKeyFrameAnimationBuilder.Composition builder = new(Property, delay); + TimedKeyFrameAnimationBuilder.Composition builder = new(Property, delay, repeatOption ?? RepeatOption.One); build(builder, state); @@ -163,9 +179,14 @@ private sealed record XamlTransformPropertyAnimationBuilder( public AnimationBuilder NormalizedKeyFrames( Action> build, TimeSpan? delay, - TimeSpan? duration) + TimeSpan? duration, + RepeatOption? repeatOption) { - NormalizedKeyFrameAnimationBuilder.Xaml builder = new(Property, delay, duration ?? DefaultDuration); + NormalizedKeyFrameAnimationBuilder.Xaml builder = new( + Property, + delay, + duration ?? DefaultDuration, + repeatOption ?? RepeatOption.One); build(builder); @@ -179,9 +200,14 @@ public AnimationBuilder NormalizedKeyFrames( TState state, Action, TState> build, TimeSpan? delay, - TimeSpan? duration) + TimeSpan? duration, + RepeatOption? repeatOption) { - NormalizedKeyFrameAnimationBuilder.Xaml builder = new(Property, delay, duration ?? DefaultDuration); + NormalizedKeyFrameAnimationBuilder.Xaml builder = new( + Property, + delay, + duration ?? DefaultDuration, + repeatOption ?? RepeatOption.One); build(builder, state); @@ -193,9 +219,10 @@ public AnimationBuilder NormalizedKeyFrames( /// public AnimationBuilder TimedKeyFrames( Action> build, - TimeSpan? delay) + TimeSpan? delay, + RepeatOption? repeatOption) { - TimedKeyFrameAnimationBuilder.Xaml builder = new(Property, delay); + TimedKeyFrameAnimationBuilder.Xaml builder = new(Property, delay, repeatOption ?? RepeatOption.One); build(builder); @@ -208,9 +235,10 @@ public AnimationBuilder TimedKeyFrames( public AnimationBuilder TimedKeyFrames( TState state, Action, TState> build, - TimeSpan? delay) + TimeSpan? delay, + RepeatOption? repeatOption) { - TimedKeyFrameAnimationBuilder.Xaml builder = new(Property, delay); + TimedKeyFrameAnimationBuilder.Xaml builder = new(Property, delay, repeatOption ?? RepeatOption.One); build(builder, state); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs index f2a3668894f..3947e0b0319 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs @@ -18,11 +18,13 @@ public interface IPropertyAnimationBuilder /// The callback to use to construct the custom animation. /// The optional initial delay for the animation. /// The animation duration. + /// The repeat option for the animation (defaults to one iteration). /// The current instance. AnimationBuilder NormalizedKeyFrames( Action> build, TimeSpan? delay = null, - TimeSpan? duration = null); + TimeSpan? duration = null, + RepeatOption? repeatOption = null); /// /// Adds a custom animation based on normalized keyframes ot the current schedule. @@ -32,22 +34,26 @@ AnimationBuilder NormalizedKeyFrames( /// The callback to use to construct the custom animation. /// The optional initial delay for the animation. /// The animation duration. + /// The repeat option for the animation (defaults to one iteration). /// The current instance. AnimationBuilder NormalizedKeyFrames( TState state, Action, TState> build, TimeSpan? delay = null, - TimeSpan? duration = null); + TimeSpan? duration = null, + RepeatOption? repeatOption = null); /// /// Adds a custom animation based on timed keyframes to the current schedule. /// /// The callback to use to construct the custom animation. /// The optional initial delay for the animation. + /// The repeat option for the animation (defaults to one iteration). /// The current instance. AnimationBuilder TimedKeyFrames( Action> build, - TimeSpan? delay = null); + TimeSpan? delay = null, + RepeatOption? repeatOption = null); /// /// Adds a custom animation based on timed keyframes to the current schedule. @@ -56,10 +62,12 @@ AnimationBuilder TimedKeyFrames( /// The state to pass to the builder. /// The callback to use to construct the custom animation. /// The optional initial delay for the animation. + /// The repeat option for the animation (defaults to one iteration). /// The current instance. AnimationBuilder TimedKeyFrames( TState state, Action, TState> build, - TimeSpan? delay = null); + TimeSpan? delay = null, + RepeatOption? repeatOption = null); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs index ea4e3e54b9d..1172a1a8edd 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs @@ -25,6 +25,7 @@ internal abstract partial class NormalizedKeyFrameAnimationBuilder /// The target property to animate. /// The optional initial delay for the animation. /// The animation duration. + /// The value for the animation /// The list of keyframes to use to build the animation. /// A instance with the specified animation. public static CompositionAnimation GetAnimation( @@ -32,6 +33,7 @@ public static CompositionAnimation GetAnimation( string property, TimeSpan? delay, TimeSpan duration, + RepeatOption repeatOption, ReadOnlySpan keyFrames) where TKeyFrame : struct, IKeyFrameInfo { @@ -241,6 +243,7 @@ public static CompositionAnimation GetAnimation( } animation.Target = property; + (animation.IterationBehavior, animation.IterationCount) = repeatOption.ToBehaviorAndCount(); return animation; } @@ -254,8 +257,8 @@ public sealed class Composition : NormalizedKeyFrameAnimationBuilder, Animati /// Initializes a new instance of the class. /// /// - public Composition(string property, TimeSpan? delay, TimeSpan duration) - : base(property, delay, duration) + public Composition(string property, TimeSpan? delay, TimeSpan duration, RepeatOption repeatOption) + : base(property, delay, duration, repeatOption) { } @@ -281,6 +284,7 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo this.property, this.delay, this.duration, + this.repeatOption, this.keyFrames.AsSpan()); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs index 2c6baf7195d..3134d460cde 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -21,8 +21,8 @@ public sealed class Xaml : NormalizedKeyFrameAnimationBuilder, AnimationBuild /// Initializes a new instance of the class. /// /// - public Xaml(string property, TimeSpan? delay, TimeSpan duration) - : base(property, delay, duration) + public Xaml(string property, TimeSpan? delay, TimeSpan duration, RepeatOption repeatOption) + : base(property, delay, duration, repeatOption) { } @@ -44,6 +44,7 @@ public Timeline GetAnimation(DependencyObject targetHint) this.property, this.delay, this.duration, + this.repeatOption, this.keyFrames.AsSpan()); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs index 337ac106867..4270aa64a9f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs @@ -35,6 +35,11 @@ internal abstract partial class NormalizedKeyFrameAnimationBuilder : INormali /// private readonly TimeSpan duration; + /// + /// The repeat options for the animation. + /// + private readonly RepeatOption repeatOption; + /// /// The list builder of keyframes to use. /// @@ -46,11 +51,13 @@ internal abstract partial class NormalizedKeyFrameAnimationBuilder : INormali /// The target property to animate. /// The target delay for the animation. /// The target duration for the animation. - protected NormalizedKeyFrameAnimationBuilder(string property, TimeSpan? delay, TimeSpan duration) + /// The repeat options for the animation. + protected NormalizedKeyFrameAnimationBuilder(string property, TimeSpan? delay, TimeSpan duration, RepeatOption repeatOption) { this.property = property; this.delay = delay; this.duration = duration; + this.repeatOption = repeatOption; } /// diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs index 8370acd59b6..6b5a189e6d5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs @@ -23,8 +23,8 @@ public sealed class Composition : TimedKeyFrameAnimationBuilder, AnimationBui /// Initializes a new instance of the class. /// /// - public Composition(string property, TimeSpan? delay) - : base(property, delay) + public Composition(string property, TimeSpan? delay, RepeatOption repeatOption) + : base(property, delay, repeatOption) { } @@ -55,6 +55,7 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo this.property, this.delay, duration, + this.repeatOption, keyFrames); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs index a3f21a87822..8d8c0946310 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -24,6 +24,7 @@ internal abstract partial class TimedKeyFrameAnimationBuilder /// The target property to animate. /// The optional initial delay for the animation. /// The animation duration. + /// The value for the animation /// The list of keyframes to use to build the animation. /// A instance with the specified animation. public static Timeline GetAnimation( @@ -31,6 +32,7 @@ public static Timeline GetAnimation( string property, TimeSpan? delay, TimeSpan duration, + RepeatOption repeatOption, ReadOnlySpan keyFrames) where TKeyFrame : struct, IKeyFrameInfo { @@ -121,6 +123,7 @@ public static Timeline GetAnimation( } animation.BeginTime = delay; + animation.RepeatBehavior = repeatOption.ToRepeatBehavior(); Storyboard.SetTarget(animation, target); Storyboard.SetTargetProperty(animation, property); @@ -137,8 +140,8 @@ public sealed class Xaml : TimedKeyFrameAnimationBuilder, AnimationBuilder.IX /// Initializes a new instance of the class. ///
/// - public Xaml(string property, TimeSpan? delay) - : base(property, delay) + public Xaml(string property, TimeSpan? delay, RepeatOption repeatOption) + : base(property, delay, repeatOption) { } @@ -160,6 +163,7 @@ public Timeline GetAnimation(DependencyObject targetHint) this.property, this.delay, default, + this.repeatOption, this.keyFrames.AsSpan()); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs index 248c752e102..5033fbde9c0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs @@ -30,6 +30,11 @@ internal abstract partial class TimedKeyFrameAnimationBuilder : ITimedKeyFram ///
private readonly TimeSpan? delay; + /// + /// The repeat options for the animation. + /// + private readonly RepeatOption repeatOption; + /// /// The list builder of keyframes to use. /// @@ -40,10 +45,12 @@ internal abstract partial class TimedKeyFrameAnimationBuilder : ITimedKeyFram ///
/// The target property to animate. /// The target delay for the animation. - protected TimedKeyFrameAnimationBuilder(string property, TimeSpan? delay) + /// The repeat options for the animation. + protected TimedKeyFrameAnimationBuilder(string property, TimeSpan? delay, RepeatOption repeatOption) { this.property = property; this.delay = delay; + this.repeatOption = repeatOption; } /// From 587f012c6b1dfacf8da140b08f7e2f6cd67795c4 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 12 Jan 2021 23:47:48 +0100 Subject: [PATCH 145/171] Implemented RepeatOption property to XAML types --- .../Xaml/Abstract/Animation.cs | 18 ++++++++++++++++++ .../Abstract/Animation{TValue,TKeyFrame}.cs | 1 + .../ImplicitAnimation{TValue,TKeyFrame}.cs | 3 ++- ...ffectAnimation{TEffect,TValue,TKeyFrame}.cs | 3 ++- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs index 591341b652b..ce080a7eaaa 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs @@ -85,6 +85,24 @@ public EasingMode? EasingMode typeof(Animation), new PropertyMetadata(null)); + /// + /// Gets or sets the repeat option for the animation. + /// + public RepeatOption Repeat + { + get => (RepeatOption)GetValue(RepeatOptionProperty); + set => SetValue(RepeatOptionProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty RepeatOptionProperty = DependencyProperty.Register( + nameof(Repeat), + typeof(RepeatOption), + typeof(Animation), + new PropertyMetadata(RepeatOption.One)); + /// public abstract AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint); } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs index d2206ff15b0..8164aa205d3 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs @@ -103,6 +103,7 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS state: (this, easingTypeHint, easingModeHint), delay: Delay ?? delayHint ?? DefaultDelay, duration: Duration ?? durationHint ?? DefaultDuration, + repeatOption: Repeat, build: static (b, s) => s.This.AppendToBuilder(b, s.EasingTypeHint, s.EasingModeHint)); } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs index 65116e596cc..d03c851e37c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/ImplicitAnimation{TValue,TKeyFrame}.cs @@ -29,7 +29,8 @@ public CompositionAnimation GetAnimation(UIElement element, out string? target) NormalizedKeyFrameAnimationBuilder.Composition builder = new( ExplicitTarget, Delay ?? DefaultDelay, - Duration ?? DefaultDuration); + Duration ?? DefaultDuration, + Repeat); var (to, from) = GetParsedValues(); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/Abstract/EffectAnimation{TEffect,TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Abstract/EffectAnimation{TEffect,TValue,TKeyFrame}.cs index 7cea88d7936..d9e761ae27b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Animations/Abstract/EffectAnimation{TEffect,TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Abstract/EffectAnimation{TEffect,TValue,TKeyFrame}.cs @@ -50,7 +50,8 @@ public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeS NormalizedKeyFrameAnimationBuilder.Composition keyFrameBuilder = new( ExplicitTarget, Delay ?? delayHint ?? DefaultDelay, - Duration ?? durationHint ?? DefaultDuration); + Duration ?? durationHint ?? DefaultDuration, + Repeat); AppendToBuilder(keyFrameBuilder, easingTypeHint, easingModeHint); From 2aed95f81b1c0c31a49ba3ec2535ec7d25be9376 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 12 Jan 2021 23:52:10 +0100 Subject: [PATCH 146/171] Added missing file header --- Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs index 1bf7469b5c4..e2f4ba84361 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs @@ -1,4 +1,8 @@ -using System; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; using System.Diagnostics.Contracts; using System.Linq; using Microsoft.Toolkit.Diagnostics; From 861569961203859e7c9684deeab26f5e1f05004c Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 13 Jan 2021 12:12:27 +0100 Subject: [PATCH 147/171] Renamed RepeatOption.One to Once --- .../Builders/AnimationBuilder.KeyFrames.cs | 16 ++++++++-------- .../AnimationBuilder.PropertyBuilders.cs | 16 ++++++++-------- .../Options/RepeatOption.cs | 2 +- .../Xaml/Abstract/Animation.cs | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.KeyFrames.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.KeyFrames.cs index da124833948..c0324865ec0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.KeyFrames.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.KeyFrames.cs @@ -253,7 +253,7 @@ public AnimationBuilder NormalizedKeyFrames( property, delay, duration ?? DefaultDuration, - repeatOption ?? RepeatOption.One); + repeatOption ?? RepeatOption.Once); build(builder); @@ -265,7 +265,7 @@ public AnimationBuilder NormalizedKeyFrames( property, delay, duration ?? DefaultDuration, - repeatOption ?? RepeatOption.One); + repeatOption ?? RepeatOption.Once); build(builder); @@ -304,7 +304,7 @@ public AnimationBuilder NormalizedKeyFrames( property, delay, duration ?? DefaultDuration, - repeatOption ?? RepeatOption.One); + repeatOption ?? RepeatOption.Once); build(builder, state); @@ -316,7 +316,7 @@ public AnimationBuilder NormalizedKeyFrames( property, delay, duration ?? DefaultDuration, - repeatOption ?? RepeatOption.One); + repeatOption ?? RepeatOption.Once); build(builder, state); @@ -346,7 +346,7 @@ public AnimationBuilder TimedKeyFrames( { if (layer == FrameworkLayer.Composition) { - TimedKeyFrameAnimationBuilder.Composition builder = new(property, delay, repeatOption ?? RepeatOption.One); + TimedKeyFrameAnimationBuilder.Composition builder = new(property, delay, repeatOption ?? RepeatOption.Once); build(builder); @@ -354,7 +354,7 @@ public AnimationBuilder TimedKeyFrames( } else { - TimedKeyFrameAnimationBuilder.Xaml builder = new(property, delay, repeatOption ?? RepeatOption.One); + TimedKeyFrameAnimationBuilder.Xaml builder = new(property, delay, repeatOption ?? RepeatOption.Once); build(builder); @@ -387,7 +387,7 @@ public AnimationBuilder TimedKeyFrames( { if (layer == FrameworkLayer.Composition) { - TimedKeyFrameAnimationBuilder.Composition builder = new(property, delay, repeatOption ?? RepeatOption.One); + TimedKeyFrameAnimationBuilder.Composition builder = new(property, delay, repeatOption ?? RepeatOption.Once); build(builder, state); @@ -395,7 +395,7 @@ public AnimationBuilder TimedKeyFrames( } else { - TimedKeyFrameAnimationBuilder.Xaml builder = new(property, delay, repeatOption ?? RepeatOption.One); + TimedKeyFrameAnimationBuilder.Xaml builder = new(property, delay, repeatOption ?? RepeatOption.Once); build(builder, state); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs index 0a3d47d9f69..35f91490874 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.PropertyBuilders.cs @@ -87,7 +87,7 @@ public AnimationBuilder NormalizedKeyFrames( Property, delay, duration ?? DefaultDuration, - repeatOption ?? RepeatOption.One); + repeatOption ?? RepeatOption.Once); build(builder); @@ -108,7 +108,7 @@ public AnimationBuilder NormalizedKeyFrames( Property, delay, duration ?? DefaultDuration, - repeatOption ?? RepeatOption.One); + repeatOption ?? RepeatOption.Once); build(builder, state); @@ -123,7 +123,7 @@ public AnimationBuilder TimedKeyFrames( TimeSpan? delay, RepeatOption? repeatOption) { - TimedKeyFrameAnimationBuilder.Composition builder = new(Property, delay, repeatOption ?? RepeatOption.One); + TimedKeyFrameAnimationBuilder.Composition builder = new(Property, delay, repeatOption ?? RepeatOption.Once); build(builder); @@ -139,7 +139,7 @@ public AnimationBuilder TimedKeyFrames( TimeSpan? delay, RepeatOption? repeatOption) { - TimedKeyFrameAnimationBuilder.Composition builder = new(Property, delay, repeatOption ?? RepeatOption.One); + TimedKeyFrameAnimationBuilder.Composition builder = new(Property, delay, repeatOption ?? RepeatOption.Once); build(builder, state); @@ -186,7 +186,7 @@ public AnimationBuilder NormalizedKeyFrames( Property, delay, duration ?? DefaultDuration, - repeatOption ?? RepeatOption.One); + repeatOption ?? RepeatOption.Once); build(builder); @@ -207,7 +207,7 @@ public AnimationBuilder NormalizedKeyFrames( Property, delay, duration ?? DefaultDuration, - repeatOption ?? RepeatOption.One); + repeatOption ?? RepeatOption.Once); build(builder, state); @@ -222,7 +222,7 @@ public AnimationBuilder TimedKeyFrames( TimeSpan? delay, RepeatOption? repeatOption) { - TimedKeyFrameAnimationBuilder.Xaml builder = new(Property, delay, repeatOption ?? RepeatOption.One); + TimedKeyFrameAnimationBuilder.Xaml builder = new(Property, delay, repeatOption ?? RepeatOption.Once); build(builder); @@ -238,7 +238,7 @@ public AnimationBuilder TimedKeyFrames( TimeSpan? delay, RepeatOption? repeatOption) { - TimedKeyFrameAnimationBuilder.Xaml builder = new(Property, delay, repeatOption ?? RepeatOption.One); + TimedKeyFrameAnimationBuilder.Xaml builder = new(Property, delay, repeatOption ?? RepeatOption.Once); build(builder, state); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs index e2f4ba84361..2bdbd08ebb2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs @@ -37,7 +37,7 @@ private RepeatOption(int value) /// /// Gets a value representing a single iteration. /// - public static RepeatOption One => new(1); + public static RepeatOption Once => new(1); /// /// Gets a value indicating an animation that repeats forever. diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs index ce080a7eaaa..6e1590697f4 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/Abstract/Animation.cs @@ -101,7 +101,7 @@ public RepeatOption Repeat nameof(Repeat), typeof(RepeatOption), typeof(Animation), - new PropertyMetadata(RepeatOption.One)); + new PropertyMetadata(RepeatOption.Once)); /// public abstract AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint); From 64a3ee617d1eae7229cf00d9386f6a6adf241fd9 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 13 Jan 2021 12:22:31 +0100 Subject: [PATCH 148/171] Fixed case sensitivity when parsing RepeatOption --- Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs index 2bdbd08ebb2..62515f7a833 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Options/RepeatOption.cs @@ -4,7 +4,6 @@ using System; using System.Diagnostics.Contracts; -using System.Linq; using Microsoft.Toolkit.Diagnostics; using Windows.Foundation.Metadata; using Windows.UI.Composition; @@ -72,7 +71,7 @@ public static RepeatOption Parse(string text) return Count(count); } - if (text.AsSpan().Trim().SequenceEqual("Forever".AsSpan())) + if (text.Trim().Equals("Forever", StringComparison.InvariantCultureIgnoreCase)) { return Forever; } From e61db4d1400f8000d498b7a4278bacdb6320f12b Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 13 Jan 2021 12:34:19 +0100 Subject: [PATCH 149/171] Minor code tweaks --- .../Builders/AnimationBuilder.KeyFrames.cs | 8 ++++---- .../Interfaces/IPropertyAnimationBuilder{T}.cs | 16 ++++++++-------- ...zedKeyFrameAnimationBuilder{T}.Composition.cs | 12 ++++++------ ...NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs | 6 +++--- .../NormalizedKeyFrameAnimationBuilder{T}.cs | 8 ++++---- ...medKeyFrameAnimationBuilder{T}.Composition.cs | 6 +++--- .../TimedKeyFrameAnimationBuilder{T}.Xaml.cs | 12 ++++++------ .../Builders/TimedKeyFrameAnimationBuilder{T}.cs | 8 ++++---- 8 files changed, 38 insertions(+), 38 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.KeyFrames.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.KeyFrames.cs index c0324865ec0..8f18f1ad6dd 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.KeyFrames.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/AnimationBuilder.KeyFrames.cs @@ -333,20 +333,20 @@ public AnimationBuilder NormalizedKeyFrames( /// The target property to animate. /// The callback to use to construct the custom animation. /// The optional initial delay for the animation. - /// The repeat option for the animation (defaults to one iteration). + /// The repeat option for the animation (defaults to one iteration). /// The target framework layer to animate. /// The current instance. public AnimationBuilder TimedKeyFrames( string property, Action> build, TimeSpan? delay = null, - RepeatOption? repeatOption = null, + RepeatOption? repeat = null, FrameworkLayer layer = FrameworkLayer.Composition) where T : unmanaged { if (layer == FrameworkLayer.Composition) { - TimedKeyFrameAnimationBuilder.Composition builder = new(property, delay, repeatOption ?? RepeatOption.Once); + TimedKeyFrameAnimationBuilder.Composition builder = new(property, delay, repeat ?? RepeatOption.Once); build(builder); @@ -354,7 +354,7 @@ public AnimationBuilder TimedKeyFrames( } else { - TimedKeyFrameAnimationBuilder.Xaml builder = new(property, delay, repeatOption ?? RepeatOption.Once); + TimedKeyFrameAnimationBuilder.Xaml builder = new(property, delay, repeat ?? RepeatOption.Once); build(builder); diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs index 3947e0b0319..40d4989b5ba 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/Interfaces/IPropertyAnimationBuilder{T}.cs @@ -18,13 +18,13 @@ public interface IPropertyAnimationBuilder /// The callback to use to construct the custom animation. /// The optional initial delay for the animation. /// The animation duration. - /// The repeat option for the animation (defaults to one iteration). + /// The repeat option for the animation (defaults to one iteration). /// The current instance. AnimationBuilder NormalizedKeyFrames( Action> build, TimeSpan? delay = null, TimeSpan? duration = null, - RepeatOption? repeatOption = null); + RepeatOption? repeat = null); /// /// Adds a custom animation based on normalized keyframes ot the current schedule. @@ -34,26 +34,26 @@ AnimationBuilder NormalizedKeyFrames( /// The callback to use to construct the custom animation. /// The optional initial delay for the animation. /// The animation duration. - /// The repeat option for the animation (defaults to one iteration). + /// The repeat option for the animation (defaults to one iteration). /// The current instance. AnimationBuilder NormalizedKeyFrames( TState state, Action, TState> build, TimeSpan? delay = null, TimeSpan? duration = null, - RepeatOption? repeatOption = null); + RepeatOption? repeat = null); /// /// Adds a custom animation based on timed keyframes to the current schedule. /// /// The callback to use to construct the custom animation. /// The optional initial delay for the animation. - /// The repeat option for the animation (defaults to one iteration). + /// The repeat option for the animation (defaults to one iteration). /// The current instance. AnimationBuilder TimedKeyFrames( Action> build, TimeSpan? delay = null, - RepeatOption? repeatOption = null); + RepeatOption? repeat = null); /// /// Adds a custom animation based on timed keyframes to the current schedule. @@ -62,12 +62,12 @@ AnimationBuilder TimedKeyFrames( /// The state to pass to the builder. /// The callback to use to construct the custom animation. /// The optional initial delay for the animation. - /// The repeat option for the animation (defaults to one iteration). + /// The repeat option for the animation (defaults to one iteration). /// The current instance. AnimationBuilder TimedKeyFrames( TState state, Action, TState> build, TimeSpan? delay = null, - RepeatOption? repeatOption = null); + RepeatOption? repeat = null); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs index 1172a1a8edd..02e17201f8b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Composition.cs @@ -25,7 +25,7 @@ internal abstract partial class NormalizedKeyFrameAnimationBuilder /// The target property to animate. /// The optional initial delay for the animation. /// The animation duration. - /// The value for the animation + /// The value for the animation /// The list of keyframes to use to build the animation. /// A instance with the specified animation. public static CompositionAnimation GetAnimation( @@ -33,7 +33,7 @@ public static CompositionAnimation GetAnimation( string property, TimeSpan? delay, TimeSpan duration, - RepeatOption repeatOption, + RepeatOption repeat, ReadOnlySpan keyFrames) where TKeyFrame : struct, IKeyFrameInfo { @@ -243,7 +243,7 @@ public static CompositionAnimation GetAnimation( } animation.Target = property; - (animation.IterationBehavior, animation.IterationCount) = repeatOption.ToBehaviorAndCount(); + (animation.IterationBehavior, animation.IterationCount) = repeat.ToBehaviorAndCount(); return animation; } @@ -257,8 +257,8 @@ public sealed class Composition : NormalizedKeyFrameAnimationBuilder, Animati /// Initializes a new instance of the class. /// /// - public Composition(string property, TimeSpan? delay, TimeSpan duration, RepeatOption repeatOption) - : base(property, delay, duration, repeatOption) + public Composition(string property, TimeSpan? delay, TimeSpan duration, RepeatOption repeat) + : base(property, delay, duration, repeat) { } @@ -284,7 +284,7 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo this.property, this.delay, this.duration, - this.repeatOption, + this.repeat, this.keyFrames.AsSpan()); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs index 3134d460cde..23665b9544b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -21,8 +21,8 @@ public sealed class Xaml : NormalizedKeyFrameAnimationBuilder, AnimationBuild /// Initializes a new instance of the class. /// /// - public Xaml(string property, TimeSpan? delay, TimeSpan duration, RepeatOption repeatOption) - : base(property, delay, duration, repeatOption) + public Xaml(string property, TimeSpan? delay, TimeSpan duration, RepeatOption repeat) + : base(property, delay, duration, repeat) { } @@ -44,7 +44,7 @@ public Timeline GetAnimation(DependencyObject targetHint) this.property, this.delay, this.duration, - this.repeatOption, + this.repeat, this.keyFrames.AsSpan()); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs index 4270aa64a9f..f3cae7d1eec 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/NormalizedKeyFrameAnimationBuilder{T}.cs @@ -38,7 +38,7 @@ internal abstract partial class NormalizedKeyFrameAnimationBuilder : INormali /// /// The repeat options for the animation. /// - private readonly RepeatOption repeatOption; + private readonly RepeatOption repeat; /// /// The list builder of keyframes to use. @@ -51,13 +51,13 @@ internal abstract partial class NormalizedKeyFrameAnimationBuilder : INormali /// The target property to animate. /// The target delay for the animation. /// The target duration for the animation. - /// The repeat options for the animation. - protected NormalizedKeyFrameAnimationBuilder(string property, TimeSpan? delay, TimeSpan duration, RepeatOption repeatOption) + /// The repeat options for the animation. + protected NormalizedKeyFrameAnimationBuilder(string property, TimeSpan? delay, TimeSpan duration, RepeatOption repeat) { this.property = property; this.delay = delay; this.duration = duration; - this.repeatOption = repeatOption; + this.repeat = repeat; } /// diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs index 6b5a189e6d5..066e7ad6c1a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Composition.cs @@ -23,8 +23,8 @@ public sealed class Composition : TimedKeyFrameAnimationBuilder, AnimationBui /// Initializes a new instance of the class. /// /// - public Composition(string property, TimeSpan? delay, RepeatOption repeatOption) - : base(property, delay, repeatOption) + public Composition(string property, TimeSpan? delay, RepeatOption repeat) + : base(property, delay, repeat) { } @@ -55,7 +55,7 @@ public CompositionAnimation GetAnimation(CompositionObject targetHint, out Compo this.property, this.delay, duration, - this.repeatOption, + this.repeat, keyFrames); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs index 8d8c0946310..3b0ca1c33e6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.Xaml.cs @@ -24,7 +24,7 @@ internal abstract partial class TimedKeyFrameAnimationBuilder /// The target property to animate. /// The optional initial delay for the animation. /// The animation duration. - /// The value for the animation + /// The value for the animation /// The list of keyframes to use to build the animation. /// A instance with the specified animation. public static Timeline GetAnimation( @@ -32,7 +32,7 @@ public static Timeline GetAnimation( string property, TimeSpan? delay, TimeSpan duration, - RepeatOption repeatOption, + RepeatOption repeat, ReadOnlySpan keyFrames) where TKeyFrame : struct, IKeyFrameInfo { @@ -123,7 +123,7 @@ public static Timeline GetAnimation( } animation.BeginTime = delay; - animation.RepeatBehavior = repeatOption.ToRepeatBehavior(); + animation.RepeatBehavior = repeat.ToRepeatBehavior(); Storyboard.SetTarget(animation, target); Storyboard.SetTargetProperty(animation, property); @@ -140,8 +140,8 @@ public sealed class Xaml : TimedKeyFrameAnimationBuilder, AnimationBuilder.IX /// Initializes a new instance of the class. /// /// - public Xaml(string property, TimeSpan? delay, RepeatOption repeatOption) - : base(property, delay, repeatOption) + public Xaml(string property, TimeSpan? delay, RepeatOption repeat) + : base(property, delay, repeat) { } @@ -163,7 +163,7 @@ public Timeline GetAnimation(DependencyObject targetHint) this.property, this.delay, default, - this.repeatOption, + this.repeat, this.keyFrames.AsSpan()); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs index 5033fbde9c0..8018ce3b521 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Builders/TimedKeyFrameAnimationBuilder{T}.cs @@ -33,7 +33,7 @@ internal abstract partial class TimedKeyFrameAnimationBuilder : ITimedKeyFram /// /// The repeat options for the animation. /// - private readonly RepeatOption repeatOption; + private readonly RepeatOption repeat; /// /// The list builder of keyframes to use. @@ -45,12 +45,12 @@ internal abstract partial class TimedKeyFrameAnimationBuilder : ITimedKeyFram /// /// The target property to animate. /// The target delay for the animation. - /// The repeat options for the animation. - protected TimedKeyFrameAnimationBuilder(string property, TimeSpan? delay, RepeatOption repeatOption) + /// The repeat options for the animation. + protected TimedKeyFrameAnimationBuilder(string property, TimeSpan? delay, RepeatOption repeat) { this.property = property; this.delay = delay; - this.repeatOption = repeatOption; + this.repeat = repeat; } /// From a3e3ffff0819f6d2c3828e679bb77431df0a4e3f Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 17 Jan 2021 19:37:06 +0100 Subject: [PATCH 150/171] Tweaked some namespaces --- .../Animations/Activities/InvokeActionsActivity.bind | 2 +- .../Animations/Activities/StartAnimationActivity.bind | 2 +- .../Animations/AnimationEndBehavior.cs | 2 +- .../Animations/AnimationStartBehavior.cs | 2 +- .../Animations/InvokeActionsActivity.cs | 1 - .../Animations/StartAnimationAction.cs | 2 +- 6 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Activities/InvokeActionsActivity.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Activities/InvokeActionsActivity.bind index ac325ddb2f7..94b95d6851e 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Activities/InvokeActionsActivity.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Activities/InvokeActionsActivity.bind @@ -7,7 +7,7 @@ xmlns:interactions="using:Microsoft.Xaml.Interactions.Core" xmlns:mediaactions="using:Microsoft.Xaml.Interactions.Media" xmlns:ani="using:Microsoft.Toolkit.Uwp.UI.Animations" - xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors.Animations" + xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors" xmlns:core="using:Microsoft.Xaml.Interactions.Core" mc:Ignorable="d"> diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Activities/StartAnimationActivity.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Activities/StartAnimationActivity.bind index 616214e3eee..29a56db3b85 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Activities/StartAnimationActivity.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Activities/StartAnimationActivity.bind @@ -6,7 +6,7 @@ xmlns:interactivity="using:Microsoft.Xaml.Interactivity" xmlns:interactions="using:Microsoft.Xaml.Interactions.Core" xmlns:ani="using:Microsoft.Toolkit.Uwp.UI.Animations" - xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors.Animations" + xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors" xmlns:core="using:Microsoft.Xaml.Interactions.Core" mc:Ignorable="d"> diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs index 546630afd72..eb0a6442bd9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationEndBehavior.cs @@ -7,7 +7,7 @@ using Microsoft.Toolkit.Uwp.UI.Animations; using Microsoft.Xaml.Interactivity; -namespace Microsoft.Toolkit.Uwp.UI.Behaviors.Animations +namespace Microsoft.Toolkit.Uwp.UI.Behaviors { /// /// A custom that fires whenever a linked ends. diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs index ceb6e6e6cf8..11c87b9cb52 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/AnimationStartBehavior.cs @@ -7,7 +7,7 @@ using Microsoft.Toolkit.Uwp.UI.Animations; using Microsoft.Xaml.Interactivity; -namespace Microsoft.Toolkit.Uwp.UI.Behaviors.Animations +namespace Microsoft.Toolkit.Uwp.UI.Behaviors { /// /// A custom that fires whenever a linked starts. diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/InvokeActionsActivity.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/InvokeActionsActivity.cs index 1d8ea52bd55..82780ce33d6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/InvokeActionsActivity.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/InvokeActionsActivity.cs @@ -5,7 +5,6 @@ using System; using System.Threading; using System.Threading.Tasks; -using Microsoft.Toolkit.Uwp.UI.Animations; using Microsoft.Xaml.Interactivity; using Windows.UI.Xaml; using Windows.UI.Xaml.Markup; diff --git a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs index 5f714192825..aa75926d7fc 100644 --- a/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs +++ b/Microsoft.Toolkit.Uwp.UI.Behaviors/Animations/StartAnimationAction.cs @@ -7,7 +7,7 @@ using Microsoft.Xaml.Interactivity; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Behaviors.Animations +namespace Microsoft.Toolkit.Uwp.UI.Behaviors { /// /// An implementation that can trigger a target instance. From 4a48c828a51f5efef176e00117bb29fb38a444fd Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 17 Jan 2021 19:37:25 +0100 Subject: [PATCH 151/171] Added effect animations sample page (WIP) --- .../Microsoft.Toolkit.Uwp.SampleApp.csproj | 1 + .../Animations/Effects/EffectAnimations.bind | 58 +++++++++++++++++++ .../SamplePages/XamlOnlyPage.xaml | 4 +- .../SamplePages/samples.json | 8 +++ 4 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/EffectAnimations.bind diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index 95766942540..d55637f37fa 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -590,6 +590,7 @@ + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/EffectAnimations.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/EffectAnimations.bind new file mode 100644 index 00000000000..330d8ee2b76 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/EffectAnimations.bind @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml index cb97cca1945..69eebe448f5 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml @@ -2,7 +2,7 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ani="using:Microsoft.Toolkit.Uwp.UI.Animations" - xmlns:anibehaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors.Animations" + xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:interactions="using:Microsoft.Xaml.Interactions.Core" xmlns:interactivity="using:Microsoft.Xaml.Interactivity" @@ -24,7 +24,7 @@ - + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json index 7eb708f0190..6d4b932601f 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json @@ -586,6 +586,14 @@ "BadgeUpdateVersionRequired": "Anniversary Update required", "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/animations/ReorderGrid.md" }, + { + "Name": "EffectAnimations", + "Subcategory": "Effect", + "About": "Effects from the Media package that can be animated from an AnimationSet schedule.", + "CodeUrl": "https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI.Media/Animations", + "XamlCodeFile": "/SamplePages/Animations/Effects/EffectAnimations.bind", + "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/animations/Fade.md" + }, { "Name": "Implicit Animations", "Type": "ImplicitAnimationsPage", From 4fdecd75c13337e96103743fedba49b324832a46 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 17 Jan 2021 19:56:52 +0100 Subject: [PATCH 152/171] Added sample page for VisualEffectFactory --- .../Microsoft.Toolkit.Uwp.SampleApp.csproj | 1 + .../VisualEffectFactory.bind | 34 +++++++++++++++++++ .../SamplePages/samples.json | 9 +++++ 3 files changed, 44 insertions(+) create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/VisualEffectFactory/VisualEffectFactory.bind diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index d55637f37fa..7bc893e22bf 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -591,6 +591,7 @@ + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/VisualEffectFactory/VisualEffectFactory.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/VisualEffectFactory/VisualEffectFactory.bind new file mode 100644 index 00000000000..5bc60f63a37 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/VisualEffectFactory/VisualEffectFactory.bind @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json index 6d4b932601f..93eba059d5d 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json @@ -1134,6 +1134,15 @@ "ApiCheck": "Windows.UI.Xaml.Media.XamlCompositionBrushBase", "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/brushes/PipelineBrush.md" }, + { + "Name": "VisualEffectFactory", + "About": "A composition pipeline which can render any custom Win2D/Composition effects chain directly on a Composition visual.", + "CodeUrl": "https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI.Media/Brushes/PipelineBrush.cs", + "XamlCodeFile": "VisualEffectFactory.bind", + "Icon": "/SamplePages/PipelineBrush/PipelineBrush.png", + "ApiCheck": "Windows.UI.Xaml.Media.XamlCompositionBrushBase", + "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/brushes/PipelineBrush.md" + }, { "Name": "AcrylicBrush", "Type": "AcrylicBrushPage", From 3ccaf64a7f2817dac4f4ba33627d198068bc7294 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 17 Jan 2021 19:58:31 +0100 Subject: [PATCH 153/171] Fixed the PipelineBrush sample page --- .../PipelineBrush/PipelineBrushXaml.bind | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PipelineBrush/PipelineBrushXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PipelineBrush/PipelineBrushXaml.bind index 65233b7e255..e37199d4a34 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PipelineBrush/PipelineBrushXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PipelineBrush/PipelineBrushXaml.bind @@ -3,8 +3,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:brushes="using:Microsoft.Toolkit.Uwp.UI.Media" - xmlns:effects="using:Microsoft.Toolkit.Uwp.UI.Media.Effects" + xmlns:media="using:Microsoft.Toolkit.Uwp.UI.Media" mc:Ignorable="d"> @@ -20,15 +19,15 @@ Grid.Column="2" Height="400"> - - - - - - - - - + + + + + + + + + From 14d5464acfe7faf4131fd2af826128be387f845e Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 20 Jan 2021 02:12:15 +0100 Subject: [PATCH 154/171] Fixed {Binding} for effect animations from AnimationScope --- .../Xaml/AnimationScope.cs | 87 ++++++++++++++----- 1 file changed, 64 insertions(+), 23 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs index afcf8619885..a917a2f0b6e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Xaml/AnimationScope.cs @@ -5,9 +5,7 @@ #nullable enable using System; -using System.Collections.Generic; using Windows.UI.Xaml; -using Windows.UI.Xaml.Markup; using Windows.UI.Xaml.Media.Animation; namespace Microsoft.Toolkit.Uwp.UI.Animations @@ -16,41 +14,84 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// A container of elements that can be used to conceptually group animations /// together and to assign shared properties to be applied to all the contained items automatically. /// - [ContentProperty(Name = nameof(Animations))] - public sealed class AnimationScope : Animation + public sealed class AnimationScope : DependencyObjectCollection, ITimeline { /// - /// Gets or sets the list of animations in the current scope. + /// Gets or sets the optional initial delay for the animation. /// - public IList Animations + public TimeSpan? Delay { - get - { - if (GetValue(AnimationsProperty) is not IList animations) - { - animations = new List(); + get => (TimeSpan?)GetValue(DelayProperty); + set => SetValue(DelayProperty, value); + } - SetValue(AnimationsProperty, animations); - } + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty DelayProperty = DependencyProperty.Register( + nameof(Delay), + typeof(TimeSpan?), + typeof(Animation), + new PropertyMetadata(null)); - return animations; - } - set => SetValue(AnimationsProperty, value); + /// + /// Gets or sets the animation duration. + /// + public TimeSpan? Duration + { + get => (TimeSpan?)GetValue(DurationProperty); + set => SetValue(DurationProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty DurationProperty = DependencyProperty.Register( + nameof(Duration), + typeof(TimeSpan?), + typeof(Animation), + new PropertyMetadata(null)); + + /// + /// Gets or sets the optional easing function type for the animation. + /// + public EasingType? EasingType + { + get => (EasingType?)GetValue(EasingTypeProperty); + set => SetValue(EasingTypeProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty EasingTypeProperty = DependencyProperty.Register( + nameof(EasingType), + typeof(EasingType?), + typeof(Animation), + new PropertyMetadata(null)); + + /// + /// Gets or sets the optional easing function mode for the animation. + /// + public EasingMode? EasingMode + { + get => (EasingMode?)GetValue(EasingModeProperty); + set => SetValue(EasingModeProperty, value); } /// - /// Identifies the dependency property. + /// Identifies the dependency property. /// - public static readonly DependencyProperty AnimationsProperty = DependencyProperty.Register( - nameof(Animations), - typeof(IList), - typeof(AnimationScope), + public static readonly DependencyProperty EasingModeProperty = DependencyProperty.Register( + nameof(EasingMode), + typeof(EasingMode?), + typeof(Animation), new PropertyMetadata(null)); /// - public override AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) + public AnimationBuilder AppendToBuilder(AnimationBuilder builder, TimeSpan? delayHint, TimeSpan? durationHint, EasingType? easingTypeHint, EasingMode? easingModeHint) { - foreach (ITimeline element in Animations) + foreach (ITimeline element in this) { builder = element.AppendToBuilder(builder, Delay ?? delayHint, Duration ?? durationHint, EasingType ?? easingTypeHint, EasingMode ?? easingModeHint); } From 4a7436aa6ee1a7eac16cdfa2dff10d703fd0ba71 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 20 Jan 2021 02:12:23 +0100 Subject: [PATCH 155/171] Fixed sample page for effect animations --- .../SamplePages/Animations/Effects/EffectAnimations.bind | 4 +++- .../SamplePages/XamlOnlyPage.xaml | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/EffectAnimations.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/EffectAnimations.bind index 330d8ee2b76..5a81c876660 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/EffectAnimations.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/EffectAnimations.bind @@ -32,6 +32,7 @@ + @@ -41,7 +42,8 @@ - + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml index 69eebe448f5..3b7a093050c 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml @@ -34,11 +34,17 @@ + + + + + + From 10a02d7e84a004ece25338dd440c3758fe4716ad Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 20 Jan 2021 22:05:36 +0100 Subject: [PATCH 156/171] Fixed an error in the Effects/Fade sample page --- .../SamplePages/Animations/Effects/FadeBehaviorXaml.bind | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind index ad9490e7528..577c3eaceac 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind @@ -6,7 +6,7 @@ xmlns:interactivity="using:Microsoft.Xaml.Interactivity" xmlns:interactions="using:Microsoft.Xaml.Interactions.Core" xmlns:ani="using:Microsoft.Toolkit.Uwp.UI.Animations" - xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors.Animations" + xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors" xmlns:core="using:Microsoft.Xaml.Interactions.Core" mc:Ignorable="d"> From e5ee018adb4602fa66c7470d33d4ab1bbe0aa8c3 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 20 Jan 2021 23:43:54 +0100 Subject: [PATCH 157/171] Updated Blur sample page --- .../Microsoft.Toolkit.Uwp.SampleApp.csproj | 3 ++ .../Behaviors}/BlurBehavior.png | Bin .../Behaviors/BlurBehaviorCode.bind | 14 ++++++ .../Behaviors/BlurBehaviorXaml.bind | 43 ++++++++++++++++++ .../Animations/Effects/FadeBehaviorXaml.bind | 37 +++++++++------ .../SamplePages/Blur/BlurBehaviorCode.bind | 8 ---- .../SamplePages/Blur/BlurBehaviorXaml.bind | 26 ----------- .../SamplePages/samples.json | 7 ++- 8 files changed, 85 insertions(+), 53 deletions(-) rename Microsoft.Toolkit.Uwp.SampleApp/SamplePages/{Blur => Animations/Behaviors}/BlurBehavior.png (100%) create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/BlurBehaviorCode.bind create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/BlurBehaviorXaml.bind delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur/BlurBehaviorCode.bind delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur/BlurBehaviorXaml.bind diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index 7bc893e22bf..be3102d3f28 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -590,6 +590,9 @@ + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur/BlurBehavior.png b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/BlurBehavior.png similarity index 100% rename from Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur/BlurBehavior.png rename to Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/BlurBehavior.png diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/BlurBehaviorCode.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/BlurBehaviorCode.bind new file mode 100644 index 00000000000..0012c6353fb --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/BlurBehaviorCode.bind @@ -0,0 +1,14 @@ +// XAML UIElement + + +// C# - Blur can be applied to any UIElement. In this case it is an image called ToolkitLogo. +using Microsoft.Toolkit.Uwp.UI.Animations; + +// Create and attacha a sprite visual with an animatable blur effect +var sprite = await PipelineBuilder + .FromBackdrop() + .Blur(0, out EffectAnimation blurAnimation) + .AttachAsync(button, button); + +// Start the animation on the applied brush +blurAnimation(sprite.Brush, 32, TimeSpan.FromSeconds(3)); diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/BlurBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/BlurBehaviorXaml.bind new file mode 100644 index 00000000000..9470d0faf6e --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/BlurBehaviorXaml.bind @@ -0,0 +1,43 @@ + + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind index 577c3eaceac..9470d0faf6e 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind @@ -6,30 +6,37 @@ xmlns:interactivity="using:Microsoft.Xaml.Interactivity" xmlns:interactions="using:Microsoft.Xaml.Interactions.Core" xmlns:ani="using:Microsoft.Toolkit.Uwp.UI.Animations" + xmlns:media="using:Microsoft.Toolkit.Uwp.UI.Media" xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors" xmlns:core="using:Microsoft.Xaml.Interactions.Core" mc:Ignorable="d"> - + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur/BlurBehaviorCode.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur/BlurBehaviorCode.bind deleted file mode 100644 index b901a0f9cc1..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur/BlurBehaviorCode.bind +++ /dev/null @@ -1,8 +0,0 @@ -// XAML UIElement - - -// C# - Blur can be applied to any UIElement. In this case it is an image called ToolkitLogo. -using Microsoft.Toolkit.Uwp.UI.Animations; - -await ToolkitLogo.Blur(value: 10, duration: 10, delay: 0).StartAsync(); - diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur/BlurBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur/BlurBehaviorXaml.bind deleted file mode 100644 index a81058031ab..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur/BlurBehaviorXaml.bind +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json index 93eba059d5d..b6af2d714c3 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json @@ -521,13 +521,12 @@ }, { "Name": "Blur", - "Type": "BlurBehaviorPage", "Subcategory": "Behavior", "About": "Blur XAML elements using composition", "CodeUrl": "https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors", - "CodeFile": "BlurBehaviorCode.bind", - "XamlCodeFile": "BlurBehaviorXaml.bind", - "Icon": "/SamplePages/Blur/blurBehavior.png", + "CodeFile": "/SamplePages/Animations/Behaviors/BlurBehaviorCode.bind", + "XamlCodeFile": "/SamplePages/Animations/Behaviors/BlurBehaviorXaml.bind", + "Icon": "/SamplePages/Animations/Behaviors/BlurBehavior.png", "BadgeUpdateVersionRequired": "Anniversary Update required", "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/animations/Blur.md" }, From b4db2f05ea1a6e30307b7839241543609ede4698 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 20 Jan 2021 23:45:30 +0100 Subject: [PATCH 158/171] Fixed some C# sample pages --- .../SamplePages/Animations/Behaviors/BlurBehaviorCode.bind | 2 +- .../SamplePages/Animations/Effects/FadeBehaviorCode.bind | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/BlurBehaviorCode.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/BlurBehaviorCode.bind index 0012c6353fb..8e2c5c48386 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/BlurBehaviorCode.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/BlurBehaviorCode.bind @@ -8,7 +8,7 @@ using Microsoft.Toolkit.Uwp.UI.Animations; var sprite = await PipelineBuilder .FromBackdrop() .Blur(0, out EffectAnimation blurAnimation) - .AttachAsync(button, button); + .AttachAsync(ToolkitLogo, ToolkitLogo); // Start the animation on the applied brush blurAnimation(sprite.Brush, 32, TimeSpan.FromSeconds(3)); diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorCode.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorCode.bind index b6c84b34f62..f915f00e0a3 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorCode.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorCode.bind @@ -4,6 +4,6 @@ // C# - Fade can be applied to any UIElement. In this case it is an image called ToolkitLogo. using Microsoft.Toolkit.Uwp.UI.Animations; -// TODO: Update to builder pattern -await ToolkitLogo.Fade(value: 0.5f, duration: 10, delay: 0).StartAsync(); +// Create and start the animation +await AnimationBuilder.Create().Opacity(to: 0.5, duration: TimeSpan.FromSeconds(3)).StartAsync(ToolkitLogo); From cd67f1dd89be9824220765716075b4f57179ea88 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 20 Jan 2021 23:50:26 +0100 Subject: [PATCH 159/171] Removed leftover files --- .../SamplePages/Blur/BlurBehaviorPage.xaml | 57 ------------------- .../SamplePages/Blur/BlurBehaviorPage.xaml.cs | 43 -------------- 2 files changed, 100 deletions(-) delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur/BlurBehaviorPage.xaml delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur/BlurBehaviorPage.xaml.cs diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur/BlurBehaviorPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur/BlurBehaviorPage.xaml deleted file mode 100644 index 8c6ef1f0512..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur/BlurBehaviorPage.xaml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur/BlurBehaviorPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur/BlurBehaviorPage.xaml.cs deleted file mode 100644 index 80e76c0dbd2..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur/BlurBehaviorPage.xaml.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Linq; -using Microsoft.Toolkit.Uwp.UI.Animations; -using Microsoft.Toolkit.Uwp.UI.Animations.Behaviors; -using Microsoft.Toolkit.Uwp.UI.Extensions; -using Microsoft.Xaml.Interactivity; -using Windows.UI.Xaml; - -namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages -{ - /// - /// A page that shows how to use the blur behavior. - /// - public sealed partial class BlurBehaviorPage : IXamlRenderListener - { - private Blur _blurBehavior; - - /// - /// Initializes a new instance of the class. - /// - public BlurBehaviorPage() - { - InitializeComponent(); - - SampleController.Current.RegisterNewCommand("Apply", (s, e) => - { - _blurBehavior?.StartAnimation(); - }); - } - - public void OnXamlRendered(FrameworkElement control) - { - if (control.FindChildByName("EffectElement") is FrameworkElement element) - { - var behaviors = Interaction.GetBehaviors(element); - _blurBehavior = behaviors.FirstOrDefault(item => item is Blur) as Blur; - } - } - } -} \ No newline at end of file From e6b1c5f6a33fc4f91c4125af11752d94e2f6c0f9 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 20 Jan 2021 23:50:48 +0100 Subject: [PATCH 160/171] Removed Light sample (for now) --- .../SamplePages/Light/LightBehavior.png | Bin 6164 -> 0 bytes .../SamplePages/Light/LightBehaviorCode.bind | 8 --- .../SamplePages/Light/LightBehaviorPage.xaml | 31 ------------ .../Light/LightBehaviorPage.xaml.cs | 47 ------------------ .../SamplePages/Light/LightBehaviorXaml.bind | 25 ---------- .../SamplePages/samples.json | 13 ----- 6 files changed, 124 deletions(-) delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehavior.png delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehaviorCode.bind delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehaviorPage.xaml delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehaviorPage.xaml.cs delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehaviorXaml.bind diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehavior.png b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehavior.png deleted file mode 100644 index b2235f1b9e4577a48af0b24d219f8485b2a71878..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6164 zcmZ9QcQl*r8^@DaF`JayBSuRrwEEhs5hB)W#0)}PlvZh#m{qg(Y|$DaX4EXAX3=4k zB34qfLlIJ=W?R+%^8WjK{&=3}+~?f)ea@|sr>nD zBb@pSO=Xcoc^X?Jv2w9hyZp#udlnKkApBQS0A-^=-~O2Sw*!Ah07a;dI>8@tDWqsS zvO-WcZOMQ#g$?zS%|vSs`r1H8)S{*az6DI&3zEMrXUdSy;e!JA-Sl`>p*MZypSqm` z(Q&_S&|w87QrGrDP{hajHkQH3UkjWS7X^U(k)5Zt34xpJtcw#uDS%&mo3Ue$uTnXA zU(?Nv0D3OC=pP9fKiaE3`HKeo2qf$|BB=nPYi$4q_~=1jzs>C|UXn@j z7X$|N)`OI|zG7_d@a4*UP99o%#{n5Uc(p5R?%?v(UG+?{z!QaIKt zfv17X#EbyAT16NpW-PaFSUY#<1CJfJj2i{OkqEG##vyj+yUH#N$0kAM;2@vg;23WW zVog{L$B0icIIRp;CidTQV=&@62l4WEiJvlCY{}@DY#>yc%)DHG5txI!J6Bn~Y;aA0 zxfWCoCO*J-NnWhtx0wBrBy%?ROlBV#X!Dl0NzPXgI9;o_Xuv;krsl?^6JZU(D5wwLPs$++zphG(nR4~VxmV711D zyz*|dt;tAz@VYYH@Y?kQ7vi%{X=F9?sHzM1J6{DlhULA>4Y-2!j%%-kS5Sn_Aix}& z@{e!+=;IK@jR({RtadgKC{idDFuZQ|!3vsnnhqIGaaMWHcCNvADB-yA~-AD$L0ItVa)BL%4~9p7JGrJ&-;bOa<)X zIqrA%O`X_0FmjOGUp`PsdvN~9LCkp)iex%(#_pljxpUmb@3A)C=M(bWCRkRly@gSp z<=u3X@=5|U=i<2}uC4=&g_6nwJbrv!$1cn5IQc|XJ| z3&C@~7&s9X4%LNt!E7I9okf~JfO3j11+KhOih`rI0Y)PA(Lc$if##Qnqv;pG-*puf zKne}Gop-U`AvbBj@}%YbWu*_HR|{4Q7-nFb$6(@>+}XQU(N=O%6-tv=YVXm-@p@N= z4=!-S9dkWcr{zEjRo{%alykS@As3V~S@W&BLJmD*OuO=^tzyV{9%i_fq~ysEb_~pQ zZoc>bgg3p=RuMdX@V==)tYDC*^5hm6YTb(hoVZ&hTG3k7Kk|JF4GcX?yTEHv%z_;A z1(z}{bg+Kw$G7OLDz2iei+p2E#Zv|ivfhRSNLj2*^dA!6QQYeIYk6+DAj^s?yWOoV z#T`~7nbAYB?5DfN#Pldss+Euc1W4}PAAT**Qbc!kc0Ysk5m9TC4)pQR`{Z-ND3XkK zN>NJ%)YNk8pZVnDix3yQCuKi<{sex6QRY;}6f0y=JG5a&F*4CXD8g8{`$H>7v1WZw zoV_&1n4~!QzT|zGvsjM!GG)3Gfe$t<9kj9$ZB?Pi zT&*4W5-HE3(AgnV$UjP8{fDX%wYNn0s{5T6Uo%YmvJ;P)X!yHET|n{}v|NdA!{U z*`%g9@kJaqKmr$W=tfG88{JhTE7YU8vM|@&gFz8fTv zi7lIQQrGie7slk5t0;`RGVAXP69h!uN_bE`btX|Ua8*wEvzDWI}1}&=7A_*mjj>{GFv%cGJH(S z)7z+C2IsyoO?=a@TBhV){a%>Y)1!%Bbtd@_+e^~8Q*r{(eas!3cIfro^^w`B(nf2Y4zFMpK5bQ(#0nU=?s0?r}BqbeBAUx9>5hlKd zb^({;ssE(|ec+oyT<|OTjaah!ztq8Xx8C5qIKbdAKO2V12E9zQ1X{oC_uLEXC~H8A zi9O8ZC^lKQKi_YyQIUS~z9fcHjuQ|YlVG!r#1Qj=5F+|DP(J<4a!3|G<{n98++~#Px725>;;kjUy$iNQ5O0G*I zrBxI7L^eg)ChOoub*||3#x9{9Sm_qW?4_h*>@wMjRr%4ICL+^b_Z)KaZC%=)1Zpl* z@#)f;dtX#b8w(psHXRwP9At)2`f9o+p@VnULV*m?s90&4gPNWlB}oLB6-;3R8%hdH z8*cEtgg@FfS{PO4*t_K&1d5jP(#To!S&f)J38f{mOwQ@iiM}(}b?Xt>af4OiO`DO# z;)75cLzMcoiCiBkIV2OVc3Y0X1+z+0qz`#(@r?kzKJ&9#u^~_2m*enQF&Ya?fGqdd zBd_M#hx9lmdn2^M#8fcBrD98rmQ|xq9zcsO+8^vP)%Rxo#9D=()OyFwpIN^9N0u?+ zI?)s%qr-=Bn(=AJ*zMMTl@5G8s1GjoYBZi@b!IF~{>oaD))Qh4nk;zfTVKyOuuVVK zZeneD2w)Kr8X^o^Rq`|NqC$Jh(j`!PD+i)KD}ch{{kc$It@(LoVb($_u|h9X+i zGrqda*Zs~rZrZZ(mK|;7MlR*Q&)jVvJEOIS9W*`K3pJJ0Bsb0NJ>QM+4STu7L$sV1 z#s7mTY-_5&#}Q!UhP^&2zp}I1BoLFS8cY~Dp1!4UWTLNx7Brd=wrgaaDFg?8=jw zo)*@^LE_n`j{ev!FS+@F$xLmrM)AD?W|uR0!jUo*Dj?`qsG7JE4*9Wwi$%dy<8?if z3A9}mvbZ|IhaK}FM+f$w825Zgw<+IP7EYY{x?uDkj&(yxe-9Qz!alARYna-Fd zG%k)DH~{c9yXKil`Q0)!?$LBF()b>Rs#^_D^crQ1Vq?w6E>`TAiK&K>Hqv zXRoPtj-1-=x{Ucf=dO3Rc)q^peMtP}g2C;gHQ#+>4zhV}NH=cV`H>4!{84Ka7@XZI z{j(KcYQ1=%b8Wp9D-Wcn2pPRap)@+%X1fDCD_@38;DiK(zN>WC2dc_ow>_Q(f7&Jfe z$v=%{!AweTalG@YXTwDd_?7wY4A`;}c!;>|yR#~bFC_6-vco3uMuT3i)^c}V{2f+7 zBey&OD1oLe9h$Y0Y*ru-FFTIuuN16`TcLWJ;8dl2w|)-n9VmAeu|rUx-Bj+yON|Q%b3w%i{*BQH(ehUu4~ui82rjAXrwtxYzXNPM zAk}3U;0%H#M0sTPwv=CKOHWTktvr>L4!#`SU_GeQ@kHu;#O1^;2lrN1Lt1RZOHcuQ zJnq)?I-qlxq7p8cb6%x8-6Pis{8olT4L$w=S=d-kz4hwqOeA{PHBNsLAPM zh#je6!>(U2KS7Prh6(7~gRz0(k=Y*|`&-MjL1yy6YI8?|7%>b=y7me^{A~0wR_u|x zix4y7{8c6;(`Qu7u^)gMQup_n-c83eA1d zu6QqBO4fR2u3P`qUCe!yV^{ScBb|@F;qLaL+ff=Rdt|;6^iGwUGZJ=!R9I*b!(ENXdh^ddO+vY(v5NP<_xsxo!m=v zIvN=E(knW?@LvkJh%ve2y~)+bK{Uo%O2YGBMD&MNhEU5uW27Pd$sD%4xc(Kdlk+u>Ie>$r2sP?;S z7PG%&=esAl0uTyG-D=LXB(Ny@4!gC0sLrb4=Via(3c1JPX==eUkIkNIja}&N{+V@u zNwiY4-jC$Q*`mP$&V7+x+0!wqI7n7+WNk51s+HRvt`95P*VX>q(%{~i**B;-qH1D# zH0in|n%(4pO+apILJ{p3yo67ezhW8n2EM)L;Kq4w5nbV@Iqv6l_DPOVejCQQ>GvG5 zjRpMB_=RiB!sF=#&C=Up>hYTEq5)>kJz;LPQ?%0sb)kWB+0!g$;xl8?ycHdIXc%KmWkd;B!sCIbw^CfTkJ2?ZEXkAerL zy@6=k{s1hpD3(=nJ;1MJ?xm(LVPf*VEwlBm+X3*ot`0oT8CXj+$h0CdFZk1K2~4BM zKPk7v$Jy%rOu9lgwG{o*^MapvHcoH?Htt?>Sh}TEl`ewpcFe2yfFA8-vzKXkCtC0L zWSWGnJ^cz~t`5^@tiu@}W4%0cxoyP!UMggVY)g|P3g1U~AE~!KX^~Nk64ZAd zYf5uzq~WETuty#%k!nuXgiq0`c+GM?p$aWorC3G?-^3R+11)17E1U>PO0+^pdz>@{Q-ag zg7HdXg**-V#o}J0#dP9zF)pjNwOFcwdYPq=XMZW8c^4MwtJSS;w507`YYUjJR0vh2 z!^Y5zam3K@KY2}z*6B>HhmbGE%{vCAq*3X5l=BmsF(-3?$$1g*Qd5yy$jx>dByGwZ z0W6B-D)tK+p-hv2?^7m6Fs$0}ULGhyucjS#O4SA&7MS*Z?c9d|zKYS-7g)##wvr@9 za%V|(2K%Hbphi=qQMaH`_EPgN%2SmfAD_qJgpRc%D6!9%^Yh%>PqM z5?J*Z5L8*_Rdk@4<9b@R`;o36ZFW%bdO>y!#D1%fE z^Y||$JBZ(0C9Ug(-*Toy;1MM>i!mcYN{AI?} zg82YveORTg$J=X|pQ=2w)A<++QK=Yf0e#$7Vu2Ch(F#et04UgQ z89VRnALfgs)+|N@N|GJ}1(YgfmM0d9=aUa3=cvD1;PRf4-`wpzTgo!LdyJ*y0cQMM zbv{cLzZIELH$X9nX(w7Jt0taxcp9j<^x>;FBCx$gDAfzaVrItBDx zAI4a)j0p?hcOYHQ4GjEyX>0I9i^^rMk%g^XABA{whf_FC0W>6tF~cK$c; zcNKKEjOT zcF9^lKld{yTej-TEM*zuUBeB-?T)E{=7+`out=LB6N*7meva&;-6_?>1Q%(EFr5K(;&Tn^F$)0hz9c@KZVerF){0nW#B zZMV>zH~MdkwEI&$qmvJ%ltADqK5%+WhqQnN!|A3(i?xvF%20K4e)b2&5yjUe1rXR# zBc6O{l3&&8-2)Frt*_Ke>r{ct>7f;;)=BI@0sDQ3u!u{5N%r^RPP0anr3~FJ*i@Jx z>by+!mtB}=zY}C)PWEo|T;=cTtq;}&jv2=eN!5g3N+1OiSA1PhQepCo@kr;ti^F+p zj_qQvz2m^d?qH-3IMVHSZmpwa=<^<*y+#npux6i$*-%VZOE6s>)%M0$8u3ckC)!osjU4IMna2Ks=$;Y+lC22-bpC&e+DV;~|LQDIGTMFM zY$<@bT7`Iah*Y}aby}#oW0dm?meXB*Xf_mJ)3HJ>^(`7OwH{i0SC}ASxT9;qO2MbJ zms3>qztX`j=6VVFA_$z}rn&)vA%YO&$8cYP+J$ErBCZ27-DZt_f|YmX2Rd2%u~ z&QIPmPa`Z>$AXCwxxfisW$nYQW^-Hoo;!BTCS4}FxRm~rqJ3B{5v4og@eoj%XN(C-A=5OmYL5ftGX@4;7U^7t?6@2 zmR;IqR%>a3;{+ksn7lf&qyb*vb5k~I%J~_Sh4#37{H<3~11=Iu0)#(Vy0=r8ObN>e z6OYX1>plX`#jZl2h_&^bB}q_qj#NO|0F1S|aG$owO;p%$g(3t{i&a*fhm9_d1~${# azb+0$RdwfQyenj4et;>;(x?G>HTHj)(0CpI diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehaviorCode.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehaviorCode.bind deleted file mode 100644 index 4019e9a2ce7..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehaviorCode.bind +++ /dev/null @@ -1,8 +0,0 @@ -// XAML UIElement - - -// C# - Light can be applied to any UIElement. In this case it is an image called ToolkitLogo. -using Microsoft.Toolkit.Uwp.UI.Animations; - -var lightAnimationSet = ToolkitLogo.Light(distance: 10, duration: 500, delay: 0, color: Colors.Red); -await lightAnimationSet.StartAsync(); \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehaviorPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehaviorPage.xaml deleted file mode 100644 index 276a3166388..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehaviorPage.xaml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehaviorPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehaviorPage.xaml.cs deleted file mode 100644 index a731da773ad..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehaviorPage.xaml.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Linq; -using Microsoft.Toolkit.Uwp.UI.Animations; -using Microsoft.Toolkit.Uwp.UI.Animations.Behaviors; -using Microsoft.Toolkit.Uwp.UI.Extensions; -using Microsoft.Xaml.Interactivity; -using Windows.UI.Xaml; - -namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages -{ - /// - /// A page that shows how to use the light behavior. - /// - public sealed partial class LightBehaviorPage : IXamlRenderListener - { -#pragma warning disable CS0618 // Type or member is obsolete - private Light _lightBehavior; -#pragma warning restore CS0618 // Type or member is obsolete - - /// - /// Initializes a new instance of the class. - /// - public LightBehaviorPage() - { - this.InitializeComponent(); - - SampleController.Current.RegisterNewCommand("Apply", (s, e) => - { - _lightBehavior?.StartAnimation(); - }); - } - - public void OnXamlRendered(FrameworkElement control) - { - if (control.FindChildByName("EffectElement") is FrameworkElement element) - { - var behaviors = Interaction.GetBehaviors(element); -#pragma warning disable CS0618 // Type or member is obsolete - _lightBehavior = behaviors.FirstOrDefault(item => item is Light) as Light; -#pragma warning restore CS0618 // Type or member is obsolete - } - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehaviorXaml.bind deleted file mode 100644 index 2ca51bf1cfc..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light/LightBehaviorXaml.bind +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json index b6af2d714c3..ab482bacd8d 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json @@ -542,19 +542,6 @@ "BadgeUpdateVersionRequired": "Anniversary Update required", "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/animations/Saturation.md" }, - { - "Name": "Light", - "Type": "LightBehaviorPage", - "Subcategory": "Behavior", - "About": "The Light effect will be removed in a future major release", - "BadgeUpdateVersionRequired": "DEPRECATED", - "DeprecatedWarning": "The Light effect will be removed in a future major release", - "CodeUrl": "https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors", - "CodeFile": "LightBehaviorCode.bind", - "XamlCodeFile": "LightBehaviorXaml.bind", - "Icon": "/SamplePages/Light/LightBehavior.png", - "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/animations/Light.md" - }, { "Name": "FadeHeader", "Type": "FadeHeaderBehaviorPage", From 9c5fd3e8b18ecc01207109c58e7e54f4eaed0dcf Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 21 Jan 2021 00:00:49 +0100 Subject: [PATCH 161/171] Updated Offset sample page --- .../Microsoft.Toolkit.Uwp.SampleApp.csproj | 3 ++ .../Behaviors/BlurBehaviorXaml.bind | 1 - .../Behaviors}/OffsetBehavior.png | Bin .../Behaviors/OffsetBehaviorCode.bind | 12 +++++++ .../Behaviors/OffsetBehaviorXaml.bind | 34 ++++++++++++++++++ .../Offset/OffsetBehaviorCode.bind | 10 ------ .../Offset/OffsetBehaviorXaml.bind | 28 --------------- .../SamplePages/samples.json | 7 ++-- 8 files changed, 52 insertions(+), 43 deletions(-) rename Microsoft.Toolkit.Uwp.SampleApp/SamplePages/{Offset => Animations/Behaviors}/OffsetBehavior.png (100%) create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/OffsetBehaviorCode.bind create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/OffsetBehaviorXaml.bind delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset/OffsetBehaviorCode.bind delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset/OffsetBehaviorXaml.bind diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index be3102d3f28..d08bce73e9c 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -593,6 +593,9 @@ + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/BlurBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/BlurBehaviorXaml.bind index 9470d0faf6e..3425f482504 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/BlurBehaviorXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/BlurBehaviorXaml.bind @@ -22,7 +22,6 @@ diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset/OffsetBehavior.png b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/OffsetBehavior.png similarity index 100% rename from Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset/OffsetBehavior.png rename to Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/OffsetBehavior.png diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/OffsetBehaviorCode.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/OffsetBehaviorCode.bind new file mode 100644 index 00000000000..6a20d6a0e78 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/OffsetBehaviorCode.bind @@ -0,0 +1,12 @@ +// XAML UIElement + + +// C# - Offset can be applied to any UIElement. In this case it is an image called ToolkitLogo. +using Microsoft.Toolkit.Uwp.UI.Animations; + +// Create and start the animation. Note that animating the offset will +// change how the item is also positioned within its parent item. If you +// want to animate the position of an element with respect to its original +// relative position to its parent, use a translation animation instead. +await AnimationBuilder.Create().Offset(to: new Vector2(20, 30), duration: TimeSpan.FromSeconds(3)).StartAsync(ToolkitLogo); + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/OffsetBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/OffsetBehaviorXaml.bind new file mode 100644 index 00000000000..ff02da20dcc --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/OffsetBehaviorXaml.bind @@ -0,0 +1,34 @@ + + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset/OffsetBehaviorCode.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset/OffsetBehaviorCode.bind deleted file mode 100644 index 8542d806b02..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset/OffsetBehaviorCode.bind +++ /dev/null @@ -1,10 +0,0 @@ -// XAML UIElement - - -// C# - Offset can be applied to any UIElement. In this case it is an image called ToolkitLogo. -using Microsoft.Toolkit.Uwp.UI.Animations; - -await ToolkitLogo.Offset(offsetX: 1.0f, - offsetY: 1.1f, - duration: 10, delay: 0).StartAsync(); - diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset/OffsetBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset/OffsetBehaviorXaml.bind deleted file mode 100644 index 1a1bbb23e30..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset/OffsetBehaviorXaml.bind +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json index ab482bacd8d..e6d9a234576 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json @@ -499,13 +499,12 @@ }, { "Name": "Offset", - "Type": "OffsetBehaviorPage", "Subcategory": "Behavior", "About": "Offset of XAML elements using composition", "CodeUrl": "https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors", - "CodeFile": "OffsetBehaviorCode.bind", - "XamlCodeFile": "OffsetBehaviorXaml.bind", - "Icon": "/SamplePages/Offset/offsetBehavior.png", + "CodeFile": "/SamplePages/Animations/Behaviors/OffsetBehaviorCode.bind", + "XamlCodeFile": "/SamplePages/Animations/Behaviors/OffsetBehaviorXaml.bind", + "Icon": "/SamplePages/Animations/Behaviors/OffsetBehavior.png", "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/animations/Offset.md" }, { From faaf5ed1cbee0bdeb5c4b9b20da71b9b307d017c Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 21 Jan 2021 00:01:05 +0100 Subject: [PATCH 162/171] Removed leftover files --- .../Offset/OffsetBehaviorPage.xaml | 28 ------------- .../Offset/OffsetBehaviorPage.xaml.cs | 42 ------------------- 2 files changed, 70 deletions(-) delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset/OffsetBehaviorPage.xaml delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset/OffsetBehaviorPage.xaml.cs diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset/OffsetBehaviorPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset/OffsetBehaviorPage.xaml deleted file mode 100644 index 25f1c57dc3c..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset/OffsetBehaviorPage.xaml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset/OffsetBehaviorPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset/OffsetBehaviorPage.xaml.cs deleted file mode 100644 index 66b0284957c..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset/OffsetBehaviorPage.xaml.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Linq; -using Microsoft.Toolkit.Uwp.UI.Animations.Behaviors; -using Microsoft.Toolkit.Uwp.UI.Extensions; -using Microsoft.Xaml.Interactivity; -using Windows.UI.Xaml; - -namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages -{ - /// - /// A page that shows how to use the offset behavior. - /// - public sealed partial class OffsetBehaviorPage : IXamlRenderListener - { - private Offset _offsetBehavior; - - /// - /// Initializes a new instance of the class. - /// - public OffsetBehaviorPage() - { - InitializeComponent(); - - SampleController.Current.RegisterNewCommand("Apply", (s, e) => - { - _offsetBehavior?.StartAnimation(); - }); - } - - public void OnXamlRendered(FrameworkElement control) - { - if (control.FindChildByName("EffectElement") is FrameworkElement element) - { - var behaviors = Interaction.GetBehaviors(element); - _offsetBehavior = behaviors.FirstOrDefault(item => item is Offset) as Offset; - } - } - } -} \ No newline at end of file From 9ee094d9e1cd3c7507f43291f860730a17aca9db Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 21 Jan 2021 00:16:31 +0100 Subject: [PATCH 163/171] Updated Saturation sample page --- .../Microsoft.Toolkit.Uwp.SampleApp.csproj | 3 ++ .../Behaviors}/SaturationBehavior.png | Bin .../Behaviors/SaturationBehaviorCode.bind | 14 ++++++ .../Behaviors/SaturationBehaviorXaml.bind | 42 +++++++++++++++++ .../Saturation/SaturationBehaviorCode.bind | 8 ---- .../Saturation/SaturationBehaviorPage.xaml | 31 ------------- .../Saturation/SaturationBehaviorPage.xaml.cs | 43 ------------------ .../Saturation/SaturationBehaviorXaml.bind | 26 ----------- .../SamplePages/samples.json | 7 ++- 9 files changed, 62 insertions(+), 112 deletions(-) rename Microsoft.Toolkit.Uwp.SampleApp/SamplePages/{Saturation => Animations/Behaviors}/SaturationBehavior.png (100%) create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/SaturationBehaviorCode.bind create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/SaturationBehaviorXaml.bind delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation/SaturationBehaviorCode.bind delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation/SaturationBehaviorPage.xaml delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation/SaturationBehaviorPage.xaml.cs delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation/SaturationBehaviorXaml.bind diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index d08bce73e9c..32caf02467b 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -596,6 +596,9 @@ + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation/SaturationBehavior.png b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/SaturationBehavior.png similarity index 100% rename from Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation/SaturationBehavior.png rename to Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/SaturationBehavior.png diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/SaturationBehaviorCode.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/SaturationBehaviorCode.bind new file mode 100644 index 00000000000..5d89f4bb8a3 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/SaturationBehaviorCode.bind @@ -0,0 +1,14 @@ +// XAML UIElement + + +// C# - Saturation can be applied to any UIElement. In this case it is an image called ToolkitLogo. +using Microsoft.Toolkit.Uwp.UI.Animations; + +// Create and attacha a sprite visual with an animatable blur effect +var sprite = await PipelineBuilder + .FromBackdrop() + .Saturation(0, out EffectAnimation saturationAnimation) + .AttachAsync(ToolkitLogo, ToolkitLogo); + +// Start the animation on the applied brush +saturationAnimation(sprite.Brush, 1, TimeSpan.FromSeconds(3)); diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/SaturationBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/SaturationBehaviorXaml.bind new file mode 100644 index 00000000000..bd6836b829f --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/SaturationBehaviorXaml.bind @@ -0,0 +1,42 @@ + + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation/SaturationBehaviorCode.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation/SaturationBehaviorCode.bind deleted file mode 100644 index e221a771fb0..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation/SaturationBehaviorCode.bind +++ /dev/null @@ -1,8 +0,0 @@ -// XAML UIElement - - -// C# - Saturation can be applied to any UIElement. In this case it is an image called ToolkitLogo. -using Microsoft.Toolkit.Uwp.UI.Animations; - -await MyImage.Saturation(value: 10, duration: 10, delay: 0).StartAsync(); - diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation/SaturationBehaviorPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation/SaturationBehaviorPage.xaml deleted file mode 100644 index 275c42f1fcd..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation/SaturationBehaviorPage.xaml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation/SaturationBehaviorPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation/SaturationBehaviorPage.xaml.cs deleted file mode 100644 index d08eb1c3962..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation/SaturationBehaviorPage.xaml.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Linq; -using Microsoft.Toolkit.Uwp.UI.Animations; -using Microsoft.Toolkit.Uwp.UI.Animations.Behaviors; -using Microsoft.Toolkit.Uwp.UI.Extensions; -using Microsoft.Xaml.Interactivity; -using Windows.UI.Xaml; - -namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages -{ - /// - /// A demonstration page of how you can use the Saturation effect using behaviors. - /// - public sealed partial class SaturationBehaviorPage : IXamlRenderListener - { - private Saturation _saturationBehavior; - - /// - /// Initializes a new instance of the class. - /// - public SaturationBehaviorPage() - { - InitializeComponent(); - - SampleController.Current.RegisterNewCommand("Apply", (s, e) => - { - _saturationBehavior?.StartAnimation(); - }); - } - - public void OnXamlRendered(FrameworkElement control) - { - if (control.FindChildByName("EffectElement") is FrameworkElement element) - { - var behaviors = Interaction.GetBehaviors(element); - _saturationBehavior = behaviors.FirstOrDefault(item => item is Saturation) as Saturation; - } - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation/SaturationBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation/SaturationBehaviorXaml.bind deleted file mode 100644 index 8ecf1e81dc4..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation/SaturationBehaviorXaml.bind +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json index e6d9a234576..f2698ee4b9d 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json @@ -531,13 +531,12 @@ }, { "Name": "Saturation", - "Type": "SaturationBehaviorPage", "Subcategory": "Behavior", "About": "Saturate XAML elements using composition", "CodeUrl": "https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors", - "CodeFile": "SaturationBehaviorCode.bind", - "XamlCodeFile": "SaturationBehaviorXaml.bind", - "Icon": "/SamplePages/Saturation/saturationBehavior.png", + "CodeFile": "/SamplePages/Animations/Behaviors/SaturationBehaviorCode.bind", + "XamlCodeFile": "/SamplePages/Animations/Behaviors/SaturationBehaviorXaml.bind", + "Icon": "/SamplePages/Animations/Behaviors/SaturationBehavior.png", "BadgeUpdateVersionRequired": "Anniversary Update required", "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/animations/Saturation.md" }, From f4c3579a89ea54f4096e56ecb5f685a1467e8b65 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 21 Jan 2021 00:28:08 +0100 Subject: [PATCH 164/171] Updated Scale sample page --- .../Microsoft.Toolkit.Uwp.SampleApp.csproj | 3 ++ .../Behaviors}/ScaleBehavior.png | Bin .../Behaviors}/ScaleBehaviorCode.bind | 6 +-- .../Behaviors/ScaleBehaviorXaml.bind | 41 +++++++++++++++++ .../SamplePages/Scale/ScaleBehaviorPage.xaml | 31 ------------- .../Scale/ScaleBehaviorPage.xaml.cs | 42 ------------------ .../SamplePages/Scale/ScaleBehaviorXaml.bind | 30 ------------- .../SamplePages/samples.json | 7 ++- 8 files changed, 48 insertions(+), 112 deletions(-) rename Microsoft.Toolkit.Uwp.SampleApp/SamplePages/{Scale => Animations/Behaviors}/ScaleBehavior.png (100%) rename Microsoft.Toolkit.Uwp.SampleApp/SamplePages/{Scale => Animations/Behaviors}/ScaleBehaviorCode.bind (64%) create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/ScaleBehaviorXaml.bind delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale/ScaleBehaviorPage.xaml delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale/ScaleBehaviorPage.xaml.cs delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale/ScaleBehaviorXaml.bind diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index 32caf02467b..9a5c09599a2 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -599,6 +599,9 @@ + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale/ScaleBehavior.png b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/ScaleBehavior.png similarity index 100% rename from Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale/ScaleBehavior.png rename to Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/ScaleBehavior.png diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale/ScaleBehaviorCode.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/ScaleBehaviorCode.bind similarity index 64% rename from Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale/ScaleBehaviorCode.bind rename to Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/ScaleBehaviorCode.bind index ebe875e1dca..4b80509233d 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale/ScaleBehaviorCode.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/ScaleBehaviorCode.bind @@ -4,8 +4,4 @@ // C# - Scale can be applied to any UIElement. In this case it is an image called ToolkitLogo. using Microsoft.Toolkit.Uwp.UI.Animations; -await ToolkitLogo.Scale(centerX: 0.5f, - centerY: 0.0f, - scaleX: 2.0f, - scaleY: 0.1f, - duration: 10, delay: 0).StartAsync(); +await AnimationBuilder.Create().Scale(to: new Vector2(1.4f), duration: TimeSpan.FromSeconds(3)).StartAsync(ToolkitLogo); diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/ScaleBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/ScaleBehaviorXaml.bind new file mode 100644 index 00000000000..acd6ab9b79b --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/ScaleBehaviorXaml.bind @@ -0,0 +1,41 @@ + + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale/ScaleBehaviorPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale/ScaleBehaviorPage.xaml deleted file mode 100644 index 74c1d43d6d6..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale/ScaleBehaviorPage.xaml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale/ScaleBehaviorPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale/ScaleBehaviorPage.xaml.cs deleted file mode 100644 index 05b27309f49..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale/ScaleBehaviorPage.xaml.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Linq; -using Microsoft.Toolkit.Uwp.UI.Animations.Behaviors; -using Microsoft.Toolkit.Uwp.UI.Extensions; -using Microsoft.Xaml.Interactivity; -using Windows.UI.Xaml; - -namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages -{ - /// - /// A page that shows how to use the scale behavior. - /// - public sealed partial class ScaleBehaviorPage : IXamlRenderListener - { - private Scale _scaleBehavior; - - /// - /// Initializes a new instance of the class. - /// - public ScaleBehaviorPage() - { - InitializeComponent(); - - SampleController.Current.RegisterNewCommand("Apply", (s, e) => - { - _scaleBehavior?.StartAnimation(); - }); - } - - public void OnXamlRendered(FrameworkElement control) - { - if (control.FindChildByName("EffectElement") is FrameworkElement element) - { - var behaviors = Interaction.GetBehaviors(element); - _scaleBehavior = behaviors.FirstOrDefault(item => item is Scale) as Scale; - } - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale/ScaleBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale/ScaleBehaviorXaml.bind deleted file mode 100644 index 84ee7671e41..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale/ScaleBehaviorXaml.bind +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json index f2698ee4b9d..c3aeeec45fc 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json @@ -488,13 +488,12 @@ }, { "Name": "Scale", - "Type": "ScaleBehaviorPage", "Subcategory": "Behavior", "About": "Scale of XAML elements using composition", "CodeUrl": "https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors", - "CodeFile": "ScaleBehaviorCode.bind", - "XamlCodeFile": "ScaleBehaviorXaml.bind", - "Icon": "/SamplePages/Scale/scaleBehavior.png", + "CodeFile": "/SamplePages/Animations/Behaviors/ScaleBehaviorCode.bind", + "XamlCodeFile": "/SamplePages/Animations/Behaviors/ScaleBehaviorXaml.bind", + "Icon": "/SamplePages/Animations/Behaviors/ScaleBehavior.png", "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/animations/Scale.md" }, { From 560648325b6712a0fa499d1a8db9bb7820b6e212 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 21 Jan 2021 00:33:22 +0100 Subject: [PATCH 165/171] Updated Rotate sample page --- .../Microsoft.Toolkit.Uwp.SampleApp.csproj | 3 ++ .../Behaviors}/RotateBehavior.png | Bin .../Behaviors}/RotateBehaviorCode.bind | 5 +-- .../Behaviors/RotateBehaviorXaml.bind | 41 +++++++++++++++++ .../Rotate/RotateBehaviorPage.xaml | 28 ------------ .../Rotate/RotateBehaviorPage.xaml.cs | 42 ------------------ .../Rotate/RotateBehaviorXaml.bind | 28 ------------ .../SamplePages/samples.json | 7 ++- 8 files changed, 48 insertions(+), 106 deletions(-) rename Microsoft.Toolkit.Uwp.SampleApp/SamplePages/{Rotate => Animations/Behaviors}/RotateBehavior.png (100%) rename Microsoft.Toolkit.Uwp.SampleApp/SamplePages/{Rotate => Animations/Behaviors}/RotateBehaviorCode.bind (67%) create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/RotateBehaviorXaml.bind delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate/RotateBehaviorPage.xaml delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate/RotateBehaviorPage.xaml.cs delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate/RotateBehaviorXaml.bind diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index 9a5c09599a2..b0e9f84eb42 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -602,6 +602,9 @@ + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate/RotateBehavior.png b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/RotateBehavior.png similarity index 100% rename from Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate/RotateBehavior.png rename to Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/RotateBehavior.png diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate/RotateBehaviorCode.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/RotateBehaviorCode.bind similarity index 67% rename from Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate/RotateBehaviorCode.bind rename to Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/RotateBehaviorCode.bind index a7f9916c585..d19ef0f5e87 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate/RotateBehaviorCode.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/RotateBehaviorCode.bind @@ -4,7 +4,4 @@ // C# - Rotate can be applied to any UIElement. In this case it is an image called ToolkitLogo. using Microsoft.Toolkit.Uwp.UI.Animations; -await ToolkitLogo.Rotate(value: 90.0f, - centerX: 0.5f, - centerY: 0.0f, - duration: 10, delay: 0).StartAsync(); +await AnimationBuilder.Create().RotationInDegrees(to: 90, duration: TimeSpan.FromSeconds(3)).StartAsync(ToolkitLogo); diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/RotateBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/RotateBehaviorXaml.bind new file mode 100644 index 00000000000..0e7450e72d9 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/RotateBehaviorXaml.bind @@ -0,0 +1,41 @@ + + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate/RotateBehaviorPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate/RotateBehaviorPage.xaml deleted file mode 100644 index 7dc91aac97d..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate/RotateBehaviorPage.xaml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate/RotateBehaviorPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate/RotateBehaviorPage.xaml.cs deleted file mode 100644 index b814ab90d11..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate/RotateBehaviorPage.xaml.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Linq; -using Microsoft.Toolkit.Uwp.UI.Animations.Behaviors; -using Microsoft.Toolkit.Uwp.UI.Extensions; -using Microsoft.Xaml.Interactivity; -using Windows.UI.Xaml; - -namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages -{ - /// - /// A page that shows how to use the Rotation behavior. - /// - public sealed partial class RotateBehaviorPage : IXamlRenderListener - { - private Rotate _rotateBehavior; - - /// - /// Initializes a new instance of the class. - /// - public RotateBehaviorPage() - { - InitializeComponent(); - - SampleController.Current.RegisterNewCommand("Apply", (s, e) => - { - _rotateBehavior?.StartAnimation(); - }); - } - - public void OnXamlRendered(FrameworkElement control) - { - if (control.FindChildByName("EffectElement") is FrameworkElement element) - { - var behaviors = Interaction.GetBehaviors(element); - _rotateBehavior = behaviors.FirstOrDefault(item => item is Rotate) as Rotate; - } - } - } -} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate/RotateBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate/RotateBehaviorXaml.bind deleted file mode 100644 index f633e0139da..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate/RotateBehaviorXaml.bind +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json index c3aeeec45fc..5b356756f2d 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json @@ -508,13 +508,12 @@ }, { "Name": "Rotate", - "Type": "RotateBehaviorPage", "Subcategory": "Behavior", "About": "Rotation on XAML elements using composition", "CodeUrl": "https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors", - "CodeFile": "RotateBehaviorCode.bind", - "XamlCodeFile": "RotateBehaviorXaml.bind", - "Icon": "/SamplePages/Rotate/rotateBehavior.png", + "CodeFile": "/SamplePages/Animations/Behaviors/RotateBehaviorCode.bind", + "XamlCodeFile": "/SamplePages/Animations/Behaviors/RotateBehaviorXaml.bind", + "Icon": "/SamplePages/Animations/Behaviors/RotateBehavior.png", "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/animations/Rotate.md" }, { From 563eb214af0fdb76c5f8fd9e268ff3b3f735a288 Mon Sep 17 00:00:00 2001 From: "Michael Hawker MSFT (XAML Llama)" <24302614+michael-hawker@users.noreply.github.com> Date: Wed, 20 Jan 2021 22:44:05 -0800 Subject: [PATCH 166/171] Update Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/EffectAnimations.bind --- .../SamplePages/Animations/Effects/EffectAnimations.bind | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/EffectAnimations.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/EffectAnimations.bind index 5a81c876660..1965efbf2b2 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/EffectAnimations.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/EffectAnimations.bind @@ -16,10 +16,10 @@ - + Date: Thu, 21 Jan 2021 13:32:02 +0100 Subject: [PATCH 167/171] Reverted accidental edit in Fade sample page Going back from e5ee018adb4602fa66c7470d33d4ab1bbe0aa8c3 --- .../Animations/Effects/FadeBehaviorXaml.bind | 35 ++++++++----------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind index 9470d0faf6e..1a0f0eb9081 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind @@ -6,37 +6,30 @@ xmlns:interactivity="using:Microsoft.Xaml.Interactivity" xmlns:interactions="using:Microsoft.Xaml.Interactions.Core" xmlns:ani="using:Microsoft.Toolkit.Uwp.UI.Animations" - xmlns:media="using:Microsoft.Toolkit.Uwp.UI.Media" xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors" xmlns:core="using:Microsoft.Xaml.Interactions.Core" mc:Ignorable="d"> From 608b308a223145da8458b90b390d92826b899874 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 21 Jan 2021 13:38:49 +0100 Subject: [PATCH 168/171] Fixed Offset sample page --- .../SamplePages/Animations/Behaviors/OffsetBehaviorXaml.bind | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/OffsetBehaviorXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/OffsetBehaviorXaml.bind index ff02da20dcc..3e46cc4021d 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/OffsetBehaviorXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Behaviors/OffsetBehaviorXaml.bind @@ -10,10 +10,11 @@ xmlns:core="using:Microsoft.Xaml.Interactions.Core" mc:Ignorable="d"> -