The UI component displays a dynamic statistic, showing an icon, value, and optional label in a customizable panel. It manages a subtle scaling animation when the displayed value changes.
@namespace CitySim.Punchboard
@using Sandbox.UI
@inherits Panel
<root class="pb-stat @Tone.Css() @(Compact ? "compact" : "")">
<div class="pb-stat-ring">
<div class="pb-stat-window">
<div class="pb-stat-icon"><PbIcon Icon=@Icon /></div>
<span class="pb-stat-value">@Value</span>
</div>
</div>
@if ( !string.IsNullOrEmpty( Label ) )
{
<span class="pb-stat-label">@(GameText.Plain(Label))</span>
}
</root>
@code
{
/// <summary>An emoji, glyph or texture path.</summary>
[Parameter] public string Icon { get; set; }
/// <summary>The number or short text to show. Changing it plays a small pop.</summary>
[Parameter] public string Value { get; set; }
[Parameter] public string Label { get; set; }
/// <summary>Keep only the labelled token window visible; the label remains available as a tooltip.</summary>
[Parameter] public bool Compact { get; set; }
[Parameter] public PbTone Tone { get; set; } = PbTone.Red;
string lastValue;
float pop = 1f;
protected override void OnParametersSet()
{
base.OnParametersSet();
Tooltip = Compact ? Label : null;
TooltipClass = "city-tooltip";
if ( lastValue != null && lastValue != Value ) pop = 0f;
lastValue = Value;
}
public override void Tick()
{
base.Tick();
if ( pop >= 1f ) return;
pop = Math.Min( 1f, pop + Time.Delta / 0.25f );
Style.Set( "transform", $"scale({Pb.F( 0.8f + 0.2f * Pb.BackOut( pop ) )})" );
}
protected override int BuildHash() => HashCode.Combine(GameText.LanguageCode, HashCode.Combine( Icon, Value, Label, Tone, Compact ));
}