Code/Demos/TarkovInventory/StashTileBlob.cs
using System;
using Goo;
using Sandbox;
using Sandbox.UI;
using static Sandbox.TarkovInventory.StashTheme;
namespace Sandbox.TarkovInventory;
// Pure presenters for a stash item: the three-row grid tile and the drag ghost. No state lives
// here - the item, its footprint rect, the drag/rotation flags and the split click all arrive as
// arguments (the PadBlob idiom). Sizes/colors/fonts/geometry come from StashTheme (using static).
internal static class StashTileBlob
{
// Three stacked rows: item name on top, the SVG glyph in the middle, the amount on the bottom. The
// labels own their rows (no overlay) so the stack count stays legible and never occludes the glyph.
public static Container Tile( StashItem item, GridRect rect, bool dragging, bool rotated, Action<MousePanelEvent> onClick ) => new Container
{
Position = PositionMode.Relative,
Width = rect.W * SlotSize, Height = rect.H * SlotSize,
BackgroundColor = KindTint( item.Kind ),
BorderRadius = 5f,
BorderWidth = 1f,
BorderColor = ItemBdr,
Opacity = dragging ? 0.35f : 1f,
FlexDirection = FlexDirection.Column,
JustifyContent = Justify.SpaceBetween,
AlignItems = Align.Center,
PointerEvents = PointerEvents.All,
OnClick = onClick,
Children =
{
NameRow( item, rect ),
IconCell( item, rect, rotated ),
CountRow( item ),
},
};
// Top row: the item name (full on wide tiles, the Short abbreviation on 1-wide tiles so it fits).
static Container NameRow( StashItem item, GridRect rect ) => new Container
{
Key = "name",
Width = Length.Percent( 100 ),
JustifyContent = Justify.Center,
AlignItems = Align.Center,
PaddingTop = 2f, PaddingLeft = 3f, PaddingRight = 3f,
Overflow = OverflowMode.Hidden,
PointerEvents = PointerEvents.None,
Children = { new Text( rect.W >= 2 ? item.Name : item.Short ) { Key = "t", FontColor = Title, FontFamily = LabelFont, FontSize = 16f } },
};
// Middle row: the SVG glyph, centered, sized to the space left between the name and amount rows.
static Container IconCell( StashItem item, GridRect rect, bool rotated ) => new Container
{
Key = "icon-cell",
JustifyContent = Justify.Center,
AlignItems = Align.Center,
PointerEvents = PointerEvents.None,
Children =
{
new Goo.SvgPanel { Key = "icon", Path = item.Icon, Color = IconTint,
Width = IconRowSide( rect ), Height = IconRowSide( rect ),
Transform = rotated ? Goo.PanelTransform.Rotate( 90f ) : (Goo.PanelTransform?)null },
},
};
// Bottom row: the stack amount, always shown so every tile keeps the same three-row shape.
static Container CountRow( StashItem item ) => new Container
{
Key = "count",
Width = Length.Percent( 100 ),
JustifyContent = Justify.Center,
AlignItems = Align.Center,
PaddingBottom = 2f,
PointerEvents = PointerEvents.None,
Children = { new Text( $"x{item.Count}" ) { Key = "t", FontColor = Title, FontFamily = LabelFont, FontSize = 18f, FontWeight = 700 } },
};
// The translucent drag ghost: just the glyph on a faint blue plate, sized to the rotated footprint.
public static Container Ghost( StashItem item, bool rotated )
{
var (w, h) = Eff( item, rotated );
var rect = new GridRect( 0, 0, w, h );
return new Container
{
Width = w * SlotSize, Height = h * SlotSize,
BackgroundColor = new Color( 0.4f, 0.7f, 1f, 0.25f ),
BorderRadius = 5f,
Opacity = 0.85f,
JustifyContent = Justify.Center,
AlignItems = Align.Center,
Children =
{
new Goo.SvgPanel { Key = "icon", Path = item.Icon, Color = IconTint,
Width = IconSide( rect ), Height = IconSide( rect ),
Transform = rotated ? Goo.PanelTransform.Rotate( 90f ) : (Goo.PanelTransform?)null },
},
};
}
}