diff --git a/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs b/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs index 0534793df0..88dc06c2af 100644 --- a/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs +++ b/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs @@ -1,12 +1,17 @@ -using Content.Shared.Forensics; using Robust.Client.GameObjects; +using Robust.Shared.Timing; +using Content.Shared.Forensics; namespace Content.Client.Forensics { public sealed class ForensicScannerBoundUserInterface : BoundUserInterface { + [Dependency] private readonly IGameTiming _gameTiming = default!; + private ForensicScannerMenu? _window; + private TimeSpan _printCooldown; + public ForensicScannerBoundUserInterface(ClientUserInterfaceComponent owner, Enum uiKey) : base(owner, uiKey) { } @@ -17,24 +22,61 @@ namespace Content.Client.Forensics _window = new ForensicScannerMenu(); _window.OnClose += Close; _window.Print.OnPressed += _ => Print(); + _window.Clear.OnPressed += _ => Clear(); _window.OpenCentered(); } private void Print() { SendMessage(new ForensicScannerPrintMessage()); - _window?.Close(); + + if (_window != null) + _window.UpdatePrinterState(true); + + // This UI does not require pinpoint accuracy as to when the Print + // button is available again, so spawning client-side timers is + // fine. The server will make sure the cooldown is honored. + Timer.Spawn(_printCooldown, () => + { + if (_window != null) + _window.UpdatePrinterState(false); + }); } - protected override void ReceiveMessage(BoundUserInterfaceMessage message) + private void Clear() { + SendMessage(new ForensicScannerClearMessage()); + } + + protected override void UpdateState(BoundUserInterfaceState state) + { + base.UpdateState(state); + if (_window == null) return; - if (message is not ForensicScannerUserMessage cast) + if (state is not ForensicScannerBoundUserInterfaceState cast) return; - _window.Populate(cast); + _printCooldown = cast.PrintCooldown; + + if (cast.PrintReadyAt > _gameTiming.CurTime) + Timer.Spawn(cast.PrintReadyAt - _gameTiming.CurTime, () => + { + if (_window != null) + _window.UpdatePrinterState(false); + }); + + _window.UpdateState(cast); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + _window?.Dispose(); } } } diff --git a/Content.Client/Forensics/ForensicScannerMenu.xaml b/Content.Client/Forensics/ForensicScannerMenu.xaml index b3bfff7771..fbfcb06f15 100644 --- a/Content.Client/Forensics/ForensicScannerMenu.xaml +++ b/Content.Client/Forensics/ForensicScannerMenu.xaml @@ -1,12 +1,25 @@ + MinSize="350 200" + SetSize="350 500"> -