Editor/ControlWidgetExtensions.cs
using Editor;
using Sandbox;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace ExtendedEditor;
public static class ControlWidgetExtensions // TODO: use one from new editor library
{
extension(ControlWidget controlWidget)
{
public void Skip()
{
if(controlWidget is null)
return;
controlWidget.Layout ??= Layout.Row();
controlWidget.Layout.Clear(true);
controlWidget.Layout.Margin = 0;
controlWidget.Layout.Spacing = 0;
controlWidget.PaintBackground = false;
var newControlWidget = ControlWidget.Create(controlWidget.SerializedProperty, controlWidget.GetType()!);
if(newControlWidget is null)
return;
controlWidget.Layout.Add(newControlWidget);
}
}
extension(ControlWidget)
{
public static Type GetControlWidgetType(SerializedProperty serializedProperty, params IEnumerable<Attribute> attributes)
{
var proxy = serializedProperty.CreateProxy(attributes);
var widget = ControlWidget.Create(proxy);
var type = widget.GetType();
widget.Destroy();
return type;
}
public static ControlWidget? Create(SerializedProperty serializedProperty, params IEnumerable<Type?>? skippingWidgetTypes)
{
var startingSerializedProperty = serializedProperty;
if(skippingWidgetTypes is null || !skippingWidgetTypes.Any())
return ControlWidget.Create(serializedProperty);
ControlWidget? possibleControlWidget = null;
Type? lastControlWidgetType = null;
do
{
var newAttributes = serializedProperty.GetAttributes().ToList();
int removeCountTotal = 0;
foreach(var widgetType in skippingWidgetTypes)
{
if(widgetType is null)
continue;
var customEditorAttributes = widgetType.GetCustomAttributes<CustomEditorAttribute>(false);
foreach(var customEditorAttribute in customEditorAttributes)
{
if(customEditorAttribute.Fits(serializedProperty))
{
if(customEditorAttribute.WithAllAttributes is null)
return null;
removeCountTotal += newAttributes.RemoveAll(x => customEditorAttribute.WithAllAttributes.Contains(x.GetType()));
}
}
}
if(removeCountTotal == 0)
return null;
lastControlWidgetType = possibleControlWidget?.GetType();
possibleControlWidget?.Destroy();
serializedProperty = startingSerializedProperty.CreateProxy(newAttributes);
possibleControlWidget = ControlWidget.Create(serializedProperty);
}
while(possibleControlWidget is not null &&
possibleControlWidget.GetType() != lastControlWidgetType &&
skippingWidgetTypes.Contains(possibleControlWidget.GetType()));
if(possibleControlWidget is not null)
{
var type = possibleControlWidget.GetType();
possibleControlWidget.Destroy();
return EditorTypeLibrary.Create<ControlWidget>(type, [startingSerializedProperty]);
}
return possibleControlWidget;
}
}
private static bool Fits(this CustomEditorAttribute attribute, SerializedProperty serializedProperty)
{
if(attribute.TargetType is not null)
{
if(!attribute.TargetType.IsAssignableFrom(serializedProperty.PropertyType))
return false;
}
if(attribute.WithAllAttributes is not null)
{
foreach(var requiredAttributeType in attribute.WithAllAttributes)
{
if(requiredAttributeType is null)
continue;
if(!serializedProperty.HasAttribute(requiredAttributeType))
return false;
}
}
return true;
}
}