194 lines
4.8 KiB
C#
194 lines
4.8 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using Newtonsoft.Json;
|
|
using Unity.Mathematics;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace BITKit.IData
|
|
{
|
|
public abstract class UXIEnumerableBindingHandler<TDataType> : IUXDataBinder
|
|
{
|
|
|
|
public Type TargetType =>typeof(IEnumerable<TDataType>);
|
|
public VisualElement VisualElement { get;private set; }
|
|
protected object target { get; private set; }
|
|
protected FieldInfo fieldInfo{ get; private set; }
|
|
protected VisualElement container { get; private set; }
|
|
protected Button addButton;
|
|
protected readonly List<TDataType> interfaceList=new();
|
|
|
|
public VisualElement CreateUI(object target, FieldInfo fieldInfo)
|
|
{
|
|
if(VisualElement is not null){throw new InvalidOperationException($"已经创建了Inspector<{VisualElement.GetType().Name}>");}
|
|
var exportAttribute = fieldInfo.GetCustomAttribute<ExportAttribute>();
|
|
|
|
this.fieldInfo = fieldInfo;
|
|
this.target = target;
|
|
|
|
// VisualElement = new Foldout();
|
|
//
|
|
// VisualElement.Create<Label>().text = exportAttribute switch
|
|
// {
|
|
// not null when string.IsNullOrEmpty(exportAttribute.Name) is false => exportAttribute.Name,
|
|
// _=>fieldInfo.Name
|
|
// };
|
|
|
|
VisualElement = new Foldout()
|
|
{
|
|
text = exportAttribute switch
|
|
{
|
|
not null when string.IsNullOrEmpty(exportAttribute.Name) is false => exportAttribute.Name,
|
|
_=>fieldInfo.Name
|
|
}
|
|
};
|
|
VisualElement.AddToClassList("--button");
|
|
|
|
container = VisualElement.Create<VisualElement>();
|
|
addButton = VisualElement.Create<Button>();
|
|
|
|
addButton.text = "+";
|
|
|
|
addButton.clicked += Add;
|
|
|
|
Rebuild();
|
|
|
|
return VisualElement;
|
|
}
|
|
|
|
|
|
private void Add()
|
|
{
|
|
interfaceList.Add(default);
|
|
|
|
switch (fieldInfo.GetValue(target))
|
|
{
|
|
case List<TDataType> list:
|
|
list.Add(default);
|
|
break;
|
|
case TDataType[] array:
|
|
Array.Resize(ref array, array.Length + 1);
|
|
fieldInfo.SetValue(target, array);
|
|
break;
|
|
}
|
|
|
|
Rebuild();
|
|
}
|
|
|
|
protected void Rebuild()
|
|
{
|
|
interfaceList.Clear();
|
|
interfaceList.AddRange((IEnumerable<TDataType>)fieldInfo.GetValue(target));
|
|
|
|
container.Clear();
|
|
|
|
for (var index = 0; index < interfaceList.Count; index++)
|
|
{
|
|
var index1 = index;
|
|
var entryContainer = container.Create<VisualElement>();
|
|
|
|
entryContainer.style.flexDirection = FlexDirection.Row;
|
|
|
|
var x = interfaceList[index];
|
|
|
|
var textField = entryContainer.Create<TextField>();
|
|
|
|
textField.isDelayed = true;
|
|
|
|
if(x is not null)
|
|
textField.SetValueWithoutNotify(JsonConvert.SerializeObject(x));
|
|
|
|
textField.style.flexGrow = 1;
|
|
textField.style.marginLeft = 0;
|
|
|
|
textField.RegisterValueChangedCallback(OnTextFieldOnValueChanged);
|
|
|
|
var removeButton = entryContainer.Create<Button>();
|
|
//removeButton.text = $"-{index}";
|
|
|
|
//u know how to do
|
|
removeButton.style.marginTop = 0;
|
|
|
|
removeButton.AddToClassList("icon-remove");
|
|
|
|
removeButton.clicked += OnRemoveButtonOnClicked;
|
|
|
|
container.Add(entryContainer);
|
|
|
|
continue;
|
|
|
|
void OnRemoveButtonOnClicked()
|
|
{
|
|
switch (fieldInfo.GetValue(target))
|
|
{
|
|
case List<TDataType> list:
|
|
list.RemoveAt(index1);
|
|
break;
|
|
case TDataType[] array:
|
|
interfaceList.RemoveAt(index1);
|
|
fieldInfo.SetValue(target, interfaceList.ToArray());
|
|
break;
|
|
}
|
|
Rebuild();
|
|
}
|
|
void OnTextFieldOnValueChanged(ChangeEvent<string> evt)
|
|
{
|
|
Deserialize(textField,index1,evt.newValue);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public void OnTick(float deltaTime)
|
|
{
|
|
}
|
|
public void Dispose()
|
|
{
|
|
|
|
// TODO 在此释放托管资源
|
|
}
|
|
protected void Deserialize(TextField textField,int index,string value)
|
|
{
|
|
try
|
|
{
|
|
var newValue = (TDataType)JsonConvert.DeserializeObject(value, typeof(TDataType));
|
|
switch (fieldInfo.GetValue(target))
|
|
{
|
|
case List<TDataType> list:
|
|
list[index] = newValue;
|
|
break;
|
|
case TDataType[] array:
|
|
array[index] = newValue;
|
|
fieldInfo.SetValue(target, array);
|
|
break;
|
|
}
|
|
Rebuild();
|
|
|
|
textField.EnableInClassList("error",false);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
textField.Query<TextElement>().First().tooltip = e.Message;
|
|
textField.EnableInClassList("error",true);
|
|
}
|
|
}
|
|
}
|
|
public sealed class UXStringIEnumerableBindingHandler : UXIEnumerableBindingHandler<string>
|
|
{
|
|
}
|
|
public sealed class UXFloatIEnumerableBindingHandler : UXIEnumerableBindingHandler<float>
|
|
{
|
|
}
|
|
public sealed class UXIntIEnumerableBindingHandler : UXIEnumerableBindingHandler<int>
|
|
{
|
|
}
|
|
public sealed class UXVector3IEnumerableBindingHandler : UXIEnumerableBindingHandler<Vector3>
|
|
{
|
|
}
|
|
public sealed class UXFloat3IEnumerableBindingHandler : UXIEnumerableBindingHandler<float3>
|
|
{
|
|
}
|
|
}
|