Browse Source

Make PageTransition.Start cancellable

pull/6018/head
Max Katz 5 years ago
parent
commit
4bbedf5815
  1. 21
      src/Avalonia.Visuals/Animation/CompositePageTransition.cs
  2. 64
      src/Avalonia.Visuals/Animation/CrossFade.cs
  3. 6
      src/Avalonia.Visuals/Animation/IPageTransition.cs
  4. 30
      src/Avalonia.Visuals/Animation/PageSlide.cs
  5. 9
      src/Avalonia.Visuals/ApiCompatBaseline.txt

21
src/Avalonia.Visuals/Animation/CompositePageTransition.cs

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Metadata;
@ -35,25 +36,11 @@ namespace Avalonia.Animation
[Content]
public List<IPageTransition> PageTransitions { get; set; } = new List<IPageTransition>();
/// <summary>
/// Starts the animation.
/// </summary>
/// <param name="from">
/// The control that is being transitioned away from. May be null.
/// </param>
/// <param name="to">
/// The control that is being transitioned to. May be null.
/// </param>
/// <param name="forward">
/// Defines the direction of the transition.
/// </param>
/// <returns>
/// A <see cref="Task"/> that tracks the progress of the animation.
/// </returns>
public Task Start(Visual from, Visual to, bool forward)
/// <inheritdoc />
public Task Start(Visual from, Visual to, bool forward, CancellationToken cancellationToken)
{
var transitionTasks = PageTransitions
.Select(transition => transition.Start(from, to, forward))
.Select(transition => transition.Start(from, to, forward, cancellationToken))
.ToList();
return Task.WhenAll(transitionTasks);
}

64
src/Avalonia.Visuals/Animation/CrossFade.cs

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Reactive.Disposables;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Animation.Easings;
using Avalonia.Styling;
@ -97,49 +99,39 @@ namespace Avalonia.Animation
set => _fadeOutAnimation.Easing = value;
}
/// <summary>
/// Starts the animation.
/// </summary>
/// <param name="from">
/// The control that is being transitioned away from. May be null.
/// </param>
/// <param name="to">
/// The control that is being transitioned to. May be null.
/// </param>
/// <returns>
/// A <see cref="Task"/> that tracks the progress of the animation.
/// </returns>
public async Task Start(Visual from, Visual to)
/// <inheritdoc cref="Start(Visual, Visual, CancellationToken)" />
public async Task Start(Visual from, Visual to, CancellationToken cancellationToken)
{
var tasks = new List<Task>();
if (to != null)
{
to.Opacity = 0;
}
if (from != null)
if (cancellationToken.IsCancellationRequested)
{
tasks.Add(_fadeOutAnimation.RunAsync(from));
return;
}
if (to != null)
var tasks = new List<Task>();
using (var disposables = new CompositeDisposable())
{
to.IsVisible = true;
tasks.Add(_fadeInAnimation.RunAsync(to));
if (to != null)
{
disposables.Add(to.SetValue(Visual.OpacityProperty, 0, Data.BindingPriority.Animation));
}
}
if (from != null)
{
tasks.Add(_fadeOutAnimation.RunAsync(from, null, cancellationToken));
}
await Task.WhenAll(tasks);
if (to != null)
{
to.IsVisible = true;
tasks.Add(_fadeInAnimation.RunAsync(to, null, cancellationToken));
}
if (from != null)
{
from.IsVisible = false;
}
await Task.WhenAll(tasks);
if (to != null)
{
to.Opacity = 1;
if (from != null && !cancellationToken.IsCancellationRequested)
{
from.IsVisible = false;
}
}
}
@ -158,9 +150,9 @@ namespace Avalonia.Animation
/// <returns>
/// A <see cref="Task"/> that tracks the progress of the animation.
/// </returns>
Task IPageTransition.Start(Visual from, Visual to, bool forward)
Task IPageTransition.Start(Visual from, Visual to, bool forward, CancellationToken cancellationToken)
{
return Start(from, to);
return Start(from, to, cancellationToken);
}
}
}

6
src/Avalonia.Visuals/Animation/IPageTransition.cs

@ -1,3 +1,4 @@
using System.Threading;
using System.Threading.Tasks;
namespace Avalonia.Animation
@ -19,9 +20,12 @@ namespace Avalonia.Animation
/// <param name="forward">
/// If the animation is bidirectional, controls the direction of the animation.
/// </param>
/// <param name="cancellationToken">
/// Animation cancellation.
/// </param>
/// <returns>
/// A <see cref="Task"/> that tracks the progress of the animation.
/// </returns>
Task Start(Visual from, Visual to, bool forward);
Task Start(Visual from, Visual to, bool forward, CancellationToken cancellationToken);
}
}

30
src/Avalonia.Visuals/Animation/PageSlide.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Animation.Easings;
using Avalonia.Media;
@ -60,23 +61,14 @@ namespace Avalonia.Animation
/// </summary>
public Easing SlideOutEasing { get; set; } = new LinearEasing();
/// <summary>
/// Starts the animation.
/// </summary>
/// <param name="from">
/// The control that is being transitioned away from. May be null.
/// </param>
/// <param name="to">
/// The control that is being transitioned to. May be null.
/// </param>
/// <param name="forward">
/// If true, the new page is slid in from the right, or if false from the left.
/// </param>
/// <returns>
/// A <see cref="Task"/> that tracks the progress of the animation.
/// </returns>
public async Task Start(Visual from, Visual to, bool forward)
/// <inheritdoc />
public async Task Start(Visual from, Visual to, bool forward, CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
{
return;
}
var tasks = new List<Task>();
var parent = GetVisualParent(from, to);
var distance = Orientation == SlideAxis.Horizontal ? parent.Bounds.Width : parent.Bounds.Height;
@ -109,7 +101,7 @@ namespace Avalonia.Animation
},
Duration = Duration
};
tasks.Add(animation.RunAsync(from));
tasks.Add(animation.RunAsync(from, null, cancellationToken));
}
if (to != null)
@ -140,12 +132,12 @@ namespace Avalonia.Animation
},
Duration = Duration
};
tasks.Add(animation.RunAsync(to));
tasks.Add(animation.RunAsync(to, null, cancellationToken));
}
await Task.WhenAll(tasks);
if (from != null)
if (from != null && !cancellationToken.IsCancellationRequested)
{
from.IsVisible = false;
}

9
src/Avalonia.Visuals/ApiCompatBaseline.txt

@ -1,4 +1,10 @@
Compat issues with assembly Avalonia.Visuals:
MembersMustExist : Member 'public System.Threading.Tasks.Task Avalonia.Animation.CompositePageTransition.Start(Avalonia.Visual, Avalonia.Visual, System.Boolean)' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Threading.Tasks.Task Avalonia.Animation.CrossFade.Start(Avalonia.Visual, Avalonia.Visual)' does not exist in the implementation but it does exist in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public System.Threading.Tasks.Task Avalonia.Animation.IPageTransition.Start(Avalonia.Visual, Avalonia.Visual, System.Boolean)' is present in the contract but not in the implementation.
MembersMustExist : Member 'public System.Threading.Tasks.Task Avalonia.Animation.IPageTransition.Start(Avalonia.Visual, Avalonia.Visual, System.Boolean)' does not exist in the implementation but it does exist in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public System.Threading.Tasks.Task Avalonia.Animation.IPageTransition.Start(Avalonia.Visual, Avalonia.Visual, System.Boolean, System.Threading.CancellationToken)' is present in the implementation but not in the contract.
MembersMustExist : Member 'public System.Threading.Tasks.Task Avalonia.Animation.PageSlide.Start(Avalonia.Visual, Avalonia.Visual, System.Boolean)' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public void Avalonia.Media.TextFormatting.DrawableTextRun.Draw(Avalonia.Media.DrawingContext)' does not exist in the implementation but it does exist in the contract.
CannotAddAbstractMembers : Member 'public void Avalonia.Media.TextFormatting.DrawableTextRun.Draw(Avalonia.Media.DrawingContext, Avalonia.Point)' is abstract in the implementation but is missing in the contract.
CannotSealType : Type 'Avalonia.Media.TextFormatting.GenericTextParagraphProperties' is actually (has the sealed modifier) sealed in the implementation but not sealed in the contract.
@ -63,9 +69,8 @@ InterfacesShouldHaveSameMembers : Interface member 'public System.Boolean Avalon
InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Platform.IGlyphRunImpl Avalonia.Platform.IPlatformRenderInterface.CreateGlyphRun(Avalonia.Media.GlyphRun)' is present in the implementation but not in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Platform.IGlyphRunImpl Avalonia.Platform.IPlatformRenderInterface.CreateGlyphRun(Avalonia.Media.GlyphRun, System.Double)' is present in the contract but not in the implementation.
MembersMustExist : Member 'public Avalonia.Platform.IGlyphRunImpl Avalonia.Platform.IPlatformRenderInterface.CreateGlyphRun(Avalonia.Media.GlyphRun, System.Double)' does not exist in the implementation but it does exist in the contract.
Total Issues: 64
InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Platform.IWriteableBitmapImpl Avalonia.Platform.IPlatformRenderInterface.LoadWriteableBitmap(System.IO.Stream)' is present in the implementation but not in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Platform.IWriteableBitmapImpl Avalonia.Platform.IPlatformRenderInterface.LoadWriteableBitmap(System.String)' is present in the implementation but not in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Platform.IWriteableBitmapImpl Avalonia.Platform.IPlatformRenderInterface.LoadWriteableBitmapToHeight(System.IO.Stream, System.Int32, Avalonia.Visuals.Media.Imaging.BitmapInterpolationMode)' is present in the implementation but not in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Platform.IWriteableBitmapImpl Avalonia.Platform.IPlatformRenderInterface.LoadWriteableBitmapToWidth(System.IO.Stream, System.Int32, Avalonia.Visuals.Media.Imaging.BitmapInterpolationMode)' is present in the implementation but not in the contract.
Total Issues: 11
Total Issues: 74

Loading…
Cancel
Save