Files
XRLib/Assets/Scripts/UVC/UIToolkit/Property/Items/UTKDateTimePropertyItem.cs
2026-01-20 20:18:47 +09:00

196 lines
5.5 KiB
C#

#nullable enable
using System;
using UnityEngine.UIElements;
namespace UVC.UIToolkit
{
/// <summary>
/// 날짜+시간 속성 아이템
/// TextField + UTKDatePicker(DateAndTime 모드) 연동
/// </summary>
public class UTKDateTimePropertyItem : UTKPropertyItemBase<DateTime>
{
#region Fields
private TextField? _dateTimeField;
private Button? _pickerButton;
private UTKDatePicker? _currentPicker;
private string _dateTimeFormat = "yyyy-MM-dd HH:mm";
#endregion
#region Properties
public override UTKPropertyType PropertyType => UTKPropertyType.DateTime;
/// <summary>날짜시간 표시 형식</summary>
public string DateTimeFormat
{
get => _dateTimeFormat;
set
{
_dateTimeFormat = value ?? "yyyy-MM-dd HH:mm";
RefreshUI();
}
}
#endregion
#region Constructor
public UTKDateTimePropertyItem(string id, string name, DateTime initialValue = default)
: base(id, name, initialValue == default ? DateTime.Now : initialValue)
{
}
#endregion
#region Override Methods
public override VisualElement CreateUI()
{
var container = CreateContainer();
var label = CreateNameLabel();
container.Add(label);
var valueContainer = new VisualElement();
valueContainer.AddToClassList("utk-property-item__value");
_dateTimeField = new TextField();
_dateTimeField.name = "datetime-field";
_dateTimeField.value = Value.ToString(_dateTimeFormat);
_dateTimeField.style.flexGrow = 1;
valueContainer.Add(_dateTimeField);
_pickerButton = new Button();
_pickerButton.name = "picker-btn";
_pickerButton.text = "...";
_pickerButton.AddToClassList("utk-property-item__picker-btn");
valueContainer.Add(_pickerButton);
container.Add(valueContainer);
return container;
}
public override void BindUI(VisualElement element)
{
base.BindUI(element);
_dateTimeField = element.Q<TextField>("datetime-field");
_pickerButton = element.Q<Button>("picker-btn");
if (_dateTimeField != null)
{
_dateTimeField.value = Value.ToString(_dateTimeFormat);
_dateTimeField.SetEnabled(!IsReadOnly);
_dateTimeField.RegisterValueChangedCallback(OnDateTimeTextChanged);
}
if (_pickerButton != null)
{
_pickerButton.SetEnabled(!IsReadOnly);
_pickerButton.clicked += OnPickerButtonClicked;
}
}
public override void UnbindUI(VisualElement element)
{
if (_dateTimeField != null)
{
_dateTimeField.UnregisterValueChangedCallback(OnDateTimeTextChanged);
_dateTimeField = null;
}
if (_pickerButton != null)
{
_pickerButton.clicked -= OnPickerButtonClicked;
_pickerButton = null;
}
ClosePicker();
base.UnbindUI(element);
}
public override void RefreshUI()
{
if (_dateTimeField != null)
{
var formatted = Value.ToString(_dateTimeFormat);
if (_dateTimeField.value != formatted)
{
_dateTimeField.SetValueWithoutNotify(formatted);
}
}
}
protected override void UpdateReadOnlyState()
{
base.UpdateReadOnlyState();
_dateTimeField?.SetEnabled(!IsReadOnly);
_pickerButton?.SetEnabled(!IsReadOnly);
}
#endregion
#region Private Methods
private void OnPickerButtonClicked()
{
OpenPicker();
}
private void OpenPicker()
{
if (_currentPicker != null || _rootElement == null) return;
var root = _rootElement;
while (root.parent != null)
{
root = root.parent;
}
_currentPicker = UTKDatePicker.Show(root, Value, UTKDatePicker.PickerMode.DateAndTime, Name);
_currentPicker.OnDateSelected += OnPickerDateSelected;
_currentPicker.OnClosed += OnPickerClosed;
}
private void ClosePicker()
{
if (_currentPicker != null)
{
_currentPicker.OnDateSelected -= OnPickerDateSelected;
_currentPicker.OnClosed -= OnPickerClosed;
_currentPicker.Dispose();
_currentPicker = null;
}
}
private void OnPickerDateSelected(DateTime dateTime)
{
Value = dateTime;
ClosePicker();
}
private void OnPickerClosed()
{
_currentPicker = null;
}
private void OnDateTimeTextChanged(ChangeEvent<string> evt)
{
if (DateTime.TryParse(evt.newValue, out DateTime dateTime))
{
DebounceValueChange(dateTime, 500).Forget();
}
}
#endregion
#region IDisposable
protected override void Dispose(bool disposing)
{
if (disposing)
{
ClosePicker();
}
base.Dispose(disposing);
}
#endregion
}
}