From 92b95aff5e28154aa44370a952b4905d8bf36a59 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Sat, 13 May 2023 16:44:35 +0200 Subject: [PATCH 1/8] Init --- .../BehaviorsAnimations/OpenSolution.bat | 3 + .../BehaviorsAnimations.Samples.csproj | 8 ++ .../samples/BehaviorsAnimations.md | 31 ++++++++ .../samples/BehaviorsInvokeActionsSample.xaml | 66 ++++++++++++++++ .../BehaviorsInvokeActionsSample.xaml.cs | 16 ++++ .../samples/Dependencies.props | 31 ++++++++ .../src/AdditionalAssemblyInfo.cs | 13 +++ .../src/AnimationCompletedTriggerBehavior.cs | 65 +++++++++++++++ .../src/AnimationStartedTriggerBehavior.cs | 69 ++++++++++++++++ ...tyToolkit.WinUI.BehaviorsAnimations.csproj | 17 ++++ .../src/Dependencies.props | 31 ++++++++ .../src/InvokeActionsActivity.cs | 49 ++++++++++++ .../BehaviorsAnimations/src/MultiTarget.props | 9 +++ .../src/StartAnimationAction.cs | 79 +++++++++++++++++++ .../src/StopAnimationAction.cs | 79 +++++++++++++++++++ .../tests/BehaviorsAnimations.Tests.projitems | 11 +++ .../tests/BehaviorsAnimations.Tests.shproj | 13 +++ 17 files changed, 590 insertions(+) create mode 100644 components/BehaviorsAnimations/OpenSolution.bat create mode 100644 components/BehaviorsAnimations/samples/BehaviorsAnimations.Samples.csproj create mode 100644 components/BehaviorsAnimations/samples/BehaviorsAnimations.md create mode 100644 components/BehaviorsAnimations/samples/BehaviorsInvokeActionsSample.xaml create mode 100644 components/BehaviorsAnimations/samples/BehaviorsInvokeActionsSample.xaml.cs create mode 100644 components/BehaviorsAnimations/samples/Dependencies.props create mode 100644 components/BehaviorsAnimations/src/AdditionalAssemblyInfo.cs create mode 100644 components/BehaviorsAnimations/src/AnimationCompletedTriggerBehavior.cs create mode 100644 components/BehaviorsAnimations/src/AnimationStartedTriggerBehavior.cs create mode 100644 components/BehaviorsAnimations/src/CommunityToolkit.WinUI.BehaviorsAnimations.csproj create mode 100644 components/BehaviorsAnimations/src/Dependencies.props create mode 100644 components/BehaviorsAnimations/src/InvokeActionsActivity.cs create mode 100644 components/BehaviorsAnimations/src/MultiTarget.props create mode 100644 components/BehaviorsAnimations/src/StartAnimationAction.cs create mode 100644 components/BehaviorsAnimations/src/StopAnimationAction.cs create mode 100644 components/BehaviorsAnimations/tests/BehaviorsAnimations.Tests.projitems create mode 100644 components/BehaviorsAnimations/tests/BehaviorsAnimations.Tests.shproj diff --git a/components/BehaviorsAnimations/OpenSolution.bat b/components/BehaviorsAnimations/OpenSolution.bat new file mode 100644 index 00000000..814a56d4 --- /dev/null +++ b/components/BehaviorsAnimations/OpenSolution.bat @@ -0,0 +1,3 @@ +@ECHO OFF + +powershell ..\..\tooling\ProjectHeads\GenerateSingleSampleHeads.ps1 -componentPath %CD% %* \ No newline at end of file diff --git a/components/BehaviorsAnimations/samples/BehaviorsAnimations.Samples.csproj b/components/BehaviorsAnimations/samples/BehaviorsAnimations.Samples.csproj new file mode 100644 index 00000000..b465b288 --- /dev/null +++ b/components/BehaviorsAnimations/samples/BehaviorsAnimations.Samples.csproj @@ -0,0 +1,8 @@ + + + BehaviorsAnimations + + + + + diff --git a/components/BehaviorsAnimations/samples/BehaviorsAnimations.md b/components/BehaviorsAnimations/samples/BehaviorsAnimations.md new file mode 100644 index 00000000..fa82500d --- /dev/null +++ b/components/BehaviorsAnimations/samples/BehaviorsAnimations.md @@ -0,0 +1,31 @@ +--- +title: BehaviorsAnimations +author: githubaccount +description: TODO: Your experiment's description here +keywords: BehaviorsAnimations, Control, Layout +dev_langs: + - csharp +category: Controls +subcategory: Layout +discussion-id: 0 +issue-id: 0 +--- + + + + + + + + + +# BehaviorsAnimations + +TODO: Fill in information about this experiment and how to get started here... + +## Custom Control + +You can inherit from an existing component as well, like `Panel`, this example shows a control without a +XAML Style that will be more light-weight to consume by an app developer: + +> [!Sample BehaviorsInvokeActionsSample] diff --git a/components/BehaviorsAnimations/samples/BehaviorsInvokeActionsSample.xaml b/components/BehaviorsAnimations/samples/BehaviorsInvokeActionsSample.xaml new file mode 100644 index 00000000..e0e95988 --- /dev/null +++ b/components/BehaviorsAnimations/samples/BehaviorsInvokeActionsSample.xaml @@ -0,0 +1,66 @@ + + + + + diff --git a/components/BehaviorsAnimations/samples/BehaviorsInvokeActionsSample.xaml.cs b/components/BehaviorsAnimations/samples/BehaviorsInvokeActionsSample.xaml.cs new file mode 100644 index 00000000..1ff9c2cc --- /dev/null +++ b/components/BehaviorsAnimations/samples/BehaviorsInvokeActionsSample.xaml.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 CommunityToolkit.WinUI.Animations; + +namespace Behaviors_AnimationsExperiment.Samples; + +[ToolkitSample(id: nameof(BehaviorsInvokeActionsSample), "InvokeActionsActivity", description: $"A sample for showing how to create and use a {nameof(InvokeActionsActivity)} behavior.")] +public sealed partial class BehaviorsInvokeActionsSample : Page +{ + public BehaviorsInvokeActionsSample() + { + this.InitializeComponent(); + } +} diff --git a/components/BehaviorsAnimations/samples/Dependencies.props b/components/BehaviorsAnimations/samples/Dependencies.props new file mode 100644 index 00000000..e622e1df --- /dev/null +++ b/components/BehaviorsAnimations/samples/Dependencies.props @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/BehaviorsAnimations/src/AdditionalAssemblyInfo.cs b/components/BehaviorsAnimations/src/AdditionalAssemblyInfo.cs new file mode 100644 index 00000000..ce142c4b --- /dev/null +++ b/components/BehaviorsAnimations/src/AdditionalAssemblyInfo.cs @@ -0,0 +1,13 @@ +// 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.Runtime.CompilerServices; + +// These `InternalsVisibleTo` calls are intended to make it easier for +// for any internal code to be testable in all the different test projects +// used with the Labs infrastructure. +[assembly: InternalsVisibleTo("BehaviorsAnimations.Tests.Uwp")] +[assembly: InternalsVisibleTo("BehaviorsAnimations.Tests.WinAppSdk")] +[assembly: InternalsVisibleTo("CommunityToolkit.Tests.Uwp")] +[assembly: InternalsVisibleTo("CommunityToolkit.Tests.WinAppSdk")] diff --git a/components/BehaviorsAnimations/src/AnimationCompletedTriggerBehavior.cs b/components/BehaviorsAnimations/src/AnimationCompletedTriggerBehavior.cs new file mode 100644 index 00000000..f2930c3f --- /dev/null +++ b/components/BehaviorsAnimations/src/AnimationCompletedTriggerBehavior.cs @@ -0,0 +1,65 @@ +using CommunityToolkit.WinUI.Animations; +using Microsoft.Xaml.Interactivity; + +namespace CommunityToolkit.WinUI.Behaviors; + +/// +/// A custom that fires whenever a linked completes. +/// +public sealed class AnimationCompletedTriggerBehavior : Trigger +{ + /// + /// The current instance in use. + /// + private AnimationSet? 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(AnimationSet? animationCollection) + { + if (this.animationCollection == animationCollection) + { + return; + } + + if (this.animationCollection is not null) + { + this.animationCollection.Completed -= AnimationCollection_Completed; + } + + this.animationCollection = animationCollection; + + if (animationCollection is not null) + { + animationCollection.Completed += AnimationCollection_Completed; + } + } + + /// + /// Invokes the current actions when the linked animations completes. + /// + /// The source instance. + /// The arguments for the event (unused). + private void AnimationCollection_Completed(object? sender, System.EventArgs e) + { + Interaction.ExecuteActions(sender, Actions, e); + } +} diff --git a/components/BehaviorsAnimations/src/AnimationStartedTriggerBehavior.cs b/components/BehaviorsAnimations/src/AnimationStartedTriggerBehavior.cs new file mode 100644 index 00000000..c8f2304f --- /dev/null +++ b/components/BehaviorsAnimations/src/AnimationStartedTriggerBehavior.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 CommunityToolkit.WinUI.Animations; +using Microsoft.Xaml.Interactivity; + +namespace CommunityToolkit.WinUI.Behaviors; + +/// +/// A custom that fires whenever a linked starts. +/// +public sealed class AnimationStartedTriggerBehavior : Trigger +{ + /// + /// The current instance in use. + /// + private AnimationSet? 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(AnimationSet? 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); + } +} diff --git a/components/BehaviorsAnimations/src/CommunityToolkit.WinUI.BehaviorsAnimations.csproj b/components/BehaviorsAnimations/src/CommunityToolkit.WinUI.BehaviorsAnimations.csproj new file mode 100644 index 00000000..e78eb347 --- /dev/null +++ b/components/BehaviorsAnimations/src/CommunityToolkit.WinUI.BehaviorsAnimations.csproj @@ -0,0 +1,17 @@ + + + BehaviorsAnimations + This package contains BehaviorsAnimations. + 0.0.1 + + + CommunityToolkit.WinUI.BehaviorsAnimationsRns + + + + + + + + + diff --git a/components/BehaviorsAnimations/src/Dependencies.props b/components/BehaviorsAnimations/src/Dependencies.props new file mode 100644 index 00000000..3f06d427 --- /dev/null +++ b/components/BehaviorsAnimations/src/Dependencies.props @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/BehaviorsAnimations/src/InvokeActionsActivity.cs b/components/BehaviorsAnimations/src/InvokeActionsActivity.cs new file mode 100644 index 00000000..310d2b92 --- /dev/null +++ b/components/BehaviorsAnimations/src/InvokeActionsActivity.cs @@ -0,0 +1,49 @@ +// 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.Xaml.Interactivity; + +namespace CommunityToolkit.WinUI.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); + } +} diff --git a/components/BehaviorsAnimations/src/MultiTarget.props b/components/BehaviorsAnimations/src/MultiTarget.props new file mode 100644 index 00000000..6a460034 --- /dev/null +++ b/components/BehaviorsAnimations/src/MultiTarget.props @@ -0,0 +1,9 @@ + + + + uwp;wasdk; + + \ No newline at end of file diff --git a/components/BehaviorsAnimations/src/StartAnimationAction.cs b/components/BehaviorsAnimations/src/StartAnimationAction.cs new file mode 100644 index 00000000..890326fc --- /dev/null +++ b/components/BehaviorsAnimations/src/StartAnimationAction.cs @@ -0,0 +1,79 @@ +// 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.Xaml.Interactivity; +using CommunityToolkit.WinUI.Animations; + +namespace CommunityToolkit.WinUI.Behaviors; + +/// +/// An implementation that can trigger a target instance. +/// +public sealed class StartAnimationAction : DependencyObject, IAction +{ + /// + /// 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( + nameof(Animation), + typeof(AnimationSet), + 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 => (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) + { + if (Animation is null) + { + ThrowArgumentNullException(); + } + + UIElement? parent = null; + if (Animation is not null) + { + if (TargetObject is not null) + { + Animation.Start(TargetObject); + } + else if (Animation.ParentReference?.TryGetTarget(out parent) == true) //// TODO: Tidy... apply same pattern to Activities? + { + Animation.Start(parent!); + } + else + { + Animation.Start(sender as UIElement); + } + } + return null!; + + static void ThrowArgumentNullException() => throw new ArgumentNullException(nameof(Animation)); + } +} diff --git a/components/BehaviorsAnimations/src/StopAnimationAction.cs b/components/BehaviorsAnimations/src/StopAnimationAction.cs new file mode 100644 index 00000000..07448c2a --- /dev/null +++ b/components/BehaviorsAnimations/src/StopAnimationAction.cs @@ -0,0 +1,79 @@ +// 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 CommunityToolkit.WinUI.Animations; +using Microsoft.Xaml.Interactivity; + +namespace CommunityToolkit.WinUI.Behaviors; + +/// +/// An implementation that can stop a target instance. +/// +public sealed class StopAnimationAction : DependencyObject, IAction +{ + /// + /// 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(StopAnimationAction), + new PropertyMetadata(null)); + + /// + /// Gets or sets the object to stop the specified animation on. 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(StopAnimationAction), + new PropertyMetadata(null)); + + /// + public object Execute(object sender, object parameter) + { + if (Animation is null) + { + ThrowArgumentNullException(); + } + + UIElement? parent = null; + if (Animation is not null) + { + if (TargetObject is not null) + { + Animation.Stop(TargetObject); + } + else if (Animation.ParentReference?.TryGetTarget(out parent) == true) //// TODO: Tidy... + { + Animation.Stop(parent); + } + else + { + Animation.Stop(sender as UIElement); + } + } + return null!; + + static void ThrowArgumentNullException() => throw new ArgumentNullException(nameof(Animation)); + } +} diff --git a/components/BehaviorsAnimations/tests/BehaviorsAnimations.Tests.projitems b/components/BehaviorsAnimations/tests/BehaviorsAnimations.Tests.projitems new file mode 100644 index 00000000..944ffa7a --- /dev/null +++ b/components/BehaviorsAnimations/tests/BehaviorsAnimations.Tests.projitems @@ -0,0 +1,11 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + DA850559-344C-4658-A17D-5A0EDF83BBBD + + + BehaviorsAnimationsExperiment.Tests + > + \ No newline at end of file diff --git a/components/BehaviorsAnimations/tests/BehaviorsAnimations.Tests.shproj b/components/BehaviorsAnimations/tests/BehaviorsAnimations.Tests.shproj new file mode 100644 index 00000000..5f70fe7e --- /dev/null +++ b/components/BehaviorsAnimations/tests/BehaviorsAnimations.Tests.shproj @@ -0,0 +1,13 @@ + + + + DA850559-344C-4658-A17D-5A0EDF83BBBD + 14.0 + + + + + + + + From d0d7a64c9b741f984d3db0a33dc0e800465b1164 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Sat, 13 May 2023 16:44:46 +0200 Subject: [PATCH 2/8] Making WeakReference public --- components/Animations/src/Xaml/AnimationSet.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/Animations/src/Xaml/AnimationSet.cs b/components/Animations/src/Xaml/AnimationSet.cs index 8cab5152..62c2d8b6 100644 --- a/components/Animations/src/Xaml/AnimationSet.cs +++ b/components/Animations/src/Xaml/AnimationSet.cs @@ -51,7 +51,7 @@ public sealed class AnimationSet : DependencyObjectCollection /// /// Gets or sets the weak reference to the parent that owns the current animation collection. /// - internal WeakReference? ParentReference { get; set; } + public WeakReference? ParentReference { get; set; } /// /// Thrown when there is no attached instance. @@ -66,9 +66,9 @@ public async void Start() } /// - public async void Start(UIElement element) + public async void Start(UIElement? element) { - await StartAsync(element); + await StartAsync(element!); } /// @@ -204,9 +204,9 @@ public void Stop() /// Cancels the current animation for a target instance. /// /// The target instance to stop the animation for. - public void Stop(UIElement element) + public void Stop(UIElement? element) { - if (this.cancellationTokenMap.TryGetValue(element, out CancellationTokenSource? value)) + if (this.cancellationTokenMap.TryGetValue(element!, out CancellationTokenSource? value)) { value.Cancel(); } From 2ae3e293f759cc716ee07fd75158c957475f7fbe Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Sat, 13 May 2023 17:12:37 +0200 Subject: [PATCH 3/8] Remove files --- .../samples/BehaviorsInvokeActionsSample.xaml | 66 ------------------- .../BehaviorsInvokeActionsSample.xaml.cs | 16 ----- 2 files changed, 82 deletions(-) delete mode 100644 components/BehaviorsAnimations/samples/BehaviorsInvokeActionsSample.xaml delete mode 100644 components/BehaviorsAnimations/samples/BehaviorsInvokeActionsSample.xaml.cs diff --git a/components/BehaviorsAnimations/samples/BehaviorsInvokeActionsSample.xaml b/components/BehaviorsAnimations/samples/BehaviorsInvokeActionsSample.xaml deleted file mode 100644 index e0e95988..00000000 --- a/components/BehaviorsAnimations/samples/BehaviorsInvokeActionsSample.xaml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - diff --git a/components/BehaviorsAnimations/samples/BehaviorsInvokeActionsSample.xaml.cs b/components/BehaviorsAnimations/samples/BehaviorsInvokeActionsSample.xaml.cs deleted file mode 100644 index 1ff9c2cc..00000000 --- a/components/BehaviorsAnimations/samples/BehaviorsInvokeActionsSample.xaml.cs +++ /dev/null @@ -1,16 +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 CommunityToolkit.WinUI.Animations; - -namespace Behaviors_AnimationsExperiment.Samples; - -[ToolkitSample(id: nameof(BehaviorsInvokeActionsSample), "InvokeActionsActivity", description: $"A sample for showing how to create and use a {nameof(InvokeActionsActivity)} behavior.")] -public sealed partial class BehaviorsInvokeActionsSample : Page -{ - public BehaviorsInvokeActionsSample() - { - this.InitializeComponent(); - } -} From 642b77fd0dc3baa49bda229b032b99b243abb2e1 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Sat, 13 May 2023 17:15:55 +0200 Subject: [PATCH 4/8] More samples --- .../samples/Assets/ToolkitIcon.png | Bin 0 -> 3460 bytes .../BehaviorsAnimations.Samples.csproj | 8 + .../samples/BehaviorsAnimations.md | 209 ++++++++++++++++-- .../samples/InvokeActionsSample.xaml | 64 ++++++ .../samples/InvokeActionsSample.xaml.cs | 16 ++ .../samples/StartAnimationActivitySample.xaml | 63 ++++++ .../StartAnimationActivitySample.xaml.cs | 16 ++ .../src/AnimationCompletedTriggerBehavior.cs | 4 + 8 files changed, 364 insertions(+), 16 deletions(-) create mode 100644 components/BehaviorsAnimations/samples/Assets/ToolkitIcon.png create mode 100644 components/BehaviorsAnimations/samples/InvokeActionsSample.xaml create mode 100644 components/BehaviorsAnimations/samples/InvokeActionsSample.xaml.cs create mode 100644 components/BehaviorsAnimations/samples/StartAnimationActivitySample.xaml create mode 100644 components/BehaviorsAnimations/samples/StartAnimationActivitySample.xaml.cs diff --git a/components/BehaviorsAnimations/samples/Assets/ToolkitIcon.png b/components/BehaviorsAnimations/samples/Assets/ToolkitIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..e6c62b30685fec8d8869662b2bd762f0d743daa2 GIT binary patch literal 3460 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 + + + + + + Always + + diff --git a/components/BehaviorsAnimations/samples/BehaviorsAnimations.md b/components/BehaviorsAnimations/samples/BehaviorsAnimations.md index fa82500d..176d0e37 100644 --- a/components/BehaviorsAnimations/samples/BehaviorsAnimations.md +++ b/components/BehaviorsAnimations/samples/BehaviorsAnimations.md @@ -1,8 +1,8 @@ --- -title: BehaviorsAnimations -author: githubaccount -description: TODO: Your experiment's description here -keywords: BehaviorsAnimations, Control, Layout +title: AnimationSet +author: Sergio0694 +description: A collection of animations that can be grouped together. +keywords: Behaviors, animations, animationset, xaml, visual, composition dev_langs: - csharp category: Controls @@ -11,21 +11,198 @@ discussion-id: 0 issue-id: 0 --- - - - - - +# AnimationSet - +The [`AnimationSet`](/dotnet/api/microsoft.toolkit.uwp.ui.animations.AnimationSet) type represents an animation schedule, effectively representing an [AnimationBuilder](/dotnet/api/microsoft.toolkit.uwp.ui.animations.AnimationBuilder) instance via XAML code. It can contain any number of animations or activities, exposes methods to start and stop an animation, and events to be notified when an animation has started or is completed. Like `AnimationBuilder`, `AnimationSet` instances can also be shared (e.g. in a [`ResourceDictionary`](/windows/uwp/design/controls-and-patterns/resourcedictionary-and-xaml-resource-references)) and then be used to start animation schedules on multiple UI elements. It can also be directly attached to a parent UI element, via the [`Explicit.Animations`](/dotnet/api/microsoft.toolkit.uwp.ui.animations.Explicit) attached property. -# BehaviorsAnimations +> **Platform APIs:** [`AnimationSet`](/dotnet/api/microsoft.toolkit.uwp.ui.animations.AnimationSet), [AnimationBuilder](/dotnet/api/microsoft.toolkit.uwp.ui.animations.AnimationBuilder), [`Explicit`](/dotnet/api/microsoft.toolkit.uwp.ui.animations.Explicit), [`ITimeline`](/dotnet/api/microsoft.toolkit.uwp.ui.animations.ITimeline), [`IActivity`](/dotnet/api/microsoft.toolkit.uwp.ui.animations.IActivity), [`AnimationScope`](/dotnet/api/microsoft.toolkit.uwp.ui.animations.AnimationScope), [`AnimationStartedTriggerBehavior`](/dotnet/api/microsoft.toolkit.uwp.ui.behaviors.AnimationStartedTriggerBehavior), [`AnimationCompletedTriggerBehavior`](/dotnet/api/microsoft.toolkit.uwp.ui.behaviors.AnimationCompletedTriggerBehavior), [`StartAnimationAction`](/dotnet/api/microsoft.toolkit.uwp.ui.behaviors.StartAnimationAction), [`StopAnimationAction`](/dotnet/api/microsoft.toolkit.uwp.ui.behaviors.StopAnimationAction) -TODO: Fill in information about this experiment and how to get started here... +## How it works -## Custom Control +Each set can contain any number of animation scopes and individual nodes, which can be either animations or "activities": -You can inherit from an existing component as well, like `Panel`, this example shows a control without a -XAML Style that will be more light-weight to consume by an app developer: +- **Animation types** are a mapping in XAML for the various APIs exposed by the `AnimationBuilder` class. They are available as both "default" animations that are ready to use and "custom" animations that can be fully configured. Each animation type also supports using keyframes in addition to just defining the starting and final values. +- **Activities** on the other hand are a way to interleave an animation schedule with all sorts of custom logic, such as triggering other animations or running arbitrary code (eg. to update a visual state while an animation is running). -> [!Sample BehaviorsInvokeActionsSample] +These two types of animation nodes implement several interfaces (such as [`ITimeline`](/dotnet/api/microsoft.toolkit.uwp.ui.animations.ITimeline) and [`IActivity`](/dotnet/api/microsoft.toolkit.uwp.ui.animations.IActivity)) which make this system extremely customizable and extensible for users as well for their own scenarios. + +Here is how a simple animation can be declared in XAML. In this case we are using `x:Name` so that we can reference it in code behind to start it when the button is clicked. The animation is also directly attached to the [`Button`](/windows/uwp/design/controls-and-patterns/buttons), so we can start it directly by calling the `Start()` method, without the need to specify the target element to animate. + +```xaml + + +``` + +By default, animations target the [Composition layer](/windows/uwp/composition/visual-layer) as it provides the best performance possible. It is also possible to explicitly target the XAML layer too though, which can enable things such as animating the color of a brush used to display some text in a `Button`. Here is an example where we use this functionality, together with explicit keyframes to have more fine-grained control over the animation to run: + +```xaml + + +``` + +Keyframes (both when declared in C# and in XAML) can also use an [expression animation](/uwp/api/windows.ui.composition.expressionanimation) when they are being used in an animation targeting the Composition layer. This provides additional control over the animation values and allows consumers to create dynamic animations that can adapt to the current state of the target element. Here is an example: + +```xaml + + +``` + +## Sequential mode + +Another feature of the `AnimationSet` type is the `IsSequential` property which configures the way top-level elements (animations, activities, and scopes) within the animation are handled. + +When this property is set to `true` each top-level node will be executed sequentially and only move to the following one when the previous completes (and the animation has not been cancelled). This can be used in conjunction with the various `IActivity` objects to create custom animation schedules that combine multiple animations running on different UI elements, with all the synchronization still done entirely from XAML. It is also helpful when combined with an [`AnimationScope`](/dotnet/api/microsoft.toolkit.uwp.ui.animations.AnimationScope) in order to more easily parse the timeline of events within an animation when creating and modifying them. + +Here is an example that showcases both the sequential mode for animations as well as the ability to combine animations and activities in the same schedule, and how different animations (even on different UI elements) can be combined and interleaved by using the available APIs: + +```xaml + + + + + + + + + + + + + + +``` + +The same functionality with respect to cancellation applies to `AnimationSet` as well: each individual invocation on an UI element internally gets its own cancellation token, which can be used to stop a running animation by invoking the `Stop()` method or one of its overloads. The same token is also forwarded to all invoked activities in the schedule, so stopping an animation set will also automatically stop all linked animations and activities as well. + +Here's an example of how all these various explicit animations can be combined together (including some of the new effect animations too): + +![AnimationSet in sequential mode and with combined animations](../resources/images/AnimationSet.gif) + +## Behaviors + +If you are also referencing the `Microsoft.Toolkit.Uwp.UI.Behaviors` package, it will be possible to also use behaviors and actions to better support the new APIs, such as by automatically triggering an animation when a given event is raised, entirely from XAML. There are four main types being introduced in this package that interoperate with the Animation APIs: + +- [`AnimationStartedTriggerBehavior`](/dotnet/api/microsoft.toolkit.uwp.ui.behaviors.AnimationStartedTriggerBehavior) and [`AnimationCompletedTriggerBehavior`](/dotnet/api/microsoft.toolkit.uwp.ui.behaviors.AnimationCompletedTriggerBehavior): these are custom triggers that can be used to execute `IAction`-s when an `AnimationSet` starts or completes. All the built-in `IAction` objects can be used from the Behaviors package, as well as custom ones as well. +- [`StartAnimationAction`](/dotnet/api/microsoft.toolkit.uwp.ui.behaviors.StartAnimationAction): an `IAction` object that can be used within behaviors to easily start a target animation, either with an attached UI element or with an explicit target to animate. +- [`StopAnimationAction`](/dotnet/api/microsoft.toolkit.uwp.ui.behaviors.StopAnimationAction): an `IAction` object that can be used within behaviors to easily stop a target animation, either with an attached UI element or with an explicit target to animate. + +Here is an example that shows how these new APIs can be used together: + +```xaml + +``` + +This makes it possible to also not having to name the target UI element, to register the event handler in code behind, and in many cases to even name the `AnimationSet` instance at all, if it doesn't need to be referenced by other animations at all. The resulting code is all in XAML, with no need for code behind at all! + +[!InvokeActionsActivitySample] + +## Effect animations + +Lastly, the `AnimationSet` class can also directly animate Composition/Win2D effects. To gain access to this feature, you will need to also reference the `Microsoft.Toolkit.Uwp.UI.Media`. This package includes some special animation types that can be plugged in into an `AnimationSet` instance and used to animate individual effects within a custom effects graph. This can then be used either from a [PipelineBrush](/dotnet/api/microsoft.toolkit.uwp.ui.media.pipelinebrush) or from an inline graph attached to a UI element through the [`PipelineVisualFactory`](/dotnet/api/microsoft.toolkit.uwp.ui.media.PipelineVisualFactory) type. All these effect animations are powered by the same `AnimationBuilder` type behind the scenes, and can facilitate creating complex animations on specific effects within a graph. + +Here is an example of how the new `PipelineVisualFactory` type can be combined with these effect animations: + +```xaml + +``` + +Here we are setting the `IsAnimatable` property for the effects we want to animate after creating the brush. This is necessary because Win2D/Composition effects do not support animation by default, and additional setup is required when creating a Composition brush to enable this functionality. Effects in a pipeline are not just all configured as being animatable by default both in order to reduce the overhead, and because there is a limit on the number of effects that can be animated in a single brush. Making this more advanced functionality opt-in for users ensures that it will still be possible to animate effects even within very large pipelines, without incurring into issues due to this limit. + +And here is the final result from the code above, with an image and some text as content: + +![AnimationSet used to animate effects in a custom pipeline](../resources/images/EffectAnimations.gif) diff --git a/components/BehaviorsAnimations/samples/InvokeActionsSample.xaml b/components/BehaviorsAnimations/samples/InvokeActionsSample.xaml new file mode 100644 index 00000000..c114a825 --- /dev/null +++ b/components/BehaviorsAnimations/samples/InvokeActionsSample.xaml @@ -0,0 +1,64 @@ + + + + + diff --git a/components/BehaviorsAnimations/samples/InvokeActionsSample.xaml.cs b/components/BehaviorsAnimations/samples/InvokeActionsSample.xaml.cs new file mode 100644 index 00000000..ebb2306b --- /dev/null +++ b/components/BehaviorsAnimations/samples/InvokeActionsSample.xaml.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 CommunityToolkit.WinUI.Animations; + +namespace BehaviorsAnimationsExperiment.Samples; + +[ToolkitSample(id: nameof(InvokeActionsActivitySample), "InvokeActionsActivity", description: $"A sample for showing how to create and use a {nameof(StartAnimationActivity)} behavior.")] +public sealed partial class InvokeActionsActivitySample : Page +{ + public InvokeActionsActivitySample() + { + this.InitializeComponent(); + } +} diff --git a/components/BehaviorsAnimations/samples/StartAnimationActivitySample.xaml b/components/BehaviorsAnimations/samples/StartAnimationActivitySample.xaml new file mode 100644 index 00000000..38cac9c7 --- /dev/null +++ b/components/BehaviorsAnimations/samples/StartAnimationActivitySample.xaml @@ -0,0 +1,63 @@ + + + + + diff --git a/components/BehaviorsAnimations/samples/StartAnimationActivitySample.xaml.cs b/components/BehaviorsAnimations/samples/StartAnimationActivitySample.xaml.cs new file mode 100644 index 00000000..81174215 --- /dev/null +++ b/components/BehaviorsAnimations/samples/StartAnimationActivitySample.xaml.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 CommunityToolkit.WinUI.Animations; + +namespace BehaviorsAnimationsExperiment.Samples; + +[ToolkitSample(id: nameof(StartAnimationActivitySample), "StartAnimationActivity", description: $"A sample for showing how to create and use a {nameof(InvokeActionsActivity)} behavior.")] +public sealed partial class StartAnimationActivitySample : Page +{ + public StartAnimationActivitySample() + { + this.InitializeComponent(); + } +} diff --git a/components/BehaviorsAnimations/src/AnimationCompletedTriggerBehavior.cs b/components/BehaviorsAnimations/src/AnimationCompletedTriggerBehavior.cs index f2930c3f..b8052e2a 100644 --- a/components/BehaviorsAnimations/src/AnimationCompletedTriggerBehavior.cs +++ b/components/BehaviorsAnimations/src/AnimationCompletedTriggerBehavior.cs @@ -1,3 +1,7 @@ +// 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 CommunityToolkit.WinUI.Animations; using Microsoft.Xaml.Interactivity; From 7646c52d30dce7544b0edee6ace795c73d820ffa Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Sun, 14 May 2023 16:13:13 +0200 Subject: [PATCH 5/8] Adding samples to docs --- components/BehaviorsAnimations/samples/BehaviorsAnimations.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/BehaviorsAnimations/samples/BehaviorsAnimations.md b/components/BehaviorsAnimations/samples/BehaviorsAnimations.md index 176d0e37..c0ddfba5 100644 --- a/components/BehaviorsAnimations/samples/BehaviorsAnimations.md +++ b/components/BehaviorsAnimations/samples/BehaviorsAnimations.md @@ -159,7 +159,9 @@ Here is an example that shows how these new APIs can be used together: This makes it possible to also not having to name the target UI element, to register the event handler in code behind, and in many cases to even name the `AnimationSet` instance at all, if it doesn't need to be referenced by other animations at all. The resulting code is all in XAML, with no need for code behind at all! -[!InvokeActionsActivitySample] +> [!SAMPLE InvokeActionsActivitySample] + +> [!SAMPLE StartAnimationActivitySample] ## Effect animations From 43c9f10d55eef392512147dce0f0ec9d182671fd Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Mon, 15 May 2023 10:18:29 +0200 Subject: [PATCH 6/8] Fix --- .../tests/BehaviorsAnimations.Tests.projitems | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/BehaviorsAnimations/tests/BehaviorsAnimations.Tests.projitems b/components/BehaviorsAnimations/tests/BehaviorsAnimations.Tests.projitems index 944ffa7a..75412c03 100644 --- a/components/BehaviorsAnimations/tests/BehaviorsAnimations.Tests.projitems +++ b/components/BehaviorsAnimations/tests/BehaviorsAnimations.Tests.projitems @@ -7,5 +7,5 @@ BehaviorsAnimationsExperiment.Tests - > + \ No newline at end of file From 5f40409c5c81b8d3f068e37cefffd8e44565e68e Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Mon, 15 May 2023 10:51:46 +0200 Subject: [PATCH 7/8] Bump version number --- .../src/CommunityToolkit.WinUI.BehaviorsAnimations.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/BehaviorsAnimations/src/CommunityToolkit.WinUI.BehaviorsAnimations.csproj b/components/BehaviorsAnimations/src/CommunityToolkit.WinUI.BehaviorsAnimations.csproj index e78eb347..e6646cb3 100644 --- a/components/BehaviorsAnimations/src/CommunityToolkit.WinUI.BehaviorsAnimations.csproj +++ b/components/BehaviorsAnimations/src/CommunityToolkit.WinUI.BehaviorsAnimations.csproj @@ -2,7 +2,7 @@ BehaviorsAnimations This package contains BehaviorsAnimations. - 0.0.1 + 8.0.0-beta.1 CommunityToolkit.WinUI.BehaviorsAnimationsRns From 35d185586e295b62b69fce35674cad152dc3d1c3 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Tue, 16 May 2023 18:27:03 +0200 Subject: [PATCH 8/8] Fix --- .../Animations/src/CommunityToolkit.WinUI.Animations.csproj | 1 + components/Animations/src/Xaml/AnimationSet.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/components/Animations/src/CommunityToolkit.WinUI.Animations.csproj b/components/Animations/src/CommunityToolkit.WinUI.Animations.csproj index fceaa5be..89331a4b 100644 --- a/components/Animations/src/CommunityToolkit.WinUI.Animations.csproj +++ b/components/Animations/src/CommunityToolkit.WinUI.Animations.csproj @@ -10,6 +10,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/components/Animations/src/Xaml/AnimationSet.cs b/components/Animations/src/Xaml/AnimationSet.cs index 62c2d8b6..f9f894a0 100644 --- a/components/Animations/src/Xaml/AnimationSet.cs +++ b/components/Animations/src/Xaml/AnimationSet.cs @@ -51,7 +51,7 @@ public sealed class AnimationSet : DependencyObjectCollection /// /// Gets or sets the weak reference to the parent that owns the current animation collection. /// - public WeakReference? ParentReference { get; set; } + internal WeakReference? ParentReference { get; set; } /// /// Thrown when there is no attached instance.