<commit_before>﻿using System;
using System.Threading;
using Avalonia.Animation;
using Avalonia.Threading;

namespace Avalonia.Controls;

/// <summary>
/// Displays <see cref="Content"/> according to a <see cref="FuncDataTemplate"/>.
/// Uses <see cref="PageTransition"/> to move between the old and new content values. 
/// </summary>
public class TransitioningContentControl : ContentControl
{
    private CancellationTokenSource? _lastTransitionCts;
    private object? _displayedContent;
    
    /// <summary>
    /// Defines the <see cref="PageTransition"/> property.
    /// </summary>
    public static readonly StyledProperty<IPageTransition?> PageTransitionProperty =
        AvaloniaProperty.Register<TransitioningContentControl, IPageTransition?>(nameof(PageTransition),
            new CrossFade(TimeSpan.FromSeconds(0.125)));


    /// <summary>
    /// Defines the <see cref="DisplayedContent"/> property.
    /// </summary>
    public static readonly DirectProperty<TransitioningContentControl, object?> DisplayedContentProperty =
        AvaloniaProperty.RegisterDirect<TransitioningContentControl, object?>(nameof(DisplayedContent),
            o => o.DisplayedContent);
    
    /// <summary>
    /// Gets or sets the animation played when content appears and disappears.
    /// </summary>
    public IPageTransition? PageTransition
    {
        get => GetValue(PageTransitionProperty);
        set => SetValue(PageTransitionProperty, value);
    }

    /// <summary>
    /// Gets or sets the content displayed whenever there is no page currently routed.
    /// </summary>
    public object? DisplayedContent
    {
        get => _displayedContent;
        private set => SetAndRaise(DisplayedContentProperty, ref _displayedContent, value);
    }

    protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
    {
        base.OnAttachedToVisualTree(e);

        Dispatcher.UIThread.Post(() => UpdateContentWithTransition(Content));
    }

    protected override void OnPropertyChanged<T>(AvaloniaPropertyChangedEventArgs<T> change)
    {
        base.OnPropertyChanged(change);

        if (change.Property == ContentProperty)
        {
            Dispatcher.UIThread.Post(() => UpdateContentWithTransition(Content));
        }
    }

    /// <summary>
    /// Updates the content with transitions.
    /// </summary>
    /// <param name="content">New content to set.</param>
    private async void UpdateContentWithTransition(object? content)
    {
        if (VisualRoot is null)
        {
            return;
        }
        
        _lastTransitionCts?.Cancel();
        _lastTransitionCts = new CancellationTokenSource();

        if (PageTransition != null)
            await PageTransition.Start(this, null, true, _lastTransitionCts.Token);

        DisplayedContent = content;
        
        if (PageTransition != null)
            await PageTransition.Start(null, this, true, _lastTransitionCts.Token);
    }
}
<commit_msg>fix warnings.<commit_after>﻿using System;
using System.Threading;
using Avalonia.Animation;
using Avalonia.Controls.Templates;
using Avalonia.Threading;

namespace Avalonia.Controls;

/// <summary>
/// Displays <see cref="ContentControl.Content"/> according to a <see cref="FuncDataTemplate"/>.
/// Uses <see cref="PageTransition"/> to move between the old and new content values. 
/// </summary>
public class TransitioningContentControl : ContentControl
{
    private CancellationTokenSource? _lastTransitionCts;
    private object? _displayedContent;

    /// <summary>
    /// Defines the <see cref="PageTransition"/> property.
    /// </summary>
    public static readonly StyledProperty<IPageTransition?> PageTransitionProperty =
        AvaloniaProperty.Register<TransitioningContentControl, IPageTransition?>(nameof(PageTransition),
            new CrossFade(TimeSpan.FromSeconds(0.125)));


    /// <summary>
    /// Defines the <see cref="DisplayedContent"/> property.
    /// </summary>
    public static readonly DirectProperty<TransitioningContentControl, object?> DisplayedContentProperty =
        AvaloniaProperty.RegisterDirect<TransitioningContentControl, object?>(nameof(DisplayedContent),
            o => o.DisplayedContent);

    /// <summary>
    /// Gets or sets the animation played when content appears and disappears.
    /// </summary>
    public IPageTransition? PageTransition
    {
        get => GetValue(PageTransitionProperty);
        set => SetValue(PageTransitionProperty, value);
    }

    /// <summary>
    /// Gets or sets the content displayed whenever there is no page currently routed.
    /// </summary>
    public object? DisplayedContent
    {
        get => _displayedContent;
        private set => SetAndRaise(DisplayedContentProperty, ref _displayedContent, value);
    }

    protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
    {
        base.OnAttachedToVisualTree(e);

        Dispatcher.UIThread.Post(() => UpdateContentWithTransition(Content));
    }

    protected override void OnPropertyChanged<T>(AvaloniaPropertyChangedEventArgs<T> change)
    {
        base.OnPropertyChanged(change);

        if (change.Property == ContentProperty)
        {
            Dispatcher.UIThread.Post(() => UpdateContentWithTransition(Content));
        }
    }

    /// <summary>
    /// Updates the content with transitions.
    /// </summary>
    /// <param name="content">New content to set.</param>
    private async void UpdateContentWithTransition(object? content)
    {
        if (VisualRoot is null)
        {
            return;
        }

        _lastTransitionCts?.Cancel();
        _lastTransitionCts = new CancellationTokenSource();

        if (PageTransition != null)
            await PageTransition.Start(this, null, true, _lastTransitionCts.Token);

        DisplayedContent = content;

        if (PageTransition != null)
            await PageTransition.Start(null, this, true, _lastTransitionCts.Token);
    }
}

{'fraction_non_alphanumeric': 0.10664218958611482, 'fraction_numerical': 0.0013351134846461949, 'mean_word_length': 3.038409703504043, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1883947', 'n_tokens_mistral': 1562, 'n_tokens_neox': 1525, 'n_words': 373}