using Content.Shared.Humanoid; using Content.Shared.Humanoid.Markings; using Content.Shared.Humanoid.Prototypes; using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; using Robust.Client.UserInterface.XAML; using Robust.Shared.Prototypes; namespace Content.Client.Humanoid; // hack for a panel that modifies an entity's markings on demand [GenerateTypedNameReferences] public sealed partial class HumanoidMarkingModifierWindow : DefaultWindow { public Action? OnMarkingAdded; public Action? OnMarkingRemoved; public Action? OnMarkingColorChange; public Action? OnMarkingRankChange; public Action? OnLayerInfoModified; private readonly IPrototypeManager _protoMan = default!; private readonly Dictionary _modifiers = new(); public HumanoidMarkingModifierWindow() { RobustXamlLoader.Load(this); _protoMan = IoCManager.Resolve(); foreach (var layer in Enum.GetValues()) { var modifier = new HumanoidBaseLayerModifier(layer); BaseLayersContainer.AddChild(modifier); _modifiers.Add(layer, modifier); modifier.OnStateChanged += () => OnStateChanged(layer, modifier); } MarkingPickerWidget.OnMarkingAdded += set => OnMarkingAdded!(set); MarkingPickerWidget.OnMarkingRemoved += set => OnMarkingRemoved!(set); MarkingPickerWidget.OnMarkingColorChange += set => OnMarkingColorChange!(set); MarkingPickerWidget.OnMarkingRankChange += set => OnMarkingRankChange!(set); MarkingForced.OnToggled += args => MarkingPickerWidget.Forced = args.Pressed; MarkingIgnoreSpecies.OnToggled += args => MarkingPickerWidget.Forced = args.Pressed; MarkingPickerWidget.Forced = MarkingForced.Pressed; MarkingPickerWidget.IgnoreSpecies = MarkingForced.Pressed; } private void OnStateChanged(HumanoidVisualLayers layer, HumanoidBaseLayerModifier modifier) { if (!modifier.Enabled) { OnLayerInfoModified?.Invoke(layer, null); return; } string? state = _protoMan.HasIndex(modifier.Text) ? modifier.Text : null; OnLayerInfoModified?.Invoke(layer, new CustomBaseLayerInfo(state, modifier.Color)); } public void SetState( MarkingSet markings, string species, Sex sex, Color skinColor, Dictionary info ) { foreach (var (layer, modifier) in _modifiers) { if (!info.TryGetValue(layer, out var layerInfo)) { modifier.SetState(false, string.Empty, Color.White); continue; } modifier.SetState(true, layerInfo.Id ?? string.Empty, layerInfo.Color ?? Color.White); } var eyesColor = Color.White; if (info.TryGetValue(HumanoidVisualLayers.Eyes, out var eyes) && eyes.Color != null) { eyesColor = eyes.Color.Value; } MarkingPickerWidget.SetData(markings, species, sex, skinColor, eyesColor); } private sealed class HumanoidBaseLayerModifier : BoxContainer { private CheckBox _enable; private LineEdit _lineEdit; private ColorSelectorSliders _colorSliders; private BoxContainer _infoBox; public bool Enabled => _enable.Pressed; public string Text => _lineEdit.Text; public Color Color => _colorSliders.Color; public Action? OnStateChanged; public HumanoidBaseLayerModifier(HumanoidVisualLayers layer) { HorizontalExpand = true; Orientation = LayoutOrientation.Vertical; var labelBox = new BoxContainer { MinWidth = 250, HorizontalExpand = true }; AddChild(labelBox); labelBox.AddChild(new Label { HorizontalExpand = true, Text = layer.ToString() }); _enable = new CheckBox { Text = Loc.GetString("humanoid-marking-modifier-enable"), HorizontalAlignment = HAlignment.Right }; labelBox.AddChild(_enable); _infoBox = new BoxContainer { Orientation = LayoutOrientation.Vertical, Visible = false }; _enable.OnToggled += args => { _infoBox.Visible = args.Pressed; OnStateChanged!(); }; var lineEditBox = new BoxContainer { SeparationOverride = 4 }; lineEditBox.AddChild(new Label { Text = Loc.GetString("humanoid-marking-modifier-prototype-id") }); // TODO: This line edit should really be an options / dropdown selector, not text. _lineEdit = new() { MinWidth = 200 }; _lineEdit.OnTextEntered += args => OnStateChanged!(); lineEditBox.AddChild(_lineEdit); _infoBox.AddChild(lineEditBox); _colorSliders = new(); _colorSliders.OnColorChanged += color => OnStateChanged!(); _infoBox.AddChild(_colorSliders); AddChild(_infoBox); } public void SetState(bool enabled, string state, Color color) { _enable.Pressed = enabled; _infoBox.Visible = enabled; _lineEdit.Text = state; _colorSliders.Color = color; } } }