Editor/ShaderGraphPlus/Widgets/Output.cs
using Editor;
using static ShaderGraphPlus.GraphCompiler;
namespace ShaderGraphPlus;
public class Output : Widget
{
private IssueListView _issueListView;
private List<GraphCompiler.GraphIssue> _graphIssues;
public List<GraphCompiler.GraphIssue> GraphIssues
{
get => _graphIssues;
set
{
_graphIssues = value;
//_issueListView.AddItems( value.Cast<object>() );
_issueListView.SetItems( value.Cast<object>() );
}
}
public Action<BaseNodePlus> OnNodeSelected { get; set; }
public void ClearErrors()
{
foreach ( var error in _issueListView.Items.Where( x => x is GraphIssue issue && issue.IsWarning == false ) )
{
_issueListView.RemoveItem( error );
}
}
internal void ClearWarnings()
{
foreach ( var warning in _issueListView.Items.Where( x => x is GraphIssue issue && issue.IsWarning == true ) )
{
_issueListView.RemoveItem( warning );
}
}
public Output( Widget parent ) : base( parent )
{
Name = "Output";
WindowTitle = "Output";
SetWindowIcon( "notes" );
Layout = Layout.Column();
_issueListView = new( this );
Layout.Add( _issueListView );
}
}
public class IssueListView : ListView
{
private Output _output;
public IssueListView( Output parent ) : base( parent )
{
_output = parent;
ItemActivated = ( a ) =>
{
if ( a is not GraphCompiler.GraphIssue issue )
return;
if ( issue.Node != null && issue.Node is not DummyNode )
{
_output.OnNodeSelected?.Invoke( issue.Node );
}
};
ItemContextMenu = OpenItemContextMenu;
ItemSize = new Vector2( 0, 48 );
ItemSpacing = 0;
Margin = 0;
}
private void OpenItemContextMenu( object item )
{
if ( item is GraphCompiler.GraphIssue issue )
{
OnOpenItemContextMenuError( item, issue );
}
}
private void OnOpenItemContextMenuError( object item, GraphIssue error )
{
var m = new Menu();
if ( error.Node != null && error.Node is not DummyNode )
{
var nodeName = DisplayInfo.ForType( error.Node.GetType() ).Name;
m.AddOption( "Go to Error", "arrow_upward", () => _output.OnNodeSelected?.Invoke( error.Node ) );
m.AddOption( "Copy Error", "content_copy", () => EditorUtility.Clipboard.Copy( $"{error.Message}\n{nodeName} #{error.Node.Identifier}" ) );
}
else
{
m.AddOption( "Copy Error", "content_copy", () => EditorUtility.Clipboard.Copy( $"{error.Message}" ) );
}
m.OpenAt( Editor.Application.CursorPosition );
}
protected override void OnPaint()
{
Paint.ClearPen();
Paint.SetBrush( Theme.WindowBackground );
Paint.DrawRect( LocalRect );
base.OnPaint();
}
public void OnPaintError( VirtualWidget item, GraphCompiler.GraphIssue error )
{
var color = Theme.Red;
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, "error", 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, error.Message, (error.Node != null ? TextFlag.LeftTop : TextFlag.LeftCenter) | TextFlag.SingleLine );
if ( error.Node != null && error.Node is not DummyNode )
{
var nodeName = DisplayInfo.ForType( error.Node.GetType() ).Name;
Paint.SetPen( Color.White.WithAlpha( Paint.HasMouseOver ? 0.5f : 0.4f ), 3.0f );
Paint.DrawText( rect, $"{nodeName}", TextFlag.LeftBottom | TextFlag.SingleLine );
}
}
public void OnPaintWarning( VirtualWidget item, GraphCompiler.GraphIssue warning )
{
var color = Theme.Yellow;
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, "error", 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, warning.Message, (warning.Node != null ? TextFlag.LeftTop : TextFlag.LeftCenter) | TextFlag.SingleLine );
if ( warning.Node != null )
{
var nodeName = DisplayInfo.ForType( warning.Node.GetType() ).Name;
Paint.SetPen( Color.White.WithAlpha( Paint.HasMouseOver ? 0.5f : 0.4f ), 3.0f );
Paint.DrawText( rect, $"{nodeName}", TextFlag.LeftBottom | TextFlag.SingleLine );
}
}
protected override void PaintItem( VirtualWidget item )
{
if ( item.Object is GraphCompiler.GraphIssue issue )
{
if ( issue.IsWarning )
{
OnPaintWarning( item, issue );
}
else
{
OnPaintError( item, issue );
}
}
}
}