#nullable enable
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
namespace UVC.UIToolkit
{
///
/// 설정 표시 정보 아이템 데이터.
///
public class ReordableListItemData
{
/// 표시 순서 (ListView 인덱스 기준)
public int Order { get; set; }
/// 사용 유무
public bool IsActive { get; set; }
/// 표시 내용
public string DisplayText { get; set; } = "";
}
///
/// 설정 표시 정보 탭 뷰.
/// UTKListView를 활용하여 마우스 드래그로 항목 순서를 변경할 수 있는 설정 목록 뷰입니다.
/// 각 항목은 드래그 핸들, 체크박스(사용 유무), 입력 필드(내용 수정)로 구성됩니다.
///
[UxmlElement]
public partial class UTKReordableList : VisualElement, IDisposable
{
#region Constants
private const string USS_PATH = "UIToolkit/List/UTKReordableListUss";
private const string ITEM_UXML_PATH = "UIToolkit/List/UTKReordableListItem";
private const string ITEM_USS_PATH = "UIToolkit/List/UTKReordableListItemUss";
private const float ITEM_HEIGHT = 36f;
#endregion
#region Fields
private bool _disposed;
private UTKListView? _listView;
private List _items = new();
private VisualTreeAsset? _itemTemplate;
private StyleSheet? _itemStyleSheet;
#endregion
#region Events
/// 순서 변경 시 발생
public event Action? OnOrderChanged;
/// 데이터(체크/텍스트) 변경 시 발생
public event Action? OnDataChanged;
#endregion
#region Constructor
public UTKReordableList() : base()
{
// 1. 테마 적용
UTKThemeManager.Instance.ApplyThemeToElement(this);
// 2. USS 로드
var uss = Resources.Load(USS_PATH);
if (uss != null)
{
styleSheets.Add(uss);
}
// 3. UI 생성
CreateUI();
// 4. 테마 변경 구독
SubscribeToThemeChanges();
}
#endregion
#region Setup
private void CreateUI()
{
AddToClassList("reordable-list");
SetupListView();
}
private void SetupListView()
{
_listView = new UTKListView();
_listView.makeItem = MakeItem;
_listView.bindItem = BindItem;
_listView.unbindItem = UnbindItem;
_listView.fixedItemHeight = ITEM_HEIGHT;
_listView.selectionType = SelectionType.Single;
_listView.reorderable = true;
_listView.reorderMode = ListViewReorderMode.Animated;
_listView.itemIndexChanged += OnItemIndexChanged;
Add(_listView);
}
private void SubscribeToThemeChanges()
{
UTKThemeManager.Instance.OnThemeChanged += OnThemeChanged;
RegisterCallback(OnAttachToPanelForTheme);
RegisterCallback(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 ListView Callbacks
private VisualElement MakeItem()
{
// UXML 캐싱
_itemTemplate ??= Resources.Load(ITEM_UXML_PATH);
// USS 캐싱 (코드에서 로드 - UXML에서 지정하지 않음)
_itemStyleSheet ??= Resources.Load(ITEM_USS_PATH);
if (_itemTemplate != null)
{
var root = _itemTemplate.Instantiate();
// USS 적용 (코드에서 적용)
if (_itemStyleSheet != null)
root.styleSheets.Add(_itemStyleSheet);
// 드래그 핸들 아이콘 설정
var handle = root.Q