#nullable enable
using System;
using UnityEngine;
using UnityEngine.UIElements;
namespace UVC.UIToolkit
{
///
/// 접을 수 있는 섹션 컴포넌트.
/// Unity Foldout을 래핑하여 커스텀 스타일을 적용합니다.
/// 헤더 클릭으로 내용을 펼치거나 접을 수 있습니다.
///
///
/// Foldout(폴드아웃)이란?
///
/// Foldout은 헤더를 클릭하여 내용을 펼치거나 접을 수 있는 컨테이너입니다.
/// 아코디언(Accordion)이라고도 불리며, 많은 내용을 정리할 때 유용합니다.
/// Unity Inspector에서 컴포넌트 섹션을 접는 것과 같은 동작입니다.
///
///
/// Foldout vs Panel 차이:
///
/// - Foldout - 간단한 접기/펼치기, 토글 화살표 표시
/// - Panel - 헤더/푸터/액션 등 풍부한 기능, 더 많은 커스터마이징
///
///
/// 주요 속성:
///
/// - text - 헤더에 표시되는 제목
/// - value / IsExpanded - 펼침 상태 (true=펼침, false=접힘)
///
///
/// 실제 활용 예시:
///
/// - 설정 페이지 - 고급 설정 숨기기
/// - FAQ - 질문 클릭 시 답변 표시
/// - 인스펙터 - 컴포넌트 섹션 접기
/// - 필터 패널 - 상세 필터 옵션 숨기기
///
///
///
/// C# 코드에서 사용:
///
/// // 기본 폴드아웃
/// var foldout = new UTKFoldout("고급 설정", expanded: false);
/// foldout.Add(new Label("옵션 1"));
/// foldout.Add(new Label("옵션 2"));
///
/// // 상태 변경 이벤트
/// foldout.OnValueChanged += (isExpanded) => {
/// Debug.Log(isExpanded ? "펼쳐짐" : "접힘");
/// };
///
/// // 프로그래밍 방식으로 상태 제어
/// foldout.IsExpanded = true;
///
/// UXML에서 사용:
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
[UxmlElement]
public partial class UTKFoldout : Foldout, IDisposable
{
#region Constants
private const string USS_PATH = "UIToolkit/Common/UTKFoldout";
#endregion
#region Fields
private bool _disposed;
#endregion
#region Events
/// 펼침/접힘 상태 변경 이벤트
public event Action? OnValueChanged;
#endregion
#region Properties
/// 펼침 상태
public bool IsExpanded
{
get => value;
set => this.value = value;
}
#endregion
#region Constructor
public UTKFoldout() : base()
{
UTKThemeManager.Instance.ApplyThemeToElement(this);
var uss = Resources.Load(USS_PATH);
if (uss != null)
{
styleSheets.Add(uss);
}
SetupStyles();
SetupEvents();
SubscribeToThemeChanges();
}
public UTKFoldout(string title, bool expanded = true) : this()
{
text = title;
value = expanded;
}
#endregion
#region Setup
private void SetupStyles()
{
AddToClassList("utk-foldout");
}
private void SetupEvents()
{
this.RegisterValueChangedCallback(OnFoldoutValueChanged);
}
private void SubscribeToThemeChanges()
{
UTKThemeManager.Instance.OnThemeChanged += OnThemeChanged;
RegisterCallback(_ =>
{
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged;
});
}
private void OnThemeChanged(UTKTheme theme)
{
UTKThemeManager.Instance.ApplyThemeToElement(this);
}
#endregion
#region Event Handlers
private void OnFoldoutValueChanged(ChangeEvent evt)
{
OnValueChanged?.Invoke(evt.newValue);
}
#endregion
#region IDisposable
public void Dispose()
{
if (_disposed) return;
_disposed = true;
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged;
OnValueChanged = null;
}
#endregion
}
}