using InABox.Core; using System; using System.ComponentModel; using System.Linq; using System.Threading; using System.Windows.Media.Imaging; namespace InABox.WPF { public class ProgressSection { public ProgressSection(string message, Action action) { Message = message; Action = action; } public string Message { get; set; } public Action Action { get; set; } } public static class Progress { private static ProgressForm? form; public static BitmapImage? DisplayImage { get; set; } public static bool IsVisible => form != null; public static void ShowModal(params ProgressSection[] sections) { if (!sections.Any()) return; var progress = new ProgressForm { DisplayImage = DisplayImage }; progress.Activated += (_, args) => { progress.Dispatcher.Invoke(() => { foreach (var section in sections) { progress.Message = section.Message; section.Action(); } progress.Close(); }); }; progress.ShowActivated = true; progress.ShowDialog(); } /// /// Shows progress dialog modally, with a cancel button. /// /// /// /// /// Whether the progress was completed without cancelling. public static bool ShowModal(string message, string cancelButtonText, Action, CancellationToken> work) { var cancellationTokenSource = new CancellationTokenSource(); var progress = new ProgressForm(cancelButtonText) { DisplayImage = DisplayImage }; progress.Message = message; progress.Loaded += (_, args) => { var worker = new BackgroundWorker(); var update = new Progress(data => progress.Message = data); progress.OnCancelled += () => { cancellationTokenSource.Cancel(); progress.Close(); }; worker.DoWork += (o, e) => work(update, cancellationTokenSource.Token); worker.RunWorkerCompleted += (o, e) => progress.Close(); worker.RunWorkerAsync(); }; progress.ShowDialog(); return !cancellationTokenSource.IsCancellationRequested; } public static Result ShowModal(String message, Func, Result> work) { Result result = Result.Error("Incomplete"); var progress = new ProgressForm { DisplayImage = DisplayImage }; progress.Message = message; progress.Loaded += (_, args) => { var worker = new BackgroundWorker(); var update = new Progress(data => progress.Message = data); progress.OnCancelled += () => { worker.CancelAsync(); }; worker.DoWork += (o, e) => { try { result = work(update); } catch (Exception ex) { result = Result.Error(ex.Message); } }; worker.RunWorkerCompleted += (o, e) => progress.Close(); worker.RunWorkerAsync(); }; progress.ShowDialog(); return result; } public static void ShowModal(string message, Action> work) { Exception? exception = null; var progress = new ProgressForm { DisplayImage = DisplayImage }; progress.Message = message; progress.Loaded += (_, args) => { var worker = new BackgroundWorker(); var update = new Progress(data => progress.Message = data); progress.OnCancelled += () => { worker.CancelAsync(); }; worker.DoWork += (o, e) => { try { work(update); } catch (Exception ex) { exception = ex; } }; worker.RunWorkerCompleted += (o, e) => progress.Close(); worker.RunWorkerAsync(); }; progress.ShowDialog(); if(exception is not null) { throw exception; } } public static void Show(string message) { if (form == null) { form = new ProgressForm { DisplayImage = DisplayImage }; form.Show(); } form.UpdateWindow(message); } public static void SetMessage(string message) { form?.UpdateWindow(message); } public static void Close() { form?.CloseWindow(); form = null; } } }