属性反射生成界面基本框架。
修复懒加载框的布局问题。
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
namespace XericUI.ReflectionUIGenerator
|
||||
{
|
||||
public interface IXuiavrgAttribute
|
||||
{
|
||||
public void BindProperty(XuiavrgInspectorProperty property);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 998589d7b3414ddd99b69cb128d7e052
|
||||
timeCreated: 1777014404
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
#if ODIN_INSPECTOR
|
||||
using Sirenix.OdinInspector;
|
||||
#endif
|
||||
using UnityEngine;
|
||||
using XericLibrary.Runtime.MacroLibrary;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace XericUI.ReflectionUIGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// 属性映射器
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[CreateAssetMenu(fileName = "Xeric UI avr Property", menuName = "Xeric Library/UI Action Vessel/Reflection UI Gen/UI avr Property", order = 10)]
|
||||
public class XuiavrPropertyScriptableObject : ScriptableObject
|
||||
{
|
||||
#if ODIN_INSPECTOR
|
||||
[LabelText("属性类型")]
|
||||
[ValueDropdown("AssemblyValueTypeNames")]
|
||||
#endif
|
||||
public string valueType;
|
||||
#if ODIN_INSPECTOR
|
||||
[LabelText("属性名称")]
|
||||
#endif
|
||||
public string propertyName;
|
||||
#if ODIN_INSPECTOR
|
||||
[LabelText("界面预制体")]
|
||||
#endif
|
||||
public GameObject prefab;
|
||||
|
||||
/// <summary>
|
||||
/// 属性类型
|
||||
/// </summary>
|
||||
public System.Type ValueType
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_valueType != null)
|
||||
return _valueType;
|
||||
return _valueType = Type.GetType(valueType);
|
||||
}
|
||||
}
|
||||
private System.Type _valueType;
|
||||
|
||||
/// <summary>
|
||||
/// 属性类型名称枚举
|
||||
/// </summary>
|
||||
private IEnumerable AssemblyValueTypeNames
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_assemblyValueTypeName != null)
|
||||
return _assemblyValueTypeName;
|
||||
_assemblyValueTypeName = new ValueDropdownList<string>();
|
||||
|
||||
// foreach (var typeName in MacroReflection.GetAllAssignableTypeInAppDomainAssembly(
|
||||
// typeof(float),
|
||||
// typeof(string),
|
||||
// typeof(bool),
|
||||
// typeof(Enum),
|
||||
// typeof(int)
|
||||
// ).Select(a => a.FullName))
|
||||
// {
|
||||
// _assemblyValueTypeName.Add(typeName);
|
||||
// }
|
||||
|
||||
_assemblyValueTypeName.AddRange(AllValueType.Select(a => new ValueDropdownItem<string>(a.Name, a.FullName)));
|
||||
return _assemblyValueTypeName;
|
||||
}
|
||||
}
|
||||
private static ValueDropdownList<string> _assemblyValueTypeName = null;
|
||||
|
||||
/// <summary>
|
||||
/// 直接定义所有需要检查的类型
|
||||
/// </summary>
|
||||
public static IEnumerable<Type> AllValueType
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return typeof(Enum);
|
||||
yield return typeof(decimal);
|
||||
yield return typeof(double);
|
||||
yield return typeof(float);
|
||||
yield return typeof(ulong);
|
||||
yield return typeof(long);
|
||||
yield return typeof(int);
|
||||
yield return typeof(uint);
|
||||
yield return typeof(short);
|
||||
yield return typeof(ushort);
|
||||
yield return typeof(byte);
|
||||
yield return typeof(sbyte);
|
||||
yield return typeof(string);
|
||||
yield return typeof(char);
|
||||
yield return typeof(bool);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be0acbdac8e549578dcccf8c076a5433
|
||||
timeCreated: 1776998687
|
||||
@@ -1,7 +1,78 @@
|
||||
namespace XericUI.ReflectionUIGenerator
|
||||
using System;
|
||||
|
||||
namespace XericUI.ReflectionUIGenerator
|
||||
{
|
||||
public class XuiavrgAttribute
|
||||
/// <summary>
|
||||
/// 反射属性标记
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||
public class XuiavrgAttribute : Attribute, IXuiavrgAttribute
|
||||
{
|
||||
|
||||
#region 字段属性
|
||||
|
||||
public readonly string LabelName;
|
||||
public readonly string UIPropertyName;
|
||||
public readonly string UnitLabelName;
|
||||
public readonly bool MustFillIn;
|
||||
public readonly int InspectorOrder;
|
||||
public readonly string GroupName;
|
||||
public readonly string OnTriggerCall;
|
||||
public readonly XuiavrgSize ArgumentSize;
|
||||
|
||||
/// <summary>
|
||||
/// 标记属性
|
||||
/// </summary>
|
||||
/// <param name="labelName">属性显示名称</param>
|
||||
/// <param name="uiPropertyName">属性标记名(对应界面元素名称)</param>
|
||||
/// <param name="unitLabelName">属性显示单位名称</param>
|
||||
/// <param name="mustFillin">是否标记为必填项目</param>
|
||||
/// <param name="inspectorOrder">属性显示顺序</param>
|
||||
/// <param name="groupName">属性组名称(可以是以/&\分割的路径)</param>
|
||||
/// <param name="onTriggerCall">属性附加的动作,调用此内联反射调用的函数</param>
|
||||
/// <param name="size">属性组名称(可以是以/&\分割的路径)</param>
|
||||
public XuiavrgAttribute(string labelName, string uiPropertyName, string unitLabelName, bool mustFillin,
|
||||
int inspectorOrder = 0, string groupName = null, string onTriggerCall = "", XuiavrgSize size = XuiavrgSize.Normal)
|
||||
{
|
||||
LabelName = labelName;
|
||||
UIPropertyName = uiPropertyName;
|
||||
UnitLabelName = unitLabelName;
|
||||
MustFillIn = mustFillin;
|
||||
InspectorOrder = inspectorOrder;
|
||||
GroupName = groupName;
|
||||
OnTriggerCall = onTriggerCall;
|
||||
ArgumentSize = size;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 生成器
|
||||
|
||||
public void BindProperty(XuiavrgInspectorProperty property)
|
||||
{
|
||||
property.labelName = LabelName;
|
||||
property.uiPropertyName = UIPropertyName;
|
||||
property.unitLabelName = UnitLabelName;
|
||||
property.mustFillIn = MustFillIn;
|
||||
property.inspectorOrder = InspectorOrder;
|
||||
property.groupName = GroupName;
|
||||
property.onTriggerCall = OnTriggerCall;
|
||||
property.argumentSize = ArgumentSize;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 属性尺寸
|
||||
/// </summary>
|
||||
public enum XuiavrgSize
|
||||
{
|
||||
None = 0,
|
||||
|
||||
Tiny = 1000 - 2,
|
||||
Small = 1000 - 1,
|
||||
Normal = 1000,
|
||||
Big,
|
||||
Large,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace XericUI.ReflectionUIGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// 隐藏标记
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||
public class XuiavrgHideAttribute : Attribute, IXuiavrgAttribute
|
||||
{
|
||||
public readonly bool Hide;
|
||||
|
||||
/// <summary>
|
||||
/// 标记属性
|
||||
/// </summary>
|
||||
/// <param name="hideInInspector">隐藏属性</param>
|
||||
public XuiavrgHideAttribute(bool hideInInspector = true)
|
||||
{
|
||||
Hide = hideInInspector;
|
||||
}
|
||||
|
||||
public void BindProperty(XuiavrgInspectorProperty property)
|
||||
{
|
||||
property.hideInInspector = Hide;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12f7aecaa5224304b1058ab9dc04a95f
|
||||
timeCreated: 1776995602
|
||||
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Deconstruction.Type.Peculiarity;
|
||||
#if ODIN_INSPECTOR
|
||||
using Sirenix.OdinInspector;
|
||||
#endif
|
||||
using UnityEngine;
|
||||
using UnityEngine.Pool;
|
||||
|
||||
namespace XericUI.ReflectionUIGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// 节点下生成反射属性管理器
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 管理器需要挂载在unity节点中,管理器中指定的属性承载节点将用于生成属性内容。
|
||||
///
|
||||
/// 为了准确生成界面属性,首先需要准备界面属性预制体。
|
||||
/// 在包含界面交互元素的预制体跟目录上挂载 <see cref="XuiavrgLocator"/> 脚本,其将作为组件入口,管理所有的交互组件,必须在脚本中添加所有允许交互的元素。
|
||||
/// (注:如果你没有odin插件,那么组件样式可能会与设计的不一致,请务必确保每个数组中只包含一个组件)
|
||||
///
|
||||
/// 然后在工程中创建 <see cref="XuiavrPropertyScriptableObject"/> 对象,指定对应的数据类型,将刚刚创建的界面预制体拖入,这样就完成了两者的绑定。
|
||||
/// 为了方便管理,再创建一个 <see cref="XuiavrgPropertyGroupScriptableObject"/> 对象,它可以成为一个组,快速管理和切换所需的数据集合。
|
||||
///
|
||||
/// 接下来,在管理器中填入使用的 <see cref="XuiavrgPropertyGroupScriptableObject"/> 对象,然后调用 SchemaHydration 方法传入负载,界面顷刻生成。
|
||||
///
|
||||
/// </remarks>
|
||||
public class XuiavrgInspectorManager : MonoBehaviour
|
||||
{
|
||||
public static Func<XuiavrgInspectorProperty> CreatInspectorProperty = () => new XuiavrgInspectorProperty();
|
||||
public static Action<XuiavrgInspectorProperty> GetInspectorProperty = a => {};
|
||||
public static Action<XuiavrgInspectorProperty> ReleaseInspectorProperty = a => a.Clear();
|
||||
public static Action<XuiavrgInspectorProperty> DestoryInspectorProperty = a => {};
|
||||
public static ObjectPool<XuiavrgInspectorProperty> InspectorPropertyPool
|
||||
= new ObjectPool<XuiavrgInspectorProperty>(CreatInspectorProperty, GetInspectorProperty, ReleaseInspectorProperty, DestoryInspectorProperty);
|
||||
|
||||
#if ODIN_INSPECTOR
|
||||
[LabelText("预制体组")]
|
||||
#endif
|
||||
public XuiavrgPropertyGroupScriptableObject propertyUIPrefabsGroup;
|
||||
#if ODIN_INSPECTOR
|
||||
[LabelText("反射属性预览")]
|
||||
#endif
|
||||
public List<XuiavrgInspectorProperty> allProperty = new List<XuiavrgInspectorProperty>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 装填数据负载
|
||||
/// </summary>
|
||||
/// <param name="payload">数据端对象</param>
|
||||
#if ODIN_INSPECTOR
|
||||
[Button]
|
||||
#endif
|
||||
public void SchemaHydration(object payload)
|
||||
{
|
||||
// 清空环境和界面
|
||||
allProperty.Clear();
|
||||
InspectorPropertyPool.Clear();
|
||||
|
||||
if (!propertyUIPrefabsGroup)
|
||||
{
|
||||
Debug.LogError("未指定编组,无法生成界面");
|
||||
return;
|
||||
}
|
||||
|
||||
if (payload != null)
|
||||
{
|
||||
Debug.LogError("未指定有效负载,无法生成界面");
|
||||
return;
|
||||
}
|
||||
|
||||
// 从反射构建
|
||||
var type = payload.GetType();
|
||||
SchemaHydration(allProperty, type, payload);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 状态数据负载
|
||||
/// </summary>
|
||||
/// <param name="properties">反射属性结合</param>
|
||||
/// <param name="payload">负载实例</param>
|
||||
/// <typeparam name="T">进行检查的负载类型</typeparam>
|
||||
private static void SchemaHydration<T>(List<XuiavrgInspectorProperty> properties, object payload)
|
||||
=> SchemaHydration(properties, typeof(T), payload);
|
||||
|
||||
/// <summary>
|
||||
/// 装填数据负载
|
||||
/// </summary>
|
||||
/// <param name="properties">反射属性集合</param>
|
||||
/// <param name="payloadType">进行检查的负载类型</param>
|
||||
/// <param name="payload">负载实例</param>
|
||||
private static void SchemaHydration(List<XuiavrgInspectorProperty> properties, Type payloadType, object payload)
|
||||
{
|
||||
bool needSort = false;
|
||||
foreach (var memberInfo in payloadType.GetRuntimeMemberInfo())
|
||||
{
|
||||
var mw = InspectorPropertyPool.Get();
|
||||
// 绑定负载
|
||||
mw.RegsiterDataValue(memberInfo, payload);
|
||||
// 字段属性上的所有特性都进行标记
|
||||
foreach (var memberAttribute in memberInfo.GetCustomAttributes()
|
||||
.OfType<IXuiavrgAttribute>())
|
||||
{
|
||||
memberAttribute.BindProperty(mw);
|
||||
needSort |= mw.inspectorOrder != 0; // 如果有成员使用了order
|
||||
}
|
||||
properties.Add(mw);
|
||||
}
|
||||
// 排序
|
||||
if (needSort)
|
||||
properties.Sort((property1, property2) => property1.inspectorOrder.CompareTo(property2.inspectorOrder));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace XericUI.ReflectionUIGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// 反射属性中间层
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class XuiavrgInspectorProperty
|
||||
{
|
||||
public object valueTarget;
|
||||
public bool isProperty;
|
||||
public PropertyInfo propertyInfo;
|
||||
public FieldInfo fieldInfo;
|
||||
|
||||
public string labelName;
|
||||
public string uiPropertyName;
|
||||
public string unitLabelName;
|
||||
public bool mustFillIn;
|
||||
public int inspectorOrder;
|
||||
public string groupName;
|
||||
public string onTriggerCall;
|
||||
public XuiavrgSize argumentSize;
|
||||
public bool hideInInspector;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 绑定到数据端
|
||||
/// </summary>
|
||||
/// <param name="memberInfo"></param>
|
||||
/// <param name="target"></param>
|
||||
public void RegsiterDataValue(MemberInfo memberInfo, object target)
|
||||
{
|
||||
switch (memberInfo)
|
||||
{
|
||||
case PropertyInfo propertyInfo:
|
||||
RegsiterDataValue(propertyInfo, target);
|
||||
break;
|
||||
case FieldInfo fieldInfo:
|
||||
RegsiterDataValue(fieldInfo, target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定到数据端
|
||||
/// </summary>
|
||||
/// <param name="memberInfo"></param>
|
||||
/// <param name="target"></param>
|
||||
public virtual void RegsiterDataValue(PropertyInfo memberInfo, object target)
|
||||
{
|
||||
valueTarget = target;
|
||||
isProperty = true;
|
||||
propertyInfo = memberInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定到数据端
|
||||
/// </summary>
|
||||
/// <param name="memberInfo"></param>
|
||||
/// <param name="target"></param>
|
||||
public virtual void RegsiterDataValue(FieldInfo memberInfo, object target)
|
||||
{
|
||||
valueTarget = target;
|
||||
isProperty = false;
|
||||
fieldInfo = memberInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定到界面端
|
||||
/// </summary>
|
||||
public virtual void RegsiterUIElement()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 数据端值发生变更
|
||||
/// </summary>
|
||||
public void CallDataValueChange()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 界面端数据发生变更
|
||||
/// </summary>
|
||||
public void CallUIValueChange()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从数据端获取值
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public object GetValueFromTargetMember()
|
||||
{
|
||||
if (isProperty)
|
||||
return propertyInfo.GetValue(valueTarget);
|
||||
else
|
||||
return fieldInfo.GetValue(valueTarget);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置值到数据端
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetValueToTargetMember(object value)
|
||||
{
|
||||
if (isProperty)
|
||||
propertyInfo.SetValue(valueTarget, value);
|
||||
else
|
||||
fieldInfo.SetValue(valueTarget, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从界面端获取值
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public object GetValueFormUIElement()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置值到界面端
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetValueToUIElement(object value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d82ae110adb48b397c09939694cc3b2
|
||||
timeCreated: 1777011022
|
||||
@@ -0,0 +1,305 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace XericUI.ReflectionUIGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// ui反射属性定位器,放在UI对象的根节点上,设定好接下来的目标即可
|
||||
/// </summary>
|
||||
public class XuiavrgLocator : MonoBehaviour
|
||||
{
|
||||
public delegate void AnyTrigger(LocatorProperty locator, object value, int selectStart, int selectEnd);
|
||||
|
||||
#if ODIN_INSPECTOR
|
||||
[LabelText("映射组件")]
|
||||
#endif
|
||||
public List<LocatorProperty> Properties;
|
||||
|
||||
[Serializable]
|
||||
public class LocatorProperty
|
||||
{
|
||||
#if ODIN_INSPECTOR
|
||||
[LabelText("组件标识名")]
|
||||
#endif
|
||||
[Tooltip("建议使用 name, label, unit, sign, input, output, button, slider, edit, select 等简单易懂的名称进行标记")]
|
||||
public string propertyName;
|
||||
#if ODIN_INSPECTOR
|
||||
[LabelText("组件类型")]
|
||||
#endif
|
||||
public UIElementClassify classify;
|
||||
#if dUI_TextMeshPro
|
||||
#if ODIN_INSPECTOR
|
||||
[ShowIf("classify", UIElementClassify.TMPText)]
|
||||
#endif
|
||||
public TMPro.TMP_Text TMPText;
|
||||
#if ODIN_INSPECTOR
|
||||
[ShowIf("classify", UIElementClassify.TMPInputField)]
|
||||
#endif
|
||||
public TMPro.TMP_InputField TMPInputField;
|
||||
#endif
|
||||
#if ODIN_INSPECTOR
|
||||
[ShowIf("classify", UIElementClassify.UIText)]
|
||||
#endif
|
||||
public UnityEngine.UI.Text UIText;
|
||||
#if ODIN_INSPECTOR
|
||||
[ShowIf("classify", UIElementClassify.UIInputField)]
|
||||
#endif
|
||||
public UnityEngine.UI.InputField UIInputField;
|
||||
#if ODIN_INSPECTOR
|
||||
[ShowIf("classify", UIElementClassify.UIToggle)]
|
||||
#endif
|
||||
public UnityEngine.UI.Toggle UIToggle;
|
||||
#if ODIN_INSPECTOR
|
||||
[ShowIf("classify", UIElementClassify.UIButton)]
|
||||
#endif
|
||||
public UnityEngine.UI.Button UIButton;
|
||||
#if ODIN_INSPECTOR
|
||||
[ShowIf("classify", UIElementClassify.UISlider)]
|
||||
#endif
|
||||
public UnityEngine.UI.Slider UISlider;
|
||||
#if ODIN_INSPECTOR
|
||||
[ShowIf("classify", UIElementClassify.UIDropdown)]
|
||||
#endif
|
||||
public UnityEngine.UI.Dropdown UIDropdown;
|
||||
|
||||
#if ODIN_INSPECTOR
|
||||
[ShowIf("classify", UIElementClassify.TMPInputField)]
|
||||
#endif
|
||||
public TMPInputTriggerEvent TMPInputTriggerOnEventType;
|
||||
#if ODIN_INSPECTOR
|
||||
[ShowIf("classify", UIElementClassify.UIInputField)]
|
||||
#endif
|
||||
public UIInputTriggerEvent UIInputTriggerOnEventType;
|
||||
|
||||
/// <summary>
|
||||
/// 支持的组件类型
|
||||
/// </summary>
|
||||
public enum UIElementClassify
|
||||
{
|
||||
None,
|
||||
#if dUI_TextMeshPro
|
||||
TMPText,
|
||||
TMPInputField,
|
||||
#endif
|
||||
UIText,
|
||||
UIInputField,
|
||||
UIToggle,
|
||||
UIButton,
|
||||
UISlider,
|
||||
UIDropdown,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum TMPInputTriggerEvent
|
||||
{
|
||||
none,
|
||||
onEndEdit = 1 << 1,
|
||||
onSubmit = 1 << 2,
|
||||
onSelect = 1 << 3,
|
||||
onDeselect = 1 << 4,
|
||||
onTextSelection = 1 << 5,
|
||||
onEndTextSelection = 1 << 6,
|
||||
onValueChanged = 1 << 7,
|
||||
onTouchScreenKeyboardStatusChanged = 1 << 8,
|
||||
}
|
||||
|
||||
public enum UIInputTriggerEvent
|
||||
{
|
||||
none,
|
||||
onEndEdit,
|
||||
onSubmit,
|
||||
onValueChanged,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取值
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||
public object GetValue()
|
||||
{
|
||||
switch (classify)
|
||||
{
|
||||
#if dUI_TextMeshPro
|
||||
case UIElementClassify.TMPText:
|
||||
return TMPText.text;
|
||||
case UIElementClassify.TMPInputField:
|
||||
return TMPInputField.text;
|
||||
#endif
|
||||
case UIElementClassify.UIText:
|
||||
return UIText.text;
|
||||
case UIElementClassify.UIInputField:
|
||||
return UIInputField.text;
|
||||
case UIElementClassify.UIToggle:
|
||||
return UIToggle.isOn;
|
||||
case UIElementClassify.UIButton:
|
||||
return false;
|
||||
case UIElementClassify.UISlider:
|
||||
return UISlider.value;
|
||||
case UIElementClassify.UIDropdown:
|
||||
return UIDropdown.value;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置值
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||
public void SetValue(object value)
|
||||
{
|
||||
switch (classify)
|
||||
{
|
||||
#if dUI_TextMeshPro
|
||||
case UIElementClassify.TMPText:
|
||||
TMPText.text = value.ToString();
|
||||
break;
|
||||
case UIElementClassify.TMPInputField:
|
||||
TMPInputField.text = value.ToString();
|
||||
break;
|
||||
#endif
|
||||
case UIElementClassify.UIText:
|
||||
UIText.text = value.ToString();
|
||||
break;
|
||||
case UIElementClassify.UIInputField:
|
||||
UIInputField.text = value.ToString();
|
||||
break;
|
||||
case UIElementClassify.UIToggle:
|
||||
UIToggle.isOn = Convert.ToBoolean(value);
|
||||
break;
|
||||
case UIElementClassify.UIButton:
|
||||
// UIButton do nothing
|
||||
break;
|
||||
case UIElementClassify.UISlider:
|
||||
UISlider.value = Convert.ToSingle(value);
|
||||
break;
|
||||
case UIElementClassify.UIDropdown:
|
||||
UIDropdown.value = Convert.ToInt32(value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ui触发事件
|
||||
/// </summary>
|
||||
public event AnyTrigger OnUITrigger
|
||||
{
|
||||
add
|
||||
{
|
||||
switch (classify)
|
||||
{
|
||||
#if dUI_TextMeshPro
|
||||
case UIElementClassify.TMPInputField:
|
||||
switch (TMPInputTriggerOnEventType)
|
||||
{
|
||||
case TMPInputTriggerEvent.onEndEdit:
|
||||
TMPInputField.onEndEdit.AddListener(a => value?.Invoke(this, a, 0, 0));
|
||||
break;
|
||||
case TMPInputTriggerEvent.onSubmit:
|
||||
TMPInputField.onSubmit.AddListener(a => value?.Invoke(this, a, 0, 0));
|
||||
break;
|
||||
case TMPInputTriggerEvent.onSelect:
|
||||
TMPInputField.onSelect.AddListener(a => value?.Invoke(this, a, 0, 0));
|
||||
break;
|
||||
case TMPInputTriggerEvent.onDeselect:
|
||||
TMPInputField.onDeselect.AddListener(a => value?.Invoke(this, a, 0, 0));
|
||||
break;
|
||||
case TMPInputTriggerEvent.onTextSelection:
|
||||
TMPInputField.onTextSelection.AddListener((content, start, end) =>
|
||||
value?.Invoke(this, content, start, end));
|
||||
break;
|
||||
case TMPInputTriggerEvent.onEndTextSelection:
|
||||
TMPInputField.onEndTextSelection.AddListener((content, start, end) =>
|
||||
value?.Invoke(this, content, start, end));
|
||||
break;
|
||||
case TMPInputTriggerEvent.onValueChanged:
|
||||
TMPInputField.onValueChanged.AddListener(a => value?.Invoke(this, a, 0, 0));
|
||||
break;
|
||||
case TMPInputTriggerEvent.onTouchScreenKeyboardStatusChanged:
|
||||
TMPInputField.onTouchScreenKeyboardStatusChanged.AddListener(a =>
|
||||
value?.Invoke(this, a, 0, 0));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
#endif
|
||||
case UIElementClassify.UIInputField:
|
||||
switch (UIInputTriggerOnEventType)
|
||||
{
|
||||
case UIInputTriggerEvent.onEndEdit:
|
||||
UIInputField.onEndEdit.AddListener(a => value?.Invoke(this, a, 0, 0));
|
||||
break;
|
||||
case UIInputTriggerEvent.onSubmit:
|
||||
UIInputField.onSubmit.AddListener(a => value?.Invoke(this, a, 0, 0));
|
||||
break;
|
||||
case UIInputTriggerEvent.onValueChanged:
|
||||
UIInputField.onValueChanged.AddListener(a => value?.Invoke(this, a, 0, 0));
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
break;
|
||||
case UIElementClassify.UIToggle:
|
||||
UIToggle.onValueChanged.AddListener(a => value?.Invoke(this, value, 0, 0));
|
||||
break;
|
||||
case UIElementClassify.UIButton:
|
||||
UIButton.onClick.AddListener(() => value?.Invoke(this, true, 0, 0));
|
||||
break;
|
||||
case UIElementClassify.UISlider:
|
||||
UISlider.onValueChanged.AddListener(a => value?.Invoke(this, a, 0, 0));
|
||||
break;
|
||||
case UIElementClassify.UIDropdown:
|
||||
UIDropdown.onValueChanged.AddListener(a => value?.Invoke(this, a, 0, 0));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
remove { Debug.Log("任意触发器无法卸载特定事件"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空ui触发事件
|
||||
/// </summary>
|
||||
public void ClearTriggerEvent()
|
||||
{
|
||||
if (TMPInputField)
|
||||
{
|
||||
TMPInputField.onEndEdit.RemoveAllListeners();
|
||||
TMPInputField.onSubmit.RemoveAllListeners();
|
||||
TMPInputField.onSelect.RemoveAllListeners();
|
||||
TMPInputField.onDeselect.RemoveAllListeners();
|
||||
TMPInputField.onTextSelection.RemoveAllListeners();
|
||||
TMPInputField.onEndTextSelection.RemoveAllListeners();
|
||||
TMPInputField.onValueChanged.RemoveAllListeners();
|
||||
TMPInputField.onTouchScreenKeyboardStatusChanged.RemoveAllListeners();
|
||||
}
|
||||
|
||||
if (UIInputField)
|
||||
{
|
||||
UIInputField.onEndEdit.RemoveAllListeners();
|
||||
UIInputField.onSubmit.RemoveAllListeners();
|
||||
UIInputField.onValueChanged.RemoveAllListeners();
|
||||
}
|
||||
|
||||
UIToggle?.onValueChanged.RemoveAllListeners();
|
||||
UIButton?.onClick.RemoveAllListeners();
|
||||
UISlider?.onValueChanged.RemoveAllListeners();
|
||||
UIDropdown?.onValueChanged.RemoveAllListeners();
|
||||
}
|
||||
}
|
||||
|
||||
// todo 使用名称,类型筛选得到组件
|
||||
// todo 根据名称组建字典树加速查找(或许不用)
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using Deconstruction.Type.Peculiarity;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XericUI.ReflectionUIGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// 节点下生成反射属性管理器
|
||||
/// </summary>
|
||||
public class XuiavrgManager
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 装填数据负载
|
||||
/// </summary>
|
||||
/// <param name="payload"></param>
|
||||
public void PerformSchemaDrivenHydration(object payload)
|
||||
{
|
||||
var type = payload.GetType();
|
||||
|
||||
var attributes = type.GetCustomAttributes(true);
|
||||
foreach (var attribute in attributes)
|
||||
{
|
||||
if (attribute is not XuiavrgAttribute xuiavrgAttribute)
|
||||
continue;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XericUI.ReflectionUIGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// ui反射属性定位器,放在池对象的根节点上,设定好接下来的目标即可
|
||||
/// </summary>
|
||||
public class XuiavrgPooledLocator : MonoBehaviour
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XericUI.ReflectionUIGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// 界面属性编组
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[CreateAssetMenu(fileName = "Xeric UI avr Property group", menuName = "Xeric Library/UI Action Vessel/Reflection UI Gen/UI avr Property Group", order = 10)]
|
||||
public class XuiavrgPropertyGroupScriptableObject : ScriptableObject, IList<XuiavrPropertyScriptableObject>
|
||||
{
|
||||
public List<XuiavrPropertyScriptableObject> propertys = new List<XuiavrPropertyScriptableObject>();
|
||||
|
||||
public IEnumerator<XuiavrPropertyScriptableObject> GetEnumerator()
|
||||
{
|
||||
return propertys.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable)propertys).GetEnumerator();
|
||||
}
|
||||
|
||||
public void Add(XuiavrPropertyScriptableObject item)
|
||||
{
|
||||
propertys.Add(item);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
propertys.Clear();
|
||||
}
|
||||
|
||||
public bool Contains(XuiavrPropertyScriptableObject item)
|
||||
{
|
||||
return propertys.Contains(item);
|
||||
}
|
||||
|
||||
public void CopyTo(XuiavrPropertyScriptableObject[] array, int arrayIndex)
|
||||
{
|
||||
propertys.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public bool Remove(XuiavrPropertyScriptableObject item)
|
||||
{
|
||||
return propertys.Remove(item);
|
||||
}
|
||||
|
||||
public int Count => propertys.Count;
|
||||
|
||||
public bool IsReadOnly => true;
|
||||
|
||||
public int IndexOf(XuiavrPropertyScriptableObject item)
|
||||
{
|
||||
return propertys.IndexOf(item);
|
||||
}
|
||||
|
||||
public void Insert(int index, XuiavrPropertyScriptableObject item)
|
||||
{
|
||||
propertys.Insert(index, item);
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
propertys.RemoveAt(index);
|
||||
}
|
||||
|
||||
public XuiavrPropertyScriptableObject this[int index]
|
||||
{
|
||||
get => propertys[index];
|
||||
set => propertys[index] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bcd1c64483d2457ab9143f086dff511d
|
||||
timeCreated: 1777024131
|
||||
@@ -1,7 +1,22 @@
|
||||
namespace XericUI.ReflectionUIGenerator
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace XericUI.ReflectionUIGenerator
|
||||
{
|
||||
public static class XuiavrgUtilities
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有运行时成员(字段和属性)
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<MemberInfo> GetRuntimeMemberInfo(this Type type)
|
||||
{
|
||||
foreach (var field in type.GetRuntimeFields())
|
||||
yield return field;
|
||||
foreach (var property in type.GetRuntimeProperties())
|
||||
yield return property;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user