New Surgery UI (#5107)

* One Commit ops

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Remove one Line

* Readonly variable

* Better Switch cases

* Actually better this way

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Sir Warock 2026-01-03 14:27:35 +01:00 committed by GitHub
parent 5885d4db79
commit 53e4097bbf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 249 additions and 27 deletions

View File

@ -0,0 +1,43 @@
using Content.Client.Stylesheets;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using static Content.Client.Stylesheets.StylesheetHelpers;
namespace Content.Client._DV.Stylesheets.Sheetlets;
[CommonSheetlet]
public sealed class SurgeryTextureButtonSheetlet <T> : Sheetlet<T> where T : PalettedStylesheet
{
private readonly Color _dollColor = Color.FromHex("#639bff");
public override StyleRule[] GetRules(T sheet, object config)
{
return
[
E<TextureButton>()
.Identifier("SurgeryTextureButton")
.PseudoHovered()
.Modulate(sheet.PositivePalette.HoveredElement),
E<TextureButton>()
.Identifier("SurgeryTextureButton")
.PseudoPressed()
.Modulate(sheet.PositivePalette.PressedElement),
E<TextureButton>()
.Identifier("SurgeryTextureButton")
.PseudoNormal()
.Modulate(_dollColor),
E<TextureButton>()
.Identifier("OpenIncision")
.PseudoHovered()
.Modulate(sheet.PositivePalette.HoveredElement),
E<TextureButton>()
.Identifier("OpenIncision")
.PseudoPressed()
.Modulate(sheet.PositivePalette.PressedElement),
E<TextureButton>()
.Identifier("OpenIncision")
.PseudoNormal()
.Modulate(sheet.HighlightPalette.HoveredElement),
];
}
}

View File

@ -1,11 +1,14 @@
using Content.Client._Shitmed.Choice.UI;
using Content.Client.Administration.UI.CustomControls;
using Content.Shared._Shitmed.Medical.Surgery;
using Content.Shared._Shitmed.Medical.Surgery.Steps.Parts; // DeltaV - New UI
using Content.Shared.Body.Components;
using Content.Shared.Body.Part;
using Content.Shared.Humanoid;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Client.UserInterface.Controls; // DeltaV - New UI
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
@ -24,6 +27,7 @@ public sealed class SurgeryBui : BoundUserInterface
private bool _isBody;
private (EntityUid Ent, EntProtoId Proto)? _surgery;
private readonly List<EntProtoId> _previousSurgeries = new();
private (EntityUid Ent, TextureButton)? _previousPart; // DeltaV - New UI
public SurgeryBui(EntityUid owner, Enum uiKey) : base(owner, uiKey) => _system = _entities.System<SurgerySystem>();
protected override void ReceiveMessage(BoundUserInterfaceMessage message)
@ -64,6 +68,7 @@ public sealed class SurgeryBui : BoundUserInterface
_isBody = false;
_surgery = null;
_previousSurgeries.Clear();
DeactivateOtherParts(); // DeltaV - New UI
View(ViewType.Parts);
};
@ -138,16 +143,37 @@ public sealed class SurgeryBui : BoundUserInterface
return GetScore(a.PartType) - GetScore(b.PartType);
});
foreach (var (netEntity, entity, partName, _) in options)
// DeltaV Start - New UI
foreach (var textureButton in _window.Buttons)
{
textureButton.Visible = false;
textureButton.StyleIdentifier = "SurgeryTextureButton";
}
// DeltaV End - New UI
foreach (var (netEntity, entity, partName, bodyPartType) in options) // DeltaV - New UI
{
//var netPart = _entities.GetNetEntity(part.Owner);
var surgeries = state.Choices[netEntity];
// Delta Start - New UI
var button = GetBodyPartTextureButton(entity, bodyPartType);
if (button != null)
{
button.Visible = true;
button.OnPressed += _ => OnPartPressed(netEntity, surgeries);
if (_entities.HasComponent<IncisionOpenComponent>(entity))
button.StyleIdentifier = "OpenIncision";
}
else
{
var partButton = new ChoiceControl();
partButton.Set(partName, null);
partButton.Button.OnPressed += _ => OnPartPressed(netEntity, surgeries);
_window.Parts.AddChild(partButton);
}
// Delta End - New UI
foreach (var surgeryId in surgeries)
{
@ -227,7 +253,35 @@ public sealed class SurgeryBui : BoundUserInterface
_part = _entities.GetEntity(netPart);
_isBody = _entities.HasComponent<BodyComponent>(_part);
var body = _entities.GetComponent<BodyPartComponent>(_part.Value).Body!.Value; // DeltaV
// DeltaV Start - New UI
var bodyPart = _entities.GetComponent<BodyPartComponent>(_part.Value);
var body = bodyPart.Body!.Value;
if (_previousPart != null)
{
(var previousEnt, var previousButton) = _previousPart.Value;
if (!_entities.HasComponent<IncisionOpenComponent>(previousEnt))
previousButton.StyleIdentifier = "SurgeryTextureButton";
}
var button = GetBodyPartTextureButton(_part.Value, bodyPart.PartType);
if (button != null && button.Pressed)
{
_previousPart = (_part.Value, button);
DeactivateOtherParts(button);
}
else if (button != null && !button.Pressed)
{
_part = null;
_isBody = false;
_surgery = null;
_previousSurgeries.Clear();
View(ViewType.Parts);
return;
}
// DeltaV End - New UI
_window.Surgeries.RemoveAllChildren();
var surgeries = new List<(Entity<SurgeryComponent> Ent, EntProtoId Id, string Name)>();
@ -277,6 +331,58 @@ public sealed class SurgeryBui : BoundUserInterface
View(ViewType.Surgeries);
}
// DeltaV Start - New UI
private TextureButton? GetBodyPartTextureButton(EntityUid entity, BodyPartType? partType)
{
if (_window == null
|| !_entities.TryGetComponent(entity, out BodyPartComponent? bodyPart))
return null;
var isLeftPart = bodyPart.Symmetry.HasFlag(BodyPartSymmetry.Left);
switch (partType)
{
case BodyPartType.Torso:
var isHumanoid = _entities.HasComponent<HumanoidAppearanceComponent>(bodyPart.Body);
return isHumanoid ? _window.ChestButton : _window.CarpButton;
case BodyPartType.Head:
return _window.HeadButton;
case BodyPartType.Arm:
return isLeftPart ? _window.LArmButton : _window.RArmButton;
case BodyPartType.Hand:
return isLeftPart ? _window.LHandButton : _window.RHandButton;
case BodyPartType.Leg:
return isLeftPart ? _window.LLegButton : _window.RLegButton;
case BodyPartType.Foot:
return isLeftPart ? _window.LFootButton : _window.RFootButton;
case BodyPartType.Tail:
case BodyPartType.Other:
case null:
return null;
default:
throw new ArgumentOutOfRangeException(nameof(partType), partType, null);
}
}
/// <summary>
/// Deactivates all other buttons that are currently active.
/// </summary>
/// <param name="activatedButton">The button that should be the only active button.</param>
private void DeactivateOtherParts(TextureButton? activatedButton = null)
{
if (_window == null)
return;
foreach (var button in _window.Buttons)
{
if (activatedButton == button)
continue;
button.Pressed = false;
}
}
// DeltaV End - New UI
private void RefreshUI()
{
if (_window == null

View File

@ -1,9 +1,65 @@
<controls:SurgeryWindow
<controls:FancyWindow
xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client._Shitmed.Medical.Surgery"
xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"
xmlns:graphics="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
xmlns:customcontrols="clr-namespace:Content.Client.Administration.UI.CustomControls"
xmlns:ui="clr-namespace:Content.Client._Shitmed.Medical.Surgery"
MinSize="400 400">
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" VerticalExpand="True" MinSize="570, 336">
<BoxContainer Orientation="Vertical" HorizontalExpand="False" VerticalExpand="False" MinSize="264, 408">
<TextureRect Name="Texture" TextureScale="6 6"
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUIBackground.png" Access="Public"
HorizontalAlignment="Center" VerticalAlignment="Center"
Stretch="KeepAspectCentered" StyleClasses="">
<PanelContainer>
<TextureButton
Name="CarpButton" Scale="8 8" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0 0 0 11"
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUICarp.png" Access="Public"/>
<TextureButton
Name="ChestButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0 0 0 11"
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUITorso.png" Access="Public"/>
<TextureButton
Name="HeadButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
VerticalAlignment="Top" HorizontalAlignment="Center" Margin="0 30 0 0"
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUIHead.png" Access="Public"/>
<TextureButton
Name="RArmButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
VerticalAlignment="Center" HorizontalAlignment="Left" Margin="30 0 0 47"
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUIRArm.png" Access="Public"/>
<TextureButton
Name="RHandButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
VerticalAlignment="Center" HorizontalAlignment="Left" Margin="30 61 0 0"
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUIRHand.png" Access="Public"/>
<TextureButton
Name="RLegButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
VerticalAlignment="Bottom" HorizontalAlignment="Left" Margin="78 0 0 42"
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUIRLeg.png" Access="Public"/>
<TextureButton
Name="RFootButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
VerticalAlignment="Bottom" HorizontalAlignment="Left" Margin="54 0 0 30"
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUIRFoot.png" Access="Public"/>
<TextureButton
Name="LArmButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0 0 30 47"
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUILArm.png" Access="Public"/>
<TextureButton
Name="LHandButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0 61 30 0"
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUILHand.png" Access="Public"/>
<TextureButton
Name="LLegButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="0 0 78 42"
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUILLeg.png" Access="Public"/>
<TextureButton
Name="LFootButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="0 0 54 30"
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUILFoot.png" Access="Public"/>
</PanelContainer>
</TextureRect>
</BoxContainer>
<customcontrols:VSeparator StyleClasses="LowDivider" />
<BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True">
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="0 0 0 10">
<Button Name="PartsButton" Access="Public" Text="{Loc 'surgery-ui-window-parts'}"
@ -13,11 +69,12 @@
<Button Name="StepsButton" Access="Public" Text="{Loc 'surgery-ui-window-steps'}"
HorizontalExpand="True" StyleClasses="OpenBoth" />
</BoxContainer>
<cc:HSeparator />
<customcontrols:HSeparator />
<ScrollContainer VScrollEnabled="True" HorizontalExpand="True" VerticalExpand="True">
<BoxContainer Name="Parts" Access="Public" Orientation="Vertical" Visible="False" />
<BoxContainer Name="Surgeries" Access="Public" Orientation="Vertical" Visible="False" />
<BoxContainer Name="Steps" Access="Public" Orientation="Vertical" Visible="False" />
</ScrollContainer>
</BoxContainer>
</controls:SurgeryWindow>
</BoxContainer>
</controls:FancyWindow>

View File

@ -1,14 +1,30 @@
using Content.Client.UserInterface.Controls; // DeltaV - New UI
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.Controls; // DeltaV - New UI
using Robust.Client.UserInterface.XAML;
namespace Content.Client._Shitmed.Medical.Surgery;
[GenerateTypedNameReferences]
public sealed partial class SurgeryWindow : DefaultWindow
public sealed partial class SurgeryWindow : FancyWindow
{
public List<TextureButton> Buttons { get; } = []; // DeltaV - New UI
public SurgeryWindow()
{
RobustXamlLoader.Load(this);
// DeltaV Start - New UI
Buttons.Add(ChestButton);
Buttons.Add(HeadButton);
Buttons.Add(LArmButton);
Buttons.Add(LHandButton);
Buttons.Add(RArmButton);
Buttons.Add(RHandButton);
Buttons.Add(LLegButton);
Buttons.Add(LFootButton);
Buttons.Add(RLegButton);
Buttons.Add(RFootButton);
Buttons.Add(CarpButton);
// DeltaV End - New UI
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B