using System;
using System.Threading.Tasks;
using PlasticGui;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace Unity.PlasticSCM.Editor.UI.UIElements
{
internal class OverlayProgressControls : VisualElement, IProgressControls
{
internal OverlayProgressControls(params VisualElement[] actionControls)
{
mActionControls = actionControls;
InitializeLayoutAndStyles();
BuildComponents();
visible = false;
}
internal Task ShowProgress(string message, TimeSpan after)
{
lock (mLock)
{
mIsOperationRunning = true;
mCurrentOperation = new object();
}
return Task.Delay(after).ContinueWith((task, state) =>
{
EditorDispatcher.Dispatch(() =>
{
lock (mLock)
{
if (!mIsOperationRunning)
return;
if (state != mCurrentOperation)
return;
}
((IProgressControls)this).ShowProgress(message);
});
}, mCurrentOperation);
}
void EnableActionControls(bool enable)
{
foreach (var control in mActionControls)
if (control != null)
control.SetEnabled(enable);
}
void IProgressControls.ShowProgress(string message)
{
lock (mLock)
{
mIsOperationRunning = true;
mProgressBar.title = message;
if (visible)
return;
visible = true;
EnableActionControls(false);
mLastUpdateTime = EditorApplication.timeSinceStartup;
mTimer = schedule.Execute(UpdateProgress).Every(16);
}
}
void IProgressControls.HideProgress()
{
lock (mLock)
{
mIsOperationRunning = false;
if (!visible)
return;
visible = false;
EnableActionControls(true);
mTimer.Pause();
mTimer = null;
}
}
void IProgressControls.ShowNotification(string message)
{
throw new System.NotImplementedException();
}
void IProgressControls.ShowError(string message)
{
throw new System.NotImplementedException();
}
void IProgressControls.ShowWarning(string message)
{
throw new System.NotImplementedException();
}
void IProgressControls.ShowSuccess(string message)
{
throw new System.NotImplementedException();
}
void UpdateProgress()
{
double now = EditorApplication.timeSinceStartup;
double deltaTime = now - mLastUpdateTime;
mLastUpdateTime = now;
double deltaPercent = deltaTime * PERCENT_PER_SECONDS;
mProgressBar.value = Mathf.Repeat(mProgressBar.value + (float)deltaPercent, 1f);
}
void InitializeLayoutAndStyles()
{
style.position = Position.Absolute;
style.top = 0;
style.left = 0;
style.bottom = 0;
style.right = 0;
style.justifyContent = Justify.Center;
style.alignContent = Align.Center;
style.backgroundColor = UnityStyles.Colors.OverlayProgressBackgroundColor;
}
void BuildComponents()
{
mProgressBar = new ProgressBar();
mProgressBar.lowValue = 0;
mProgressBar.highValue = 1;
mProgressBar.style.alignSelf = Align.Center;
Label progressBarLabel = mProgressBar.Q<Label>();
progressBarLabel.style.marginLeft = 30;
progressBarLabel.style.marginRight = 30;
progressBarLabel.style.textOverflow = TextOverflow.Ellipsis;
progressBarLabel.style.overflow = Overflow.Hidden;
progressBarLabel.style.unityTextOverflowPosition = TextOverflowPosition.End;
Add(mProgressBar);
}
double mLastUpdateTime;
const double PERCENT_PER_SECONDS = 0.6;
object mLock = new object();
object mCurrentOperation = new object();
bool mIsOperationRunning;
IVisualElementScheduledItem mTimer;
ProgressBar mProgressBar;
readonly VisualElement[] mActionControls;
}
}