Editor/Sprite/SpriteResource/SpriteResourceMenu.cs
using Editor;
using Sandbox;
using System.Collections.Generic;
using System.Linq;
namespace SpriteTools;
internal static class SpriteResourceMenu
{
static SpriteImportSettings ImportSettings;
[Event( "asset.contextmenu", Priority = 50 )]
public static void OnSpriteResourceAssetContext ( AssetContextMenu e )
{
// Are all the files we have selected image assets?
if ( !e.SelectedList.All( x => x.TypeName == AssetType.ImageFile.FriendlyName ) )
return;
e.Menu.AddOption( $"Create 2D Sprite", "emoji_emotions", action: () => CreateSpriteResourceUsingImageFiles( e.SelectedList ) );
if ( e.SelectedList.Count > 1 )
{
e.Menu.AddOption( $"Create {e.SelectedList.Count} 2D Sprites", "emoji_emotions", action: () => CreateSpriteResourcesPopup( e.SelectedList ) );
}
}
private static async void CreateSpriteResourceUsingImageFiles ( IEnumerable<AssetEntry> assets )
{
var asset = assets.First().Asset;
var assetName = asset.Name;
var fd = new FileDialog( null );
fd.Title = "Create Sprite Resource from Image Files..";
fd.Directory = System.IO.Path.GetDirectoryName( asset.AbsolutePath );
fd.DefaultSuffix = ".sprite";
fd.SelectFile( $"{assetName}.sprite" );
fd.SetFindFile();
fd.SetModeSave();
fd.SetNameFilter( "2D Sprite (*.sprite)" );
if ( !fd.Execute() )
return;
var paths = assets.Select( x => System.IO.Path.ChangeExtension( x.Asset.Path, System.IO.Path.GetExtension( x.Asset.AbsolutePath ) ) );
asset = AssetSystem.CreateResource( "spr", fd.SelectedFile );
await asset.CompileIfNeededAsync();
var sprite = asset.LoadResource<SpriteResource>();
var anim = sprite.Animations.FirstOrDefault();
anim.Name = "default";
anim.Frames ??= new();
anim.Frames.Clear();
foreach ( var path in paths )
{
var frame = new SpriteAnimationFrame( path );
anim.Frames.Add( frame );
}
anim.LoopMode = SpriteResource.LoopMode.Forward;
asset.SaveToDisk( sprite );
MainAssetBrowser.Instance?.Local?.UpdateAssetList();
MainAssetBrowser.Instance?.Local?.FocusOnAsset( asset );
EditorUtility.InspectorObject = asset;
}
private static async void CreateSpriteResourcesUsingImageFiles ( IEnumerable<AssetEntry> assets )
{
foreach ( var entry in assets )
{
var asset = entry.Asset;
var newAsset = AssetSystem.CreateResource( "spr", System.IO.Path.ChangeExtension( asset.AbsolutePath, ".sprite" ) );
await newAsset.CompileIfNeededAsync();
var sprite = newAsset.LoadResource<SpriteResource>();
var anim = sprite.Animations.FirstOrDefault();
anim.Name = ImportSettings.AnimationName;
anim.Origin = ImportSettings.Origin;
anim.Frames ??= new();
anim.Frames.Clear();
var frame = new SpriteAnimationFrame( System.IO.Path.ChangeExtension( asset.Path, System.IO.Path.GetExtension( asset.AbsolutePath ) ) );
anim.Frames.Add( frame );
anim.LoopMode = SpriteResource.LoopMode.Forward;
newAsset.SaveToDisk( sprite );
}
MainAssetBrowser.Instance?.Local?.UpdateAssetList();
}
private static void CreateSpriteResourcesPopup ( IEnumerable<AssetEntry> assets )
{
ImportSettings = new();
var popup = new Dialog();
popup.Window.MinimumWidth = 500;
popup.Window.Height = 200;
popup.WindowTitle = "Create Sprite Resources from Image Files...";
popup.Window.SetWindowIcon( "info" );
popup.Window.SetModal( true, true );
popup.Layout = Layout.Column();
popup.Layout.Margin = 20;
popup.Layout.Spacing = 20;
popup.Layout.Add( new Label( "Set import settings for each sprite", popup ) );
var controlSheet = new ControlSheet();
controlSheet.AddProperty( ImportSettings, x => x.AnimationName );
controlSheet.AddProperty( ImportSettings, x => x.Origin );
popup.Layout.Add( controlSheet );
popup.Layout.AddStretchCell();
var okButton = new Button.Primary( "Import", popup );
okButton.Icon = "download";
okButton.MinimumWidth = 64;
okButton.MouseLeftPress += () =>
{
CreateSpriteResourcesUsingImageFiles( assets );
popup.Close();
};
var cancelButton = new Button( "Cancel", popup );
cancelButton.MinimumWidth = 64;
cancelButton.MouseLeftPress += () => popup.Close();
var buttonLayout = Layout.Row();
buttonLayout.Spacing = 5;
popup.Layout.Add( buttonLayout );
buttonLayout.AddStretchCell();
buttonLayout.Add( okButton );
buttonLayout.Add( cancelButton );
popup.Show();
}
public class SpriteImportSettings
{
public string AnimationName { get; set; } = "default";
public Vector2 Origin { get; set; } = Vector2.One * 0.5f;
}
}