Files
XRLib/Assets/Scripts/UVC/UI/Window/PropertyWindow/UI/DateTimePropertyUI.cs
2025-09-25 16:31:52 +09:00

189 lines
7.3 KiB
C#

using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UVC.Extention;
using UVC.UI.Modal.DatePicker;
using UVC.UI.Tooltip;
using UVC.Util; // DateTimePickerManager가 위치할 네임스페이스
namespace UVC.UI.Window.PropertyWindow.UI
{
/// <summary>
/// DateTimeProperty를 위한 UI를 제어하는 스크립트입니다.
/// 날짜와 시간을 텍스트로 표시하고, 버튼을 통해 DateTime Picker를 엽니다.
/// </summary>
[RequireComponent(typeof(LayoutElement))]
public class DateTimePropertyUI : MonoBehaviour, IPropertyUI
{
[Header("UI Components")]
[SerializeField]
private TextMeshProUGUI _nameLabel; // 속성 이름을 표시할 Text
[SerializeField]
private TextMeshProUGUI _descriptionLabel;
[SerializeField]
private TMP_InputField _dateText; // 선택된 날짜를 표시할 Text
[SerializeField]
private TMP_Dropdown _hourDropDown; // 선택된 시간을 표시
[SerializeField]
private TMP_Dropdown _miniteDropDown; // 선택된 분을 표시
[SerializeField]
private Button _dateTimePickerButton; // DateTime Picker를 열기 위한 Button
private DateTimeProperty _propertyItem;
private PropertyWindow _controller;
private const string DateFormat = "yyyy-MM-dd"; // 날짜 표시 형식
private const string FullDateFormat = "yyyy-MM-dd HH:mm:ss"; // 날짜 표시 형식
/// <summary>
/// PropertyView에 의해 호출되어 UI를 초기화하고 데이터를 설정합니다.
/// </summary>
/// <param name="item">UI에 표시할 속성 데이터(IPropertyItem)</param>
/// <param name="controller">상호작용할 PropertyWindow</param>
public void Setup(IPropertyItem item, PropertyWindow controller)
{
if (!(item is DateTimeProperty typedItem))
{
Debug.LogError($"DateTimePropertyUI에 잘못된 타입의 PropertyItem이 전달되었습니다. {item.GetType()}");
return;
}
_propertyItem = typedItem;
_controller = controller;
List<string> hourOptions = new List<string>();
List<string> minuteOptions = new List<string>();
for (int i = 0; i < 60; i++)
{
if (i < 24) hourOptions.Add(i.ToString("D2"));
minuteOptions.Add(i.ToString("D2"));
}
_hourDropDown.AddOptions(hourOptions);
_miniteDropDown.AddOptions(minuteOptions);
// --- 데이터 바인딩 ---
_nameLabel.text = _propertyItem.Name;
// 툴팁 설정 (TooltipHandler 컴포넌트가 있다면 연동)
TooltipHandler tooltipHandler = _nameLabel.GetComponent<TooltipHandler>();
if (tooltipHandler != null && !_propertyItem.Tooltip.IsNullOrEmpty())
{
tooltipHandler.Tooltip = _propertyItem.Tooltip;
}
if (_propertyItem.Description.IsNullOrEmpty())
{
_descriptionLabel.gameObject.SetActive(false);
}
else
{
_descriptionLabel.gameObject.SetActive(true);
_descriptionLabel.text = _propertyItem.Description;
}
_dateText.text = _propertyItem.Value.ToString(DateFormat);
_hourDropDown.SetValueWithoutNotify(_propertyItem.Value.Hour);
_miniteDropDown.SetValueWithoutNotify(_propertyItem.Value.Minute);
_dateText.interactable = !_propertyItem.IsReadOnly;
_dateTimePickerButton.interactable = !_propertyItem.IsReadOnly;
_dateTimePickerButton.gameObject.SetActive(!_propertyItem.IsReadOnly);
// --- 이벤트 리스너 등록 ---
_dateTimePickerButton.onClick.RemoveAllListeners();
_dateTimePickerButton.onClick.AddListener(OpenDateTimePicker);
_hourDropDown.interactable = !_propertyItem.IsReadOnly;
_hourDropDown.onValueChanged.RemoveAllListeners();
_hourDropDown.onValueChanged.AddListener((int hour) =>
{
DateTime newDateTime = new DateTime(
_propertyItem.Value.Year,
_propertyItem.Value.Month,
_propertyItem.Value.Day,
hour,
_propertyItem.Value.Minute,
0
);
OnDateTimeSelected(newDateTime);
});
_miniteDropDown.interactable = !_propertyItem.IsReadOnly;
_miniteDropDown.onValueChanged.RemoveAllListeners();
_miniteDropDown.onValueChanged.AddListener((int minute) =>
{
DateTime newDateTime = new DateTime(
_propertyItem.Value.Year,
_propertyItem.Value.Month,
_propertyItem.Value.Day,
_propertyItem.Value.Hour,
minute,
0
);
OnDateTimeSelected(newDateTime);
});
}
/// <summary>
/// 날짜 및 시간 선택기 버튼을 클릭했을 때 호출됩니다.
/// </summary>
private async void OpenDateTimePicker()
{
CursorManager.Instance.SetCursor(CursorType.Wait);
await DatePicker.Show(_propertyItem.Value, newDate =>
{
DateTime newDateTime = new DateTime(
newDate.Year,
newDate.Month,
newDate.Day,
_propertyItem.Value.Hour,
_propertyItem.Value.Minute,
0
);
OnDateTimeSelected(newDateTime);
});
CursorManager.Instance.SetDefaultCursor();
}
/// <summary>
/// 날짜 및 시간 선택기에서 새로운 값이 선택되었을 때 호출되는 메서드입니다.
/// </summary>
/// <param name="newDateTime">선택된 새로운 날짜와 시간</param>
public void OnDateTimeSelected(DateTime newDateTime)
{
// 선택된 날짜가 현재 값과 다를 때만 업데이트
if (_propertyItem.Value.ToString(FullDateFormat) == newDateTime.ToString(FullDateFormat))
{
return; // 변경 사항이 없으므로 아무 작업도 하지 않음
}
// 1. UI의 텍스트를 업데이트합니다.
_dateText.text = newDateTime.ToString(DateFormat);
// 2. PropertyController를 통해 데이터 모델의 값을 업데이트합니다.
_controller.UpdatePropertyValue(_propertyItem.Id, _propertyItem.PropertyType, newDateTime);
}
/// <summary>
/// 이 UI 오브젝트가 파괴될 때 Unity에 의해 호출됩니다.
/// </summary>
private void OnDestroy()
{
if (_dateTimePickerButton != null)
{
_dateTimePickerButton.onClick.RemoveAllListeners();
}
_hourDropDown.onValueChanged.RemoveAllListeners();
_miniteDropDown.onValueChanged.RemoveAllListeners();
}
}
}