140 lines
4.5 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|