Editor/ShaderGraphPlus/ShaderGraphPlusEditorMenus.cs
using Editor;
using MaterialDesign;
using ShaderGraphPlus.Internal;
namespace ShaderGraphPlus;
internal static class ShaderGraphPlusEditorMenus
{
/*
[Menu( "Editor", "Shader Graph Plus/Convert ShaderGraph projects to ShaderGraphPlus projects ( Experimental )" )]
public static void ConvertShaderGraphToShaderGraphPlus()
{
var projectPaths = Directory.GetFiles( $"{Project.Current.GetAssetsPath()}/shaders", "*.shdrgrph", SearchOption.AllDirectories ).ToList();
var subgraphProjectPaths = Directory.GetFiles( $"{Project.Current.GetAssetsPath()}/shaders", "*.shdrfunc", SearchOption.AllDirectories ).ToList();
if ( subgraphProjectPaths != null )
{
projectPaths.AddRange( subgraphProjectPaths );
}
var projectItems = new List<ProjectItem>();
foreach ( var path in projectPaths )
{
//SGPLog.Info( $"project at path \"{path}\"" );
var extention = Path.GetExtension( path );
projectItems.Add( new ProjectItem( path.Replace( '\\', '/' ), extention == ".shdrfunc" ) );
}
ProjectConverterDialog.DisplayDialog( projectItems );
}
*/
/*
[Menu( "Editor", "Shader Graph Plus/Update Subgraphs internal Path String" )]
public static void UpdateSubgraphsInternalPath()
{
var projectPaths = Directory.GetFiles( $"{Project.Current.GetAssetsPath()}/shaders", $"*.{ShaderGraphPlusGlobals.SubgraphAssetTypeExtension}", SearchOption.AllDirectories );
if ( projectPaths.Any() )
{
SGPLog.Info( $"Found \"{projectPaths.Count()}\" subgraphs" );
foreach ( var projectPath in projectPaths )
{
var graph = new ShaderGraphPlus();
var file = System.IO.File.ReadAllText( projectPath );
graph.Deserialize( file );
var asset = AssetSystem.FindByPath( projectPath );
var oldPath = graph.Path;
graph.Path = asset.RelativePath;
graph.IsSubgraph = true;
SGPLog.Info( $"Upgraded project subgraphPath from \"{oldPath}\" to \"{graph.Path}\"" );
System.IO.File.WriteAllText( asset.AbsolutePath, graph.Serialize() );
asset ??= AssetSystem.RegisterFile( asset.AbsolutePath );
}
}
EditorUtility.DisplayDialog( "", $"Updated \"{projectPaths.Count()}\" subgraphs internal path property." );
}
*/
}
file class ProjectConverterDialog : Dialog
{
private ProjectList _projectList;
private Layout ListLayout;
private Layout ButtonLayout;
private Button ConvertButton;
private Button CloseButton;
public Action ConverButtonClick { get; set; }
public ProjectConverterDialog( List<ProjectItem> projectItems ) : base( null, true )
{
Window.FixedWidth = 700f;
Window.MaximumSize = Window.Size;
Window.MinimumSize = Window.Size;
Window.Title = "Convert ShaderGraph To ShaderGraphPlus ( Experimental )";
Window.SetWindowIcon( MaterialIcons.Gradient );
Window.SetModal( true, true );
CreateUI();
SetItems( projectItems );
}
private void CreateUI()
{
Layout = Layout.Column();
Layout.Spacing = 3;
Layout.AddSpacingCell( 8 );
var label = Layout.Add( new Label() );
label.Text = "Projects to convert";
label.Alignment = TextFlag.Center;
ListLayout = Layout.AddColumn();
ListLayout.Add( _projectList = new ProjectList( this ) );
ListLayout.Spacing = 8f;
ListLayout.Margin = 16f;
ButtonLayout = Layout.AddRow();
ButtonLayout.Spacing = 8f;
ButtonLayout.Margin = 16f;
ConvertButton = ButtonLayout.Add( new Button.Primary( "Convert Projects" )
{
Clicked = delegate
{
ConverButtonClick?.Invoke();
ConvertButton.Enabled = false;
}
} );
CloseButton = ButtonLayout.Add( new Button( "Close" )
{
Clicked = delegate
{
Destroy();
Close();
}
} );
}
private void SetItems( List<ProjectItem> projectItems )
{
_projectList.Projects = projectItems;
}
protected override bool OnClose()
{
return true;
}
public static void DisplayDialog( List<ProjectItem> projectItems )
{
var dialog = new ProjectConverterDialog( projectItems );
foreach ( var project in projectItems )
{
var shaderGraph = new Editor.ShaderGraph.ShaderGraph();
shaderGraph.Deserialize( System.IO.File.ReadAllText( project.Path ) );
projectItems[projectItems.IndexOf( project )].NodeCount = shaderGraph.Nodes.Count();
}
dialog.SetItems( projectItems );
dialog.ConverButtonClick = delegate
{
ConvertProjects( dialog );
};
dialog.SetModal( on: true, application: true );
dialog.Hide();
dialog.Show();
}
private static void ConvertProjects( ProjectConverterDialog dialog )
{
var projects = dialog._projectList.Projects;
foreach ( var project in projects )
{
SGPLogger.Info( $"Converting project at path \"{project.Path}\"" );
var shaderGraph = new Editor.ShaderGraph.ShaderGraph();
shaderGraph.Deserialize( System.IO.File.ReadAllText( project.Path ) );
var shaderGraphPlus = new ShaderGraphPlus();
var projectConverter = new ProjectConverter( shaderGraph, shaderGraphPlus, project.IsSubgraph );
var conversionResult = projectConverter.Convert();
if ( !projectConverter.Errored )
{
var extension = Path.GetExtension( project.Path );
var targetExtension = extension switch
{
".shdrgrph" => $".{ShaderGraphPlusGlobals.AssetTypeExtension}",
".shdrfunc" => $".{ShaderGraphPlusGlobals.SubgraphAssetTypeExtension}",
_ => throw new NotImplementedException()
};
var shaderGraphPlusFullPath = project.Path.Replace( extension, targetExtension );
System.IO.File.WriteAllText( shaderGraphPlusFullPath, conversionResult.Serialize() );
var asset = AssetSystem.RegisterFile( shaderGraphPlusFullPath );
if ( asset == null )
{
SGPLogger.Error( $"Unable to register asset at path \"{shaderGraphPlusFullPath}\"" );
Utilities.EdtiorSound.Failure();
}
else
{
Utilities.EdtiorSound.Success();
projects[projects.IndexOf( project )].SetConverted();
}
}
else
{
SGPLogger.Error( $"Unable to convert shadergraph project at path \"{project.Path}\"" );
Utilities.EdtiorSound.Failure();
}
}
dialog.SetItems( projects );
}
}
class ProjectItem
{
public bool Converted { get; private set; } = false;
public string Path { get; private set; }
public bool IsSubgraph { get; private set; } = false;
public int NodeCount { get; set; } = 0;
public ProjectItem( string path, bool isSubgraph )
{
Path = path;
IsSubgraph = isSubgraph;
}
public void SetConverted()
{
Converted = true;
}
}
class ProjectList : Widget
{
private List<ProjectItem> _projects;
public List<ProjectItem> Projects
{
get
{
return _projects;
}
set
{
_projectListView.Clear();
_projects = value;
_projectListView.SetItems( _projects.Cast<object>() );
}
}
private ProjectListView _projectListView;
public void UpdateList( List<ProjectItem> items )
{
Projects = items;
}
public ProjectList( Widget parent ) : base( parent )
{
Name = "ShaderGraph Projects";
WindowTitle = "ShaderGraph Projects";
SetWindowIcon( "notes" );
Layout = Layout.Column();
_projectListView = new ProjectListView( this );
Layout.Add( _projectListView );
}
class ProjectListView : ListView
{
private ProjectList _projectList;
public ProjectListView( ProjectList parent ) : base( parent )
{
_projectList = parent;
ItemClicked = ( item ) =>
{
SGPLogger.Info( $"Clicked Item" );
};
ItemContextMenu = OpenItemContextMenu;
ItemSize = new Vector2( 0, 48 );
Margin = 0;
}
private void OpenItemContextMenu( object item )
{
}
protected override void OnPaint()
{
Paint.ClearPen();
Paint.SetBrush( Theme.WindowBackground );
Paint.DrawRect( LocalRect );
base.OnPaint();
}
protected override void PaintItem( VirtualWidget item )
{
if ( item.Object is ProjectItem projectItem )
{
var color = Theme.Text;
if ( projectItem.Converted )
{
color = Theme.Green;
}
Paint.SetBrush( color.WithAlpha( Paint.HasMouseOver ? 0.1f : 0.03f ) );
Paint.ClearPen();
Paint.DrawRect( item.Rect.Shrink( 0, -1 ) );
Paint.Antialiasing = true;
Paint.SetPen( color.WithAlpha( Paint.HasMouseOver ? 1 : 0.7f ), 3.0f );
Paint.ClearBrush();
var iconRect = item.Rect.Shrink( 12, 0 );
iconRect.Width = 24;
Paint.DrawIcon( iconRect, "account_tree", 24 );
var rect = item.Rect.Shrink( 48, 8, 0, 8 );
Paint.SetPen( Color.White.WithAlpha( Paint.HasMouseOver ? 1 : 0.8f ), 3.0f );
Paint.DrawText( rect, $"{projectItem.Path} - {projectItem.NodeCount} nodes", TextFlag.LeftCenter | TextFlag.SingleLine );
//Paint.DrawText( rect, $"{projectItem.NodeCount} nodes", TextFlag.RightCenter | TextFlag.SingleLine );
}
}
}
}