Skip to content
13 changes: 6 additions & 7 deletions Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
using Content.Shared.Containers.ItemSlots;
using Content.Shared.CrewManifest;
using Content.Shared.Roles;
using Content.Shared.StatusIcon;
using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
using static Content.Shared.Access.Components.IdCardConsoleComponent;
// Starlight-edit: Start
using Robust.Client.UserInterface;
using Content.Shared._Starlight.Access;
// Starlight-edit: End

namespace Content.Client.Access.UI
{
Expand Down Expand Up @@ -66,8 +65,8 @@ protected override void UpdateState(BoundUserInterfaceState state)
var castState = (IdCardConsoleBoundUserInterfaceState) state;
_window?.UpdateState(castState);
}

public void SubmitData(string newFullName, string newJobTitle, List<ProtoId<AccessLevelPrototype>> newAccessList, ProtoId<JobPrototype>? newJobPrototype) // Starlight: Nullable newJobPrototype
// Starlight-edit: Start
public void SubmitData(string newFullName, string newJobTitle, List<ProtoId<AccessLevelPrototype>> newAccessList, ProtoId<JobPrototype>? newJobPrototype, ProtoId<JobIconPrototype>? newJobIcon) // Starlight: Nullable newJobPrototype, newJobIcon
{
if (newFullName.Length > _maxNameLength)
newFullName = newFullName[.._maxNameLength];
Expand All @@ -79,14 +78,14 @@ public void SubmitData(string newFullName, string newJobTitle, List<ProtoId<Acce
newFullName,
newJobTitle,
newAccessList,
newJobPrototype));
newJobPrototype,
newJobIcon));
}
// Starlight-edit: Start
// Starlight-edit: End

public void OnGroupSelected(ProtoId<AccessGroupPrototype> group)
{
SendMessage(new IdCardConsoleComponent.AccessGroupSelectedMessage(group)); // Starlight-edit
}
// Starlight-edit: End
}
}
8 changes: 7 additions & 1 deletion Content.Client/Access/UI/IdCardConsoleWindow.xaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"
MinSize="650 290">
MinSize="650 340">
<BoxContainer Orientation="Vertical">
<!-- Privileged and target IDs, crew manifest button. -->
<GridContainer Columns="2">
Expand Down Expand Up @@ -29,6 +29,12 @@
<Button Name="JobTitleSaveButton" Text="{Loc 'id-card-console-window-save-button'}" Disabled="True" />
</GridContainer>
<Control MinSize="0 8" />
<!-- Starlight-start: Job icon selection -->
<Label Name="JobIconLabel" Text="{Loc 'agent-id-card-job-icon-label'}"/>
<GridContainer Name="IconGrid" Columns="10">
</GridContainer>
<Control MinSize="0 8" />
<!-- Starlight-end -->
<!-- Job preset selection, grant/revoke all access buttons. -->
<BoxContainer Margin="0 8 0 4">
<BoxContainer>
Expand Down
80 changes: 79 additions & 1 deletion Content.Client/Access/UI/IdCardConsoleWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
using System.Linq;
using System.Numerics;
using Content.Client._Starlight.Access.UI; // Starlight-edit
using Content.Client.Stylesheets;
using Content.Shared.Access;
using Content.Shared.Access.Systems;
using Content.Shared.CCVar;
using Content.Shared.Roles;
using Content.Shared.StatusIcon;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
Expand All @@ -20,21 +25,27 @@ public sealed partial class IdCardConsoleWindow : DefaultWindow
[Dependency] private IConfigurationManager _cfgManager = default!;
[Dependency] private IPrototypeManager _prototypeManager = default!;
[Dependency] private ILogManager _logManager = default!;
[Dependency] private IEntitySystemManager _entitySystem = default!; // Starlight-edit
private readonly ISawmill _logMill = default!;
private readonly SpriteSystem _spriteSystem; // Starlight-edit

private IdCardConsoleBoundUserInterface? _owner; // Starlight edit

// CCVar.
private int _maxNameLength;
private int _maxIdJobLength;

private const int JobIconColumnCount = 10; // Starlight-edit

private AccessLevelControl _accessButtons = new();
private AccessGroupControl _accessGroups = new(); // Starlight-edit: Access Groups
private readonly List<string> _jobPrototypeIds = new();

private string? _lastFullName;
private string? _lastJobTitle;
private string? _lastJobProto;
private ProtoId<JobIconPrototype> _currentJobIcon = "JobIconUnknown"; // Starlight-edit
private bool _allIconsUnlocked; // Starlight-edit

// The job that will be picked if the ID doesn't have a job on the station.
private static ProtoId<JobPrototype> _defaultJob = "Assistant";
Expand All @@ -54,6 +65,7 @@ public IdCardConsoleWindow()
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_logMill = _logManager.GetSawmill(SharedIdCardConsoleSystem.Sawmill);
_spriteSystem = _entitySystem.GetEntitySystem<SpriteSystem>(); // Starlight-edit

// Starlight _owner = owner; // Starlight edit

Expand Down Expand Up @@ -147,6 +159,12 @@ private void SelectJobPreset(OptionButton.ItemSelectedEventArgs args)
JobTitleLineEdit.Text = Loc.GetString(job.Name);
args.Button.SelectId(args.Id);

// Starlight-edit: Start - picking a job preset will reset the id card's hud icon to that job's default.
// This can be overrided by picking another icon in the UI.
_currentJobIcon = job.Icon;
PopulateIcons(true);
// Starlight-edit: End

SetAllAccess(false);

// Collect all access levels for this job (direct + all groups)
Expand Down Expand Up @@ -218,6 +236,13 @@ public void UpdateState(IdCardConsoleBoundUserInterfaceState state)

JobTitleSaveButton.Disabled = !interfaceEnabled || !jobTitleDirty;

// Starlight-edit: Start - job icon selection
_currentJobIcon = state.TargetIdJobIcon ?? _currentJobIcon;
_allIconsUnlocked = state.AllIconsUnlocked;
JobIconLabel.Modulate = interfaceEnabled ? Color.White : Color.Gray;
PopulateIcons(interfaceEnabled);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
// Starlight-edit: End

JobPresetOptionButton.Disabled = !interfaceEnabled;

// Starlight-edit: Start
Expand Down Expand Up @@ -360,6 +385,58 @@ public void UpdateState(IdCardConsoleBoundUserInterfaceState state)
_lastJobProto = state.TargetIdJobPrototype;
}

// Starlight-edit: Start - job icon grid, based on AgentIDCardWindow/JobIdentityConsoleWindow
private void PopulateIcons(bool enabled)
{
IconGrid.RemoveAllChildren();

var jobIconButtonGroup = new ButtonGroup();
var i = 0;
var icons = _prototypeManager.EnumeratePrototypes<JobIconPrototype>()
.Where(icon => icon.AllowSelection && (_allIconsUnlocked || icon.Tags.Contains(SharedIdCardConsoleSystem.CrewJobIconTag)))
.ToList();
icons.Sort((x, y) => string.Compare(x.LocalizedJobName, y.LocalizedJobName, StringComparison.CurrentCulture));

foreach (var jobIcon in icons)
{
var styleBase = StyleClass.ButtonOpenBoth;
var modulo = i % JobIconColumnCount;
if (modulo == 0)
styleBase = StyleClass.ButtonOpenRight;
else if (modulo == JobIconColumnCount - 1)
styleBase = StyleClass.ButtonOpenLeft;

var jobIconButton = new Button
{
Access = AccessLevel.Public,
StyleClasses = { styleBase },
MaxSize = new Vector2(42, 28),
Group = jobIconButtonGroup,
Pressed = _currentJobIcon == jobIcon.ID,
Disabled = !enabled,
ToolTip = jobIcon.LocalizedJobName,
};

var jobIconTexture = new TextureRect
{
Texture = _spriteSystem.Frame0(jobIcon.Icon),
TextureScale = new Vector2(2.5f, 2.5f),
Stretch = TextureRect.StretchMode.KeepCentered,
};

jobIconButton.AddChild(jobIconTexture);
jobIconButton.OnPressed += _ =>
{
_currentJobIcon = jobIcon.ID;
SubmitData();
};
IconGrid.AddChild(jobIconButton);

i++;
}
}
// Starlight-edit: End

private void SubmitData()
{
// Don't send this if it isn't dirty.
Expand All @@ -371,7 +448,8 @@ private void SubmitData()
FullNameLineEdit.Text,
JobTitleLineEdit.Text,
_pendingPressedAccessLevels.ToList(),
jobProtoDirty ? _jobPrototypeIds[JobPresetOptionButton.SelectedId] : null);
jobProtoDirty ? _jobPrototypeIds[JobPresetOptionButton.SelectedId] : null,
_currentJobIcon);

// Clear the override after submit so next UpdateState can update pressed state as normal
_pendingAccessOverride = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using Content.Shared._Starlight.Access.Components;
using Content.Shared.CCVar;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.StatusIcon;
using Robust.Client.UserInterface;
using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
using static Content.Shared._Starlight.Access.Components.JobIdentityConsoleComponent;

namespace Content.Client._Starlight.Access.UI;

public sealed partial class JobIdentityConsoleBoundUserInterface : BoundUserInterface
{
[Dependency] private IConfigurationManager _cfgManager = default!;

private JobIdentityConsoleWindow? _window;

private readonly int _maxIdJobLength;

public JobIdentityConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
_maxIdJobLength = _cfgManager.GetCVar(CCVars.MaxIdJobLength);
}

protected override void Open()
{
base.Open();

var requiredTags = EntMan.GetComponent<JobIdentityConsoleComponent>(Owner).RequiredTags;

_window = this.CreateWindow<JobIdentityConsoleWindow>();
_window.Initialize(this, requiredTags);
_window.Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName;

_window.PrivilegedIdButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(PrivilegedIdCardSlotId));
_window.TargetIdButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(TargetIdCardSlotId));

_window.OnClose += Close;
_window.OpenCentered();
}

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;

_window?.Dispose();
}

protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
var castState = (JobIdentityConsoleBoundUserInterfaceState) state;
_window?.UpdateState(castState);
}

public void SubmitData(string newJobTitle, ProtoId<JobIconPrototype> newJobIcon)
{
if (newJobTitle.Length > _maxIdJobLength)
newJobTitle = newJobTitle[.._maxIdJobLength];

SendMessage(new WriteJobIdentityMessage(newJobTitle, newJobIcon));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="{Loc 'job-identity-console-window-title'}"
MinSize="420 280">
<BoxContainer Orientation="Vertical">
<!-- Privileged and target IDs. -->
<GridContainer Columns="3" HorizontalExpand="True">
<Label Text="{Loc 'id-card-console-window-privileged-id'}" />
<Button Name="PrivilegedIdButton" Access="Public"/>
<Label Name="PrivilegedIdLabel" />

<Label Text="{Loc 'id-card-console-window-target-id'}" />
<Button Name="TargetIdButton" Access="Public"/>
<Label Name="TargetIdLabel" />
</GridContainer>
<Control MinSize="0 8" />
<!-- Job title editing. -->
<GridContainer Columns="3" HSeparationOverride="4">
<Label Name="JobTitleLabel" Text="{Loc 'id-card-console-window-job-title-label'}" />
<LineEdit Name="JobTitleLineEdit" HorizontalExpand="True" />
<Button Name="JobTitleSaveButton" Text="{Loc 'id-card-console-window-save-button'}" Disabled="True" />
</GridContainer>
<Control MinSize="0 8" />
<!-- Job icon selection. -->
<Label Name="IconGridLabel" Text="{Loc 'agent-id-card-job-icon-label'}"/>
<GridContainer Name="IconGrid" Columns="10">
<!-- Job icon buttons are generated in code -->
</GridContainer>
</BoxContainer>
</DefaultWindow>
Loading
Loading