Editor/SeamlessSuiteAboutDialog.cs
using System;
using System.IO;
using Editor;
using Sandbox;
public sealed class SeamlessSuiteAboutDialog : Dialog
{
private const string VersionText = "0.1.0 editor preview";
private const string AuthorText = "Forsomethings";
private const string PackageText = "forsomethings.seamless";
public SeamlessSuiteAboutDialog()
{
Window.WindowTitle = "About Seam-Less™ Material Suite";
Window.Size = new Vector2( 540, 500 );
Window.MinimumWidth = 480;
Window.SetWindowIcon( "info" );
Layout = Layout.Column();
Layout.Margin = 18;
Layout.Spacing = 12;
var banner = new SeamlessSuiteBannerWidget( this );
Layout.Add( banner );
var text = new Label(
"Seam-Less™ Material Suite is an editor toolkit for preparing game-ready PBR materials directly in s&box.\n\n" +
"It includes a Seam-Less tool for helping make textures tile more cleanly, plus a PBR Generator for creating full stack PBR maps including albedo, height, normal, roughness, ambient occlusion, metallic, and ORM maps from a single image.\n\n" +
"The generated PBR maps are practical estimates. They are meant to give you a useful starting point that can be adjusted, previewed, and exported quickly and are not ment to be perfect or as good as baked hand crafted maps.",
this );
text.WordWrap = true;
text.TextSelectable = true;
text.SetStyles( "font-size: 12px; color: #dddddd; line-height: 1.35;" );
Layout.Add( text, 1 );
var infoPanel = new Widget( this );
infoPanel.Layout = Layout.Column();
infoPanel.Layout.Margin = 10;
infoPanel.Layout.Spacing = 5;
infoPanel.SetStyles( "background-color: #202020; border: 1px solid #303030; border-radius: 4px;" );
Layout.Add( infoPanel );
AddInfoRow( infoPanel, "Author", AuthorText );
AddInfoRow( infoPanel, "Version", VersionText );
AddInfoRow( infoPanel, "Library", PackageText );
var buttonRow = Layout.AddRow();
buttonRow.AddStretchCell();
var closeButton = new Button( "Close", this );
closeButton.MinimumWidth = 90;
closeButton.Clicked = () => Close();
buttonRow.Add( closeButton );
}
private static void AddInfoRow( Widget parent, string labelText, string valueText )
{
var row = new Widget( parent );
row.Layout = Layout.Row();
row.Layout.Spacing = 8;
var label = new Label( labelText, row );
label.FixedWidth = 72;
label.SetStyles( "font-size: 12px; color: #9f9f9f; font-weight: bold;" );
row.Layout.Add( label );
var value = new Label( valueText, row );
value.TextSelectable = true;
value.SetStyles( "font-size: 12px; color: #eeeeee;" );
row.Layout.Add( value, 1 );
parent.Layout.Add( row );
}
}
internal sealed class SeamlessSuiteBannerWidget : Widget
{
private const float BannerHeight = 150f;
private const string BannerFileName = "seamlessLOGO-Banner.png";
private const string FallbackTitle = "Seam-Less™ Material Suite";
private readonly Pixmap bannerPixmap = LoadBannerPixmap();
public SeamlessSuiteBannerWidget( Widget parent ) : base( parent )
{
FixedHeight = BannerHeight;
MinimumHeight = BannerHeight;
NoSystemBackground = true;
}
protected override void OnPaint()
{
if ( bannerPixmap == null )
{
Paint.ClearPen();
Paint.SetBrush( new Color( 0.06f, 0.06f, 0.065f ) );
Paint.DrawRect( LocalRect, 3 );
Paint.SetDefaultFont( 18, 700, false, false );
Paint.SetPen( Theme.TextLight );
Paint.DrawText( LocalRect, FallbackTitle, TextFlag.Center );
return;
}
var scale = MathF.Max(
LocalRect.Width / Math.Max( 1f, bannerPixmap.Width ),
LocalRect.Height / Math.Max( 1f, bannerPixmap.Height )
);
var width = bannerPixmap.Width * scale;
var height = bannerPixmap.Height * scale;
var imageRect = new Rect(
(LocalRect.Width - width) * 0.5f,
(LocalRect.Height - height) * 0.5f,
width,
height
);
Paint.BilinearFiltering = true;
Paint.Draw( imageRect, bannerPixmap, 1f, 3 );
}
private static Pixmap LoadBannerPixmap()
{
try
{
var path = FindBannerPath();
if ( string.IsNullOrWhiteSpace( path ) )
return null;
return Pixmap.FromBitmap( SeamlessSuiteImageUtility.LoadBitmapFromFile( path ) );
}
catch ( Exception ex )
{
Log.Info( $"Seam-Less: Falling back to text banner because the image could not be loaded: {ex.Message}" );
return null;
}
}
private static string FindBannerPath()
{
var projectRoot = Sandbox.Project.Current?.GetRootPath();
if ( string.IsNullOrWhiteSpace( projectRoot ) )
return null;
var librariesFolder = Path.Combine( projectRoot, "Libraries" );
if ( !Directory.Exists( librariesFolder ) )
return null;
foreach ( var libraryFolder in Directory.EnumerateDirectories( librariesFolder ) )
{
var path = Path.Combine( libraryFolder, "Assets", "UI", BannerFileName );
if ( File.Exists( path ) )
return path;
}
return null;
}
}