Editor/Sprite/SpriteResource/SpriteInspector.cs
using Editor;
using Editor.Assets;
using Sandbox;
using System;
using System.Collections.Generic;
using System.Linq;
using static Editor.Inspectors.AssetInspector;
namespace SpriteTools;
[CanEdit( "asset:spr" )]
public class SpriteInspector : Widget, IAssetInspector
{
private SpriteResource Sprite;
private AssetPreview AssetPreview;
private readonly ExpandGroup AnimationGroup;
private readonly AnimationList Animations;
public SpriteInspector ( Widget parent ) : base( parent )
{
Layout = Layout.Column();
Layout.Margin = 4;
Layout.Spacing = 4;
AnimationGroup = new ExpandGroup( this );
AnimationGroup.StateCookieName = $"{nameof( SpriteInspector )}.{nameof( AnimationGroup )}";
AnimationGroup.Icon = "directions_run";
AnimationGroup.Title = $"Animations";
AnimationGroup.Visible = false;
Layout.Add( AnimationGroup );
Animations = new AnimationList( AnimationGroup );
Animations.ItemSelected = PlayAnimation;
AnimationGroup.SetWidget( Animations );
}
private void PlayAnimation ( string name )
{
if ( AssetPreview is null )
return;
if ( AssetPreview is PreviewSprite preview )
{
preview.SetAnimation( name );
}
}
public void SetAssetPreview ( AssetPreview preview )
{
AssetPreview = preview;
}
public void SetAsset ( Asset asset )
{
Sprite = asset.LoadResource<SpriteResource>();
if ( Sprite == null ) return;
if ( Sprite.Animations.Count > 0 )
{
AnimationGroup.Visible = true;
Animations.SetSprite( Sprite );
}
AnimationGroup.Update();
}
private class AnimationList : ItemList
{
public override string ItemName => "Animation";
public override string ItemIcon => "animgraph_editor/single_frame_icon.png";
public AnimationList ( Widget parent ) : base( parent )
{
}
public override void SetSprite ( SpriteResource sprite )
{
Items = Enumerable.Range( 0, sprite.Animations.Count )
.Select( x => sprite.Animations[x].Name )
.OrderBy( x => x )
.ToList();
ListView.SetItems( Items );
}
}
private abstract class ItemList : Widget
{
protected readonly ListView ListView;
protected List<string> Items;
public abstract string ItemName { get; }
public abstract string ItemIcon { get; }
public Action<string> ItemSelected { get; set; }
public abstract void SetSprite ( SpriteResource model );
public ItemList ( Widget parent ) : base( parent )
{
Layout = Layout.Column();
Layout.Margin = 4;
Layout.Spacing = 4;
ListView = new ListView( this )
{
ItemSize = new Vector2( 0, 25 ),
Margin = new( 4, 4, 16, 4 ),
ItemPaint = PaintAnimationItem,
ItemContextMenu = ShowItemContext,
ToggleSelect = true,
ItemSelected = ( o ) => ItemSelected?.Invoke( o as string ),
ItemDeselected = ( o ) => ItemSelected?.Invoke( null ),
};
var filter = new LineEdit( this )
{
PlaceholderText = $"Filter {ItemName}s..",
FixedHeight = 25
};
filter.TextEdited += ( t ) =>
{
ListView.SetItems( Items == null || Items.Count == 0 ? null : string.IsNullOrWhiteSpace( t ) ? Items :
Items.Where( x => x.Contains( t, StringComparison.OrdinalIgnoreCase ) ) );
};
Layout.Add( filter );
Layout.Add( ListView, 1 );
}
private void ShowItemContext ( object obj )
{
if ( obj is not string name ) return;
var m = new Menu();
m.AddOption( "Copy", "content_copy", () =>
{
EditorUtility.Clipboard.Copy( name );
} );
m.OpenAt( Editor.Application.CursorPosition );
}
private void PaintAnimationItem ( VirtualWidget v )
{
if ( v.Object is not string name )
return;
var rect = v.Rect;
Paint.Antialiasing = true;
var fg = Theme.Text.Darken( 0.2f );
if ( Paint.HasSelected )
{
fg = Theme.Text;
Paint.ClearPen();
Paint.SetBrush( Theme.Primary.WithAlpha( 0.5f ) );
Paint.DrawRect( rect, 2 );
Paint.SetBrush( Theme.Primary.WithAlpha( 0.4f ) );
}
else if ( Paint.HasMouseOver )
{
Paint.ClearPen();
Paint.SetBrush( Theme.Primary.WithAlpha( 0.25f ) );
Paint.DrawRect( rect, 2 );
}
var iconRect = rect.Shrink( 8, 4 );
iconRect.Width = iconRect.Height;
Paint.Draw( iconRect, ItemIcon );
var textRect = rect.Shrink( 4 );
textRect.Left = iconRect.Right + 8;
Paint.SetDefaultFont();
Paint.SetPen( fg );
Paint.DrawText( textRect, $"{name}", TextFlag.LeftCenter );
}
}
}