192 lines
5.7 KiB
C#
192 lines
5.7 KiB
C#
#nullable enable
|
|
using System;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
|
|
namespace UVC.UI.List
|
|
{
|
|
/// <summary>
|
|
/// 개별 드래그 가능한 아이템의 UI 컴포넌트
|
|
/// 드래그 동작과 시각적 피드백을 담당
|
|
/// </summary>
|
|
public class DraggableListItem : MonoBehaviour
|
|
{
|
|
[Header("UI 컴포넌트")]
|
|
[SerializeField] protected CanvasGroup? canvasGroup;
|
|
[SerializeField] protected RectTransform? rectTransform;
|
|
[SerializeField] protected DraggableItem? dragAnchor;
|
|
[SerializeField] protected TMP_InputField? inputField;
|
|
|
|
[Header("드래그 설정")]
|
|
[SerializeField] protected float dragAlpha = 0.6f;
|
|
[SerializeField] protected bool blockRaycastsWhileDragging = false;
|
|
|
|
// 프로퍼티
|
|
public DraggableItemData? Data { get; private set; }
|
|
public RectTransform? RectTransform => rectTransform;
|
|
public bool IsDragging { get; private set; }
|
|
|
|
public event Action<DraggableListItem>? OnBeginDragEvent;
|
|
public event Action<DraggableListItem, Vector2>? OnDragEvent;
|
|
public event Action<DraggableListItem>? OnEndDragEvent;
|
|
|
|
private Vector2 originalPosition;
|
|
private Transform? originalParent;
|
|
private int originalSiblingIndex;
|
|
|
|
/// <summary>
|
|
/// 컴포넌트 초기화
|
|
/// </summary>
|
|
private void Awake()
|
|
{
|
|
// null 체크 및 자동 할당
|
|
if (rectTransform == null)
|
|
rectTransform = GetComponent<RectTransform>();
|
|
|
|
if (canvasGroup == null)
|
|
canvasGroup = GetComponent<CanvasGroup>();
|
|
|
|
// CanvasGroup이 없으면 추가
|
|
if (canvasGroup == null)
|
|
canvasGroup = gameObject.AddComponent<CanvasGroup>();
|
|
|
|
if (dragAnchor == null)
|
|
{
|
|
Debug.LogError("Drag Anchor is not assigned. Please assign it in the inspector.");
|
|
return;
|
|
}
|
|
|
|
dragAnchor.OnBeginDragEvent += OnBeginDrag;
|
|
dragAnchor.OnDragEvent += OnDrag;
|
|
dragAnchor.OnEndDragEvent += OnEndDrag;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 아이템 데이터로 UI 업데이트
|
|
/// </summary>
|
|
/// <param name="data">표시할 데이터</param>
|
|
public void SetData(DraggableItemData? data)
|
|
{
|
|
if (data == null) return;
|
|
|
|
Data = data;
|
|
UpdateUI();
|
|
}
|
|
|
|
/// <summary>
|
|
/// UI 요소들을 데이터에 맞게 업데이트
|
|
/// </summary>
|
|
protected virtual void UpdateUI()
|
|
{
|
|
if (Data == null) return;
|
|
if(inputField != null)
|
|
{
|
|
inputField.text = Data.Id;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 드래그 시작 시 호출
|
|
/// </summary>
|
|
public void OnBeginDrag(PointerEventData eventData)
|
|
{
|
|
if (rectTransform == null) return;
|
|
|
|
IsDragging = true;
|
|
|
|
// 원래 위치와 부모 저장
|
|
originalPosition = rectTransform.anchoredPosition;
|
|
originalParent = transform.parent;
|
|
originalSiblingIndex = transform.GetSiblingIndex();
|
|
|
|
// 시각적 피드백 적용
|
|
ApplyDragVisuals(true);
|
|
|
|
// 이벤트 발생
|
|
OnBeginDragEvent?.Invoke(this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 드래그 중 호출
|
|
/// </summary>
|
|
public void OnDrag(PointerEventData eventData)
|
|
{
|
|
if (rectTransform == null) return;
|
|
|
|
// 마우스 위치로 아이템 이동
|
|
rectTransform.anchoredPosition += new Vector2(0, eventData.delta.y);//eventData.delta
|
|
|
|
// 이벤트 발생
|
|
OnDragEvent?.Invoke(this, rectTransform.anchoredPosition);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 드래그 종료 시 호출
|
|
/// </summary>
|
|
public void OnEndDrag(PointerEventData eventData)
|
|
{
|
|
IsDragging = false;
|
|
|
|
// 시각적 피드백 복원
|
|
ApplyDragVisuals(false);
|
|
|
|
// 이벤트 발생
|
|
OnEndDragEvent?.Invoke(this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 드래그 시각적 효과 적용/해제
|
|
/// </summary>
|
|
/// <param name="isDragging">드래그 중인지 여부</param>
|
|
private void ApplyDragVisuals(bool isDragging)
|
|
{
|
|
if (canvasGroup == null) return;
|
|
|
|
if (isDragging)
|
|
{
|
|
canvasGroup.alpha = dragAlpha;
|
|
canvasGroup.blocksRaycasts = blockRaycastsWhileDragging;
|
|
}
|
|
else
|
|
{
|
|
canvasGroup.alpha = 1f;
|
|
canvasGroup.blocksRaycasts = true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 원래 위치로 되돌리기 (드래그 취소 시 사용)
|
|
/// </summary>
|
|
public void ResetToOriginalPosition()
|
|
{
|
|
if (rectTransform == null || originalParent == null) return;
|
|
|
|
transform.SetParent(originalParent);
|
|
transform.SetSiblingIndex(originalSiblingIndex);
|
|
rectTransform.anchoredPosition = originalPosition;
|
|
}
|
|
|
|
public void OnDestroy()
|
|
{
|
|
// 이벤트 구독 해제
|
|
if (dragAnchor != null)
|
|
{
|
|
dragAnchor.OnBeginDragEvent -= OnBeginDrag;
|
|
dragAnchor.OnDragEvent -= OnDrag;
|
|
dragAnchor.OnEndDragEvent -= OnEndDrag;
|
|
}
|
|
|
|
OnBeginDragEvent = null;
|
|
OnDragEvent = null;
|
|
OnEndDragEvent = null;
|
|
|
|
// 리소스 정리
|
|
canvasGroup = null;
|
|
rectTransform = null;
|
|
dragAnchor = null;
|
|
}
|
|
|
|
}
|
|
}
|