Skip to content

Commit

Permalink
fix(backgroundtransition): animations should ignore background transi…
Browse files Browse the repository at this point in the history
…tions
  • Loading branch information
ramezgerges committed Aug 7, 2024
1 parent 57ec013 commit 01b2ca1
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
#nullable enable

using System;
using Windows.UI;

namespace Microsoft.UI.Composition;

internal sealed class ColorBrushTransitionState
internal readonly record struct ColorBrushTransitionState(
BorderVisual Visual,
Color FromColor,
Color ToColor,
long StartTimestamp,
long EndTimestamp,
bool IsActive)
{
internal ColorBrushTransitionState(BorderVisual visual, Color fromColor, Color toColor, long startTimestamp, long endTimestamp)
{
Visual = visual;
FromColor = fromColor;
ToColor = toColor;
StartTimestamp = startTimestamp;
EndTimestamp = endTimestamp;
}

internal BorderVisual Visual { get; }
internal Color FromColor { get; }
internal Color ToColor { get; }
internal long StartTimestamp { get; }
internal long EndTimestamp { get; }

internal Color CurrentColor
{
get
Expand Down
35 changes: 30 additions & 5 deletions src/Uno.UI.Composition/Composition/Compositor.skia.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,42 @@ internal void UnregisterAnimation(CompositionAnimation animation)
}
}

internal void DisableBackgroundTransition(BorderVisual visual)
{
for (int i = 0; i < _backgroundTransitions.Count; i++)
{
if (_backgroundTransitions[i].Visual == visual)
{
_backgroundTransitions[i] = _backgroundTransitions[i] with { IsActive = false };
break;
}
}
}

internal void RegisterBackgroundTransition(BorderVisual visual, Color fromColor, Color toColor, TimeSpan duration)
{
var start = TimestampInTicks;
var end = start + duration.Ticks;

for (int i = 0; i < _backgroundTransitions.Count; i++)
{
if (_backgroundTransitions[i].Visual == visual)
var transition = _backgroundTransitions[i];
if (transition.Visual == visual)
{
if (!transition.IsActive)
{
_backgroundTransitions[i] = transition with { IsActive = true };
return;
}
// when the background changes when already in a transition, the new transition
// picks up from where the preexisting transition stopped.
fromColor = _backgroundTransitions[i].CurrentColor;
fromColor = transition.CurrentColor;
_backgroundTransitions.RemoveAt(i);
break;
}
}

_backgroundTransitions.Add(new ColorBrushTransitionState(visual, fromColor, toColor, start, end));
_backgroundTransitions.Add(new ColorBrushTransitionState(visual, fromColor, toColor, start, end, true));
}

internal bool TryGetEffectiveBackgroundColor(CompositionSpriteShape shape, out Color color)
Expand All @@ -58,8 +76,15 @@ internal bool TryGetEffectiveBackgroundColor(CompositionSpriteShape shape, out C
{
if (transition.Visual.BackgroundShape == shape)
{
color = transition.CurrentColor;
return true;
if (transition.IsActive)
{
color = transition.CurrentColor;
return true;
}
else
{
break;
}
}
}

Expand Down
14 changes: 12 additions & 2 deletions src/Uno.UI/UI/Xaml/BorderHelper.skia.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,23 @@ public static void UpdateAllBorderProperties(this IBorderInfoProvider @this)
@this.UpdateBorderThickness();
}

public static void SetUpBrushTransitionIfAllowed(BorderVisual visual, Brush fromBrush, Brush toBrush, BrushTransition transition)
public static void SetUpBrushTransitionIfAllowed(BorderVisual visual, Brush fromBrush, Brush toBrush, BrushTransition transition, bool isAnimation)
{
if (transition is null)
{
return;
}

if (isAnimation)
{
// When an animation sets the background, it skips the transition logic and is applied immediately.
// However, it "deactivates" the currently active transition if one exists. Once the animation is done,
// the deactivated transition is reactivated and continues as if it was running (i.e. it's not paused,
// but takes into account the duration during which it was deactivated).
visual.Compositor.DeactivateBackgroundTransition(visual);
return;
}

var oldBrush = fromBrush as SolidColorBrush;
var newBrush = toBrush as SolidColorBrush;

Expand All @@ -69,7 +79,7 @@ newBrush is not null
// SolidColorBrush animations work only on static brushes. Neither brush can be animating.
//&& oldBrushIsNullOrStatic
//&& !newBrush->IsEffectiveValueInSparseStorage(KnownPropertyIndex::SolidColorBrush_ColorAnimation)
)
)
{
visual.Compositor.RegisterBackgroundTransition(visual, oldBrush?.Color ?? Colors.Transparent, newBrush.Color, transition.Duration);
}
Expand Down
7 changes: 6 additions & 1 deletion src/Uno.UI/UI/Xaml/Controls/Border/Border.cs
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,12 @@ protected override void OnBackgroundChanged(DependencyPropertyChangedEventArgs e
{
#if UNO_HAS_BORDER_VISUAL
this.UpdateBackground();
BorderHelper.SetUpBrushTransitionIfAllowed((BorderVisual)this.Visual, e.OldValue as Brush, e.NewValue as Brush, this.BackgroundTransition);
BorderHelper.SetUpBrushTransitionIfAllowed(
(BorderVisual)this.Visual,
e.OldValue as Brush,
e.NewValue as Brush,
this.BackgroundTransition,
(this as IDependencyObjectStoreProvider).Store.GetPropertyDetails(BackgroundProperty).CurrentHighestValuePrecedence == DependencyPropertyValuePrecedences.Animations);
#else
UpdateBorder();
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1219,7 +1219,12 @@ protected override void OnBackgroundChanged(DependencyPropertyChangedEventArgs e
{
#if UNO_HAS_BORDER_VISUAL
this.UpdateBackground();
BorderHelper.SetUpBrushTransitionIfAllowed((BorderVisual)this.Visual, e.OldValue as Brush, e.NewValue as Brush, this.BackgroundTransition);
BorderHelper.SetUpBrushTransitionIfAllowed(
(BorderVisual)this.Visual,
e.OldValue as Brush,
e.NewValue as Brush,
this.BackgroundTransition,
(this as IDependencyObjectStoreProvider).Store.GetPropertyDetails(BackgroundProperty).CurrentHighestValuePrecedence == DependencyPropertyValuePrecedences.Animations);
#else
UpdateBorder();
#endif
Expand Down
7 changes: 6 additions & 1 deletion src/Uno.UI/UI/Xaml/Controls/Panel/Panel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,12 @@ protected override void OnBackgroundChanged(DependencyPropertyChangedEventArgs e
{
#if UNO_HAS_BORDER_VISUAL
this.UpdateBackground();
BorderHelper.SetUpBrushTransitionIfAllowed((BorderVisual)this.Visual, e.OldValue as Brush, e.NewValue as Brush, this.BackgroundTransition);
BorderHelper.SetUpBrushTransitionIfAllowed(
(BorderVisual)this.Visual,
e.OldValue as Brush,
e.NewValue as Brush,
this.BackgroundTransition,
(this as IDependencyObjectStoreProvider).Store.GetPropertyDetails(BackgroundProperty).CurrentHighestValuePrecedence == DependencyPropertyValuePrecedences.Animations);
#else
UpdateBorder();
#endif
Expand Down

0 comments on commit 01b2ca1

Please sign in to comment.