naps2/NAPS2.Lib/EtoForms/EtoOperationProgress.cs
2024-03-30 13:00:25 -07:00

127 lines
3.7 KiB
C#

using Eto.Forms;
using NAPS2.EtoForms.Notifications;
using NAPS2.EtoForms.Ui;
namespace NAPS2.EtoForms;
public class EtoOperationProgress : OperationProgress
{
private readonly IFormFactory _formFactory;
private readonly INotify _notify;
private readonly Naps2Config _config;
private readonly HashSet<IOperation> _activeOperations = [];
public EtoOperationProgress(IFormFactory formFactory, INotify notify, Naps2Config config)
{
_formFactory = formFactory;
_notify = notify;
_config = config;
}
public override void Attach(IOperation op)
{
lock (this)
{
if (!_activeOperations.Contains(op))
{
_activeOperations.Add(op);
op.Finished += (sender, args) => _activeOperations.Remove(op);
if (op.IsFinished) _activeOperations.Remove(op);
}
}
}
public override void ShowProgress(IOperation op)
{
if (PlatformCompat.System.ShouldRememberBackgroundOperations &&
_config.Get(c => c.BackgroundOperations).Contains(op.GetType().Name))
{
ShowBackgroundProgress(op);
}
else
{
ShowModalProgress(op);
}
}
public override void ShowModalProgress(IOperation op)
{
Attach(op);
if (!op.IsFinished)
{
Invoker.Current.Invoke(() =>
{
var form = _formFactory.Create<ProgressForm>();
form.Operation = op;
form.ShowModal();
});
}
if (!op.IsFinished)
{
ShowBackgroundProgress(op);
}
}
public override void ShowBackgroundProgress(IOperation op)
{
Attach(op);
if (!op.IsFinished)
{
Invoker.Current.Invoke(() => _notify.OperationProgress(this, op));
}
}
public static void RenderStatus(IOperation op, Label textLabel, Label numberLabel, ProgressBar progressBar)
{
var status = op.Status ?? new OperationStatus();
textLabel.Text = status.StatusText;
progressBar.Indeterminate = status.MaxProgress == 1 || status.IndeterminateProgress;
// TODO: Continuous?
if (status.MaxProgress == 1 || status.ProgressType == OperationProgressType.None)
{
numberLabel.Text = "";
}
else if (status.MaxProgress == 0)
{
numberLabel.Text = "";
progressBar.MaxValue = 1;
progressBar.Value = 0;
}
else if (status.ProgressType == OperationProgressType.BarOnly)
{
numberLabel.Text = "";
progressBar.MaxValue = status.MaxProgress;
progressBar.Value = status.CurrentProgress;
}
else
{
numberLabel.Text = status.ProgressType == OperationProgressType.MB
? string.Format(MiscResources.SizeProgress, (status.CurrentProgress / 1000000.0).ToString("f1"),
(status.MaxProgress / 1000000.0).ToString("f1"))
: string.Format(MiscResources.ProgressFormat, status.CurrentProgress, status.MaxProgress);
progressBar.MaxValue = status.MaxProgress;
progressBar.Value = status.CurrentProgress;
}
// Force the progress bar to render immediately
if (progressBar.Value < progressBar.MaxValue)
{
progressBar.Value += 1;
progressBar.Value -= 1;
}
}
public override List<IOperation> ActiveOperations
{
get
{
lock (_activeOperations)
{
return _activeOperations.ToList();
}
}
}
}