Editor/TrimmedAssetInspector.cs
using System;
using Editor.Assets;
using System.IO;
using System.Linq;
using System.Text.Json.Serialization;
using Editor;
using Editor.Inspectors;
using Sandbox;
using FileSystem = Sandbox.FileSystem;
namespace ResourceEmbed.Editor;
public class TrimmedAssetInspector : Widget
{
const float HeaderHeight = 64 + 8 + 8;
public Asset Asset { get; set; }
public Asset[] Assets { get; set; }
ToolBar ToolBar;
Option SaveOption;
Widget Scroller;
Layout ContentLayout;
public TrimmedAssetInspector( SerializedObject so )
{
Asset = so.Targets.Cast<Asset>().First();
Assets = so.Targets.Cast<Asset>().ToArray();
SetContext( "asset", Asset );
SetContext( "path", Asset.AbsolutePath );
SetContext( "filename", System.IO.Path.GetFileName( Asset.AbsolutePath ) );
SetContext( "folder", System.IO.Path.GetDirectoryName( Asset.AbsolutePath ) );
Layout = Layout.Column();
SetSizeMode( SizeMode.CanGrow, SizeMode.CanGrow );
ToolBar = new ToolBar( this );
ToolBar.SetIconSize( 23 );
ToolBar.MaximumSize = new Vector2( Width, 26 );
ToolBar.Size = new Vector2( Width, 26 );
var Splitter = new Splitter( this );
Splitter.IsVertical = true;
Layout.Add(ToolBar);
Layout.Add( Splitter, 1 );
var mainWidget = new Widget( this );
mainWidget.Layout = Layout.Column();
if ( !so.IsMultipleTargets )
{
ToolBar.AddOption( new Option( "Open In Editor", "edit", () => Asset.OpenInEditor() ) );
ToolBar.AddOption( new Option( "Open Asset Location", "folder", () => EditorUtility.OpenFileFolder( Asset.AbsolutePath ) ) );
ToolBar.AddSeparator();
}
ToolBar.AddOption( new Option( "Full Recompile", "restart_alt", () => Asset.Compile( true ) ) );
Scroller = new Widget( this );
Scroller.Layout = Layout.Column();
mainWidget.Layout.Add( Scroller );
RebuildUI();
Scroller.Layout.AddStretchCell();
Splitter.AddWidget( mainWidget );
Enabled = true;
}
[EditorEvent.Hotload]
public void RebuildUI()
{
CreateContentUI( Asset );
}
private void CreateContentLayout()
{
if ( !(ContentLayout?.IsValid ?? false) )
{
ContentLayout = Layout.Column();
Scroller.Layout.Add( ContentLayout );
Scroller.Layout.AddStretchCell();
}
else
{
ContentLayout?.Clear( true );
}
}
private void CreateSaveOption( Action saveAction )
{
if ( !(SaveOption?.IsValid ?? false) )
{
var option = new Option( "Save", "save", saveAction );
option.ShortcutName = "editor.save";
option.Enabled = false;
ToolBar.AddOption( option );
SaveOption = option;
}
}
private void CreateContentUI( Asset target )
{
CreateContentLayout();
if ( target.TryLoadResource<GameResource>( out var assetObject ) )
{
Action saveAction = () => SaveAsset( target, assetObject );
var sheet = new ControlSheet();
var so = assetObject.GetSerialized();
so.OnPropertyChanged += x =>
{
if ( SaveOption.IsValid ) SaveOption.Enabled = true;
};
if ( AssetSystem.IsCloudInstalled( target.Package ) )
{
// todo so = so.AsReadOnly();
}
sheet.AddObject( so, filter: FilterProperties );
ContentLayout.Add( sheet );
ContentLayout.AddStretchCell();
CreateSaveOption( saveAction );
}
ContentLayout.AddStretchCell();
Scroller?.Update();
}
bool FilterProperties( SerializedProperty prop )
{
// only show stuff that'll actually be serialised
if ( !prop.IsProperty ) return false;
if ( prop.HasAttribute<JsonIgnoreAttribute>() ) return false;
return prop.IsPublic || prop.HasAttribute<JsonIncludeAttribute>();
}
protected void Save()
{
if ( !SaveOption.IsValid() )
return;
if ( !SaveOption.Enabled )
return;
SaveOption.Triggered?.Invoke();
}
public void SaveAsset( Asset target, Sandbox.GameResource assetObject )
{
if ( target.SaveToDisk( assetObject ) )
{
SaveOption.Enabled = false;
}
}
protected override void OnMouseRightClick( MouseEvent e )
{
if ( e.LocalPosition.y <= HeaderHeight )
{
var m = new ContextMenu();
m.AddOption( "Copy Asset Name", "content_copy", () => EditorUtility.Clipboard.Copy( Asset.Name ) );
m.AddOption( "Copy Path", "file_copy", () => EditorUtility.Clipboard.Copy( Asset.RelativePath ) );
m.OpenAt( e.ScreenPosition );
}
base.OnMouseRightClick( e );
}
}