Code/Demos/BeatPad/ModeButtonBlob.cs
using System;
using Goo;
using Sandbox.UI;
using static Sandbox.BeatPadTokens;
namespace Sandbox;
// Pure presenter for one mode button. Flood (0..1) crossfades paper->hot for the
// Active state; PressOffset collapses the shadow on press (same feel as a pad).
internal static class ModeButtonBlob
{
public readonly record struct Props(
int Index,
string Label,
float Flood,
float PressOffset,
bool Hovered,
Action<MousePanelEvent> OnDown,
Action<MousePanelEvent> OnUp);
public static Container Build(Props p)
{
float off = p.PressOffset;
Color face = Color.Lerp(Paper, Hot, p.Flood);
Color shadowColor = p.Hovered ? Hot : Ink;
Color text = Color.Lerp(Ink, Paper, p.Flood);
return new Container
{
Key = $"mode-{p.Index}",
Width = ModeW,
Height = ModeH,
Position = PositionMode.Relative,
OnMouseDown = p.OnDown,
OnMouseUp = p.OnUp,
Children =
{
new Container
{
Key = "shadow",
Position = PositionMode.Absolute,
Left = ModeShadow, Top = ModeShadow,
Width = Length.Percent(100), Height = Length.Percent(100),
BackgroundColor = shadowColor,
BorderRadius = ModeRadius,
PointerEvents = PointerEvents.None,
},
new Container
{
Key = "face",
Position = PositionMode.Absolute,
Left = 0, Top = 0,
Width = Length.Percent(100), Height = Length.Percent(100),
BackgroundColor = face,
BorderColor = Ink,
BorderWidth = OutlineWidth,
BorderRadius = ModeRadius,
JustifyContent = Justify.Center,
AlignItems = Align.Center,
Transform = Goo.PanelTransform.Translate(off, off),
PointerEvents = PointerEvents.None,
Children =
{
new Text(p.Label)
{
FontSize = 12f,
FontColor = text,
FontFamily = FontLabel,
FontWeight = 600,
TextTransform = TextTransform.Uppercase,
LetterSpacing = 2f,
TextAlign = TextAlign.Center,
},
},
},
},
};
}
}