258 lines
7.1 KiB
C#
258 lines
7.1 KiB
C#
#nullable enable
|
|
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace UVC.UIToolkit
|
|
{
|
|
/// <summary>
|
|
/// 프로그레스 바 컴포넌트.
|
|
/// Unity ProgressBar를 래핑하여 커스텀 스타일을 적용합니다.
|
|
/// </summary>
|
|
/// <example>
|
|
/// <para><b>C# 코드에서 사용:</b></para>
|
|
/// <code>
|
|
/// // 기본 프로그레스 바
|
|
/// var progressBar = new UTKProgressBar();
|
|
/// progressBar.title = "다운로드 중...";
|
|
/// progressBar.MinValue = 0;
|
|
/// progressBar.MaxValue = 100;
|
|
/// progressBar.Value = 50;
|
|
///
|
|
/// // 값 표시 설정
|
|
/// progressBar.ShowValue = true;
|
|
/// progressBar.ShowPercentage = true;
|
|
///
|
|
/// // 무한 로딩 (불확정 상태)
|
|
/// progressBar.IsIndeterminate = true;
|
|
///
|
|
/// // 변형 스타일
|
|
/// progressBar.Variant = UTKProgressBar.ProgressBarVariant.Success;
|
|
/// </code>
|
|
/// <para><b>UXML에서 사용:</b></para>
|
|
/// <code>
|
|
/// <ui:UXML xmlns:utk="UVC.UIToolkit">
|
|
/// <!-- 기본 프로그레스 바 -->
|
|
/// <utk:UTKProgressBar title="진행률" low-value="0" high-value="100" value="30" />
|
|
///
|
|
/// <!-- 퍼센트 표시 -->
|
|
/// <utk:UTKProgressBar ShowPercentage="true" value="75" />
|
|
///
|
|
/// <!-- 성공 스타일 -->
|
|
/// <utk:UTKProgressBar Variant="Success" value="100" />
|
|
/// </ui:UXML>
|
|
/// </code>
|
|
/// </example>
|
|
[UxmlElement]
|
|
public partial class UTKProgressBar : ProgressBar, IDisposable
|
|
{
|
|
#region Constants
|
|
private const string USS_PATH = "UIToolkit/Slider/UTKProgressBar";
|
|
#endregion
|
|
|
|
#region Fields
|
|
private bool _disposed;
|
|
private bool _showValue = true;
|
|
private bool _showPercentage = true;
|
|
private bool _isIndeterminate;
|
|
private ProgressBarVariant _variant = ProgressBarVariant.Default;
|
|
#endregion
|
|
|
|
#region Properties
|
|
/// <summary>현재 값</summary>
|
|
public float Value
|
|
{
|
|
get => value;
|
|
set => SetValue(value);
|
|
}
|
|
|
|
/// <summary>최소값</summary>
|
|
public float MinValue
|
|
{
|
|
get => lowValue;
|
|
set
|
|
{
|
|
lowValue = value;
|
|
UpdateValueLabel();
|
|
}
|
|
}
|
|
|
|
/// <summary>최대값</summary>
|
|
public float MaxValue
|
|
{
|
|
get => highValue;
|
|
set
|
|
{
|
|
highValue = value;
|
|
UpdateValueLabel();
|
|
}
|
|
}
|
|
|
|
/// <summary>값 표시 여부</summary>
|
|
[UxmlAttribute("show-value")]
|
|
public bool ShowValue
|
|
{
|
|
get => _showValue;
|
|
set
|
|
{
|
|
_showValue = value;
|
|
UpdateValueLabel();
|
|
}
|
|
}
|
|
|
|
/// <summary>퍼센트로 표시 여부</summary>
|
|
[UxmlAttribute("show-percentage")]
|
|
public bool ShowPercentage
|
|
{
|
|
get => _showPercentage;
|
|
set
|
|
{
|
|
_showPercentage = value;
|
|
UpdateValueLabel();
|
|
}
|
|
}
|
|
|
|
/// <summary>불확정 상태 (애니메이션)</summary>
|
|
[UxmlAttribute("is-indeterminate")]
|
|
public bool IsIndeterminate
|
|
{
|
|
get => _isIndeterminate;
|
|
set
|
|
{
|
|
_isIndeterminate = value;
|
|
EnableInClassList("utk-progress--indeterminate", value);
|
|
UpdateValueLabel();
|
|
}
|
|
}
|
|
|
|
/// <summary>스타일 변형</summary>
|
|
[UxmlAttribute("variant")]
|
|
public ProgressBarVariant Variant
|
|
{
|
|
get => _variant;
|
|
set
|
|
{
|
|
_variant = value;
|
|
UpdateVariant();
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Enums
|
|
public enum ProgressBarVariant
|
|
{
|
|
Default,
|
|
Success,
|
|
Warning,
|
|
Error
|
|
}
|
|
#endregion
|
|
|
|
#region Constructor
|
|
public UTKProgressBar() : base()
|
|
{
|
|
UTKThemeManager.Instance.ApplyThemeToElement(this);
|
|
|
|
var uss = Resources.Load<StyleSheet>(USS_PATH);
|
|
if (uss != null)
|
|
{
|
|
styleSheets.Add(uss);
|
|
}
|
|
|
|
SetupStyles();
|
|
SubscribeToThemeChanges();
|
|
}
|
|
|
|
public UTKProgressBar(string text, float value = 0f, float maxValue = 100f) : this()
|
|
{
|
|
title = text;
|
|
highValue = maxValue;
|
|
SetValue(value);
|
|
}
|
|
#endregion
|
|
|
|
#region Setup
|
|
private void SetupStyles()
|
|
{
|
|
AddToClassList("utk-progress");
|
|
UpdateVariant();
|
|
UpdateValueLabel();
|
|
}
|
|
|
|
private void SubscribeToThemeChanges()
|
|
{
|
|
UTKThemeManager.Instance.OnThemeChanged += OnThemeChanged;
|
|
RegisterCallback<DetachFromPanelEvent>(_ =>
|
|
{
|
|
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged;
|
|
});
|
|
}
|
|
|
|
private void OnThemeChanged(UTKTheme theme)
|
|
{
|
|
UTKThemeManager.Instance.ApplyThemeToElement(this);
|
|
}
|
|
#endregion
|
|
|
|
#region Methods
|
|
/// <summary>
|
|
/// 값 설정
|
|
/// </summary>
|
|
public void SetValue(float newValue)
|
|
{
|
|
value = Mathf.Clamp(newValue, lowValue, highValue);
|
|
UpdateValueLabel();
|
|
}
|
|
|
|
private void UpdateValueLabel()
|
|
{
|
|
if (_isIndeterminate || !_showValue)
|
|
{
|
|
title = title?.Split(' ')[0] ?? "";
|
|
return;
|
|
}
|
|
|
|
string baseTitle = title?.Split(' ')[0] ?? "";
|
|
|
|
if (_showPercentage)
|
|
{
|
|
float range = highValue - lowValue;
|
|
float percent = range > 0 ? (value - lowValue) / range * 100 : 0;
|
|
title = string.IsNullOrEmpty(baseTitle) ? $"{percent:F0}%" : $"{baseTitle} {percent:F0}%";
|
|
}
|
|
else
|
|
{
|
|
title = string.IsNullOrEmpty(baseTitle) ? $"{value:F0}/{highValue:F0}" : $"{baseTitle} {value:F0}/{highValue:F0}";
|
|
}
|
|
}
|
|
|
|
private void UpdateVariant()
|
|
{
|
|
RemoveFromClassList("utk-progress--default");
|
|
RemoveFromClassList("utk-progress--success");
|
|
RemoveFromClassList("utk-progress--warning");
|
|
RemoveFromClassList("utk-progress--error");
|
|
|
|
var variantClass = _variant switch
|
|
{
|
|
ProgressBarVariant.Success => "utk-progress--success",
|
|
ProgressBarVariant.Warning => "utk-progress--warning",
|
|
ProgressBarVariant.Error => "utk-progress--error",
|
|
_ => "utk-progress--default"
|
|
};
|
|
AddToClassList(variantClass);
|
|
}
|
|
#endregion
|
|
|
|
#region IDisposable
|
|
public void Dispose()
|
|
{
|
|
if (_disposed) return;
|
|
_disposed = true;
|
|
|
|
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|