Code/UI/PanelAttribute.cs
namespace Nodebox.UI;
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class PanelAttribute : Attribute {
public Type Type { get; set; }
public PanelAttribute(Type type) {
Assert.True(type.IsAssignableTo(typeof(NodePanel)), $"{type} doesn't inherit {nameof(NodePanel)}");
Type = type;
}
public static NodePanel CreatePanelFor(Node node) => CreatePanelFor(node.GetType());
public static NodePanel CreatePanelFor(Type nodeType) {
Assert.NotNull(nodeType);
var typeDescription = TypeLibrary.GetType(FindPanelFor(nodeType));
if (!typeDescription.IsGenericType) {
return typeDescription.Create<NodePanel>();
}
var typeArgs = new Type[typeDescription.GenericArguments.Length];
Array.Fill(typeArgs, typeof(object));
Type[] nodeTypeArgs = [];
if (TypeLibrary.GetType(nodeType).IsGenericType) {
nodeTypeArgs = TypeLibrary.GetGenericArguments(nodeType);
}
foreach (var (index, arg) in nodeTypeArgs.Enumerate()) {
if (index >= typeArgs.Length) { break; }
typeArgs[index] = arg;
}
return typeDescription.CreateGeneric<NodePanel>(typeArgs, []);
}
public static Type FindPanelFor(Node node) => FindPanelFor(node?.GetType());
public static Type FindPanelFor(Type nodeType) {
Assert.NotNull(nodeType);
// Assert.True(nodeType.IsAssignableTo(typeof(Node)), $"{nodeType} doesn't inherit {nameof(Node)}");
var genericDefNodeType = TypeLibrary.GetType(nodeType).TargetType;
var panelAttribute = TypeLibrary.GetAttributes<PanelAttribute>(genericDefNodeType)?.FirstOrDefault();
if (panelAttribute == null) {
// Log.Info($"{nodeType} --Panel-> {typeof(Basic)}");
return typeof(Basic);
}
// Log.Info($"{nodeType} --Panel-> {panelAttribute.Type}");
return panelAttribute.Type;
}
public static Type FindPanelFor<T>() => FindPanelFor(typeof(T));
}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class PanelAttribute<T>() : PanelAttribute(typeof(T)) { }