213 lines
6.5 KiB
C#
213 lines
6.5 KiB
C#
using System.Linq;
|
|
using Content.Client.Guidebook.Controls;
|
|
using Content.Shared.Body;
|
|
using Content.Shared.Humanoid;
|
|
using Content.Shared.Humanoid.Markings;
|
|
using Robust.Client.AutoGenerated;
|
|
using Robust.Client.GameObjects;
|
|
using Robust.Client.UserInterface.Controls;
|
|
using Robust.Client.UserInterface.XAML;
|
|
using Robust.Client.UserInterface;
|
|
using Robust.Shared.Input;
|
|
using Robust.Shared.Prototypes;
|
|
using Robust.Shared.Utility;
|
|
|
|
namespace Content.Client.Humanoid;
|
|
|
|
[GenerateTypedNameReferences]
|
|
public sealed partial class LayerMarkingItem : BoxContainer, ISearchableControl
|
|
{
|
|
[Dependency] private readonly IEntityManager _entity = default!;
|
|
|
|
private readonly SpriteSystem _sprite;
|
|
|
|
private readonly MarkingsViewModel _markingsModel;
|
|
private readonly MarkingPrototype _markingPrototype;
|
|
private readonly ProtoId<OrganCategoryPrototype> _organ;
|
|
private readonly HumanoidVisualLayers _layer;
|
|
private bool _interactive;
|
|
|
|
private List<ColorSelectorSliders>? _colorSliders;
|
|
|
|
public event Action<GUIBoundKeyEventArgs, LayerMarkingItem>? Pressed;
|
|
public event Action<GUIBoundKeyEventArgs, LayerMarkingItem>? Unpressed;
|
|
public ProtoId<MarkingPrototype> MarkingId => _markingPrototype.ID;
|
|
|
|
public LayerMarkingItem(MarkingsViewModel model, ProtoId<OrganCategoryPrototype> organ, HumanoidVisualLayers layer, MarkingPrototype prototype, bool interactive)
|
|
{
|
|
RobustXamlLoader.Load(this);
|
|
IoCManager.InjectDependencies(this);
|
|
|
|
_sprite = _entity.System<SpriteSystem>();
|
|
|
|
_markingsModel = model;
|
|
_markingPrototype = prototype;
|
|
_organ = organ;
|
|
_layer = layer;
|
|
_interactive = interactive;
|
|
|
|
UpdateData();
|
|
UpdateSelection();
|
|
|
|
SelectButton.OnPressed += SelectButtonPressed;
|
|
ColorsButton.OnPressed += ColorsButtonPressed;
|
|
|
|
OnKeyBindDown += OnPressed;
|
|
OnKeyBindUp += OnUnpressed;
|
|
|
|
if (!interactive)
|
|
{
|
|
SelectButton.MouseFilter = Control.MouseFilterMode.Ignore;
|
|
}
|
|
}
|
|
|
|
protected override void EnteredTree()
|
|
{
|
|
base.EnteredTree();
|
|
|
|
_markingsModel.MarkingsReset += UpdateSelection;
|
|
_markingsModel.MarkingsChanged += MarkingsChanged;
|
|
}
|
|
|
|
protected override void ExitedTree()
|
|
{
|
|
base.ExitedTree();
|
|
|
|
_markingsModel.MarkingsReset -= UpdateSelection;
|
|
_markingsModel.MarkingsChanged -= MarkingsChanged;
|
|
}
|
|
|
|
private void MarkingsChanged(ProtoId<OrganCategoryPrototype> organ, HumanoidVisualLayers layer)
|
|
{
|
|
if (_organ != organ || _layer != layer)
|
|
return;
|
|
|
|
UpdateSelection();
|
|
}
|
|
|
|
private void UpdateData()
|
|
{
|
|
MarkingTexture.Textures = _markingPrototype.Sprites.Select(layer => _sprite.Frame0(layer)).ToList();
|
|
SelectButton.Text = Loc.GetString($"marking-{_markingPrototype.ID}");
|
|
}
|
|
|
|
private void UpdateSelection()
|
|
{
|
|
var selected = _markingsModel.IsMarkingSelected(_organ, _layer, _markingPrototype.ID);
|
|
SelectButton.Pressed = selected && _interactive;
|
|
ColorsButton.Visible = selected && _interactive && _markingsModel.IsMarkingColorCustomizable(_organ, _layer, _markingPrototype.ID);
|
|
|
|
if (!selected || !_interactive)
|
|
{
|
|
ColorsButton.Pressed = false;
|
|
ColorsContainer.Visible = false;
|
|
}
|
|
|
|
if (_markingsModel.GetMarking(_organ, _layer, _markingPrototype.ID) is { } marking &&
|
|
_colorSliders is { } sliders)
|
|
{
|
|
for (var i = 0; i < _markingPrototype.Sprites.Count; i++)
|
|
{
|
|
sliders[i].Color = marking.MarkingColors[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
private void SelectButtonPressed(BaseButton.ButtonEventArgs args)
|
|
{
|
|
if (!_interactive)
|
|
{
|
|
SelectButton.Pressed = false;
|
|
return;
|
|
}
|
|
|
|
if (_markingsModel.IsMarkingSelected(_organ, _layer, _markingPrototype.ID))
|
|
{
|
|
if (!_markingsModel.TryDeselectMarking(_organ, _layer, _markingPrototype.ID))
|
|
{
|
|
SelectButton.Pressed = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!_markingsModel.TrySelectMarking(_organ, _layer, _markingPrototype.ID))
|
|
{
|
|
SelectButton.Pressed = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ColorsButtonPressed(BaseButton.ButtonEventArgs args)
|
|
{
|
|
ColorsContainer.Visible = ColorsButton.Pressed;
|
|
|
|
if (_colorSliders is not null)
|
|
return;
|
|
|
|
if (_markingsModel.GetMarking(_organ, _layer, _markingPrototype.ID) is not { } marking)
|
|
return;
|
|
|
|
_colorSliders = new();
|
|
|
|
for (var i = 0; i < _markingPrototype.Sprites.Count; i++)
|
|
{
|
|
var container = new BoxContainer()
|
|
{
|
|
Orientation = LayoutOrientation.Vertical,
|
|
HorizontalExpand = true,
|
|
};
|
|
|
|
ColorsContainer.AddChild(container);
|
|
|
|
var selector = new ColorSelectorSliders();
|
|
selector.SelectorType = ColorSelectorSliders.ColorSelectorType.Hsv;
|
|
|
|
var label = _markingPrototype.Sprites[i] switch
|
|
{
|
|
SpriteSpecifier.Rsi rsi => Loc.GetString($"marking-{_markingPrototype.ID}-{rsi.RsiState}"),
|
|
SpriteSpecifier.Texture texture => Loc.GetString($"marking-{_markingPrototype.ID}-{texture.TexturePath.Filename}"),
|
|
_ => throw new InvalidOperationException("SpriteSpecifier not of known type"),
|
|
};
|
|
|
|
container.AddChild(new Label { Text = label });
|
|
container.AddChild(selector);
|
|
|
|
selector.Color = marking.MarkingColors[i];
|
|
|
|
_colorSliders.Add(selector);
|
|
|
|
var colorIndex = i;
|
|
selector.OnColorChanged += _ =>
|
|
{
|
|
_markingsModel.TrySetMarkingColor(_organ, _layer, _markingPrototype.ID, colorIndex, selector.Color);
|
|
};
|
|
}
|
|
}
|
|
|
|
public bool CheckMatchesSearch(string query)
|
|
{
|
|
return Loc.GetString($"marking-{_markingPrototype.ID}").Contains(query, StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
|
|
public void SetHiddenState(bool state, string query)
|
|
{
|
|
Visible = CheckMatchesSearch(query) ? state : !state;
|
|
}
|
|
|
|
private void OnPressed(GUIBoundKeyEventArgs args)
|
|
{
|
|
if (args.Function != EngineKeyFunctions.UIClick)
|
|
return;
|
|
|
|
Pressed?.Invoke(args, this);
|
|
}
|
|
|
|
private void OnUnpressed(GUIBoundKeyEventArgs args)
|
|
{
|
|
if (args.Function != EngineKeyFunctions.UIClick)
|
|
return;
|
|
|
|
Unpressed?.Invoke(args, this);
|
|
}
|
|
}
|