-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5886 from AvaloniaUI/animations/tryfix-scb-localv…
…alue Revamp IBrush animator selection + Stop SCBAnimator from setting localvalues on animation apply
- Loading branch information
Dan Walmsley
committed
May 10, 2021
1 parent
f2b9114
commit 98ab542
Showing
7 changed files
with
112 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
src/Avalonia.Visuals/Animation/Animators/BaseBrushAnimator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Reactive.Disposables; | ||
using Avalonia.Logging; | ||
using Avalonia.Media; | ||
|
||
namespace Avalonia.Animation.Animators | ||
{ | ||
/// <summary> | ||
/// Animator that handles all animations on properties | ||
/// with <see cref="IBrush"/> as their type and | ||
/// redirect them to the properly registered | ||
/// animators in this class. | ||
/// </summary> | ||
public class BaseBrushAnimator : Animator<IBrush> | ||
{ | ||
private IAnimator _targetAnimator; | ||
|
||
private static readonly List<(Func<Type, bool> Match, Type AnimatorType)> _brushAnimators = | ||
new List<(Func<Type, bool> Match, Type AnimatorType)>(); | ||
|
||
/// <summary> | ||
/// Register an <see cref="Animator{T}"/> that handles a specific | ||
/// <see cref="IBrush"/>'s descendant value type. | ||
/// </summary> | ||
/// <param name="condition"> | ||
/// The condition to which the <see cref="Animator{T}"/> | ||
/// is to be activated and used. | ||
/// </param> | ||
/// <typeparam name="TAnimator"> | ||
/// The type of the animator to instantiate. | ||
/// </typeparam> | ||
public static void RegisterBrushAnimator<TAnimator>(Func<Type, bool> condition) | ||
where TAnimator : IAnimator | ||
{ | ||
_brushAnimators.Insert(0, (condition, typeof(TAnimator))); | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override IDisposable Apply(Animation animation, Animatable control, IClock clock, | ||
IObservable<bool> match, Action onComplete) | ||
{ | ||
foreach (var valueType in _brushAnimators) | ||
{ | ||
if (!valueType.Match(this[0].Value.GetType())) continue; | ||
|
||
_targetAnimator = (IAnimator)Activator.CreateInstance(valueType.AnimatorType); | ||
|
||
foreach (var keyframe in this) | ||
{ | ||
_targetAnimator.Add(keyframe); | ||
} | ||
|
||
_targetAnimator.Property = this.Property; | ||
|
||
return _targetAnimator.Apply(animation, control, clock, match, onComplete); | ||
} | ||
|
||
Logger.TryGet(LogEventLevel.Error, LogArea.Animations)?.Log( | ||
this, | ||
"The animation's keyframe values didn't match any brush animators registered in BaseBrushAnimator."); | ||
|
||
return Disposable.Empty; | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override IBrush Interpolate(double progress, IBrush oldValue, IBrush newValue) => null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 16 additions & 55 deletions
71
src/Avalonia.Visuals/Animation/Animators/SolidColorBrushAnimator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,71 +1,32 @@ | ||
using System; | ||
using System.Reactive.Disposables; | ||
using Avalonia.Data; | ||
using Avalonia.Media; | ||
using Avalonia.Media.Immutable; | ||
|
||
namespace Avalonia.Animation.Animators | ||
{ | ||
/// <summary> | ||
/// Animator that handles <see cref="SolidColorBrush"/>. | ||
/// Animator that handles <see cref="SolidColorBrush"/> values. | ||
/// </summary> | ||
public class SolidColorBrushAnimator : Animator<SolidColorBrush> | ||
public class ISolidColorBrushAnimator : Animator<ISolidColorBrush> | ||
{ | ||
private ColorAnimator _colorAnimator; | ||
|
||
private void InitializeColorAnimator() | ||
public override ISolidColorBrush Interpolate(double progress, ISolidColorBrush oldValue, ISolidColorBrush newValue) | ||
{ | ||
_colorAnimator = new ColorAnimator(); | ||
|
||
foreach (AnimatorKeyFrame keyframe in this) | ||
{ | ||
_colorAnimator.Add(keyframe); | ||
} | ||
|
||
_colorAnimator.Property = SolidColorBrush.ColorProperty; | ||
return new ImmutableSolidColorBrush(ColorAnimator.InterpolateCore(progress, oldValue.Color, newValue.Color)); | ||
} | ||
|
||
public override IDisposable Apply(Animation animation, Animatable control, IClock clock, IObservable<bool> match, Action onComplete) | ||
public override IDisposable BindAnimation(Animatable control, IObservable<ISolidColorBrush> instance) | ||
{ | ||
// Preprocess keyframe values to Color if the xaml parser converts them to ISCB. | ||
foreach (var keyframe in this) | ||
{ | ||
if (keyframe.Value is ISolidColorBrush colorBrush) | ||
{ | ||
keyframe.Value = colorBrush.Color; | ||
} | ||
else | ||
{ | ||
return Disposable.Empty; | ||
} | ||
} | ||
|
||
SolidColorBrush finalTarget; | ||
var targetVal = control.GetValue(Property); | ||
if (targetVal is null) | ||
{ | ||
finalTarget = new SolidColorBrush(Colors.Transparent); | ||
control.SetValue(Property, finalTarget); | ||
} | ||
else if (targetVal is ImmutableSolidColorBrush immutableSolidColorBrush) | ||
{ | ||
finalTarget = new SolidColorBrush(immutableSolidColorBrush.Color); | ||
control.SetValue(Property, finalTarget); | ||
} | ||
else if (targetVal is ISolidColorBrush) | ||
{ | ||
finalTarget = targetVal as SolidColorBrush; | ||
} | ||
else | ||
{ | ||
return Disposable.Empty; | ||
} | ||
|
||
if (_colorAnimator == null) | ||
InitializeColorAnimator(); | ||
|
||
return _colorAnimator.Apply(animation, finalTarget, clock ?? control.Clock, match, onComplete); | ||
return control.Bind((AvaloniaProperty<IBrush>)Property, instance, BindingPriority.Animation); | ||
} | ||
} | ||
|
||
[Obsolete] | ||
public class SolidColorBrushAnimator : Animator<SolidColorBrush> | ||
{ | ||
public override SolidColorBrush Interpolate(double progress, SolidColorBrush oldValue, SolidColorBrush newValue) | ||
{ | ||
return new SolidColorBrush(ColorAnimator.InterpolateCore(progress, oldValue.Color, newValue.Color)); | ||
} | ||
|
||
public override SolidColorBrush Interpolate(double p, SolidColorBrush o, SolidColorBrush n) => null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters