CatStation/Content.Client/Communications/UI/Widgets/AlertLevelControls.xaml.cs
Whatstone 041a7e6504
Scrolling text screens (#43997)
* Scrolling text screens

* remove ScrollingTextScreenComponent, fix comments

* shave a pixel off of the frame, commas cut off

* logMissing to false, state does may not exist

* variable timing, offset array serializer

* namespaces are a state of mind

* Use CustomArraySerializer instead of a one-off

* better alphabetize punctuation text

* Unneeded VV access, 4-space meta.json

* Subscription attributes

* cleanup pass

* shift left

* AJCM's suggestions

Co-authored-by: AJCM-git <60196617+AJCM-git@users.noreply.github.com>

* PadRight returns a string.

* kill the loop, use funny division instead

* smoother animations, dark stripe on outer frame

* Update for the new comms console UI

* communications console changes

* can't spell pain without UI

* the ocho

* it's big brain time

* just a touch wider

* UI polish pass - forgive the sins

* look at my attributions dog

* EDITED

* Text screen layer init deferred until startup

* that's a new one

---------

Co-authored-by: AJCM-git <60196617+AJCM-git@users.noreply.github.com>
2026-08-15 22:03:22 +00:00

149 lines
5.4 KiB
C#

using Content.Shared.AlertLevel;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
namespace Content.Client.Communications.UI.Widgets;
/// <summary>
/// A set of controls to change the alert level for a station.
/// </summary>
[GenerateTypedNameReferences]
public sealed partial class AlertLevelControls : BoxContainer
{
[Dependency] private ILocalizationManager _loc = default!;
[Dependency] private IPrototypeManager _protoman = default!;
private bool _alertLevelSelectable;
private ProtoId<AlertLevelPrototype>? _currentAlertLevel = null;
public event Action<string>? OnAlertLevelChanged;
public AlertLevelControls()
{
IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this);
AlertLevelSelector.OnItemSelected += args =>
{
AlertLevelSelector.Select(args.Id);
EnableDisableConfirmLevelChangeButton();
};
ConfirmAlertLevelButton.OnPressed += _ =>
{
var metadata = AlertLevelSelector.GetItemMetadata(AlertLevelSelector.SelectedId);
if (metadata is ProtoId<AlertLevelPrototype> cast)
{
OnAlertLevelChanged?.Invoke(cast);
}
};
AlertLevelSelector.Disabled = !_alertLevelSelectable;
}
/// <summary>
/// Updates the UI components to display the current alert level and the
/// selectable alert levels
/// </summary>
public void UpdateAlertLevels(List<ProtoId<AlertLevelPrototype>>? selectableAlertLevels, ProtoId<AlertLevelPrototype> currentAlertLevel, bool alertLevelSelectable)
{
_alertLevelSelectable = alertLevelSelectable;
_currentAlertLevel = currentAlertLevel;
CurrentAlertLevelLabel.Text = GetLocalizedAlertName(currentAlertLevel);
if (_protoman.TryIndex(currentAlertLevel, out var alertData))
{
CurrentAlertLevelLabel.ModulateSelfOverride = alertData.Color;
}
else
{
CurrentAlertLevelLabel.ModulateSelfOverride = Color.White;
}
AlertLevelSelector.Disabled = selectableAlertLevels == null || !_alertLevelSelectable;
// If user had changed the selection, but hadn't pressed the confirm
// button at the point we received an update message, we want to
// remember what they had selected, so we can attempt to re-select it
// if it's still an option in the new set of alert level possibilities.
ProtoId<AlertLevelPrototype>? previousSelection = null;
if (AlertLevelSelector.ItemCount > 1)
{
var metadata = AlertLevelSelector.GetItemMetadata(AlertLevelSelector.SelectedId);
if (metadata is ProtoId<AlertLevelPrototype> cast)
{
previousSelection = cast;
}
}
// The server will only send alert levels which are selectable, but
// unfortunately, for a short time after changing the alert level, no
// level is selectable, so we won't have any levels to put into the
// alert level list. Here, we make a dummy item to handle that; this
// item also informs the user what this combo box is for.
AlertLevelSelector.Clear();
AlertLevelSelector.AddItem(Loc.GetString("comms-console-change-alert-level-button"));
AlertLevelSelector.Select(0);
if (selectableAlertLevels != null)
{
foreach (var alert in selectableAlertLevels)
{
AlertLevelSelector.AddItem(GetLocalizedAlertName(alert));
AlertLevelSelector.SetItemMetadata(AlertLevelSelector.ItemCount - 1, alert);
if (alert == previousSelection)
{
AlertLevelSelector.Select(AlertLevelSelector.ItemCount - 1);
}
}
}
if (_loc.TryGetString($"comms-console-level-{currentAlertLevel}-flavour-label", out var flavour))
{
CurrentAlertLevelFlavorLabel.Text = flavour;
}
else
{
CurrentAlertLevelFlavorLabel.Text = string.Empty;
}
EnableDisableConfirmLevelChangeButton();
}
/// <summary>
/// Configure the "confirm alert level changed" button to be consistent with
/// the server state and user interactions
/// </summary>
private void EnableDisableConfirmLevelChangeButton()
{
// Disable the button when:
// 1. Server says we can't change level
// 2. User selected special info option (id 0)
// 3. User selected the same level the station is currently on
var selectedId = AlertLevelSelector.SelectedId;
ConfirmAlertLevelButton.Disabled = !_alertLevelSelectable || selectedId == 0;
if (selectedId != 0)
{
var metadata = AlertLevelSelector.GetItemMetadata(selectedId);
if (metadata is ProtoId<AlertLevelPrototype> selected)
{
ConfirmAlertLevelButton.Disabled |= selected == _currentAlertLevel;
}
}
}
/// <summary>
/// Utility function to convert an alert level identifier into a localized string
/// </summary>
private string GetLocalizedAlertName(ProtoId<AlertLevelPrototype> alertProto)
{
if (_protoman.TryIndex(alertProto, out var alertData))
{
return alertData.LocalizedName;
}
return alertProto;
}
}