Editor/WeaponImporter/Tool/UI/Widgets/Pill.cs
using Editor;
using Sandbox;
namespace WeaponImporter.Tool.UI;
/// <summary>
/// A rounded tinted label: type, confidence, quality. A column pill keeps a fixed width (and
/// stays in the layout when empty) so pills at the end of rows line up; the pill is drawn
/// right-aligned inside it.
/// </summary>
public class Pill : Widget
{
private string _text = "";
private Color _color = Theme.TextLight;
private readonly bool _column;
public Pill( Widget parent, string text, Color color, string tooltip = null, bool column = false ) : base( parent )
{
_column = column;
FixedHeight = UiStyle.ControlHeight;
ToolTip = tooltip;
if ( column )
FixedWidth = UiStyle.PillColumn;
_text = null;
Set( text, color );
}
public string Text => _text;
public void Set( string text, Color color )
{
text ??= "";
if ( _text == text && _color == color )
return;
_text = text;
_color = color;
if ( !_column )
{
FixedWidth = MeasureWidth( text );
Visible = text.Length > 0;
}
Update();
}
public static float MeasureWidth( string text ) => 7.2f * text.Length + 18;
protected override void OnPaint()
{
if ( string.IsNullOrEmpty( _text ) )
return;
var w = MathF.Min( Width, MeasureWidth( _text ) );
Draw( new Rect( Width - w, (Height - 20) * .5f, w, 20 ), _text, _color );
}
public static void Draw( Rect rect, string text, Color color )
{
Paint.Antialiasing = true;
Paint.ClearPen();
Paint.SetBrush( color.WithAlpha( 0.18f ) );
Paint.DrawRect( rect, rect.Height * 0.5f );
Paint.SetPen( color );
Paint.SetDefaultFont( 7, 600 );
Paint.DrawText( rect, text );
}
}
/// <summary>A pill showing how sure the importer is about an automatic choice (always a column pill).</summary>
public sealed class ConfidencePill : Pill
{
public ConfidencePill( Widget parent, float confidence, bool manual = false, string reason = null )
: base( parent, UiStyle.ConfidenceText( confidence, manual ), UiStyle.ConfidenceColor( confidence, manual ), column: true )
{
SetConfidence( confidence, manual, reason );
}
public void SetConfidence( float confidence, bool manual, string reason = null )
{
Set( UiStyle.ConfidenceText( confidence, manual ), UiStyle.ConfidenceColor( confidence, manual ) );
ToolTip = manual
? "Set by you; re-running the analysis keeps it."
: $"Detected automatically ({confidence * 100f:0}% sure){(string.IsNullOrEmpty( reason ) ? "" : ": " + reason)}";
}
}
/// <summary>A clickable rounded chip: quick animation switches and overlay toggles.</summary>
public sealed class Chip : Widget
{
private string _text;
private readonly string _icon;
private bool _active;
public Action Clicked { get; set; }
public Chip( Widget parent, string text, string icon = null, string tooltip = null ) : base( parent )
{
_text = text;
_icon = icon;
ToolTip = tooltip;
FixedHeight = 22;
Cursor = CursorShape.Finger;
MouseTracking = true;
Measure();
}
public string Text
{
get => _text;
set
{
_text = value;
Measure();
Update();
}
}
public bool Active
{
get => _active;
set
{
if ( _active == value )
return;
_active = value;
Update();
}
}
private void Measure() => FixedWidth = 7.4f * _text.Length + (_icon is null ? 20 : 38);
protected override void OnMouseEnter() => Update();
protected override void OnMouseLeave() => Update();
protected override void OnMouseClick( MouseEvent e )
{
if ( !Enabled )
return;
Clicked?.Invoke();
e.Accepted = true;
}
protected override void OnPaint()
{
Paint.Antialiasing = true;
var accent = Theme.Green;
var fill = _active ? accent.WithAlpha( .22f ) : Paint.HasMouseOver && Enabled ? Theme.ControlBackground.Lighten( .5f ) : Theme.WindowBackground;
var edge = _active ? accent.WithAlpha( .8f ) : Theme.ControlBackground.Lighten( .55f );
Paint.SetPen( edge, 1 );
Paint.SetBrush( fill );
var r = LocalRect.Shrink( .5f );
Paint.DrawRect( r, r.Height * .5f );
var color = !Enabled ? Theme.TextDisabled : _active ? accent : Theme.Text;
Paint.SetPen( color );
var textRect = r;
if ( _icon is not null )
{
Paint.DrawIcon( new Rect( r.Left + 8, r.Top, 14, r.Height ), _icon, 13 );
textRect = new Rect( r.Left + 24, r.Top, r.Width - 30, r.Height );
}
Paint.SetDefaultFont( 8, _active ? 600 : 400 );
Paint.DrawText( textRect, _text, TextFlag.Center );
}
}