#nullable enable
using System;
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UIElements;
namespace UVC.UIToolkit
{
///
/// 아이콘 토글 버튼 컴포넌트.
/// IsOn 상태에 따라 OnIcon/OffIcon 이미지가 전환됩니다.
/// Material Icons(1순위)와 Image Icons(2순위)를 자동 감지하여 적용합니다.
///
///
/// C# 코드에서 사용:
///
/// // Material Icon 사용 (자동 감지)
/// var btn = new UTKImageToggleButton();
/// btn.OnIcon = UTKMaterialIcons.Visibility;
/// btn.OffIcon = UTKMaterialIcons.VisibilityOff;
/// btn.OnValueChanged += (isOn) => Debug.Log($"상태: {isOn}");
///
/// // Image Icon 사용 (자동 감지)
/// var btn2 = new UTKImageToggleButton(UTKImageIcons.IconEye, UTKImageIcons.IconSetting22);
///
/// // IsEnabled vs IsInteractive
/// btn.IsEnabled = false; // 시각적 비활성화 + 모든 변경 불가
/// btn.IsInteractive = false; // 사용자 입력만 차단, 시각적 활성화 유지
///
/// // 프로그래밍 방식으로 상태 변경 (notify 여부 선택)
/// btn.SetOn(true, notify: false);
///
/// UXML에서 사용:
///
///
///
///
///
///
///
///
///
///
///
///
///
[UxmlElement]
public partial class UTKImageToggleButton : VisualElement, IDisposable
{
#region Constants
private const string UXML_PATH = "UIToolkit/Button/UTKImageToggleButton";
private const string USS_PATH = "UIToolkit/Button/UTKImageToggleButtonUss";
private const int DEFAULT_ICON_SIZE = 24;
#endregion
#region Fields
private bool _disposed;
private bool _isOn;
private bool _isEnabled = true;
private bool _isInteractive = true;
private string _onIcon = "";
private string _offIcon = "";
private int _iconSize = DEFAULT_ICON_SIZE;
private Vector2Int _size = Vector2Int.zero; // zero = 미설정 (USS 기본값 사용)
// 아이콘 표시용 요소 (캐싱)
private Label? _materialIconLabel;
private VisualElement? _imageIconElement;
// 현재 표시 중인 아이콘 타입
private enum IconDisplayType { None, Material, Image }
private IconDisplayType _currentDisplayType = IconDisplayType.None;
#endregion
#region Events
/// 상태 변경 이벤트
public event Action? OnValueChanged;
#endregion
#region Properties
///
/// On 상태일 때 표시할 아이콘.
/// Material Icon 이름(예: "visibility") 또는 Image Icon 경로(예: UTKImageIcons.IconEye)를 지정합니다.
/// Material Icons를 1순위로 자동 감지합니다.
///
[UxmlAttribute("on-icon")]
public string OnIcon
{
get => _onIcon;
set
{
_onIcon = value;
UpdateIconDisplay();
}
}
///
/// Off 상태일 때 표시할 아이콘.
/// Material Icon 이름(예: "visibility_off") 또는 Image Icon 경로를 지정합니다.
///
[UxmlAttribute("off-icon")]
public string OffIcon
{
get => _offIcon;
set
{
_offIcon = value;
UpdateIconDisplay();
}
}
///
/// 버튼 크기 (픽셀). Vector2Int.zero이면 USS 기본값(var(--size-icon-btn))을 사용합니다.
///
[UxmlAttribute("size")]
public Vector2Int Size
{
get => _size;
set
{
_size = value;
if (_size == Vector2Int.zero)
{
style.width = StyleKeyword.Null;
style.height = StyleKeyword.Null;
}
else
{
style.width = _size.x;
style.height = _size.y;
}
}
}
/// 아이콘 크기 (픽셀)
[UxmlAttribute("icon-size")]
public int IconSize
{
get => _iconSize;
set
{
_iconSize = value;
ApplyIconSize();
}
}
/// 토글 상태
[UxmlAttribute("is-on")]
public bool IsOn
{
get => _isOn;
set => SetOn(value, notify: true);
}
/// 활성화 상태. false이면 시각적 비활성화 + 모든 변경 불가.
[UxmlAttribute("is-enabled")]
public bool IsEnabled
{
get => _isEnabled;
set
{
_isEnabled = value;
SetEnabled(value);
EnableInClassList("utk-image-toggle-btn--disabled", !value);
}
}
///
/// 상호작용 가능 여부. false이면 마우스/키보드 입력을 무시하지만
/// 프로그래밍 방식으로는 값 변경 가능. 시각적으로는 활성화 상태 유지.
///
[UxmlAttribute("is-interactive")]
public bool IsInteractive
{
get => _isInteractive;
set
{
_isInteractive = value;
focusable = value;
EnableInClassList("utk-image-toggle-btn--non-interactive", !value);
}
}
#endregion
#region Constructor
public UTKImageToggleButton()
{
UTKThemeManager.Instance.ApplyThemeToElement(this);
var uss = Resources.Load(USS_PATH);
if (uss != null)
{
styleSheets.Add(uss);
}
CreateUI();
SetupEvents();
SubscribeToThemeChanges();
}
///
/// OnIcon/OffIcon을 지정하여 생성합니다.
/// Material Icon 이름 또는 Image Icon 경로를 사용할 수 있습니다.
///
/// On 상태 아이콘
/// Off 상태 아이콘
/// 아이콘 크기 (픽셀)
public UTKImageToggleButton(string onIcon, string offIcon, int iconSize = DEFAULT_ICON_SIZE) : this()
{
_onIcon = onIcon;
_offIcon = offIcon;
_iconSize = iconSize;
UpdateIconDisplay();
}
#endregion
#region Setup
private void CreateUI()
{
AddToClassList("utk-image-toggle-btn");
focusable = true;
pickingMode = PickingMode.Position;
var asset = Resources.Load(UXML_PATH);
if (asset != null)
{
var root = asset.Instantiate();
_materialIconLabel = root.Q