HumanoidMarkingModifierWindow.xaml.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. using Content.Shared.Humanoid;
  2. using Content.Shared.Humanoid.Markings;
  3. using Content.Shared.Humanoid.Prototypes;
  4. using Robust.Client.AutoGenerated;
  5. using Robust.Client.UserInterface.Controls;
  6. using Robust.Client.UserInterface.CustomControls;
  7. using Robust.Client.UserInterface.XAML;
  8. using Robust.Shared.Prototypes;
  9. namespace Content.Client.Humanoid;
  10. // hack for a panel that modifies an entity's markings on demand
  11. [GenerateTypedNameReferences]
  12. public sealed partial class HumanoidMarkingModifierWindow : DefaultWindow
  13. {
  14. public Action<MarkingSet>? OnMarkingAdded;
  15. public Action<MarkingSet>? OnMarkingRemoved;
  16. public Action<MarkingSet>? OnMarkingColorChange;
  17. public Action<MarkingSet>? OnMarkingRankChange;
  18. public Action<HumanoidVisualLayers, CustomBaseLayerInfo?>? OnLayerInfoModified;
  19. private readonly IPrototypeManager _protoMan = default!;
  20. private readonly Dictionary<HumanoidVisualLayers, HumanoidBaseLayerModifier> _modifiers = new();
  21. public HumanoidMarkingModifierWindow()
  22. {
  23. RobustXamlLoader.Load(this);
  24. _protoMan = IoCManager.Resolve<IPrototypeManager>();
  25. foreach (var layer in Enum.GetValues<HumanoidVisualLayers>())
  26. {
  27. var modifier = new HumanoidBaseLayerModifier(layer);
  28. BaseLayersContainer.AddChild(modifier);
  29. _modifiers.Add(layer, modifier);
  30. modifier.OnStateChanged += () => OnStateChanged(layer, modifier);
  31. }
  32. MarkingPickerWidget.OnMarkingAdded += set => OnMarkingAdded!(set);
  33. MarkingPickerWidget.OnMarkingRemoved += set => OnMarkingRemoved!(set);
  34. MarkingPickerWidget.OnMarkingColorChange += set => OnMarkingColorChange!(set);
  35. MarkingPickerWidget.OnMarkingRankChange += set => OnMarkingRankChange!(set);
  36. MarkingForced.OnToggled += args => MarkingPickerWidget.Forced = args.Pressed;
  37. MarkingIgnoreSpecies.OnToggled += args => MarkingPickerWidget.Forced = args.Pressed;
  38. MarkingPickerWidget.Forced = MarkingForced.Pressed;
  39. MarkingPickerWidget.IgnoreSpecies = MarkingForced.Pressed;
  40. }
  41. private void OnStateChanged(HumanoidVisualLayers layer, HumanoidBaseLayerModifier modifier)
  42. {
  43. if (!modifier.Enabled)
  44. {
  45. OnLayerInfoModified?.Invoke(layer, null);
  46. return;
  47. }
  48. string? state = _protoMan.HasIndex<HumanoidSpeciesSpriteLayer>(modifier.Text) ? modifier.Text : null;
  49. OnLayerInfoModified?.Invoke(layer, new CustomBaseLayerInfo(state, modifier.Color));
  50. }
  51. public void SetState(
  52. MarkingSet markings,
  53. string species,
  54. Sex sex,
  55. Color skinColor,
  56. Dictionary<HumanoidVisualLayers, CustomBaseLayerInfo> info
  57. )
  58. {
  59. foreach (var (layer, modifier) in _modifiers)
  60. {
  61. if (!info.TryGetValue(layer, out var layerInfo))
  62. {
  63. modifier.SetState(false, string.Empty, Color.White);
  64. continue;
  65. }
  66. modifier.SetState(true, layerInfo.Id ?? string.Empty, layerInfo.Color ?? Color.White);
  67. }
  68. var eyesColor = Color.White;
  69. if (info.TryGetValue(HumanoidVisualLayers.Eyes, out var eyes) && eyes.Color != null)
  70. {
  71. eyesColor = eyes.Color.Value;
  72. }
  73. MarkingPickerWidget.SetData(markings, species, sex, skinColor, eyesColor);
  74. }
  75. private sealed class HumanoidBaseLayerModifier : BoxContainer
  76. {
  77. private CheckBox _enable;
  78. private LineEdit _lineEdit;
  79. private ColorSelectorSliders _colorSliders;
  80. private BoxContainer _infoBox;
  81. public bool Enabled => _enable.Pressed;
  82. public string Text => _lineEdit.Text;
  83. public Color Color => _colorSliders.Color;
  84. public Action? OnStateChanged;
  85. public HumanoidBaseLayerModifier(HumanoidVisualLayers layer)
  86. {
  87. HorizontalExpand = true;
  88. Orientation = LayoutOrientation.Vertical;
  89. var labelBox = new BoxContainer
  90. {
  91. MinWidth = 250,
  92. HorizontalExpand = true
  93. };
  94. AddChild(labelBox);
  95. labelBox.AddChild(new Label
  96. {
  97. HorizontalExpand = true,
  98. Text = layer.ToString()
  99. });
  100. _enable = new CheckBox
  101. {
  102. Text = "Enable",
  103. HorizontalAlignment = HAlignment.Right
  104. };
  105. labelBox.AddChild(_enable);
  106. _infoBox = new BoxContainer
  107. {
  108. Orientation = LayoutOrientation.Vertical,
  109. Visible = false
  110. };
  111. _enable.OnToggled += args =>
  112. {
  113. _infoBox.Visible = args.Pressed;
  114. OnStateChanged!();
  115. };
  116. var lineEditBox = new BoxContainer();
  117. lineEditBox.AddChild(new Label { Text = "Prototype id: "});
  118. // TODO: This line edit should really be an options / dropdown selector, not text.
  119. _lineEdit = new() { MinWidth = 200 };
  120. _lineEdit.OnTextEntered += args => OnStateChanged!();
  121. lineEditBox.AddChild(_lineEdit);
  122. _infoBox.AddChild(lineEditBox);
  123. _colorSliders = new();
  124. _colorSliders.OnColorChanged += color => OnStateChanged!();
  125. _infoBox.AddChild(_colorSliders);
  126. AddChild(_infoBox);
  127. }
  128. public void SetState(bool enabled, string state, Color color)
  129. {
  130. _enable.Pressed = enabled;
  131. _infoBox.Visible = enabled;
  132. _lineEdit.Text = state;
  133. _colorSliders.Color = color;
  134. }
  135. }
  136. }