Files
tbd-station-14/Content.Client/Humanoid/HumanoidMarkingModifierWindow.xaml.cs
2023-01-26 18:04:58 -04:00

151 lines
5.3 KiB
C#

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;
using static Content.Shared.Humanoid.HumanoidAppearanceState;
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<MarkingSet>? OnMarkingAdded;
public Action<MarkingSet>? OnMarkingRemoved;
public Action<MarkingSet>? OnMarkingColorChange;
public Action<MarkingSet>? OnMarkingRankChange;
public Action<HumanoidVisualLayers, CustomBaseLayerInfo?>? OnLayerInfoModified;
private readonly IPrototypeManager _protoMan = default!;
private readonly Dictionary<HumanoidVisualLayers, HumanoidBaseLayerModifier> _modifiers = new();
public HumanoidMarkingModifierWindow()
{
RobustXamlLoader.Load(this);
_protoMan = IoCManager.Resolve<IPrototypeManager>();
foreach (var layer in Enum.GetValues<HumanoidVisualLayers>())
{
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<HumanoidSpeciesSpriteLayer>(modifier.Text) ? modifier.Text : null;
OnLayerInfoModified?.Invoke(layer, new CustomBaseLayerInfo(state, modifier.Color));
}
public void SetState(MarkingSet markings, string species, Color skinColor, Dictionary<HumanoidVisualLayers, CustomBaseLayerInfo> info)
{
MarkingPickerWidget.SetData(markings, species, skinColor);
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);
}
}
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 = "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();
lineEditBox.AddChild(new Label { Text = "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;
}
}
}