Last active
April 7, 2021 08:12
-
-
Save CoffeeVampir3/bc2f4ab2469eb7d1c47548294db274c2 to your computer and use it in GitHub Desktop.
Unity UITK Auto Drawer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class FieldFactory | |
{ | |
private delegate VisualElement CreationDelegate(Type t, object o); | |
private static readonly Dictionary<Type, CreationDelegate> creationDictionary = | |
new Dictionary<Type, CreationDelegate>(); | |
private static readonly List<Type> creationTypes = new List<Type>(); | |
private static bool initialized = false; | |
private static void Register<T>(CreationDelegate creationAction) | |
{ | |
creationTypes.Add(typeof(T)); | |
creationDictionary.Add(typeof(T), creationAction); | |
} | |
private static void FastRegister<ArgType, FieldType>() | |
where FieldType: BaseField<ArgType>, new() | |
{ | |
Register<ArgType>(ConstructField<ArgType, FieldType>); | |
} | |
private static FieldType ConstructField<ArgType, FieldType>(Type t, object o) | |
where FieldType: BaseField<ArgType>, new() | |
{ | |
var m = new FieldType(); | |
if(o != null) | |
m.SetValueWithoutNotify((ArgType)o); | |
return m; | |
} | |
private static void RegisterAll() | |
{ | |
FastRegister<float, FloatField>(); | |
FastRegister<int, IntegerField>(); | |
FastRegister<string, TextField>(); | |
FastRegister<Vector2, Vector2Field>(); | |
FastRegister<Vector3, Vector3Field>(); | |
FastRegister<Vector4, Vector4Field>(); | |
FastRegister<Vector2Int, Vector2IntField>(); | |
FastRegister<Vector3Int, Vector3IntField>(); | |
FastRegister<Bounds, BoundsField>(); | |
FastRegister<BoundsInt, BoundsIntField>(); | |
FastRegister<Color, ColorField>(); | |
FastRegister<AnimationCurve, CurveField>(); | |
FastRegister<Gradient, GradientField>(); | |
FastRegister<Rect, RectField>(); | |
FastRegister<RectInt, RectIntField>(); | |
FastRegister<bool, Toggle>(); | |
Register<UnityEngine.Object>((t, o) => | |
{ | |
var m = new ObjectField {objectType = t, allowSceneObjects = true}; | |
if (o != null) | |
{ | |
m.SetValueWithoutNotify((UnityEngine.Object) o); | |
} | |
return m; | |
}); | |
Register<Enum>(CreateEnum); | |
} | |
private static VisualElement CreateEnum(Type t, object o) | |
{ | |
if (o == null) | |
return null; | |
var en = (Enum)o; | |
bool isFlags = t.GetCustomAttributes<FlagsAttribute>().Any(); | |
static EnumFlagsField CreateFlagsEnums(Enum someEnum) | |
{ | |
EnumFlagsField ff = new EnumFlagsField(someEnum); | |
return ff; | |
} | |
static PopupField<string> CreateNormalEnumField(Enum someEnum, Type t) | |
{ | |
Array vals = Enum.GetValues(t); | |
List<string> strings = new List<string>(); | |
foreach (var item in vals) | |
{ | |
strings.Add(item.ToString()); | |
} | |
if (strings.Count == 0) | |
return null; | |
PopupField<string> pf = new PopupField<string>(strings, someEnum.ToString()); | |
pf.SetValueWithoutNotify(someEnum.ToString()); | |
return pf; | |
} | |
return isFlags ? CreateFlagsEnums(en) as VisualElement : CreateNormalEnumField(en, t); | |
} | |
private static CreationDelegate CheckIfRegistered(Type t) | |
{ | |
if (!initialized) | |
{ | |
RegisterAll(); | |
initialized = true; | |
} | |
//Check for exact matches | |
if (creationDictionary.TryGetValue(t, out var creationFunc)) | |
return creationFunc; | |
//We found no exact match, our fall back is checking the entire inheritance tree. | |
return (from item | |
in creationTypes | |
where item.IsAssignableFrom(t) | |
select creationDictionary[item]).FirstOrDefault(); | |
} | |
public static VisualElement Create(Type t, object someObject) | |
{ | |
CreationDelegate func = CheckIfRegistered(t); | |
return func?.Invoke(t, someObject); | |
} | |
public static VisualElement Create<T>(object someObject = null) | |
{ | |
CreationDelegate func = CheckIfRegistered(typeof(T)); | |
return func?.Invoke(typeof(T), someObject); | |
} | |
public static VisualElement Create<T>(T someObject) | |
{ | |
CreationDelegate func = CheckIfRegistered(typeof(T)); | |
return func?.Invoke(typeof(T), someObject); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment