Code/Demos/TarkovInventory/SplitModalBlob.cs
using System;
using Goo;
using Sandbox.UI;
using static Sandbox.TarkovInventory.StashTheme;
namespace Sandbox.TarkovInventory;
// Pure stateless presenter for the stack-split modal (centered window, backdrop dim, peel-off slider); everything arrives as Props. The controller owns the _splitId/_splitAmount state and DoSplit.
internal static class SplitModalBlob
{
public readonly record struct Props(
StashItem Item,
int Amount,
bool HasRoom,
Action OnCancel,
Action<float> OnAmount,
Action OnSplit );
public static Container Build( Props p ) => new Container
{
Key = "split-slot",
Position = PositionMode.Absolute,
Left = 0f, Top = 0f,
Width = Length.Percent( 100 ),
Height = Length.Percent( 100 ),
JustifyContent = Justify.Center,
AlignItems = Align.Center,
BackgroundColor = Backdrop,
PointerEvents = PointerEvents.All,
OnClick = _ => p.OnCancel(), // click outside the panel cancels
Children =
{
new Container
{
Key = "panel",
Width = 360f,
FlexDirection = FlexDirection.Column,
Gap = 16f,
Padding = 24f,
BackgroundColor = CrateTheme.Steel,
BorderWidth = 1f,
BorderColor = CrateTheme.Edge,
BorderRadius = 6f,
PointerEvents = PointerEvents.All,
OnClick = e => e.StopPropagation(),
Children =
{
new Text( $"Split {p.Item.Name}" ) { Key = "title", FontColor = Title, FontFamily = LabelFont, FontSize = 24f, FontWeight = 700 },
Goo.Controls.Slider(
value: p.Amount, min: 1f, max: p.Item.Count - 1, step: 1f,
onChanged: p.OnAmount, key: "slider" ),
new Text( $"{p.Amount} / {p.Item.Count}" ) { Key = "amt", FontColor = Title, FontFamily = LabelFont, FontSize = 18f },
Buttons( p ),
},
},
},
};
static Container Buttons( Props p ) => new Container
{
Key = "btns",
FlexDirection = FlexDirection.Row,
Gap = 12f,
JustifyContent = Justify.FlexEnd,
AlignItems = Align.Center,
Children =
{
p.HasRoom
? new Container { Key = "hint", PointerEvents = PointerEvents.None }
: new Container
{
Key = "hint",
PointerEvents = PointerEvents.None,
Children = { new Text( "no free space" ) { Key = "t", FontColor = Faint, FontFamily = LabelFont, FontSize = 14f } },
},
new Container
{
Key = "cancel",
Padding = 10f,
BackgroundColor = BtnOff,
BorderRadius = 6f,
PointerEvents = PointerEvents.All,
OnClick = _ => p.OnCancel(),
Children = { new Text( "Cancel" ) { Key = "t", FontColor = Title, FontFamily = LabelFont, FontSize = 16f } },
},
new Container
{
Key = "split",
Padding = 10f,
BackgroundColor = p.HasRoom ? CrateTheme.Stamp : BtnGrey,
BorderRadius = 6f,
PointerEvents = PointerEvents.All,
OnClick = _ => { if ( p.HasRoom ) p.OnSplit(); },
Children = { new Text( "Split" ) { Key = "t", FontColor = p.HasRoom ? CrateTheme.StampInk : Title, FontFamily = LabelFont, FontSize = 16f } },
},
},
};
}