Add a 'Copy' button to the fax UI (#22027)

* Add a 'Copy' button to the fax UI

* Add ValidatePrototypeId attribute

Co-authored-by: Kara <lunarautomaton6@gmail.com>

---------

Co-authored-by: Kara <lunarautomaton6@gmail.com>
This commit is contained in:
Arimah Greene
2023-12-25 02:08:15 +01:00
committed by GitHub
parent 28310a131c
commit b20fcf5141
6 changed files with 76 additions and 4 deletions

View File

@@ -22,6 +22,7 @@ public sealed class FaxBoundUi : BoundUserInterface
_window.OpenCentered(); _window.OpenCentered();
_window.OnClose += Close; _window.OnClose += Close;
_window.CopyButtonPressed += OnCopyButtonPressed;
_window.SendButtonPressed += OnSendButtonPressed; _window.SendButtonPressed += OnSendButtonPressed;
_window.RefreshButtonPressed += OnRefreshButtonPressed; _window.RefreshButtonPressed += OnRefreshButtonPressed;
_window.PeerSelected += OnPeerSelected; _window.PeerSelected += OnPeerSelected;
@@ -32,6 +33,11 @@ public sealed class FaxBoundUi : BoundUserInterface
SendMessage(new FaxSendMessage()); SendMessage(new FaxSendMessage());
} }
private void OnCopyButtonPressed()
{
SendMessage(new FaxCopyMessage());
}
private void OnRefreshButtonPressed() private void OnRefreshButtonPressed()
{ {
SendMessage(new FaxRefreshMessage()); SendMessage(new FaxRefreshMessage());

View File

@@ -20,6 +20,10 @@
</BoxContainer> </BoxContainer>
<Control HorizontalExpand="True" MinHeight="20" /> <Control HorizontalExpand="True" MinHeight="20" />
<BoxContainer Orientation="Horizontal" HorizontalExpand="True"> <BoxContainer Orientation="Horizontal" HorizontalExpand="True">
<Button Name="CopyButton"
Text="{Loc 'fax-machine-ui-copy-button'}"
HorizontalExpand="False"
Disabled="True" />
<Button Name="SendButton" <Button Name="SendButton"
Text="{Loc 'fax-machine-ui-send-button'}" Text="{Loc 'fax-machine-ui-send-button'}"
HorizontalExpand="True" HorizontalExpand="True"

View File

@@ -9,6 +9,7 @@ namespace Content.Client.Fax.UI;
[GenerateTypedNameReferences] [GenerateTypedNameReferences]
public sealed partial class FaxWindow : DefaultWindow public sealed partial class FaxWindow : DefaultWindow
{ {
public event Action? CopyButtonPressed;
public event Action? SendButtonPressed; public event Action? SendButtonPressed;
public event Action? RefreshButtonPressed; public event Action? RefreshButtonPressed;
public event Action<string>? PeerSelected; public event Action<string>? PeerSelected;
@@ -17,6 +18,7 @@ public sealed partial class FaxWindow : DefaultWindow
{ {
RobustXamlLoader.Load(this); RobustXamlLoader.Load(this);
CopyButton.OnPressed += _ => CopyButtonPressed?.Invoke();
SendButton.OnPressed += _ => SendButtonPressed?.Invoke(); SendButton.OnPressed += _ => SendButtonPressed?.Invoke();
RefreshButton.OnPressed += _ => RefreshButtonPressed?.Invoke(); RefreshButton.OnPressed += _ => RefreshButtonPressed?.Invoke();
PeerSelector.OnItemSelected += args => PeerSelector.OnItemSelected += args =>
@@ -25,6 +27,7 @@ public sealed partial class FaxWindow : DefaultWindow
public void UpdateState(FaxUiState state) public void UpdateState(FaxUiState state)
{ {
CopyButton.Disabled = !state.CanCopy;
SendButton.Disabled = !state.CanSend; SendButton.Disabled = !state.CanSend;
FromLabel.Text = state.DeviceName; FromLabel.Text = state.DeviceName;

View File

@@ -22,6 +22,7 @@ using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.Player; using Robust.Shared.Player;
using Robust.Shared.Prototypes;
namespace Content.Server.Fax; namespace Content.Server.Fax;
@@ -43,6 +44,13 @@ public sealed class FaxSystem : EntitySystem
private const string PaperSlotId = "Paper"; private const string PaperSlotId = "Paper";
/// <summary>
/// The prototype ID to use for faxed or copied entities if we can't get one from
/// the paper entity for whatever reason.
/// </summary>
[ValidatePrototypeId<EntityPrototype>]
private const string DefaultPaperPrototypeId = "Paper";
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
@@ -63,6 +71,7 @@ public sealed class FaxSystem : EntitySystem
// UI // UI
SubscribeLocalEvent<FaxMachineComponent, AfterActivatableUIOpenEvent>(OnToggleInterface); SubscribeLocalEvent<FaxMachineComponent, AfterActivatableUIOpenEvent>(OnToggleInterface);
SubscribeLocalEvent<FaxMachineComponent, FaxCopyMessage>(OnCopyButtonPressed);
SubscribeLocalEvent<FaxMachineComponent, FaxSendMessage>(OnSendButtonPressed); SubscribeLocalEvent<FaxMachineComponent, FaxSendMessage>(OnSendButtonPressed);
SubscribeLocalEvent<FaxMachineComponent, FaxRefreshMessage>(OnRefreshButtonPressed); SubscribeLocalEvent<FaxMachineComponent, FaxRefreshMessage>(OnRefreshButtonPressed);
SubscribeLocalEvent<FaxMachineComponent, FaxDestinationMessage>(OnDestinationSelected); SubscribeLocalEvent<FaxMachineComponent, FaxDestinationMessage>(OnDestinationSelected);
@@ -291,6 +300,11 @@ public sealed class FaxSystem : EntitySystem
UpdateUserInterface(uid, component); UpdateUserInterface(uid, component);
} }
private void OnCopyButtonPressed(EntityUid uid, FaxMachineComponent component, FaxCopyMessage args)
{
Copy(uid, component);
}
private void OnSendButtonPressed(EntityUid uid, FaxMachineComponent component, FaxSendMessage args) private void OnSendButtonPressed(EntityUid uid, FaxMachineComponent component, FaxSendMessage args)
{ {
Send(uid, component, args.Session.AttachedEntity); Send(uid, component, args.Session.AttachedEntity);
@@ -329,7 +343,10 @@ public sealed class FaxSystem : EntitySystem
component.DestinationFaxAddress != null && component.DestinationFaxAddress != null &&
component.SendTimeoutRemaining <= 0 && component.SendTimeoutRemaining <= 0 &&
component.InsertingTimeRemaining <= 0; component.InsertingTimeRemaining <= 0;
var state = new FaxUiState(component.FaxName, component.KnownFaxes, canSend, isPaperInserted, component.DestinationFaxAddress); var canCopy = isPaperInserted &&
component.SendTimeoutRemaining <= 0 &&
component.InsertingTimeRemaining <= 0;
var state = new FaxUiState(component.FaxName, component.KnownFaxes, canSend, canCopy, isPaperInserted, component.DestinationFaxAddress);
_userInterface.TrySetUiState(uid, FaxUiKey.Key, state); _userInterface.TrySetUiState(uid, FaxUiKey.Key, state);
} }
@@ -369,9 +386,42 @@ public sealed class FaxSystem : EntitySystem
_deviceNetworkSystem.QueuePacket(uid, null, payload); _deviceNetworkSystem.QueuePacket(uid, null, payload);
} }
/// <summary>
/// Copies the paper in the fax. A timeout is set after copying,
/// which is shared by the send button.
/// </summary>
public void Copy(EntityUid uid, FaxMachineComponent? component = null)
{
if (!Resolve(uid, ref component))
return;
var sendEntity = component.PaperSlot.Item;
if (sendEntity == null)
return;
if (!TryComp<MetaDataComponent>(sendEntity, out var metadata) ||
!TryComp<PaperComponent>(sendEntity, out var paper))
return;
// TODO: See comment in 'Send()' about not being able to copy whole entities
var printout = new FaxPrintout(paper.Content,
metadata.EntityName,
metadata.EntityPrototype?.ID ?? DefaultPaperPrototypeId,
paper.StampState,
paper.StampedBy);
component.PrintingQueue.Enqueue(printout);
component.SendTimeoutRemaining += component.SendTimeout;
// Don't play component.SendSound - it clashes with the printing sound, which
// will start immediately.
UpdateUserInterface(uid, component);
}
/// <summary> /// <summary>
/// Sends message to addressee if paper is set and a known fax is selected /// Sends message to addressee if paper is set and a known fax is selected
/// A timeout is set after sending /// A timeout is set after sending, which is shared by the copy button.
/// </summary> /// </summary>
public void Send(EntityUid uid, FaxMachineComponent? component = null, EntityUid? sender = null) public void Send(EntityUid uid, FaxMachineComponent? component = null, EntityUid? sender = null)
{ {
@@ -404,7 +454,7 @@ public sealed class FaxSystem : EntitySystem
// TODO: Ideally, we could just make a copy of the whole entity when it's // TODO: Ideally, we could just make a copy of the whole entity when it's
// faxed, in order to preserve visuals, etc.. This functionality isn't // faxed, in order to preserve visuals, etc.. This functionality isn't
// available yet, so we'll pass along the originating prototypeId and fall // available yet, so we'll pass along the originating prototypeId and fall
// back to "Paper" in SpawnPaperFromQueue if we can't find one here. // back to DefaultPaperPrototypeId in SpawnPaperFromQueue if we can't find one here.
payload[FaxConstants.FaxPaperPrototypeData] = metadata.EntityPrototype.ID; payload[FaxConstants.FaxPaperPrototypeData] = metadata.EntityPrototype.ID;
} }
@@ -454,7 +504,7 @@ public sealed class FaxSystem : EntitySystem
var printout = component.PrintingQueue.Dequeue(); var printout = component.PrintingQueue.Dequeue();
var entityToSpawn = printout.PrototypeId.Length == 0 ? "Paper" : printout.PrototypeId; var entityToSpawn = printout.PrototypeId.Length == 0 ? DefaultPaperPrototypeId : printout.PrototypeId;
var printed = EntityManager.SpawnEntity(entityToSpawn, Transform(uid).Coordinates); var printed = EntityManager.SpawnEntity(entityToSpawn, Transform(uid).Coordinates);
if (TryComp<PaperComponent>(printed, out var paper)) if (TryComp<PaperComponent>(printed, out var paper))

View File

@@ -16,10 +16,12 @@ public sealed class FaxUiState : BoundUserInterfaceState
public string? DestinationAddress { get; } public string? DestinationAddress { get; }
public bool IsPaperInserted { get; } public bool IsPaperInserted { get; }
public bool CanSend { get; } public bool CanSend { get; }
public bool CanCopy { get; }
public FaxUiState(string deviceName, public FaxUiState(string deviceName,
Dictionary<string, string> peers, Dictionary<string, string> peers,
bool canSend, bool canSend,
bool canCopy,
bool isPaperInserted, bool isPaperInserted,
string? destAddress) string? destAddress)
{ {
@@ -27,10 +29,16 @@ public sealed class FaxUiState : BoundUserInterfaceState
AvailablePeers = peers; AvailablePeers = peers;
IsPaperInserted = isPaperInserted; IsPaperInserted = isPaperInserted;
CanSend = canSend; CanSend = canSend;
CanCopy = canCopy;
DestinationAddress = destAddress; DestinationAddress = destAddress;
} }
} }
[Serializable, NetSerializable]
public sealed class FaxCopyMessage : BoundUserInterfaceMessage
{
}
[Serializable, NetSerializable] [Serializable, NetSerializable]
public sealed class FaxSendMessage : BoundUserInterfaceMessage public sealed class FaxSendMessage : BoundUserInterfaceMessage
{ {

View File

@@ -8,6 +8,7 @@ fax-machine-dialog-rename = Rename
fax-machine-dialog-field-name = Name fax-machine-dialog-field-name = Name
fax-machine-ui-window = Fax Machine fax-machine-ui-window = Fax Machine
fax-machine-ui-copy-button = Copy
fax-machine-ui-send-button = Send fax-machine-ui-send-button = Send
fax-machine-ui-refresh-button = Refresh fax-machine-ui-refresh-button = Refresh
fax-machine-ui-no-peers = No Peers fax-machine-ui-no-peers = No Peers