196 lines
5.5 KiB
C#
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
|
|
}
|
|
}
|