Files
OldThink/Content.Client/Access/UI/IdCardConsoleWindow.xaml.cs
Remuchi d2d501dbc0 Merge remote-tracking branch 'upstream/master' into upstream
# Conflicts:
#	Content.Client/Access/AccessOverlay.cs
#	Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs
#	Content.Client/Access/UI/IdCardConsoleWindow.xaml
#	Content.Client/Access/UI/IdCardConsoleWindow.xaml.cs
#	Content.Client/Chemistry/UI/InjectorStatusControl.cs
#	Content.Client/StatusIcon/StatusIconOverlay.cs
#	Content.Client/Stylesheets/StyleNano.cs
#	Content.Client/UserInterface/Systems/Chat/ChatUIController.cs
#	Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml
#	Content.Server/Access/Systems/IdCardConsoleSystem.cs
#	Content.Server/Administration/Commands/AGhost.cs
#	Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs
#	Content.Server/Connection/ConnectionManager.cs
#	Content.Server/DeviceLinking/Systems/SignalTimerSystem.cs
#	Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs
#	Content.Server/GameTicking/GameTicker.RoundFlow.cs
#	Content.Server/GameTicking/GameTicker.Spawning.cs
#	Content.Server/Humanoid/Systems/HumanoidAppearanceSystem.cs
#	Content.Server/Resist/EscapeInventorySystem.cs
#	Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs
#	Content.Shared/Access/Components/IdCardConsoleComponent.cs
#	Content.Shared/Anomaly/SharedAnomalySystem.cs
#	Content.Shared/Bed/Sleep/SharedSleepingSystem.cs
#	Content.Shared/Humanoid/SharedHumanoidAppearanceSystem.cs
#	Content.Shared/Lock/LockSystem.cs
#	Content.Shared/RCD/Systems/RCDSystem.cs
#	Content.Shared/Roles/JobPrototype.cs
#	Content.Shared/StatusIcon/StatusIconPrototype.cs
#	Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs
#	Resources/Audio/Machines/attributions.yml
#	Resources/Locale/en-US/rcd/components/rcd-component.ftl
#	Resources/Maps/reach.yml
#	Resources/Prototypes/Catalog/Cargo/cargo_vending.yml
#	Resources/Prototypes/Catalog/Fills/Lockers/heads.yml
#	Resources/Prototypes/Catalog/Fills/Lockers/security.yml
#	Resources/Prototypes/Catalog/ReagentDispensers/beverage.yml
#	Resources/Prototypes/Catalog/VendingMachines/Inventories/boozeomat.yml
#	Resources/Prototypes/Catalog/VendingMachines/Inventories/cola.yml
#	Resources/Prototypes/Catalog/VendingMachines/Inventories/lawdrobe.yml
#	Resources/Prototypes/Catalog/VendingMachines/Inventories/pwrgame.yml
#	Resources/Prototypes/Catalog/VendingMachines/Inventories/shamblersjuice.yml
#	Resources/Prototypes/Catalog/VendingMachines/Inventories/soda.yml
#	Resources/Prototypes/Catalog/VendingMachines/Inventories/spaceup.yml
#	Resources/Prototypes/Catalog/VendingMachines/Inventories/starkist.yml
#	Resources/Prototypes/Catalog/VendingMachines/Inventories/theater.yml
#	Resources/Prototypes/DeviceLinking/sink_ports.yml
#	Resources/Prototypes/Entities/Clothing/Back/duffel.yml
#	Resources/Prototypes/Entities/Clothing/Belt/base_clothingbelt.yml
#	Resources/Prototypes/Entities/Clothing/Neck/misc.yml
#	Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml
#	Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml
#	Resources/Prototypes/Entities/Mobs/Customization/Markings/gauze.yml
#	Resources/Prototypes/Entities/Objects/Devices/Electronics/door.yml
#	Resources/Prototypes/Entities/Objects/Magic/books.yml
#	Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml
#	Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml
#	Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml
#	Resources/Prototypes/Entities/Objects/Misc/tiles.yml
#	Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml
#	Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml
#	Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml
#	Resources/Prototypes/Entities/Structures/Doors/Airlocks/airlocks.yml
#	Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_assembly.yml
#	Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml
#	Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml
#	Resources/Prototypes/Entities/Structures/Doors/Firelocks/firelock.yml
#	Resources/Prototypes/Entities/Structures/Doors/Firelocks/frame.yml
#	Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml
#	Resources/Prototypes/Entities/Structures/Doors/SecretDoor/secret_door.yml
#	Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml
#	Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml
#	Resources/Prototypes/Entities/Structures/Machines/lathe.yml
#	Resources/Prototypes/Entities/Structures/Power/cable_terminal.yml
#	Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml
#	Resources/Prototypes/Entities/Structures/Walls/grille.yml
#	Resources/Prototypes/Recipes/Construction/Graphs/structures/shutter.yml
#	Resources/Prototypes/Recipes/Crafting/Graphs/improvised/flowercrown.yml
#	Resources/Prototypes/Recipes/Crafting/improvised.yml
#	Resources/Prototypes/Roles/Jobs/Security/detective.yml
#	Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml
#	Resources/Prototypes/Roles/Jobs/Security/security_officer.yml
#	Resources/Prototypes/Roles/Jobs/Security/warden.yml
#	Resources/Prototypes/StatusEffects/health.yml
#	Resources/Prototypes/Voice/speech_emotes.yml
#	Resources/Prototypes/lobbyscreens.yml
#	Resources/Textures/Clothing/OuterClothing/Hardsuits/ERTSuits/ertchaplain.rsi/equipped-OUTERCLOTHING-body-slim.png
#	Resources/Textures/Decals/bricktile.rsi/white_box.png
#	Resources/Textures/Objects/Misc/books.rsi/meta.json
#	Resources/migration.yml
2024-04-13 11:29:33 +07:00

272 lines
10 KiB
C#

using System.Linq;
using System.Numerics;
using Content.Shared.Access;
using Content.Shared.Access.Components;
using Content.Shared.Roles;
using Robust.Client.AutoGenerated;
using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
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!;
[Dependency] private readonly IResourceCache _resource = default!; //WD-EDIT
[Dependency] private readonly IEntityManager _entityManager = default!; //WD-EDIT
private readonly IdCardConsoleBoundUserInterface _owner;
private AccessLevelControl _accessButtons = new();
private readonly Dictionary<string, TextureButton> _jobIconButtons = new(); //WD-EDIT
private readonly List<string> _jobPrototypeIds = new();
private string? _lastFullName;
private string? _lastJobTitle;
private string? _lastJobProto;
private string? _lastJobIcon; //WD-EDIT
public IdCardConsoleWindow(
IdCardConsoleBoundUserInterface owner,
IPrototypeManager prototypeManager,
List<ProtoId<AccessLevelPrototype>> accessLevels)
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_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();
}
//WD-EDIT
if (!_entityManager.TryGetComponent<IdCardConsoleComponent>(owner.Owner, out var idConsoleComponent))
return;
var path = new ResPath("/Textures/Interface/Misc/job_icons.rsi");
_resource.TryGetResource(path, out RSIResource? rsi);
if (rsi == null)
return;
foreach (var jobIcon in idConsoleComponent.JobIcons)
{
var newButton = new TextureButton
{
TextureNormal = rsi.RSI.TryGetState(jobIcon, out var state) ? state.Frame0
: rsi.RSI.TryGetState("CustomId", out var customState) ? customState.Frame0
: null,
Scale = new Vector2(5, 5)
};
_jobIconButtons.Add(jobIcon, newButton);
newButton.OnPressed += _ =>
{
_lastJobIcon = "JobIcon" + jobIcon;
SubmitData();
};
JobIconsGrid.AddChild(newButton);
}
//WD-EDIT
}
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;
}
}
}
_lastJobIcon = job.Icon;
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);
}
//WD-EDIT
if (_resource.TryGetResource(new ResPath("/Textures/Interface/Misc/job_icons.rsi"), out RSIResource? rsi))
{
CurrentJobIcon.RemoveAllChildren();
var newLabel = new Label
{
Text = "Текущая выбранная иконка для роли: "
};
CurrentJobIcon.AddChild(newLabel);
var newIcon = new TextureRect
{
Texture = rsi.RSI.TryGetState(state.TargetIdJobIcon?.Replace("JobIcon", ""), out var iconState)
? iconState.Frame0
: rsi.RSI.TryGetState("CustomId", out var customState)
? customState.Frame0
: null,
TextureScale = new Vector2(4, 4)
};
CurrentJobIcon.AddChild(newIcon);
}
foreach (var (jobIcon, button) in _jobIconButtons)
{
button.Disabled = !interfaceEnabled;
button.Pressed = state.TargetIdJobIcon?.Contains(jobIcon) ?? false;
}
//WD-EDIT
_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,
_lastJobIcon);
}
}
}