Files
2025-07-14 12:03:59 +02:00

140 lines
4.5 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MaterialSkin.Controls
{
public partial class MaterialLoader : MaterialForm
{
private static MaterialLoader _instance;
private static Thread _loaderThread;
private static ManualResetEvent _instanceReadyEvent = new ManualResetEvent(false);
private readonly Dictionary<string, (MaterialProgressBar ProgressBar, Label Label)> _loadingProcesses;
private MaterialLoader()
{
InitializeComponent();
RemoveMessageFilter();
_loadingProcesses = new Dictionary<string, (MaterialProgressBar, Label)>();
this.MaximizeBox = false;
this.MinimizeBox = false;
this.StartPosition = FormStartPosition.CenterScreen;
}
public static MaterialLoader Instance
{
get
{
if (_instance == null || _instance.IsDisposed)
{
_instanceReadyEvent.Reset();
_loaderThread = new Thread(() =>
{
_instance = new MaterialLoader();
_instance.Shown += (_, _) =>
{
_instanceReadyEvent.Set();
};
Application.Run(_instance);
});
_loaderThread.SetApartmentState(ApartmentState.STA);
_loaderThread.Start();
_instanceReadyEvent.WaitOne();
}
return _instance;
}
}
public void StartLoading(string title)
{
if (_instance == null || !_instance.Visible)
{
Instance.Invoke(new Action(() =>
{
Instance.Show();
Instance.Visible= true;
}));
}
Instance.Invoke(new Action(() =>
{
if (_loadingProcesses.ContainsKey(title))
{
return; // Prevent duplicate loading processes with the same title
}
var progressBar = new MaterialProgressBar
{
Width = Instance.ClientSize.Width - 20,
Height = 20,
Top = 50 + (_loadingProcesses.Count * 30),
Left = 10,
Style = ProgressBarStyle.Marquee,
MarqueeAnimationSpeed = 30,
Value = 50,
BackColor = Color.White
};
var label = new Label
{
Text = title,
AutoSize = true,
Top = progressBar.Top - 20,
Left = progressBar.Left,
BackColor = Color.White
};
_loadingProcesses[title] = (progressBar, label);
Instance.Controls.Add(label);
Instance.Controls.Add(progressBar);
Instance.Height = 50 + (_loadingProcesses.Count * 30);
Instance.Refresh();
}));
}
public void FinishLoading(string title)
{
if (_instance == null)
{
return;
}
Instance.Invoke(new Action(() =>
{
if (_loadingProcesses.TryGetValue(title, out var components))
{
Instance.Controls.Remove(components.ProgressBar);
Instance.Controls.Remove(components.Label);
_loadingProcesses.Remove(title);
RearrangeProgressBarsAndLabels();
}
if (_loadingProcesses.Count == 0)
{
Instance.Visible= false;
}
}));
}
private void RearrangeProgressBarsAndLabels()
{
int index = 0;
foreach (var components in _loadingProcesses.Values)
{
components.ProgressBar.Top = 50 + (index * 30);
components.Label.Top = components.ProgressBar.Top - 20;
index++;
}
this.Height = 50 + (_loadingProcesses.Count * 30);
}
}
}