Editor/sandmod.libraryplus/Widget/LibraryDetail.cs
using System.Linq;
using System.Threading.Tasks;
using Editor;
using Sandbox;
using Button = Editor.Button;
using Label = Editor.Label;
namespace LibraryPlus;
internal class LibraryDetail : Widget
{
/// <summary>
/// The "install" button
/// </summary>
private Button ActionButton;
/// <summary>
/// If this is installed, this will be the installed project
/// </summary>
private Library Installed;
/// <summary>
/// The package holding the description for this library
/// </summary>
private Package Package;
/// <summary>
/// The revision currently selected in the version list
/// </summary>
private Package.IRevision SelectedRevision;
/// <summary>
/// The "uninstall" button
/// </summary>
private Button UninstallButton;
/// <summary>
/// List of versions
/// </summary>
private ComboBox VersionList;
public LibraryDetail( Package package )
{
Package = package;
Layout = Layout.Column();
Layout.Margin = 8;
Layout.Spacing = 4;
_ = FetchAndBuild();
}
private async Task FetchAndBuild()
{
if ( !this.IsValid() )
{
return;
}
Layout.Clear( true );
if ( !Package.TryParseIdent( Package.FullIdent, out var ident ) )
{
return;
}
Installed = LibrarySystemPlus.All.FirstOrDefault( x =>
x.Package.ReferenceIdent() == Package.ReferenceIdent() );
// do we have this package installed? what is the version?
if ( ident.org != "local" )
{
Package = await Package.FetchAsync( Package.ReferenceIdent(), false ) ?? Package;
if ( !this.IsValid() )
{
return;
}
}
// Header, todo, icon and title
var titleLayout = Layout.Row();
titleLayout.Alignment = TextFlag.Left;
titleLayout.Spacing = 4;
titleLayout.Add( new Label( Package.Title ) );
if ( Package.Org.Ident != "local" )
{
// org icon and title
titleLayout.Add( new Label.Small( $"by {Package.Org.Title}" ), 1 );
}
Layout.Add( titleLayout );
Layout.Add( new Label.Small( Package.ReferenceIdent() ) );
// all of the versions
VersionList = new ComboBox( this );
Layout.Add( VersionList );
{
ActionButton = new Button( "Install", this ) { Pressed = () => _ = OnActionPressed() };
Layout.Add( ActionButton );
ActionButton.Hide();
}
{
UninstallButton = new Button( "Remove Library", "remove" )
{
Pressed = () => Dialog.AskConfirm( OnUninstall, $"Are you sure you want to remove {Package.Title}?",
"Remove Library", "Uninstall" )
};
Layout.Add( UninstallButton );
UninstallButton.Visible = Installed != null;
}
if ( Installed != null )
{
Layout.AddSpacingCell( 10 );
var referenceLayout = Layout.Grid();
referenceLayout.AddCell( 0, 0, new Label( "Reference" ) );
referenceLayout.AddCell( 1, 0, new Label( "Version" ) );
foreach ( var reference in Installed.Config.LibraryReferences.Select( ( entry, index ) =>
new { entry, index = index + 1 } ) )
{
referenceLayout.AddCell( 0, reference.index, new Label( reference.entry.Key ) );
referenceLayout.AddCell( 1, reference.index, new Label(
$">= {reference.entry.Value.Min}{(reference.entry.Value.Max != null ? $", <= {reference.entry.Value.Min}" : "")}" ) );
var actionLayout = referenceLayout.AddCell( 2, reference.index, Layout.Row() );
var editButton = actionLayout.Add( new IconButton( "edit" )
{
OnClick = () => ReferenceDialog.Open( "Edit Reference",
data => LibrarySystemPlus.AddReference( Installed, data ),
(reference.entry.Key, reference.entry.Value.Min, reference.entry.Value.Max) )
} );
editButton.ToolTip = "Edit Reference";
var removeButton = actionLayout.Add( new IconButton( "remove" )
{
OnClick = () => Dialog.AskConfirm(
() => LibrarySystemPlus.RemoveReference( Installed, reference.entry.Key ),
$"Are you sure you want to remove {reference.entry.Key}?",
"Remove Reference", "Remove" )
} );
removeButton.ToolTip = "Remove Reference";
}
var addButton = new Button( "Add Reference", "add" )
{
Pressed = () => ReferenceDialog.Open( "Add Reference",
data => LibrarySystemPlus.AddReference( Installed, data ), "Add" )
};
referenceLayout.AddCell( 0, Installed.Config.LibraryReferences.Count + 1, addButton
, 3 );
Layout.Add( referenceLayout );
}
// information about this
Layout.Add( new Label( Package.Description ) );
Layout.AddStretchCell();
if ( ident.org == "local" )
{
VersionList.Hide();
return;
}
var versions = await Package.FetchVersions( $"{ident.org}.{ident.package}" );
if ( !this.IsValid() )
{
return;
}
if ( versions != null )
{
if ( Installed != null )
{
SelectedRevision = versions.FirstOrDefault( x => x.VersionId == Installed.Version.Build );
}
SelectedRevision ??= versions.FirstOrDefault();
foreach ( var v in versions )
{
var version = v;
var subtitle = Installed != null && Installed.Version.Build == version.VersionId
? " (Installed)"
: "";
VersionList.AddItem( $"{v.Created.DateTime} - {v.VersionId}{subtitle}", null,
() => OnVersionSelected( v ), null, SelectedRevision == version );
}
OnVersionSelected( SelectedRevision );
}
}
private void OnVersionSelected( Package.IRevision revision )
{
SelectedRevision = revision;
// update action button - install/uninstall/update
// ActionButton
// Is this fucker installed?
if ( Installed != null )
{
// is this the installed version?
if ( revision.VersionId == Installed.Version.Build )
{
ActionButton.Hide();
}
else
{
ActionButton.Show();
ActionButton.Icon = "get_app";
ActionButton.Text = $"Update to {revision.VersionId}";
}
}
else
{
ActionButton.Show();
ActionButton.Icon = "get_app";
ActionButton.Text = "Install";
}
}
private async Task OnActionPressed()
{
LibrarySystemPlus.Install( Package.FullIdent, SelectedRevision.VersionId );
// window closed
if ( !IsValid )
{
return;
}
await FetchAndBuild();
}
private void OnUninstall()
{
UninstallButton.Enabled = false;
Installed.Remove();
_ = FetchAndBuild();
}
protected override Vector2 SizeHint()
{
return new Vector2( 300, 100 );
}
[EditorEvent.Frame]
public void Frame()
{
if ( !Visible )
{
return;
}
SetContentHash( Installed?.GetHashCode() ?? 0 );
}
}