#nullable enable
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.UIToolkit.List;
namespace UVC.UIToolkit.Window
{
///
/// UTKImageList를 래핑하여 윈도우 형태로 제공하는 컴포넌트입니다.
/// LibraryWindow의 UIToolkit 버전입니다.
///
/// 개요:
///
/// UTKImageListWindow는 UTKImageList를 내부에 포함하고 헤더(타이틀, 닫기 버튼)를 추가한
/// 윈도우 형태의 컴포넌트입니다. 모든 리스트 관련 기능은 내부 UTKImageList에 위임됩니다.
///
///
/// 주요 기능:
///
/// 윈도우 형태의 UI 제공 (헤더 + 닫기 버튼)
/// 내부 UTKImageList의 모든 기능 위임
/// 드래그 앤 드롭 이벤트 전달
///
///
/// UXML에서 사용:
///
/// <uvc:UTKImageListWindow name="library-window" />
///
///
/// 코드에서 사용:
///
/// var window = root.Q<UTKImageListWindow>();
/// window.OnItemClick += (item) => Debug.Log($"클릭: {item.itemName}");
/// window.SetData(imageItems);
///
///
/// 관련 리소스:
///
/// Resources/UIToolkit/Window/UTKImageListWindow.uxml - 윈도우 레이아웃
/// Resources/UIToolkit/Window/UTKImageListWindow.uss - 윈도우 스타일
///
///
[UxmlElement]
public partial class UTKImageListWindow : VisualElement, IDisposable
{
#region 상수 (Constants)
/// 메인 UXML 파일 경로 (Resources 폴더 기준)
private const string UXML_PATH = "UIToolkit/Window/UTKImageListWindow";
#endregion
#region UI 컴포넌트 참조 (UI Component References)
/// 내부 UTKImageList 컴포넌트
private UTKImageList? _imageList;
/// 윈도우 닫기 버튼
private Button? _closeButton;
/// 윈도우 제목 라벨
private Label? _titleLabel;
#endregion
#region IDisposable
private bool _disposed;
#endregion
#region 공개 속성 (Public Properties)
///
/// 드래그 시 이미지가 커서를 따라다니도록 설정합니다.
/// 내부 UTKImageList에 위임됩니다.
///
public bool DragImageFollowCursor
{
get => _imageList?.DragImageFollowCursor ?? true;
set { if (_imageList != null) _imageList.DragImageFollowCursor = value; }
}
///
/// 드래그 영역 체크에 사용할 요소를 설정합니다.
/// 기본값은 윈도우 자체입니다.
///
public VisualElement? DragBoundsElement
{
get => _imageList?.DragBoundsElement;
set { if (_imageList != null) _imageList.DragBoundsElement = value; }
}
///
/// 윈도우 제목을 가져오거나 설정합니다.
///
public string Title
{
get => _titleLabel?.text ?? string.Empty;
set { if (_titleLabel != null) _titleLabel.text = value; }
}
///
/// 닫기 버튼 표시 여부를 설정합니다.
///
public bool ShowCloseButton
{
get => _closeButton?.style.display == DisplayStyle.Flex;
set { if (_closeButton != null) _closeButton.style.display = value ? DisplayStyle.Flex : DisplayStyle.None; }
}
///
/// 현재 표시 중인 아이템 수를 반환합니다.
///
public int ItemCount => _imageList?.ItemCount ?? 0;
#endregion
#region 이벤트 위임 (Event Delegation)
///
/// 아이템 클릭 이벤트입니다.
/// 내부 UTKImageList에서 발생한 이벤트를 전달합니다.
///
public Action? OnItemClick
{
get => _imageList?.OnItemClick;
set { if (_imageList != null) _imageList.OnItemClick = value; }
}
///
/// 아이템 드롭 이벤트입니다.
///
public Action? OnItemDrop
{
get => _imageList?.OnItemDrop;
set { if (_imageList != null) _imageList.OnItemDrop = value; }
}
///
/// 드래그 시작 이벤트입니다.
/// (아이템 데이터, 화면 좌표)
///
public Action? OnItemBeginDrag
{
get => _imageList?.OnItemBeginDrag;
set { if (_imageList != null) _imageList.OnItemBeginDrag = value; }
}
///
/// 드래그 중 이벤트입니다.
/// (아이템 데이터, 화면 좌표)
///
public Action? OnItemDrag
{
get => _imageList?.OnItemDrag;
set { if (_imageList != null) _imageList.OnItemDrag = value; }
}
///
/// 드래그 종료 이벤트입니다.
/// (아이템 데이터, 화면 좌표)
///
public Action? OnItemEndDrag
{
get => _imageList?.OnItemEndDrag;
set { if (_imageList != null) _imageList.OnItemEndDrag = value; }
}
///
/// 드래그 중 리스트 영역을 벗어났을 때 발생하는 이벤트입니다.
/// (아이템 데이터, 화면 좌표)
/// 3D 프리팹 미리보기를 표시하는데 사용합니다.
///
public Action? OnDragExitList
{
get => _imageList?.OnDragExitList;
set { if (_imageList != null) _imageList.OnDragExitList = value; }
}
///
/// 드래그 중 리스트 영역에 다시 진입했을 때 발생하는 이벤트입니다.
/// (아이템 데이터, 화면 좌표)
/// 3D 프리팹 미리보기를 숨기는데 사용합니다.
///
public Action? OnDragEnterList
{
get => _imageList?.OnDragEnterList;
set { if (_imageList != null) _imageList.OnDragEnterList = value; }
}
///
/// 윈도우가 닫힐 때(숨겨질 때) 발생합니다.
/// 닫기 버튼 클릭 또는 Close() 메서드 호출 시 트리거됩니다.
///
public event Action? OnClosed;
#endregion
#region 생성자 (Constructor)
///
/// UTKImageListWindow 컴포넌트를 초기화합니다.
/// UXML 템플릿을 로드하고 내부 UTKImageList를 설정합니다.
///
public UTKImageListWindow()
{
// 1. 메인 UXML 로드 및 복제
var visualTree = Resources.Load(UXML_PATH);
if (visualTree == null)
{
Debug.LogError($"[UTKImageListWindow] UXML not found at: {UXML_PATH}");
return;
}
visualTree.CloneTree(this);
// 2. 내부 UTKImageList 찾기 (UXML에서 생성된 컴포넌트)
_imageList = this.Q();
if (_imageList == null)
{
Debug.LogError("[UTKImageListWindow] UTKImageList not found in UXML");
}
else
{
// 드래그 영역 체크에 윈도우 전체 영역을 사용하도록 설정
_imageList.DragBoundsElement = this;
}
// 3. 헤더 요소 참조
_titleLabel = this.Q