287 lines
12 KiB
C#
287 lines
12 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;
|
|
|
|
namespace UVC.UI.Window.PropertyWindow.UI
|
|
{
|
|
/// <summary>
|
|
/// DateTimeRangeProperty를 위한 UI를 제어하는 스크립트입니다.
|
|
/// 범위의 시작 날짜/시간과 끝 날짜/시간을 별도의 버튼으로 관리합니다.
|
|
/// </summary>
|
|
[RequireComponent(typeof(LayoutElement))]
|
|
public class DateTimeRangePropertyUI : MonoBehaviour, IPropertyUI
|
|
{
|
|
[Header("UI Components")]
|
|
[SerializeField]
|
|
private TextMeshProUGUI _nameLabel; // 속성 전체 이름
|
|
|
|
[SerializeField]
|
|
private TextMeshProUGUI _descriptionLabel;
|
|
|
|
[SerializeField]
|
|
private TMP_InputField _startDateText; // 시작 날짜 표시
|
|
[SerializeField]
|
|
private Button _startDatePickerButton; // 시작 날짜/시간 선택 버튼
|
|
|
|
[SerializeField]
|
|
private TMP_Dropdown _startHourDropDown; // 선택된 시간을 표시
|
|
|
|
[SerializeField]
|
|
private TMP_Dropdown _startMiniteDropDown; // 선택된 분을 표시
|
|
|
|
[SerializeField]
|
|
private TMP_InputField _endDateText; // 끝 날짜/시간 표시
|
|
[SerializeField]
|
|
private Button _endDatePickerButton; // 끝 날짜/시간 선택 버튼
|
|
|
|
[SerializeField]
|
|
private TMP_Dropdown _endHourDropDown; // 선택된 시간을 표시
|
|
|
|
[SerializeField]
|
|
private TMP_Dropdown _endMiniteDropDown; // 선택된 분을 표시
|
|
|
|
private DateTimeRangeProperty _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>
|
|
public void Setup(IPropertyItem item, PropertyWindow controller)
|
|
{
|
|
if (!(item is DateTimeRangeProperty dateTimeRangeItem))
|
|
{
|
|
Debug.LogError($"DateTimeRangePropertyUI에 잘못된 타입의 PropertyItem이 전달되었습니다. {item.GetType()}");
|
|
return;
|
|
}
|
|
|
|
_propertyItem = dateTimeRangeItem;
|
|
_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"));
|
|
}
|
|
_startHourDropDown.AddOptions(hourOptions);
|
|
_startMiniteDropDown.AddOptions(minuteOptions);
|
|
_endHourDropDown.AddOptions(hourOptions);
|
|
_endMiniteDropDown.AddOptions(minuteOptions);
|
|
|
|
_startHourDropDown.SetValueWithoutNotify(_propertyItem.Value.Item1.Hour);
|
|
_startMiniteDropDown.SetValueWithoutNotify(_propertyItem.Value.Item1.Minute);
|
|
|
|
_endHourDropDown.SetValueWithoutNotify(_propertyItem.Value.Item2.Hour);
|
|
_endMiniteDropDown.SetValueWithoutNotify(_propertyItem.Value.Item2.Minute);
|
|
|
|
// --- 데이터 바인딩 ---
|
|
_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;
|
|
}
|
|
|
|
// 초기 값 설정
|
|
_startDateText.text = _propertyItem.Value.Item1.ToString(DateFormat);
|
|
_endDateText.text = _propertyItem.Value.Item2.ToString(DateFormat);
|
|
|
|
// 읽기 전용 상태 설정
|
|
bool isReadOnly = _propertyItem.IsReadOnly;
|
|
_startDateText.interactable = !isReadOnly;
|
|
_endDateText.interactable = !isReadOnly;
|
|
_startDatePickerButton.interactable = !isReadOnly;
|
|
_endDatePickerButton.interactable = !isReadOnly;
|
|
|
|
_startDatePickerButton.gameObject.SetActive(!isReadOnly);
|
|
_endDatePickerButton.gameObject.SetActive(!isReadOnly);
|
|
|
|
// --- 이벤트 리스너 등록 ---
|
|
_startDatePickerButton.onClick.RemoveAllListeners();
|
|
_endDatePickerButton.onClick.RemoveAllListeners();
|
|
_startDatePickerButton.onClick.AddListener(OpenStartDateTimePicker);
|
|
_endDatePickerButton.onClick.AddListener(OpenEndDateTimePicker);
|
|
|
|
_startHourDropDown.interactable = !isReadOnly;
|
|
_startHourDropDown.onValueChanged.RemoveAllListeners();
|
|
_startHourDropDown.onValueChanged.AddListener((int hour) =>
|
|
{
|
|
DateTime newDateTime = new DateTime(
|
|
_propertyItem.Value.Item1.Year,
|
|
_propertyItem.Value.Item1.Month,
|
|
_propertyItem.Value.Item1.Day,
|
|
hour,
|
|
_propertyItem.Value.Item1.Minute,
|
|
0
|
|
);
|
|
OnStartDateTimeSelected(newDateTime);
|
|
});
|
|
_startMiniteDropDown.interactable = !isReadOnly;
|
|
_startMiniteDropDown.onValueChanged.RemoveAllListeners();
|
|
_startMiniteDropDown.onValueChanged.AddListener((int minute) =>
|
|
{
|
|
DateTime newDateTime = new DateTime(
|
|
_propertyItem.Value.Item1.Year,
|
|
_propertyItem.Value.Item1.Month,
|
|
_propertyItem.Value.Item1.Day,
|
|
_propertyItem.Value.Item1.Hour,
|
|
minute,
|
|
0
|
|
);
|
|
OnStartDateTimeSelected(newDateTime);
|
|
});
|
|
|
|
_endHourDropDown.interactable = !isReadOnly;
|
|
_endHourDropDown.onValueChanged.RemoveAllListeners();
|
|
_endHourDropDown.onValueChanged.AddListener((int hour) =>
|
|
{
|
|
DateTime newDateTime = new DateTime(
|
|
_propertyItem.Value.Item2.Year,
|
|
_propertyItem.Value.Item2.Month,
|
|
_propertyItem.Value.Item2.Day,
|
|
hour,
|
|
_propertyItem.Value.Item2.Minute,
|
|
0
|
|
);
|
|
OnEndDateTimeSelected(newDateTime);
|
|
});
|
|
_endMiniteDropDown.interactable = !isReadOnly;
|
|
_endMiniteDropDown.onValueChanged.RemoveAllListeners();
|
|
_endMiniteDropDown.onValueChanged.AddListener((int minute) =>
|
|
{
|
|
DateTime newDateTime = new DateTime(
|
|
_propertyItem.Value.Item2.Year,
|
|
_propertyItem.Value.Item2.Month,
|
|
_propertyItem.Value.Item2.Day,
|
|
_propertyItem.Value.Item2.Hour,
|
|
minute,
|
|
0
|
|
);
|
|
OnEndDateTimeSelected(newDateTime);
|
|
});
|
|
}
|
|
|
|
private async void OpenStartDateTimePicker()
|
|
{
|
|
CursorManager.Instance.SetDefaultCursor();
|
|
await DatePicker.Show(_propertyItem.Value.Item1, newDate =>
|
|
{
|
|
DateTime newDateTime = new DateTime(
|
|
newDate.Year,
|
|
newDate.Month,
|
|
newDate.Day,
|
|
_propertyItem.Value.Item1.Hour,
|
|
_propertyItem.Value.Item1.Minute,
|
|
0
|
|
);
|
|
OnStartDateTimeSelected(newDateTime);
|
|
});
|
|
CursorManager.Instance.SetDefaultCursor();
|
|
Debug.LogWarning($"'{_propertyItem.Name}'의 시작 날짜/시간 선택기 로직이 구현되지 않았습니다.");
|
|
}
|
|
|
|
private async void OpenEndDateTimePicker()
|
|
{
|
|
CursorManager.Instance.SetDefaultCursor();
|
|
await DatePicker.Show(_propertyItem.Value.Item2, newDate =>
|
|
{
|
|
DateTime newDateTime = new DateTime(
|
|
newDate.Year,
|
|
newDate.Month,
|
|
newDate.Day,
|
|
_propertyItem.Value.Item2.Hour,
|
|
_propertyItem.Value.Item2.Minute,
|
|
0
|
|
);
|
|
OnEndDateTimeSelected(newDateTime);
|
|
});
|
|
CursorManager.Instance.SetDefaultCursor();
|
|
Debug.LogWarning($"'{_propertyItem.Name}'의 끝 날짜/시간 선택기 로직이 구현되지 않았습니다.");
|
|
}
|
|
|
|
private void OnStartDateTimeSelected(DateTime newStartDateTime)
|
|
{
|
|
//이전 값이랑 같으면 리턴
|
|
if (_propertyItem.Value.Item1.ToString(FullDateFormat) == newStartDateTime.ToString(FullDateFormat)) return;
|
|
|
|
DateTime Item1 = newStartDateTime;
|
|
DateTime Item2 = _propertyItem.Value.Item2;
|
|
|
|
// 시작 날짜/시간이 끝 날짜/시간보다 늦어지지 않도록 보정
|
|
if (newStartDateTime > Item2) Item2 = newStartDateTime;
|
|
|
|
var newValue = new Tuple<DateTime, DateTime>(Item1, Item2);
|
|
|
|
// UI 업데이트
|
|
_startDateText.text = Item1.ToString(DateFormat);
|
|
_endDateText.text = Item2.ToString(DateFormat);
|
|
|
|
_startHourDropDown.SetValueWithoutNotify(Item1.Hour);
|
|
_startMiniteDropDown.SetValueWithoutNotify(Item1.Minute);
|
|
|
|
_endHourDropDown.SetValueWithoutNotify(Item2.Hour);
|
|
_endMiniteDropDown.SetValueWithoutNotify(Item2.Minute);
|
|
|
|
|
|
// 변경 이벤트 알림
|
|
_controller.UpdatePropertyValue(_propertyItem.Id, _propertyItem.PropertyType, newValue);
|
|
}
|
|
|
|
private void OnEndDateTimeSelected(DateTime newEndDateTime)
|
|
{
|
|
//이전 값이랑 같으면 리턴
|
|
if (_propertyItem.Value.Item2.ToString(FullDateFormat) == newEndDateTime.ToString(FullDateFormat)) return;
|
|
|
|
DateTime Item1 = _propertyItem.Value.Item1;
|
|
DateTime Item2 = newEndDateTime;
|
|
|
|
// 끝 날짜/시간이 시작 날짜/시간보다 빨라지지 않도록 보정
|
|
if (newEndDateTime < Item1) Item1 = newEndDateTime;
|
|
|
|
var newValue = new Tuple<DateTime, DateTime>(Item1, Item2);
|
|
|
|
// UI 업데이트
|
|
_startDateText.text = Item1.ToString(DateFormat);
|
|
_endDateText.text = Item2.ToString(DateFormat);
|
|
|
|
_startHourDropDown.SetValueWithoutNotify(Item1.Hour);
|
|
_startMiniteDropDown.SetValueWithoutNotify(Item1.Minute);
|
|
|
|
_endHourDropDown.SetValueWithoutNotify(Item2.Hour);
|
|
_endMiniteDropDown.SetValueWithoutNotify(Item2.Minute);
|
|
|
|
// 변경 이벤트 알림
|
|
_controller.UpdatePropertyValue(_propertyItem.Id, _propertyItem.PropertyType, newValue);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 이 UI 오브젝트가 파괴될 때 Unity에 의해 호출됩니다.
|
|
/// </summary>
|
|
private void OnDestroy()
|
|
{
|
|
if (_startDatePickerButton != null) _startDatePickerButton.onClick.RemoveAllListeners();
|
|
if (_endDatePickerButton != null) _endDatePickerButton.onClick.RemoveAllListeners();
|
|
}
|
|
}
|
|
} |