BITKit/Src/Unity/Scripts/UX/Utils/UXUtils.cs

109 lines
2.9 KiB
C#
Raw Normal View History

2023-11-30 00:25:43 +08:00
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.UIElements;
namespace BITKit.UX
{
2024-11-03 16:38:17 +08:00
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
2023-11-30 00:25:43 +08:00
public class UXBindPathAttribute : Attribute
{
public string Path;
2024-03-31 23:31:00 +08:00
public bool CanBeNull;
2024-11-03 16:38:17 +08:00
public UXBindPathAttribute()
{
}
2023-11-30 00:25:43 +08:00
public UXBindPathAttribute(string path)
{
Path = path;
}
2024-11-03 16:38:17 +08:00
public UXBindPathAttribute(string path, bool canBeNull)
2024-03-31 23:31:00 +08:00
{
Path = path;
CanBeNull = canBeNull;
}
2023-11-30 00:25:43 +08:00
}
2024-11-03 16:38:17 +08:00
public class UXUtils
2023-11-30 00:25:43 +08:00
{
2024-11-03 16:38:17 +08:00
public static void Inject(object self,VisualElement root=null)
2023-11-30 00:25:43 +08:00
{
2024-11-03 16:38:17 +08:00
UIDocument document = null;
2023-11-30 00:25:43 +08:00
var field = self.GetType().GetField("document",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
2024-03-31 23:31:00 +08:00
2024-11-03 16:38:17 +08:00
var rootVisualElementFieldInfo = self.GetType().GetField("RootVisualElement",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
var rootVisualElementPropertyInfo = self.GetType().GetProperty("RootVisualElement",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
var rootVisualElement = (rootVisualElementFieldInfo, rootVisualElementPropertyInfo) switch
{
{ } when rootVisualElementPropertyInfo?.GetValue(self) is VisualElement ve => ve,
{ } when rootVisualElementFieldInfo?.GetValue(self) is VisualElement ve => ve,
_ => root,
};
2024-03-31 23:31:00 +08:00
2024-11-03 16:38:17 +08:00
if (rootVisualElement is not null)
2023-11-30 00:25:43 +08:00
{
2024-11-03 16:38:17 +08:00
2023-11-30 00:25:43 +08:00
}
2024-11-03 16:38:17 +08:00
else
{
switch (field)
{
case null when self is MonoBehaviour monoBehaviour &&
monoBehaviour.TryGetComponent<UIDocument>(out document):
break;
case not null when field.GetValue(self) is UIDocument _document:
document = _document;
break;
default:
BIT4Log.Warning<UXUtils>($"document 未赋值或未找到@{self.GetType().Name}");
return;
}
}
2024-08-13 18:42:51 +08:00
2023-11-30 00:25:43 +08:00
foreach (var fieldInfo in self.GetType()
.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
2024-08-13 18:42:51 +08:00
.Where(x => x.GetCustomAttribute<UXBindPathAttribute>() is not null)
2024-03-31 23:31:00 +08:00
)
2023-11-30 00:25:43 +08:00
{
var bindPathAtt = fieldInfo.GetCustomAttribute<UXBindPathAttribute>();
2024-11-03 16:38:17 +08:00
VisualElement ve = (document, rootVisualElement) switch
{
(_, not null) => rootVisualElement,
(not null, _) => document.rootVisualElement,
_ => throw new NotImplementedException(),
};
2024-04-16 04:06:46 +08:00
foreach (var path in bindPathAtt.Path.Split("."))
{
ve = ve.Q(path);
}
2024-08-13 18:42:51 +08:00
2024-04-16 04:06:46 +08:00
//ve = document.rootVisualElement.Q(bindPathAtt.Path);
2024-08-13 18:42:51 +08:00
if (bindPathAtt.CanBeNull is false && ve is null)
2024-12-25 11:11:31 +08:00
BIT4Log.LogException(new NullReferenceException($"{self.GetType().Name},{rootVisualElement.name}上未找到{bindPathAtt.Path}"));
2024-05-31 01:23:15 +08:00
2024-08-13 18:42:51 +08:00
try
2024-05-31 01:23:15 +08:00
{
2024-08-13 18:42:51 +08:00
fieldInfo.SetValue(self, ve);
2024-05-31 01:23:15 +08:00
}
2024-08-13 18:42:51 +08:00
catch (Exception e)
2024-05-31 01:23:15 +08:00
{
2024-12-13 16:14:20 +08:00
BIT4Log.Warning<UXUtils>(fieldInfo!.Name);
2024-05-31 01:23:15 +08:00
}
2023-11-30 00:25:43 +08:00
}
}
}
}