Editor/sandmod.libraryplus/Widget/LibraryList.cs
using System;
using System.Linq;
using System.Threading.Tasks;
using Editor;
using Sandbox;
namespace LibraryPlus;
public class LibraryList : ListView
{
public LibraryList( Widget parget ) : base( parget )
{
ItemContextMenu = ShowItemContext;
ItemSelected = OnItemClicked;
ItemSize = new Vector2( -1, 64 );
}
public Action<Package> OnLibrarySelected { get; set; }
public bool ShowInstalled { get; set; }
public bool ShowAvailable { get; set; }
public string Filter { get; set; } = "";
public void OnItemClicked( object value )
{
if ( value is Library lib )
{
OnLibrarySelected?.Invoke( lib.Package );
}
if ( value is Package p )
{
OnLibrarySelected?.Invoke( p );
}
}
private void ShowItemContext( object obj )
{
var project = obj as Library;
var package = obj as Package ?? project?.Package;
var m = new ContextMenu();
if ( package != null && package.Org.Ident != "local" )
{
m.AddOption( "View in Browser", "public", () => EditorUtility.OpenFolder( package.Url ) );
m.AddSeparator();
}
if ( project is PlusLibrary plusLibrary )
{
m.AddOption( "Convert to Standard Library", "sync", () => LibrarySystemPlus.Convert( plusLibrary ) );
m.AddSeparator();
}
else if ( project is ProjectLibrary projectLibrary )
{
m.AddOption( "Convert to Plus Library", "sync", () => LibrarySystemPlus.Convert( projectLibrary ) );
m.AddSeparator();
m.AddOption( "Project Properties", "tune",
() => _ = ProjectSettingsWindow.OpenForProject( projectLibrary.Project.Project ) );
m.AddSeparator();
m.AddOption( "Publish Project", "upload_file",
() => _ = ProjectSettingsWindow.OpenForProject( projectLibrary.Project.Project, "upload" ) );
m.AddSeparator();
}
if ( project != null )
{
m.AddOption( "Show in Explorer", "folder",
() => EditorUtility.OpenFolder( project.FileSystem.Settings.FullName ) );
}
{
m.OpenAtCursor();
}
}
protected override void PaintItem( VirtualWidget item )
{
if ( item.Object is Library c )
{
PaintItem( item, c.Package );
}
if ( item.Object is Package p )
{
PaintItem( item, p );
}
}
private void PaintItem( VirtualWidget item, Package package )
{
var rect = item.Rect;
if ( Paint.HasPressed )
{
rect = rect.Shrink( 2, 2, 0, 0 );
}
var library = LibrarySystemPlus.All
.FirstOrDefault( x => x.Package.ReferenceIdent() == package.ReferenceIdent() );
var pen = Color.White.WithAlpha( 0.6f );
if ( Paint.HasMouseOver || Paint.HasSelected )
{
Paint.SetBrush( Theme.Primary.WithAlpha( Paint.HasMouseOver ? 0.8f : 0.5f ) );
Paint.ClearPen();
Paint.DrawRect( rect, 4 );
pen = Color.White.WithAlpha( Paint.HasMouseOver ? 1 : 0.9f );
Paint.ClearBrush();
}
rect = rect.Shrink( 4 );
// Icon
{
var iconRect = rect;
iconRect.Width = iconRect.Height;
iconRect = iconRect.Shrink( 8 );
Paint.SetBrushAndPen( Theme.Grey.WithAlpha( 0.4f ) );
if ( !string.IsNullOrWhiteSpace( package.Thumb ) && !package.Thumb.StartsWith( "/" ) )
{
Paint.Draw( iconRect, package.Thumb );
}
else
{
Paint.DrawRect( iconRect, 4 );
}
rect.Left = iconRect.Right + 8;
}
//header
{
rect.Top += 8;
Paint.SetFont( "Poppins", 11, 450 );
Paint.Pen = pen;
var r = Paint.DrawText( rect, package.Title, TextFlag.LeftTop );
r.Left = r.Right + 8;
r.Right = rect.Right;
r.Bottom -= 3;
rect.Top = r.Bottom + 4;
var installedVersion = library != null ? $"v{library?.Version}" : "";
var type = library != null ? $"({(library.IsPlus ? "plus" : "standard")})" : "";
Paint.Pen = pen.WithAlphaMultiplied( 0.6f );
Paint.SetDefaultFont();
Paint.DrawText( r,
$"{package.Org.Title} {installedVersion} {type}",
TextFlag.LeftBottom );
}
// body text
{
Paint.Pen = pen.WithAlphaMultiplied( 0.6f );
Paint.SetDefaultFont();
Paint.DrawText( rect, package.Summary, TextFlag.LeftTop );
}
}
protected override void OnPaint()
{
Paint.ClearPen();
Paint.SetBrush( Theme.ControlBackground );
Paint.DrawRect( LocalRect );
Paint.Antialiasing = true;
Paint.TextAntialiasing = true;
base.OnPaint();
}
[EditorEvent.Frame]
public void Frame()
{
if ( !Visible )
{
return;
}
if ( ShowInstalled )
{
if ( SetContentHash( GetContentHash(), 0.5f ) )
{
SetItems( LibrarySystemPlus.All );
SelectItem( LibrarySystemPlus.All );
}
}
if ( ShowAvailable )
{
if ( SetContentHash( GetContentHash(), 0.5f ) )
{
_ = UpdateAsync();
}
}
}
private async Task UpdateAsync()
{
var search = "";
if ( !string.IsNullOrEmpty( Filter ) )
{
search = Filter + " ";
}
var found = await Package.FindAsync( $"{search}type:library sort:updated" );
SetItems( found.Packages );
SelectItem( found.Packages.FirstOrDefault() );
}
private int GetContentHash()
{
if ( ShowInstalled )
{
return LibrarySystemPlus.All.GetHashCode();
}
return HashCode.Combine( Filter );
}
}