using Avalonia; using Avalonia.Controls; using Avalonia.Media; using Avalonia.Threading; using DynamicData.Binding; using SPTInstaller.Models; using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; namespace SPTInstaller.CustomControls; public partial class ProgressableTaskList : UserControl { public ProgressableTaskList() { InitializeComponent(); this.AttachedToVisualTree += ProgressableTaskList_AttachedToVisualTree; } private int _taskProgress; public int TaskProgress { get => _taskProgress; set => SetAndRaise(ProgressableTaskList.TaskProgressProperty, ref _taskProgress, value); } public static readonly DirectProperty TaskProgressProperty = AvaloniaProperty.RegisterDirect(nameof(TaskProgress), o => o.TaskProgress); public ObservableCollection Tasks { get => GetValue(TasksProperty); set => SetValue(TasksProperty, value); } public static readonly StyledProperty> TasksProperty = AvaloniaProperty.Register>(nameof(Tasks)); public IBrush PendingColor { get => GetValue(PendingColorProperty); set => SetValue(PendingColorProperty, value); } public static readonly StyledProperty PendingColorProperty = AvaloniaProperty.Register(nameof(PendingColor)); public IBrush RunningColor { get => GetValue(RunningColorProperty); set => SetValue(RunningColorProperty, value); } public static readonly StyledProperty RunningColorProperty = AvaloniaProperty.Register(nameof(PendingColor)); public IBrush CompletedColor { get => GetValue(CompletedColorProperty); set => SetValue(CompletedColorProperty, value); } public static readonly StyledProperty CompletedColorProperty = AvaloniaProperty.Register(nameof(PendingColor)); private void UpdateTaskProgress() { Dispatcher.UIThread.InvokeAsync(async () => { var completedTasks = Tasks.Where(x => x.IsCompleted == true).Count(); var progress = (int)Math.Floor((double)completedTasks / (Tasks.Count - 1) * 100); for (; TaskProgress < progress;) { TaskProgress += 1; await Task.Delay(1); } }); } private void ProgressableTaskList_AttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e) { if (Tasks == null) return; foreach (var task in Tasks) { task.WhenPropertyChanged(x => x.IsCompleted) .Subscribe(x => UpdateTaskProgress()); } } }