UI Panel component that renders a single LCD-style text line as a texture fitted into a fixed viewport. It computes a texture via WalletFont.GetLineTexture, picks scale to fit LCD glass constraints, sets panel size and background image, and updates when Text or Small change.
namespace NoChillquarium;
/// <summary>
/// Full LCD text line as one texture, fitted into a fixed viewport.
/// Device size never grows — long values scale down inside the glass.
/// </summary>
[Library( "walletlcd" )]
public class WalletLcdLine : Panel
{
string _text = "";
bool _small;
string _appliedKey;
public string Text
{
get => _text;
set
{
var v = value ?? "";
if ( string.Equals( _text, v, StringComparison.Ordinal ) )
return;
_text = v;
Apply();
}
}
public bool Small
{
get => _small;
set
{
if ( _small == value )
return;
_small = value;
Apply();
}
}
public WalletLcdLine()
{
AddClass( "wallet-lcd-line" );
}
public override void Tick()
{
base.Tick();
var want = _text ?? "";
var key = (_small ? "s:" : "b:") + want;
if ( _appliedKey != key )
Apply();
}
void Apply()
{
var maxChars = _small ? WalletFont.MaxRateChars : WalletFont.MaxBalanceChars;
var tex = WalletFont.GetLineTexture( _text, maxChars );
var key = (_small ? "s:" : "b:") + (_text ?? "");
if ( tex is null )
{
Style.BackgroundImage = null;
_appliedKey = null;
return;
}
// Preferred pixel scale (crisp), then shrink to fit fixed LCD glass.
// Rate line stays much smaller than the balance.
var prefer = _small ? 0.8f : 2f;
var maxW = WalletFont.LcdGlassInnerW;
var maxH = _small ? WalletFont.LcdRateMaxH : WalletFont.LcdBalanceMaxH;
var floor = _small ? 0.5f : 0.9f;
var scale = prefer;
if ( tex.Width * scale > maxW )
scale = maxW / tex.Width;
if ( tex.Height * scale > maxH )
scale = MathF.Min( scale, maxH / tex.Height );
scale = Math.Clamp( scale, floor, prefer );
// Snap to half-pixels for stable alignment
scale = MathF.Round( scale * 2f ) / 2f;
if ( scale < floor )
scale = floor;
// Integer panel size — avoids subpixel drift / misalignment in S&box UI
var w = MathF.Max( 1f, MathF.Round( tex.Width * scale ) );
var h = MathF.Max( 1f, MathF.Round( tex.Height * scale ) );
Style.Width = Length.Pixels( w );
Style.Height = Length.Pixels( h );
Style.BackgroundImage = tex;
try
{
Style.BackgroundSizeX = Length.Pixels( w );
Style.BackgroundSizeY = Length.Pixels( h );
}
catch
{
// optional style props
}
_appliedKey = key;
}
}