From cf8b072c5cb00fd9fc6d40a5cb23b1b4f0792cac Mon Sep 17 00:00:00 2001 From: Alshain <4256578+Alshain01@users.noreply.github.com> Date: Mon, 30 Oct 2023 19:37:17 -0500 Subject: [PATCH] Allow TransitioningContentControl to be reversed. (#13003) * Allow TransitioningContentControl to be reversed. (#12442) * Fix incorrect property name. * Add missing pseudoclass attribute. * Remove reversed transition pseudo class as discussed in review. * Update samples/ControlCatalog/ViewModels/TransitioningContentControlPageViewModel.cs Co-authored-by: Max Katz --------- Co-authored-by: Max Katz --- .../TransitioningContentControlPage.axaml | 3 +- ...ransitioningContentControlPageViewModel.cs | 12 +++++++ .../TransitioningContentControl.cs | 20 +++++++++++- .../TransitioningContentControlTests.cs | 31 +++++++++++++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/samples/ControlCatalog/Pages/TransitioningContentControlPage.axaml b/samples/ControlCatalog/Pages/TransitioningContentControlPage.axaml index 88f2aa68fc..541385dd9f 100644 --- a/samples/ControlCatalog/Pages/TransitioningContentControlPage.axaml +++ b/samples/ControlCatalog/Pages/TransitioningContentControlPage.axaml @@ -69,7 +69,8 @@ + PageTransition="{Binding SelectedTransition.Transition}" + IsTransitionReversed="{Binding Reversed}"> diff --git a/samples/ControlCatalog/ViewModels/TransitioningContentControlPageViewModel.cs b/samples/ControlCatalog/ViewModels/TransitioningContentControlPageViewModel.cs index 03ffb44b4a..00d1da46e9 100644 --- a/samples/ControlCatalog/ViewModels/TransitioningContentControlPageViewModel.cs +++ b/samples/ControlCatalog/ViewModels/TransitioningContentControlPageViewModel.cs @@ -46,6 +46,7 @@ namespace ControlCatalog.ViewModels private Bitmap _SelectedImage; + private bool _Reversed; /// /// Gets or Sets the selected image @@ -97,6 +98,15 @@ namespace ControlCatalog.ViewModels } } + /// + /// Gets or sets a value indicating whether the animation is reversed. + /// + public bool Reversed + { + get => _Reversed; + set => this.RaiseAndSetIfChanged(ref _Reversed, value); + } + private void SetupTransitions() { if (PageTransitions.Count == 0) @@ -127,6 +137,7 @@ namespace ControlCatalog.ViewModels public void NextImage() { + Reversed = false; var index = Images.IndexOf(SelectedImage) + 1; if (index >= Images.Count) @@ -139,6 +150,7 @@ namespace ControlCatalog.ViewModels public void PrevImage() { + Reversed = true; var index = Images.IndexOf(SelectedImage) - 1; if (index < 0) diff --git a/src/Avalonia.Controls/TransitioningContentControl.cs b/src/Avalonia.Controls/TransitioningContentControl.cs index 951cd209f0..619f7bd2f0 100644 --- a/src/Avalonia.Controls/TransitioningContentControl.cs +++ b/src/Avalonia.Controls/TransitioningContentControl.cs @@ -28,6 +28,14 @@ public class TransitioningContentControl : ContentControl nameof(PageTransition), defaultValue: new ImmutableCrossFade(TimeSpan.FromMilliseconds(125))); + /// + /// Defines the property. + /// + public static readonly StyledProperty IsTransitionReversedProperty = + AvaloniaProperty.Register( + nameof(IsTransitionReversed), + defaultValue: false); + /// /// Gets or sets the animation played when content appears and disappears. /// @@ -37,6 +45,16 @@ public class TransitioningContentControl : ContentControl set => SetValue(PageTransitionProperty, value); } + /// + /// Gets or sets a value indicating whether the control will be animated in the reverse direction. + /// + /// May not apply to all transitions. + public bool IsTransitionReversed + { + get => GetValue(IsTransitionReversedProperty); + set => SetValue(IsTransitionReversedProperty, value); + } + protected override Size ArrangeOverride(Size finalSize) { var result = base.ArrangeOverride(finalSize); @@ -57,7 +75,7 @@ public class TransitioningContentControl : ContentControl var from = _isFirstFull ? _presenter2 : presenter; var to = _isFirstFull ? presenter : _presenter2; - transition.Start(from, to, true, cancel.Token).ContinueWith(x => + transition.Start(from, to, !IsTransitionReversed, cancel.Token).ContinueWith(x => { if (!cancel.IsCancellationRequested) { diff --git a/tests/Avalonia.Controls.UnitTests/TransitioningContentControlTests.cs b/tests/Avalonia.Controls.UnitTests/TransitioningContentControlTests.cs index 5ca9b54731..1bcc805f82 100644 --- a/tests/Avalonia.Controls.UnitTests/TransitioningContentControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TransitioningContentControlTests.cs @@ -183,6 +183,37 @@ namespace Avalonia.Controls.UnitTests Assert.Equal("bar", presenter2.Content); } + [Theory] + [InlineData(false)] + [InlineData(true)] + public void Transition_Should_Be_Reversed_If_Property_Is_Set(bool reversed) + { + using var app = Start(); + using var sync = UnitTestSynchronizationContext.Begin(); + var (target, transition) = CreateTarget("foo"); + var presenter2 = GetContentPresenters2(target); + + target.IsTransitionReversed = reversed; + + target.Content = "bar"; + + var startedRaised = 0; + + transition.Started += (from, to, forward) => + { + Assert.Equal(reversed, !forward); + + ++startedRaised; + }; + + Layout(target); + sync.ExecutePostedCallbacks(); + + Assert.Equal(1, startedRaised); + Assert.Equal("foo", target.Presenter!.Content); + Assert.Equal("bar", presenter2.Content); + } + [Fact] public void Logical_Children_Should_Not_Be_Duplicated() {