189 lines
7.3 KiB
C#
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();
|
|
}
|
|
}
|
|
} |