236 lines
6.6 KiB
C#
236 lines
6.6 KiB
C#
#nullable enable
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace UVC.UIToolkit
|
|
{
|
|
/// <summary>
|
|
/// 정수 속성 아이템
|
|
/// IntegerField 또는 SliderInt 사용
|
|
/// </summary>
|
|
public class UTKIntPropertyItem : UTKPropertyItemBase<int>
|
|
{
|
|
#region Fields
|
|
private UTKIntegerField? _intField;
|
|
private UTKSliderInt? _slider;
|
|
private bool _useSlider;
|
|
private int _minValue;
|
|
private int _maxValue = 100;
|
|
#endregion
|
|
|
|
#region Properties
|
|
public override UTKPropertyType PropertyType => UTKPropertyType.Int;
|
|
|
|
/// <summary>슬라이더 사용 여부</summary>
|
|
public bool UseSlider
|
|
{
|
|
get => _useSlider;
|
|
set => _useSlider = value;
|
|
}
|
|
|
|
/// <summary>최소값 (슬라이더 모드)</summary>
|
|
public int MinValue
|
|
{
|
|
get => _minValue;
|
|
set
|
|
{
|
|
_minValue = value;
|
|
if (_slider != null)
|
|
{
|
|
_slider.lowValue = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>최대값 (슬라이더 모드)</summary>
|
|
public int MaxValue
|
|
{
|
|
get => _maxValue;
|
|
set
|
|
{
|
|
_maxValue = value;
|
|
if (_slider != null)
|
|
{
|
|
_slider.highValue = value;
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Constructor
|
|
public UTKIntPropertyItem(string id, string name, int initialValue = 0)
|
|
: base(id, name, initialValue)
|
|
{
|
|
}
|
|
|
|
public UTKIntPropertyItem(string id, string name, int initialValue, int minValue, int maxValue, bool useSlider = true)
|
|
: base(id, name, initialValue)
|
|
{
|
|
_minValue = minValue;
|
|
_maxValue = maxValue;
|
|
_useSlider = useSlider;
|
|
}
|
|
#endregion
|
|
|
|
#region Override Methods
|
|
public override VisualElement CreateUI()
|
|
{
|
|
string uxmlName = _useSlider ? "UTKIntPropertyItemSlider" : "UTKIntPropertyItem";
|
|
var container = CreateUIFromUxml(uxmlName);
|
|
if (container == null)
|
|
{
|
|
return CreateUIFallback();
|
|
}
|
|
|
|
_intField = container.Q<UTKIntegerField>("value-field");
|
|
_slider = container.Q<UTKSliderInt>("slider-field");
|
|
|
|
if (_intField != null)
|
|
{
|
|
_intField.Value = Value;
|
|
}
|
|
|
|
if (_slider != null)
|
|
{
|
|
_slider.lowValue = _minValue;
|
|
_slider.highValue = _maxValue;
|
|
_slider.Value = Value;
|
|
}
|
|
|
|
return container;
|
|
}
|
|
|
|
private VisualElement CreateUIFallback()
|
|
{
|
|
var container = CreateContainer();
|
|
|
|
if (_useSlider)
|
|
{
|
|
container.AddToClassList("utk-property-item--slider");
|
|
}
|
|
|
|
var label = CreateNameLabel();
|
|
container.Add(label);
|
|
|
|
var valueContainer = new VisualElement();
|
|
valueContainer.AddToClassList("utk-property-item__value");
|
|
|
|
if (_useSlider)
|
|
{
|
|
_slider = new UTKSliderInt("", _minValue, _maxValue, Value);
|
|
_slider.name = "slider-field";
|
|
_slider.AddToClassList("utk-property-item__slider");
|
|
valueContainer.Add(_slider);
|
|
|
|
_intField = new UTKIntegerField();
|
|
_intField.name = "value-field";
|
|
_intField.Value = Value;
|
|
_intField.AddToClassList("utk-property-item__number-field");
|
|
valueContainer.Add(_intField);
|
|
}
|
|
else
|
|
{
|
|
_intField = new UTKIntegerField();
|
|
_intField.name = "value-field";
|
|
_intField.Value = Value;
|
|
valueContainer.Add(_intField);
|
|
}
|
|
|
|
container.Add(valueContainer);
|
|
|
|
return container;
|
|
}
|
|
|
|
public override void BindUI(VisualElement element)
|
|
{
|
|
base.BindUI(element);
|
|
|
|
_intField = element.Q<UTKIntegerField>("value-field");
|
|
_slider = element.Q<UTKSliderInt>("slider-field");
|
|
|
|
if (_intField != null)
|
|
{
|
|
_intField.Value = Value;
|
|
_intField.IsEnabled = !IsReadOnly;
|
|
_intField.OnValueChanged += OnIntFieldChanged;
|
|
}
|
|
|
|
if (_slider != null)
|
|
{
|
|
_slider.lowValue = _minValue;
|
|
_slider.highValue = _maxValue;
|
|
_slider.Value = Value;
|
|
_slider.IsEnabled = !IsReadOnly;
|
|
_slider.OnValueChanged += OnSliderChanged;
|
|
}
|
|
}
|
|
|
|
public override void UnbindUI(VisualElement element)
|
|
{
|
|
if (_intField != null)
|
|
{
|
|
_intField.OnValueChanged -= OnIntFieldChanged;
|
|
_intField = null;
|
|
}
|
|
|
|
if (_slider != null)
|
|
{
|
|
_slider.OnValueChanged -= OnSliderChanged;
|
|
_slider = null;
|
|
}
|
|
|
|
base.UnbindUI(element);
|
|
}
|
|
|
|
public override void RefreshUI()
|
|
{
|
|
if (_intField != null && _intField.Value != Value)
|
|
{
|
|
_intField.SetValueWithoutNotify(Value);
|
|
}
|
|
|
|
if (_slider != null && _slider.Value != Value)
|
|
{
|
|
_slider.SetValueWithoutNotify(Value);
|
|
}
|
|
}
|
|
|
|
protected override void UpdateReadOnlyState()
|
|
{
|
|
base.UpdateReadOnlyState();
|
|
|
|
if (_intField != null)
|
|
{
|
|
_intField.IsEnabled = !IsReadOnly;
|
|
}
|
|
if (_slider != null) _slider.IsEnabled = !IsReadOnly;
|
|
}
|
|
#endregion
|
|
|
|
#region Private Methods
|
|
private void OnIntFieldChanged(int newValue)
|
|
{
|
|
int clampedValue = _useSlider ? Mathf.Clamp(newValue, _minValue, _maxValue) : newValue;
|
|
|
|
if (_slider != null && _slider.Value != clampedValue)
|
|
{
|
|
_slider.SetValueWithoutNotify(clampedValue);
|
|
}
|
|
|
|
DebounceValueChange(clampedValue, 100).Forget();
|
|
}
|
|
|
|
private void OnSliderChanged(int newValue)
|
|
{
|
|
if (_intField != null && _intField.Value != newValue)
|
|
{
|
|
_intField.SetValueWithoutNotify(newValue);
|
|
}
|
|
|
|
// 슬라이더는 빠른 반응이 필요하므로 짧은 디바운스
|
|
DebounceValueChange(newValue, 50).Forget();
|
|
}
|
|
#endregion
|
|
}
|
|
}
|