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; } }