using System.Numerics;
using Content.Client.Stylesheets;
using Content.Shared.Decals;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
namespace Content.Client.SprayPainter.UI;
///
/// Used to control decal painting parameters for the spray painter.
///
[GenerateTypedNameReferences]
public sealed partial class SprayPainterDecals : Control
{
public Action>? OnDecalSelected;
public Action? OnColorChanged;
public Action? OnAngleChanged;
public Action? OnSnapChanged;
private SpriteSystem? _sprite;
private string _selectedDecal = string.Empty;
private List _decals = [];
public SprayPainterDecals()
{
RobustXamlLoader.Load(this);
AddAngleButton.OnButtonUp += _ => AngleSpinBox.Value += 90;
SubAngleButton.OnButtonUp += _ => AngleSpinBox.Value -= 90;
SetZeroAngleButton.OnButtonUp += _ => AngleSpinBox.Value = 0;
AngleSpinBox.ValueChanged += args => OnAngleChanged?.Invoke(args.Value);
UseCustomColorCheckBox.OnPressed += UseCustomColorCheckBoxOnOnPressed;
SnapToTileCheckBox.OnPressed += SnapToTileCheckBoxOnOnPressed;
ColorSelector.OnColorChanged += OnColorSelected;
}
private void UseCustomColorCheckBoxOnOnPressed(BaseButton.ButtonEventArgs _)
{
OnColorChanged?.Invoke(UseCustomColorCheckBox.Pressed ? ColorSelector.Color : null);
UpdateColorButtons(UseCustomColorCheckBox.Pressed);
}
private void SnapToTileCheckBoxOnOnPressed(BaseButton.ButtonEventArgs _)
{
OnSnapChanged?.Invoke(SnapToTileCheckBox.Pressed);
}
///
/// Updates the decal list.
///
public void PopulateDecals(List decals, SpriteSystem sprite)
{
_sprite ??= sprite;
_decals = decals;
DecalsGrid.Children.Clear();
foreach (var decal in decals)
{
var button = new TextureButton()
{
TextureNormal = sprite.Frame0(decal.Sprite),
Name = decal.Name,
ToolTip = decal.Name,
Scale = new Vector2(2, 2),
};
button.OnPressed += DecalButtonOnPressed;
if (UseCustomColorCheckBox.Pressed)
{
button.Modulate = ColorSelector.Color;
}
if (_selectedDecal == decal.Name)
{
var panelContainer = new PanelContainer()
{
PanelOverride = new StyleBoxFlat()
{
BackgroundColor = StyleNano.ButtonColorDefault,
},
Children =
{
button,
},
};
DecalsGrid.AddChild(panelContainer);
}
else
{
DecalsGrid.AddChild(button);
}
}
}
private void OnColorSelected(Color color)
{
if (!UseCustomColorCheckBox.Pressed)
return;
OnColorChanged?.Invoke(color);
UpdateColorButtons(UseCustomColorCheckBox.Pressed);
}
private void UpdateColorButtons(bool apply)
{
Color modulateColor = apply ? ColorSelector.Color : Color.White;
foreach (var button in DecalsGrid.Children)
{
switch (button)
{
case TextureButton:
button.Modulate = modulateColor;
break;
case PanelContainer panelContainer:
{
foreach (TextureButton textureButton in panelContainer.Children)
textureButton.Modulate = modulateColor;
break;
}
}
}
}
private void DecalButtonOnPressed(BaseButton.ButtonEventArgs obj)
{
if (obj.Button.Name is not { } name)
return;
_selectedDecal = name;
OnDecalSelected?.Invoke(_selectedDecal);
if (_sprite is null)
return;
PopulateDecals(_decals, _sprite);
}
public void SetSelectedDecal(string name)
{
_selectedDecal = name;
if (_sprite is null)
return;
PopulateDecals(_decals, _sprite);
}
public void SetAngle(int degrees)
{
AngleSpinBox.OverrideValue(degrees);
}
public void SetColor(Color? color)
{
UseCustomColorCheckBox.Pressed = color != null;
if (color != null)
ColorSelector.Color = color.Value;
UpdateColorButtons(UseCustomColorCheckBox.Pressed);
}
public void SetSnap(bool snap)
{
SnapToTileCheckBox.Pressed = snap;
}
}