Files
XRLib/Assets/Scripts/UVC/UIToolkit/Modal/Setting/UTKSettingDisplayInfoTabView.cs
2026-02-23 19:38:27 +09:00

194 lines
6.5 KiB
C#

#nullable enable
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
namespace UVC.UIToolkit
{
/// <summary>
/// 설정 표시 정보 탭 뷰.
/// UTKReordableList를 사용하여 표시 항목의 순서, 사용 유무, 내용을 관리합니다.
/// </summary>
[UxmlElement]
public partial class UTKSettingDisplayInfoTabView : VisualElement, IDisposable
{
#region Constants
private const string USS_PATH = "UIToolkit/Modal/Setting/UTKSettingDisplayInfoTabViewUss";
#endregion
#region Fields
private bool _disposed;
private UTKReordableList? _reordableList;
#endregion
#region Events
/// <summary>순서 변경 시 발생</summary>
public event Action? OnOrderChanged;
/// <summary>데이터(체크/텍스트) 변경 시 발생</summary>
public event Action? OnDataChanged;
#endregion
#region Constructor
public UTKSettingDisplayInfoTabView() : base()
{
// 1. 테마 적용
UTKThemeManager.Instance.ApplyThemeToElement(this);
// 2. USS 로드
var uss = Resources.Load<StyleSheet>(USS_PATH);
if (uss != null)
{
styleSheets.Add(uss);
}
// 3. UI 생성
CreateUI();
// 4. 테마 변경 구독
SubscribeToThemeChanges();
SampleSetAndGetWithDictionary();
}
#endregion
#region Setup
private void CreateUI()
{
AddToClassList("setting-display-tab-view");
_reordableList = new UTKReordableList();
_reordableList.style.flexGrow = 1;
_reordableList.OnOrderChanged += () => OnOrderChanged?.Invoke();
_reordableList.OnDataChanged += () => OnDataChanged?.Invoke();
Add(_reordableList);
// 하단 버튼 영역
var buttonContainer = new VisualElement();
buttonContainer.style.flexDirection = FlexDirection.Row;
buttonContainer.style.justifyContent = Justify.FlexEnd;
buttonContainer.style.paddingTop = 8;
var saveBtn = new UTKButton("저장", variant: UTKButton.ButtonVariant.Primary);
saveBtn.OnClicked += OnSaveButtonClicked;
buttonContainer.Add(saveBtn);
Add(buttonContainer);
}
private void OnSaveButtonClicked()
{
List<Dictionary<string, string>> result = ToDictionary();
foreach (var dict in result)
{
Debug.Log($"order={dict["order"]}, active={dict["active"]}, text={dict["text"]}");
}
}
private void SubscribeToThemeChanges()
{
UTKThemeManager.Instance.OnThemeChanged += OnThemeChanged;
RegisterCallback<AttachToPanelEvent>(OnAttachToPanelForTheme);
RegisterCallback<DetachFromPanelEvent>(OnDetachFromPanelForTheme);
}
private void OnAttachToPanelForTheme(AttachToPanelEvent evt)
{
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged;
UTKThemeManager.Instance.OnThemeChanged += OnThemeChanged;
UTKThemeManager.Instance.ApplyThemeToElement(this);
}
private void OnDetachFromPanelForTheme(DetachFromPanelEvent evt)
{
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged;
}
private void OnThemeChanged(UTKTheme theme)
{
UTKThemeManager.Instance.ApplyThemeToElement(this);
}
#endregion
#region Public API
/// <summary>
/// 데이터를 설정하고 리스트를 갱신합니다.
/// </summary>
/// <param name="items">표시할 아이템 데이터 목록.</param>
public void SetData(List<ReordableListItemData> items)
{
_reordableList?.SetData(items);
}
/// <summary>
/// List<Dictionary>로부터 데이터를 변환하여 설정합니다.
/// Dictionary 키: "order" (순서), "active" (사용 유무), "text" (표시 내용)
/// </summary>
/// <param name="listDict">변환할 Dictionary 목록.</param>
public void SetData(List<Dictionary<string, string>> listDict)
{
_reordableList?.SetData(listDict);
}
/// <summary>
/// Order 값이 동기화된 데이터 목록을 반환합니다.
/// </summary>
/// <returns>현재 리스트 순서가 반영된 데이터 목록.</returns>
public List<ReordableListItemData> GetData()
{
return _reordableList?.GetData() ?? new List<ReordableListItemData>();
}
/// <summary>
/// 전체 아이템을 List<Dictionary<string, string>>로 변환하여 반환합니다.
/// Dictionary 키: "order" (순서), "active" (사용 유무), "text" (표시 내용)
/// </summary>
/// <returns>각 아이템을 Dictionary로 변환한 목록.</returns>
public List<Dictionary<string, string>> ToDictionary()
{
return _reordableList?.ToDictionary() ?? new List<Dictionary<string, string>>();
}
#endregion
#region Sample
/// <summary>
/// Dictionary 기반 데이터 설정 및 조회 샘플.
/// </summary>
public void SampleSetAndGetWithDictionary()
{
// 1. Dictionary 데이터로 설정
var listDict = new List<Dictionary<string, string>>
{
new() { ["order"] = "0", ["active"] = "True", ["text"] = "온도" },
new() { ["order"] = "1", ["active"] = "False", ["text"] = "습도" },
new() { ["order"] = "2", ["active"] = "True", ["text"] = "압력" },
};
SetData(listDict);
}
#endregion
#region IDisposable
public void Dispose()
{
if (_disposed) return;
_disposed = true;
// 테마 구독 해제
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged;
UnregisterCallback<AttachToPanelEvent>(OnAttachToPanelForTheme);
UnregisterCallback<DetachFromPanelEvent>(OnDetachFromPanelForTheme);
// ReordableList 정리
_reordableList?.Dispose();
_reordableList = null;
// 이벤트 정리
OnOrderChanged = null;
OnDataChanged = null;
}
#endregion
}
}