#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using Unity.VisualScripting;
using UnityEditorInternal.VersionControl;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace UVC.UI.List
{
///
/// 드래그 가능한 ScrollRect 목록을 관리하는 메인 컨트롤러
/// Model-View 패턴을 적용하여 데이터와 UI를 분리
///
///
/// 사용 예제:
/// 1. 이벤트 구독
/// 2. DraggableItemData 설정
///
/// public class DraggableScrollListSetup : MonoBehaviour
/// {
/// [SerializeField]
/// private DraggableScrollList? draggableList;
///
/// protected virtual void Awake()
/// {
/// if (draggableList == null)
/// {
/// Debug.LogError("draggableList 참조가 설정되지 않았습니다.");
/// return;
/// }
///
/// // 이벤트 구독
/// draggableList.OnItemReordered += OnItemReordered;
/// draggableList.OnItemSelected += OnItemSelected;
/// }
///
/// void Start()
/// {
/// // 1. DraggableItemData 설정
/// draggableList?.AddItem(new DraggableItemData("AGV", 0));
/// draggableList?.AddItem(new DraggableItemData("ALARM", 1));
/// }
///
/// ///
/// /// 아이템 순서 변경 이벤트 처리
/// ///
/// /// 이벤트 발생자
/// /// 이벤트 인자
/// private void OnItemReordered(object? sender, DraggableItemReorderEventArgs e)
/// {
/// Debug.Log($"아이템 순서 변경됨: ID={e.ItemId}, {e.OldIndex} -> {e.NewIndex}");
///
/// // 여기에 순서 변경에 대한 비즈니스 로직 구현
/// // 예: 서버에 변경사항 전송, 설정 저장 등
/// }
///
/// ///
/// /// 아이템 선택 이벤트 처리
/// ///
/// /// 이벤트 발생자
/// /// 선택된 아이템
/// private void OnItemSelected(object? sender, DraggableListItem item)
/// {
/// if (item?.Data != null)
/// {
/// Debug.Log($"아이템 선택됨: {item.Data.Id}");
///
/// // 선택된 아이템에 대한 처리
/// // 예: 상세 정보 표시, 편집 모드 진입 등
/// }
/// }
///
/// ///
/// /// 컴포넌트 정리
/// ///
/// private void OnDestroy()
/// {
/// if (draggableList != null)
/// {
/// draggableList.OnItemReordered -= OnItemReordered;
/// draggableList.OnItemSelected -= OnItemSelected;
/// }
/// }
/// }
///
///
public class DraggableScrollList : MonoBehaviour
{
[Header("UI 참조")]
[SerializeField] private ScrollRect? scrollRect;
[SerializeField] private RectTransform? contentParent;
[SerializeField] private VerticalLayoutGroup? layoutGroup;
[Header("드롭 인디케이터")]
[SerializeField] private Sprite? dropLineSprite;
[SerializeField] private Color dropLineColor = Color.cyan;
[SerializeField] private float dropLineHeight = 3f;
[SerializeField] private float dropLineMargin = 10f;
[SerializeField] private Material? dropLineMaterial; // 선택적: 특별한 Material 사용 시
[Header("프리팹 설정")]
[SerializeField] private string itemPrefabPath = "Prefabs/UI/List/DraggableListItem";
[Header("드래그 설정")]
[SerializeField] private float dropZoneThreshold = 50f;
[SerializeField] private float scrollSensitivity = 100f;
[SerializeField] private bool enableAutoScroll = true;
// 이벤트
public event EventHandler? OnItemReordered;
public event EventHandler? OnItemSelected;
// 데이터 및 UI 관리
private List itemDataList = new List();
private List itemUIList = new List();
private GameObject? itemPrefab;
// 드래그 상태 관리
private DraggableListItem? currentDraggingItem;
private int dragStartIndex = -1;
private int currentDropIndex = -1;
private Camera? uiCamera;
// 드롭 라인 관리 (동적 생성)
private GameObject? dropLineObject;
private Image? dropLineImage;
private RectTransform? dropLineRectTransform;
private bool isDropLineVisible = false;
///
/// 현재 아이템 데이터 목록 (읽기 전용)
///
public IReadOnlyList ItemDataList => itemDataList.AsReadOnly();
///
/// 컴포넌트 초기화
///
private void Awake()
{
InitializeComponents();
LoadItemPrefab();
}
///
/// UI 카메라 참조 설정
///
private void Start()
{
// UI 카메라 찾기 (Canvas의 카메라 또는 메인 카메라)
Canvas? canvas = GetComponentInParent