diff --git a/Content.Client/Communications/CommunicationsConsoleComponent.cs b/Content.Client/Communications/CommunicationsConsoleComponent.cs
new file mode 100644
index 0000000000..5fdb2771da
--- /dev/null
+++ b/Content.Client/Communications/CommunicationsConsoleComponent.cs
@@ -0,0 +1,14 @@
+using Content.Shared.Communications;
+using Robust.Shared.Prototypes;
+
+namespace Content.Client.Communications;
+
+[RegisterComponent]
+public sealed partial class CommunicationsConsoleComponent : SharedCommunicationsConsoleComponent
+{
+ ///
+ /// The prototype ID to use in the UI to show what entities a broadcast will display on
+ ///
+ [DataField]
+ public EntProtoId ScreenDisplayId = "Screen";
+}
diff --git a/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs b/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs
index 0310e91eeb..1cb38c8ef2 100644
--- a/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs
+++ b/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs
@@ -1,9 +1,8 @@
-using Content.Shared.CCVar;
+using Content.Shared.CCVar;
using Content.Shared.Chat;
using Content.Shared.Communications;
using Robust.Client.UserInterface;
using Robust.Shared.Configuration;
-using Robust.Shared.Timing;
namespace Content.Client.Communications.UI
{
@@ -23,37 +22,31 @@ namespace Content.Client.Communications.UI
base.Open();
_menu = this.CreateWindow();
- _menu.OnAnnounce += AnnounceButtonPressed;
- _menu.OnBroadcast += BroadcastButtonPressed;
- _menu.OnAlertLevel += AlertLevelSelected;
- _menu.OnEmergencyLevel += EmergencyShuttleButtonPressed;
+ _menu.OnRadioAnnounce += RadioAnnounceButtonPressed;
+ _menu.OnScreenBroadcast += ScreenBroadcastButtonPressed;
+ _menu.OnAlertLevelChanged += AlertLevelSelected;
+ _menu.OnShuttleCalled += CallShuttle;
+ _menu.OnShuttleRecalled += RecallShuttle;
+
+ if (EntMan.TryGetComponent(Owner, out var console))
+ {
+ _menu.SetBroadcastDisplayEntity(console.ScreenDisplayId);
+ }
}
public void AlertLevelSelected(string level)
{
- if (_menu!.AlertLevelSelectable)
- {
- _menu.CurrentLevel = level;
- SendMessage(new CommunicationsConsoleSelectAlertLevelMessage(level));
- }
+ SendMessage(new CommunicationsConsoleSelectAlertLevelMessage(level));
}
- public void EmergencyShuttleButtonPressed()
- {
- if (_menu!.CountdownStarted)
- RecallShuttle();
- else
- CallShuttle();
- }
-
- public void AnnounceButtonPressed(string message)
+ public void RadioAnnounceButtonPressed(string message)
{
var maxLength = _cfg.GetCVar(CCVars.ChatMaxAnnouncementLength);
var msg = SharedChatSystem.SanitizeAnnouncement(message, maxLength);
SendMessage(new CommunicationsConsoleAnnounceMessage(msg));
}
- public void BroadcastButtonPressed(string message)
+ public void ScreenBroadcastButtonPressed(string message)
{
SendMessage(new CommunicationsConsoleBroadcastMessage(message));
}
@@ -77,20 +70,7 @@ namespace Content.Client.Communications.UI
if (_menu != null)
{
- _menu.CanAnnounce = commsState.CanAnnounce;
- _menu.CanBroadcast = commsState.CanBroadcast;
- _menu.CanCall = commsState.CanCall;
- _menu.CountdownStarted = commsState.CountdownStarted;
- _menu.AlertLevelSelectable = commsState.AlertLevels != null && !float.IsNaN(commsState.CurrentAlertDelay) && commsState.CurrentAlertDelay <= 0;
- _menu.CurrentLevel = commsState.CurrentAlert;
- _menu.CountdownEnd = commsState.ExpectedCountdownEnd;
-
- _menu.UpdateCountdown();
- _menu.UpdateAlertLevels(commsState.AlertLevels, _menu.CurrentLevel);
- _menu.AlertLevelButton.Disabled = !_menu.AlertLevelSelectable;
- _menu.EmergencyShuttleButton.Disabled = !_menu.CanCall;
- _menu.AnnounceButton.Disabled = !_menu.CanAnnounce;
- _menu.BroadcastButton.Disabled = !_menu.CanBroadcast;
+ _menu.UpdateState(commsState);
}
}
}
diff --git a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml
index b74df979cf..d9b571cd3c 100644
--- a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml
+++ b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml
@@ -1,62 +1,32 @@
-
+ MouseFilter="Stop" MinSize="400 660" SetWidth="450">
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
-
-
-
-
-
-
+
diff --git a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs
index 926b8c6567..9cece775fa 100644
--- a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs
+++ b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs
@@ -1,137 +1,83 @@
-using System.Globalization;
-using Content.Client.UserInterface.Controls;
-using Content.Shared.CCVar;
+using System.Numerics;
+using Content.Shared.Communications;
using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
-using Robust.Shared.Configuration;
-using Robust.Shared.Timing;
-using Robust.Shared.Utility;
+using Robust.Shared.Prototypes;
-namespace Content.Client.Communications.UI
+namespace Content.Client.Communications.UI;
+
+[GenerateTypedNameReferences]
+public sealed partial class CommunicationsConsoleMenu : BaseWindow
{
- [GenerateTypedNameReferences]
- public sealed partial class CommunicationsConsoleMenu : FancyWindow
+ private const int DragMoveSize = 40;
+ private const int DragResizeSize = 7;
+
+ public event Action? OnShuttleCalled;
+ public event Action? OnShuttleRecalled;
+ public event Action? OnAlertLevelChanged;
+ public event Action? OnRadioAnnounce;
+ public event Action? OnScreenBroadcast;
+
+ public CommunicationsConsoleMenu()
{
- [Dependency] private readonly IConfigurationManager _cfg = default!;
- [Dependency] private readonly IGameTiming _timing = default!;
- [Dependency] private readonly ILocalizationManager _loc = default!;
+ IoCManager.InjectDependencies(this);
+ RobustXamlLoader.Load(this);
- public bool CanAnnounce;
- public bool CanBroadcast;
- public bool CanCall;
- public bool AlertLevelSelectable;
- public bool CountdownStarted;
- public string CurrentLevel = string.Empty;
- public TimeSpan? CountdownEnd;
+ CloseButton.OnPressed += _ => Close();
- public event Action? OnEmergencyLevel;
- public event Action? OnAlertLevel;
- public event Action? OnAnnounce;
- public event Action? OnBroadcast;
+ MessagingControls.OnRadioAnnounce += message => OnRadioAnnounce?.Invoke(message);
+ MessagingControls.OnScreenBroadcast += message => OnScreenBroadcast?.Invoke(message);
- public CommunicationsConsoleMenu()
+ AlertLevelControls.OnAlertLevelChanged += newLevel => OnAlertLevelChanged?.Invoke(newLevel);
+
+ ShuttleControls.OnShuttleCalled += () => OnShuttleCalled?.Invoke();
+ ShuttleControls.OnShuttleRecalled += () => OnShuttleRecalled?.Invoke();
+ }
+
+ ///
+ /// Use the specified prototype ID as an example display in the
+ /// UI subsection where users type broadcast messages
+ ///
+ public void SetBroadcastDisplayEntity(EntProtoId broadcastEntityId)
+ {
+ MessagingControls.SetBroadcastDisplayEntity(broadcastEntityId);
+ }
+
+ ///
+ /// Configure UI to be consistent with the input state
+ ///
+ public void UpdateState(CommunicationsConsoleInterfaceState commsState)
+ {
+ MessagingControls.CanRadioAnnounce = commsState.CanAnnounce;
+ MessagingControls.CanScreenBroadcast = commsState.CanBroadcast;
+
+ var alertLevelSelectable = commsState.AlertLevels != null && commsState.CurrentAlertDelay <= 0;
+ AlertLevelControls.UpdateAlertLevels(commsState.AlertLevels, commsState.CurrentAlert, commsState.CurrentAlertColor, alertLevelSelectable);
+
+ ShuttleControls.UpdateState(commsState.CanCall, commsState.CountdownStarted, commsState.ExpectedCountdownEnd);
+ }
+
+ protected override DragMode GetDragModeFor(Vector2 relativeMousePos)
+ {
+ if (relativeMousePos.Y < DragMoveSize)
{
- IoCManager.InjectDependencies(this);
- RobustXamlLoader.Load(this);
-
- MessageInput.Placeholder = new Rope.Leaf(_loc.GetString("comms-console-menu-announcement-placeholder"));
-
- var maxAnnounceLength = _cfg.GetCVar(CCVars.ChatMaxAnnouncementLength);
- MessageInput.OnTextChanged += (args) =>
- {
- if (args.Control.TextLength > maxAnnounceLength)
- {
- AnnounceButton.Disabled = true;
- AnnounceButton.ToolTip = Loc.GetString("comms-console-message-too-long");
- }
- else
- {
- AnnounceButton.Disabled = !CanAnnounce;
- AnnounceButton.ToolTip = null;
-
- }
- };
-
- AnnounceButton.OnPressed += _ => OnAnnounce?.Invoke(Rope.Collapse(MessageInput.TextRope));
- AnnounceButton.Disabled = !CanAnnounce;
-
- BroadcastButton.OnPressed += _ => OnBroadcast?.Invoke(Rope.Collapse(MessageInput.TextRope));
- BroadcastButton.Disabled = !CanBroadcast;
-
- AlertLevelButton.OnItemSelected += args =>
- {
- var metadata = AlertLevelButton.GetItemMetadata(args.Id);
- if (metadata != null && metadata is string cast)
- {
- OnAlertLevel?.Invoke(cast);
- }
- };
-
-
- AlertLevelButton.Disabled = !AlertLevelSelectable;
-
- EmergencyShuttleButton.OnPressed += _ => OnEmergencyLevel?.Invoke();
- EmergencyShuttleButton.Disabled = !CanCall;
+ return DragMode.Move;
}
-
- protected override void FrameUpdate(FrameEventArgs args)
+ else
{
- base.FrameUpdate(args);
- UpdateCountdown();
- }
+ var mode = DragMode.None;
- // The current alert could make levels unselectable, so we need to ensure that the UI reacts properly.
- // If the current alert is unselectable, the only item in the alerts list will be
- // the current alert. Otherwise, it will be the list of alerts, with the current alert
- // selected.
- public void UpdateAlertLevels(List? alerts, string currentAlert)
- {
- AlertLevelButton.Clear();
-
- if (alerts == null)
+ if (relativeMousePos.Y > Size.Y - DragResizeSize)
{
- var name = currentAlert;
- if (_loc.TryGetString($"alert-level-{currentAlert}", out var locName))
- {
- name = locName;
- }
- AlertLevelButton.AddItem(name);
- AlertLevelButton.SetItemMetadata(AlertLevelButton.ItemCount - 1, currentAlert);
- }
- else
- {
- foreach (var alert in alerts)
- {
- var name = alert;
- if (_loc.TryGetString($"alert-level-{alert}", out var locName))
- {
- name = locName;
- }
- AlertLevelButton.AddItem(name);
- AlertLevelButton.SetItemMetadata(AlertLevelButton.ItemCount - 1, alert);
- if (alert == currentAlert)
- {
- AlertLevelButton.Select(AlertLevelButton.ItemCount - 1);
- }
- }
- }
- }
-
- public void UpdateCountdown()
- {
- if (!CountdownStarted)
- {
- CountdownLabel.SetMessage(string.Empty);
- EmergencyShuttleButton.Text = Loc.GetString("comms-console-menu-call-shuttle");
- return;
+ mode |= DragMode.Bottom;
}
- var diff = MathHelper.Max((CountdownEnd - _timing.CurTime) ?? TimeSpan.Zero, TimeSpan.Zero);
-
- EmergencyShuttleButton.Text = Loc.GetString("comms-console-menu-recall-shuttle");
- var infoText = Loc.GetString($"comms-console-menu-time-remaining",
- ("time", diff.ToString(@"hh\:mm\:ss", CultureInfo.CurrentCulture)));
- CountdownLabel.SetMessage(infoText);
+ if (relativeMousePos.X > Size.X - DragResizeSize)
+ {
+ mode |= DragMode.Right;
+ }
+ return mode;
}
}
}
diff --git a/Content.Client/Communications/UI/CommunicationsConsoleSheetlet.cs b/Content.Client/Communications/UI/CommunicationsConsoleSheetlet.cs
new file mode 100644
index 0000000000..207e547be9
--- /dev/null
+++ b/Content.Client/Communications/UI/CommunicationsConsoleSheetlet.cs
@@ -0,0 +1,42 @@
+using Content.Client.Resources;
+using Content.Client.Stylesheets;
+using Content.Client.Stylesheets.Stylesheets;
+using Content.Client.Stylesheets.SheetletConfigs;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.UserInterface.Controls;
+
+[CommonSheetlet]
+public sealed class CommunicationsConsoleSheetlet : Sheetlet where T : PalettedStylesheet, IButtonConfig, IIconConfig
+{
+ public override StyleRule[] GetRules(T sheet, object config)
+ {
+ var lcdFontLarge = ResCache.GetFont("/Fonts/7SegmentDisplayDigits.ttf", 20);
+
+ return [
+ E