Editor/EmededResourceEditorWidget.cs
using System;
using System.Linq;
using System.Reflection;
using Editor;
using Editor.Experimental;
using Editor.Inspectors;
using Sandbox;
using Sandbox.UI;
using Button = Editor.Button;
namespace ResourceEmbed.Editor;
[CustomEditor(typeof(GameResource), WithAllAttributes = new[] { typeof(EmbedAttribute) })]
public class EmbeddedResourceEditorWidget : ControlWidget
{
public override bool SupportsMultiEdit => false;
private Widget resourceProperty;
private IconButton dropDownButton;
private TrimmedAssetInspector inspector;
private Guid GameObjectId;
string ExpandedCookieString => $"embed_expand.{GameObjectId}.{SerializedProperty.Name}";
/// <summary>
/// The user's local preference to having this component expanded or not.
/// </summary>
bool ExpandedCookie
{
get => ProjectCookie.Get( ExpandedCookieString, true );
set
{
// Don't bother storing the cookie if it's an expanded component
if ( value )
{
ProjectCookie.Remove( ExpandedCookieString );
}
else
{
ProjectCookie.Set( ExpandedCookieString, value );
}
}
}
/// <summary>
/// Is this component currently expanded?
/// </summary>
internal bool Expanded { get; set; } = true;
/// <summary>
/// Expands/shrinks the component in the component list.
/// </summary>
/// <param name="expanded"></param>
internal void SetExpanded( bool expanded )
{
if (expanded)
Layout.Margin = new Margin(0, 0, 0, 5);
else
Layout.Margin = new Margin(0, 0, 0, 0);
Expanded = expanded;
RebuildContent();
ExpandedCookie = expanded;
dropDownButton.Icon = expanded ? "arrow_drop_down" : "arrow_left";
}
public EmbeddedResourceEditorWidget(SerializedProperty property) : base(property)
{
GameObjectId = property.Parent.Targets.OfType<Component>().Select( x => x.Id ).Single();
Expanded = ExpandedCookie;
Layout = Layout.Column();
Layout.Spacing = 2;
resourceProperty = CanEditAttribute.CreateEditorFor(property.PropertyType);
resourceProperty.Layout = Layout.Row();
resourceProperty.Layout.Alignment = TextFlag.Right;
Layout.Add( resourceProperty );
resourceProperty.Bind("Value").From(() =>
{
return SerializedProperty.GetValue<Resource>();
},
x =>
{
var oldValue = SerializedProperty.GetValue<Resource>();
SerializedProperty.SetValue(x);
if (x is null || oldValue is null)
{
RebuildContent();
return;
}
if (inspector is not null)
{
inspector.Asset = AssetSystem.FindByPath( x.ResourcePath );
inspector.RebuildUI();
}
});
RebuildContent();
}
private void RebuildContent()
{
dropDownButton?.Destroy();
inspector?.Destroy();
var resource = SerializedProperty.GetValue<Resource>();
if (resource is null)
return;
dropDownButton = new IconButton("expand_more", () => SetExpanded(!Expanded), resourceProperty);
dropDownButton.FixedSize = resourceProperty.MinimumHeight;
dropDownButton.IconSize = resourceProperty.MinimumHeight;
resourceProperty.Layout.Add(dropDownButton);
var asset = AssetSystem.FindByPath(resource.ResourcePath);
inspector = new TrimmedAssetInspector( asset.GetSerialized() );
if (!Expanded)
return;
Layout.Add( inspector );
}
}