An editor window UI for the Library System, shown under Tools > Library System. It lists the project libraries and provides controls to view versions, install from sbox.game, publish and remove libraries by calling LibraryTools helper methods and LibrarySystem APIs.
using Editor;
using Sandbox;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace LibraryTools;
/// <summary>
/// Library System as an editor window (Tools > Library System). Same actions as the MCP tools, which it
/// calls directly: list the project's libraries, check published versions, install, remove and publish.
/// </summary>
[EditorApp( "Library System", "library_books", "List, install, remove and publish the project's libraries" )]
public sealed class LibrarySystemWindow : Widget
{
readonly Widget _list;
readonly LineEdit _ident;
readonly Label _output;
public LibrarySystemWindow() : base( null )
{
WindowTitle = "Library System";
SetWindowIcon( "library_books" );
WindowFlags = WindowFlags.Dialog | WindowFlags.Customized | WindowFlags.WindowTitle | WindowFlags.CloseButton | WindowFlags.WindowSystemMenuHint;
DeleteOnClose = true;
MinimumSize = new Vector2( 620, 420 );
Layout = Layout.Column();
Layout.Margin = 12;
Layout.Spacing = 8;
Layout.Add( new Label.Subtitle( "Libraries in this project" ) );
_list = Layout.Add( new Widget( this ) );
_list.Layout = Layout.Column();
_list.Layout.Spacing = 4;
Layout.Add( new Label.Subtitle( "Install from sbox.game" ) );
var row = Layout.AddRow();
row.Spacing = 4;
_ident = row.Add( new LineEdit( this ) { PlaceholderText = "org.package, e.g. rwtrcsc.lobbysystem" }, 1 );
row.Add( new Button( "Versions", "history", this ) { Clicked = () => Run( "Versions", () => LibraryTools.LibraryVersions( Ident() ) ) } );
row.Add( new Button.Primary( "Install", "download", this ) { Clicked = () => Run( "Install", async () => { var r = await LibraryTools.LibraryInstall( Ident() ); Refresh(); return r; } ) } );
Layout.AddStretchCell();
_output = Layout.Add( new Label( "Ready.", this ) { WordWrap = true, TextSelectable = true } );
Refresh();
}
string Ident() => _ident.Value?.Trim() ?? "";
void Refresh()
{
_list.Layout.Clear( true );
var libs = LibrarySystem.All.ToList();
if ( libs.Count == 0 ) _list.Layout.Add( new Label( "No libraries in Libraries/ yet.", _list ) );
foreach ( var lib in libs )
{
var ident = (lib.Project?.Package?.FullIdent ?? "").Split( '#' )[0];
var title = lib.Project?.Config?.Title ?? ident;
var row = _list.Layout.AddRow();
row.Spacing = 4;
row.Add( new Label( $"{title} {ident} {(lib.Version?.ToString() ?? "local")}", _list ), 1 );
row.Add( new Button( "Versions", "history", _list ) { Clicked = () => Run( $"Versions of {ident}", () => LibraryTools.LibraryVersions( ident ) ) } );
row.Add( new Button( "Publish", "publish", _list )
{
Clicked = () => Dialog.AskString( change => Run( $"Publish {ident}", () => LibraryTools.LibraryPublish( ident, change ) ),
$"Publish a new revision of {title}. Revision title:", "Publish", "Cancel", "", "Publish library" )
} );
row.Add( new Button( "Remove", "delete", _list )
{
Clicked = () => Dialog.AskConfirm( () => { _output.Text = LibraryTools.LibraryUninstall( ident ); Refresh(); },
$"Remove {title} and delete its folder from Libraries/?", "Remove library", "Remove", "Cancel" )
} );
}
}
// Runs an action, showing progress and the result (or the error) in the output line.
async void Run( string what, Func<Task<string>> action )
{
_output.Text = $"{what}...";
try { _output.Text = await action(); }
catch ( Exception e ) { _output.Text = $"{what} failed: {e.Message}"; }
}
}