From d6d87b1a32c91bbaa9c066b95d20350bee047ad1 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Mon, 14 Jun 2021 12:31:45 +0200 Subject: [PATCH] Fix fetching neutral value in animations. Animators fetched the neutral value when the animation is instantiated but did not update the neutral value if it's updated after that. #6063 was caused by the fact that the neutral value does not take effect until the batch update due to styling has finished on the control, which is _after_ the animation has been instantiated. Listen for changes on the property and if the change is not an animated value change, update the neutral value. This isn't perfect because it won't react to changes to the neutral value while the animation is actually running and producing values because `PropertyChanged` events don't get fired for non-active values: for that we'd need to hook into `OnPropertyChangedCore`. But this at least fixes the simple case of the initial neutral value. --- src/Avalonia.Animation/AnimationInstance`1.cs | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Animation/AnimationInstance`1.cs b/src/Avalonia.Animation/AnimationInstance`1.cs index 6f601a3e13..0e1882ce75 100644 --- a/src/Avalonia.Animation/AnimationInstance`1.cs +++ b/src/Avalonia.Animation/AnimationInstance`1.cs @@ -5,6 +5,7 @@ using Avalonia.Animation.Animators; using Avalonia.Animation.Utils; using Avalonia.Data; using Avalonia.Reactive; +using JetBrains.Annotations; namespace Avalonia.Animation { @@ -45,8 +46,9 @@ namespace Avalonia.Animation _onCompleteAction = OnComplete; _interpolator = Interpolator; _baseClock = baseClock; - _neutralValue = (T)_targetControl.GetValue(_animator.Property); + control.PropertyChanged += ControlPropertyChanged; + UpdateNeutralValue(); FetchProperties(); } @@ -216,5 +218,22 @@ namespace Avalonia.Animation } } } + + private void UpdateNeutralValue() + { + var property = _animator.Property; + var baseValue = _targetControl.GetBaseValue(property, BindingPriority.LocalValue); + + _neutralValue = baseValue != AvaloniaProperty.UnsetValue ? + (T)baseValue : (T)_targetControl.GetValue(property); + } + + private void ControlPropertyChanged(object sender, AvaloniaPropertyChangedEventArgs e) + { + if (e.Property == _animator.Property && e.Priority > BindingPriority.Animation) + { + UpdateNeutralValue(); + } + } } }