#nullable enable
using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace UVC.UI.List.Draggable
{
///
/// 리스트 아이템의 드래그와 비주얼을 관리하는 컴포넌트입니다.
/// DragBehavior와 함께 사용되어 드래그 시 시각적 효과를 처리합니다.
///
/// 필수 설정:
/// 1. 이 컴포넌트가 있는 GameObject에 또는 자식에 DragBehavior를 함께 추가해야 합니다.
/// 2. CanvasGroup이 없으면 자동으로 추가됩니다.
///
/// Inspector 설정:
/// - Drag Alpha: 드래그 중 투명도 (0~1, 기본값 0.6)
///
/// 사용 예시:
/// GameObject listItem = Instantiate(itemPrefab);
/// listItem.AddComponent();
/// listItem.AddComponent();
///
public class ListItemController : MonoBehaviour
{
// 컴포넌트 참조들
private CanvasGroup? canvasGroup;
private ListReorderHandler? reorderHandler;
private GameObject? placeholder;
[Header("DragBehavior 설정")]
[SerializeField]
private DragBehavior? dragBehavior;
[Header("비주얼 설정")]
[SerializeField, Range(0f, 1f)]
[Tooltip("드래그 중일 때의 투명도 값입니다. 0은 완전 투명, 1은 완전 불투명")]
private float dragAlpha = 0.6f;
///
/// 현재 생성된 플레이스홀더를 가져옵니다
///
public GameObject? Placeholder => placeholder;
///
/// 원래 순서(인덱스)를 가져옵니다
///
public int OriginalIndex => dragBehavior?.OriginalIndex ?? -1;
///
/// 컴포넌트 초기화 - Unity가 자동으로 호출
///
void Awake()
{
// 필수 컴포넌트들을 가져옵니다
if(dragBehavior == null)
dragBehavior = GetComponentInChildren();
// CanvasGroup이 없으면 추가합니다 (알파값 조절을 위해 필요)
canvasGroup = GetComponent();
if (canvasGroup == null)
{
canvasGroup = gameObject.AddComponent();
Debug.Log($"[ListItemController] CanvasGroup을 자동으로 추가했습니다 - {gameObject.name}");
}
// 드래그 이벤트에 핸들러 메서드들을 연결합니다
if (dragBehavior != null)
{
dragBehavior.OnDragStarted += HandleDragStart;
dragBehavior.OnDragging += HandleDragging;
dragBehavior.OnDragEnded += HandleDragEnd;
}
else
{
Debug.LogError($"[ListItemController] DragBehavior를 찾을 수 없습니다! - {gameObject.name}");
}
}
///
/// Start는 Awake 이후에 호출되며, 다른 오브젝트의 컴포넌트를 찾을 때 사용
///
void Start()
{
// 부모에서 ListReorderHandler를 찾습니다
reorderHandler = GetComponentInParent();
if (reorderHandler == null)
{
Debug.LogWarning($"[ListItemController] ListReorderHandler를 찾을 수 없습니다. 재정렬 기능이 작동하지 않을 수 있습니다. - {gameObject.name}");
}
}
///
/// 드래그가 시작될 때 호출되는 핸들러
///
private void HandleDragStart(PointerEventData eventData)
{
Debug.Log($"[ListItemController] 드래그 시작 처리 - {gameObject.name}");
// 1. 플레이스홀더(빈 공간 표시)를 생성합니다
CreatePlaceholder();
// 2. 드래그 중인 아이템을 반투명하게 만듭니다
if (canvasGroup != null)
{
canvasGroup.alpha = dragAlpha;
canvasGroup.blocksRaycasts = false; // 드래그 중에는 클릭을 받지 않습니다
}
// 3. 아이템을 최상위 Canvas로 이동시켜 다른 UI 위에 표시되도록 합니다
Canvas? rootCanvas = GetComponentInParent