Files
tbd-station-14/Content.Client/Access/UI/IdCardConsoleWindow.xaml.cs
c4llv07e 64bb8dbdd5 Add door electronics access configuration menu (#17778)
* Add door electronics configuration menu

* Use file-scoped namespaces

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Open door electronics configuration menu only with network configurator

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Doors will now try to move their AccessReaderComponent to their door electronics when the map is initialized

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Make the access list in the id card computer a separate control

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Fix merge conflict

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Remove DoorElectronics tag

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Integrate doors with #17927

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Move door electornics ui stuff to the right place

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Some review fixes

Signed-off-by: c4llv07e <kseandi@gmail.com>

* More fixes

Signed-off-by: c4llv07e <kseandi@gmail.com>

* review fix

Signed-off-by: c4llv07e <kseandi@gmail.com>

* move all accesses from airlock prototypes to door electronics

Signed-off-by: c4llv07e <kseandi@gmail.com>

* rework door electronics config access list

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Remove Linq from the door electronics user interface

* [WIP] Add EntityWhitelist to the activatable ui component

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Better interaction system

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Refactor

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Fix some door electronics not working without AccessReaderComponent

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Move AccessReaderComponent update code to the AccessReaderSystem

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Remove unnecesary newlines in the door access prototypes

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Remove unused variables in access level control

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Remove unnecessary method from the door electronics configuration menu

Signed-off-by: c4llv07e <kseandi@gmail.com>

* [WIP] change access type from string to ProtoId<AccessLevelPrototype>

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Remove unused methods

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Newline fix

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Restored to a functional state

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Fix access configurator not working with door electronics AccessReaderComponent

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Replace all string access fields with ProtoId

Signed-off-by: c4llv07e <kseandi@gmail.com>

* move access level control initialization into Populate method

Signed-off-by: c4llv07e <kseandi@gmail.com>

* Review

---------

Signed-off-by: c4llv07e <kseandi@gmail.com>
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2024-04-01 17:06:13 +11:00

200 lines
7.5 KiB
C#

using System.Linq;
using Content.Shared.Access;
using Content.Shared.Access.Systems;
using Content.Shared.Roles;
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.Access.Components.IdCardConsoleComponent;
namespace Content.Client.Access.UI
{
[GenerateTypedNameReferences]
public sealed partial class IdCardConsoleWindow : DefaultWindow
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly ILogManager _logManager = default!;
private readonly ISawmill _logMill = default!;
private readonly IdCardConsoleBoundUserInterface _owner;
private AccessLevelControl _accessButtons = new();
private readonly List<string> _jobPrototypeIds = new();
private string? _lastFullName;
private string? _lastJobTitle;
private string? _lastJobProto;
public IdCardConsoleWindow(IdCardConsoleBoundUserInterface owner, IPrototypeManager prototypeManager,
List<ProtoId<AccessLevelPrototype>> accessLevels)
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_logMill = _logManager.GetSawmill(SharedIdCardConsoleSystem.Sawmill);
_owner = owner;
FullNameLineEdit.OnTextEntered += _ => SubmitData();
FullNameLineEdit.OnTextChanged += _ =>
{
FullNameSaveButton.Disabled = FullNameSaveButton.Text == _lastFullName;
};
FullNameSaveButton.OnPressed += _ => SubmitData();
JobTitleLineEdit.OnTextEntered += _ => SubmitData();
JobTitleLineEdit.OnTextChanged += _ =>
{
JobTitleSaveButton.Disabled = JobTitleLineEdit.Text == _lastJobTitle;
};
JobTitleSaveButton.OnPressed += _ => SubmitData();
var jobs = _prototypeManager.EnumeratePrototypes<JobPrototype>().ToList();
jobs.Sort((x, y) => string.Compare(x.LocalizedName, y.LocalizedName, StringComparison.CurrentCulture));
foreach (var job in jobs)
{
if (!job.OverrideConsoleVisibility.GetValueOrDefault(job.SetPreference))
{
continue;
}
_jobPrototypeIds.Add(job.ID);
JobPresetOptionButton.AddItem(Loc.GetString(job.Name), _jobPrototypeIds.Count - 1);
}
JobPresetOptionButton.OnItemSelected += SelectJobPreset;
_accessButtons.Populate(accessLevels, prototypeManager);
AccessLevelControlContainer.AddChild(_accessButtons);
foreach (var (id, button) in _accessButtons.ButtonsList)
{
button.OnPressed += _ => SubmitData();
}
}
private void ClearAllAccess()
{
foreach (var button in _accessButtons.ButtonsList.Values)
{
if (button.Pressed)
{
button.Pressed = false;
}
}
}
private void SelectJobPreset(OptionButton.ItemSelectedEventArgs args)
{
if (!_prototypeManager.TryIndex(_jobPrototypeIds[args.Id], out JobPrototype? job))
{
return;
}
JobTitleLineEdit.Text = Loc.GetString(job.Name);
args.Button.SelectId(args.Id);
ClearAllAccess();
// this is a sussy way to do this
foreach (var access in job.Access)
{
if (_accessButtons.ButtonsList.TryGetValue(access, out var button) && !button.Disabled)
{
button.Pressed = true;
}
}
foreach (var group in job.AccessGroups)
{
if (!_prototypeManager.TryIndex(group, out AccessGroupPrototype? groupPrototype))
{
continue;
}
foreach (var access in groupPrototype.Tags)
{
if (_accessButtons.ButtonsList.TryGetValue(access, out var button) && !button.Disabled)
{
button.Pressed = true;
}
}
}
SubmitData();
}
public void UpdateState(IdCardConsoleBoundUserInterfaceState state)
{
PrivilegedIdButton.Text = state.IsPrivilegedIdPresent
? Loc.GetString("id-card-console-window-eject-button")
: Loc.GetString("id-card-console-window-insert-button");
PrivilegedIdLabel.Text = state.PrivilegedIdName;
TargetIdButton.Text = state.IsTargetIdPresent
? Loc.GetString("id-card-console-window-eject-button")
: Loc.GetString("id-card-console-window-insert-button");
TargetIdLabel.Text = state.TargetIdName;
var interfaceEnabled =
state.IsPrivilegedIdPresent && state.IsPrivilegedIdAuthorized && state.IsTargetIdPresent;
var fullNameDirty = _lastFullName != null && FullNameLineEdit.Text != state.TargetIdFullName;
var jobTitleDirty = _lastJobTitle != null && JobTitleLineEdit.Text != state.TargetIdJobTitle;
FullNameLabel.Modulate = interfaceEnabled ? Color.White : Color.Gray;
FullNameLineEdit.Editable = interfaceEnabled;
if (!fullNameDirty)
{
FullNameLineEdit.Text = state.TargetIdFullName ?? string.Empty;
}
FullNameSaveButton.Disabled = !interfaceEnabled || !fullNameDirty;
JobTitleLabel.Modulate = interfaceEnabled ? Color.White : Color.Gray;
JobTitleLineEdit.Editable = interfaceEnabled;
if (!jobTitleDirty)
{
JobTitleLineEdit.Text = state.TargetIdJobTitle ?? string.Empty;
}
JobTitleSaveButton.Disabled = !interfaceEnabled || !jobTitleDirty;
JobPresetOptionButton.Disabled = !interfaceEnabled;
_accessButtons.UpdateState(state.TargetIdAccessList?.ToList() ??
new List<ProtoId<AccessLevelPrototype>>(),
state.AllowedModifyAccessList?.ToList() ??
new List<ProtoId<AccessLevelPrototype>>());
var jobIndex = _jobPrototypeIds.IndexOf(state.TargetIdJobPrototype);
if (jobIndex >= 0)
{
JobPresetOptionButton.SelectId(jobIndex);
}
_lastFullName = state.TargetIdFullName;
_lastJobTitle = state.TargetIdJobTitle;
_lastJobProto = state.TargetIdJobPrototype;
}
private void SubmitData()
{
// Don't send this if it isn't dirty.
var jobProtoDirty = _lastJobProto != null &&
_jobPrototypeIds[JobPresetOptionButton.SelectedId] != _lastJobProto;
_owner.SubmitData(
FullNameLineEdit.Text,
JobTitleLineEdit.Text,
// Iterate over the buttons dictionary, filter by `Pressed`, only get key from the key/value pair
_accessButtons.ButtonsList.Where(x => x.Value.Pressed).Select(x => x.Key).ToList(),
jobProtoDirty ? _jobPrototypeIds[JobPresetOptionButton.SelectedId] : string.Empty);
}
}
}