202 lines
6.1 KiB
C#
202 lines
6.1 KiB
C#
#nullable enable
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace UVC.UIToolkit
|
|
{
|
|
/// <summary>
|
|
/// 3D 벡터 속성 아이템
|
|
/// X, Y, Z 세 개의 FloatField 사용
|
|
/// </summary>
|
|
public class UTKVector3PropertyItem : UTKPropertyItemBase<Vector3>
|
|
{
|
|
#region Fields
|
|
private FloatField? _xField;
|
|
private FloatField? _yField;
|
|
private FloatField? _zField;
|
|
#endregion
|
|
|
|
#region Properties
|
|
public override UTKPropertyType PropertyType => UTKPropertyType.Vector3;
|
|
#endregion
|
|
|
|
#region Constructor
|
|
public UTKVector3PropertyItem(string id, string name, Vector3 initialValue = default)
|
|
: base(id, name, 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");
|
|
|
|
// X 필드
|
|
var xContainer = new VisualElement();
|
|
xContainer.AddToClassList("utk-property-item__vector-field");
|
|
xContainer.style.flexDirection = FlexDirection.Row;
|
|
|
|
var xLabel = new Label("X");
|
|
xLabel.AddToClassList("utk-property-item__vector-label");
|
|
xLabel.AddToClassList("utk-vector-label--x");
|
|
|
|
_xField = new FloatField();
|
|
_xField.name = "x-field";
|
|
_xField.value = Value.x;
|
|
_xField.style.flexGrow = 1;
|
|
|
|
xContainer.Add(xLabel);
|
|
xContainer.Add(_xField);
|
|
valueContainer.Add(xContainer);
|
|
|
|
// Y 필드
|
|
var yContainer = new VisualElement();
|
|
yContainer.AddToClassList("utk-property-item__vector-field");
|
|
yContainer.style.flexDirection = FlexDirection.Row;
|
|
|
|
var yLabel = new Label("Y");
|
|
yLabel.AddToClassList("utk-property-item__vector-label");
|
|
yLabel.AddToClassList("utk-vector-label--y");
|
|
|
|
_yField = new FloatField();
|
|
_yField.name = "y-field";
|
|
_yField.value = Value.y;
|
|
_yField.style.flexGrow = 1;
|
|
|
|
yContainer.Add(yLabel);
|
|
yContainer.Add(_yField);
|
|
valueContainer.Add(yContainer);
|
|
|
|
// Z 필드
|
|
var zContainer = new VisualElement();
|
|
zContainer.AddToClassList("utk-property-item__vector-field");
|
|
zContainer.style.flexDirection = FlexDirection.Row;
|
|
|
|
var zLabel = new Label("Z");
|
|
zLabel.AddToClassList("utk-property-item__vector-label");
|
|
zLabel.AddToClassList("utk-vector-label--z");
|
|
|
|
_zField = new FloatField();
|
|
_zField.name = "z-field";
|
|
_zField.value = Value.z;
|
|
_zField.style.flexGrow = 1;
|
|
|
|
zContainer.Add(zLabel);
|
|
zContainer.Add(_zField);
|
|
valueContainer.Add(zContainer);
|
|
|
|
container.Add(valueContainer);
|
|
|
|
return container;
|
|
}
|
|
|
|
public override void BindUI(VisualElement element)
|
|
{
|
|
base.BindUI(element);
|
|
|
|
_xField = element.Q<FloatField>("x-field");
|
|
_yField = element.Q<FloatField>("y-field");
|
|
_zField = element.Q<FloatField>("z-field");
|
|
|
|
if (_xField != null)
|
|
{
|
|
_xField.value = Value.x;
|
|
_xField.SetEnabled(!IsReadOnly);
|
|
_xField.RegisterValueChangedCallback(OnXChanged);
|
|
}
|
|
|
|
if (_yField != null)
|
|
{
|
|
_yField.value = Value.y;
|
|
_yField.SetEnabled(!IsReadOnly);
|
|
_yField.RegisterValueChangedCallback(OnYChanged);
|
|
}
|
|
|
|
if (_zField != null)
|
|
{
|
|
_zField.value = Value.z;
|
|
_zField.SetEnabled(!IsReadOnly);
|
|
_zField.RegisterValueChangedCallback(OnZChanged);
|
|
}
|
|
}
|
|
|
|
public override void UnbindUI(VisualElement element)
|
|
{
|
|
if (_xField != null)
|
|
{
|
|
_xField.UnregisterValueChangedCallback(OnXChanged);
|
|
_xField = null;
|
|
}
|
|
|
|
if (_yField != null)
|
|
{
|
|
_yField.UnregisterValueChangedCallback(OnYChanged);
|
|
_yField = null;
|
|
}
|
|
|
|
if (_zField != null)
|
|
{
|
|
_zField.UnregisterValueChangedCallback(OnZChanged);
|
|
_zField = null;
|
|
}
|
|
|
|
base.UnbindUI(element);
|
|
}
|
|
|
|
public override void RefreshUI()
|
|
{
|
|
if (_xField != null && !Mathf.Approximately(_xField.value, Value.x))
|
|
{
|
|
_xField.SetValueWithoutNotify(Value.x);
|
|
}
|
|
|
|
if (_yField != null && !Mathf.Approximately(_yField.value, Value.y))
|
|
{
|
|
_yField.SetValueWithoutNotify(Value.y);
|
|
}
|
|
|
|
if (_zField != null && !Mathf.Approximately(_zField.value, Value.z))
|
|
{
|
|
_zField.SetValueWithoutNotify(Value.z);
|
|
}
|
|
}
|
|
|
|
protected override void UpdateReadOnlyState()
|
|
{
|
|
base.UpdateReadOnlyState();
|
|
|
|
_xField?.SetEnabled(!IsReadOnly);
|
|
_yField?.SetEnabled(!IsReadOnly);
|
|
_zField?.SetEnabled(!IsReadOnly);
|
|
}
|
|
#endregion
|
|
|
|
#region Private Methods
|
|
private void OnXChanged(ChangeEvent<float> evt)
|
|
{
|
|
var newValue = new Vector3(evt.newValue, Value.y, Value.z);
|
|
DebounceValueChange(newValue, 100).Forget();
|
|
}
|
|
|
|
private void OnYChanged(ChangeEvent<float> evt)
|
|
{
|
|
var newValue = new Vector3(Value.x, evt.newValue, Value.z);
|
|
DebounceValueChange(newValue, 100).Forget();
|
|
}
|
|
|
|
private void OnZChanged(ChangeEvent<float> evt)
|
|
{
|
|
var newValue = new Vector3(Value.x, Value.y, evt.newValue);
|
|
DebounceValueChange(newValue, 100).Forget();
|
|
}
|
|
#endregion
|
|
}
|
|
}
|