diff --git a/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs b/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs index c1b63dc4d0..d80c600c03 100644 --- a/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs +++ b/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Access; using Content.Shared.Access.Components; using Content.Shared.Access.Systems; using Content.Shared.Containers.ItemSlots; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; using static Content.Shared.Access.Components.AccessOverriderComponent; @@ -23,6 +24,28 @@ namespace Content.Client.Access.UI { base.Open(); + _window = this.CreateWindow(); + RefreshAccess(); + _window.Title = EntMan.GetComponent(Owner).EntityName; + _window.OnSubmit += SubmitData; + + _window.PrivilegedIdButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(PrivilegedIdCardSlotId)); + } + + public override void OnProtoReload(PrototypesReloadedEventArgs args) + { + base.OnProtoReload(args); + if (!args.WasModified()) + return; + + RefreshAccess(); + + if (State != null) + _window?.UpdateState(_prototypeManager, (AccessOverriderBoundUserInterfaceState) State); + } + + private void RefreshAccess() + { List> accessLevels; if (EntMan.TryGetComponent(Owner, out var accessOverrider)) @@ -30,38 +53,20 @@ namespace Content.Client.Access.UI accessLevels = accessOverrider.AccessLevels; accessLevels.Sort(); } - else { accessLevels = new List>(); _accessOverriderSystem.Log.Error($"No AccessOverrider component found for {EntMan.ToPrettyString(Owner)}!"); } - _window = new AccessOverriderWindow(this, _prototypeManager, accessLevels) - { - Title = EntMan.GetComponent(Owner).EntityName - }; - - _window.PrivilegedIdButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(PrivilegedIdCardSlotId)); - - _window.OnClose += Close; - _window.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _window?.Dispose(); + _window?.SetAccessLevels(_prototypeManager, accessLevels); } protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); var castState = (AccessOverriderBoundUserInterfaceState) state; - _window?.UpdateState(castState); + _window?.UpdateState(_prototypeManager, castState); } public void SubmitData(List> newAccessList) diff --git a/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs b/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs index 6025c3b551..ba08771858 100644 --- a/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs +++ b/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs @@ -13,26 +13,24 @@ namespace Content.Client.Access.UI [GenerateTypedNameReferences] public sealed partial class AccessOverriderWindow : DefaultWindow { - [Dependency] private readonly ILogManager _logManager = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - - private readonly AccessOverriderBoundUserInterface _owner; private readonly Dictionary _accessButtons = new(); - public AccessOverriderWindow(AccessOverriderBoundUserInterface owner, IPrototypeManager prototypeManager, - List> accessLevels) + public event Action>>? OnSubmit; + + public AccessOverriderWindow() { RobustXamlLoader.Load(this); - IoCManager.InjectDependencies(this); - var logMill = _logManager.GetSawmill(SharedAccessOverriderSystem.Sawmill); + } - _owner = owner; + public void SetAccessLevels(IPrototypeManager protoManager, List> accessLevels) + { + _accessButtons.Clear(); + AccessLevelGrid.DisposeAllChildren(); foreach (var access in accessLevels) { - if (!prototypeManager.TryIndex(access, out var accessLevel)) + if (!protoManager.TryIndex(access, out var accessLevel)) { - logMill.Error($"Unable to find accesslevel for {access}"); continue; } @@ -44,11 +42,16 @@ namespace Content.Client.Access.UI AccessLevelGrid.AddChild(newButton); _accessButtons.Add(accessLevel.ID, newButton); - newButton.OnPressed += _ => SubmitData(); + newButton.OnPressed += _ => + { + OnSubmit?.Invoke( + // Iterate over the buttons dictionary, filter by `Pressed`, only get key from the key/value pair + _accessButtons.Where(x => x.Value.Pressed).Select(x => new ProtoId(x.Key)).ToList()); + }; } } - public void UpdateState(AccessOverriderBoundUserInterfaceState state) + public void UpdateState(IPrototypeManager protoManager, AccessOverriderBoundUserInterfaceState state) { PrivilegedIdLabel.Text = state.PrivilegedIdName; PrivilegedIdButton.Text = state.IsPrivilegedIdPresent @@ -66,11 +69,11 @@ namespace Content.Client.Access.UI if (state.MissingPrivilegesList != null && state.MissingPrivilegesList.Any()) { - List missingPrivileges = new List(); + var missingPrivileges = new List(); foreach (string tag in state.MissingPrivilegesList) { - string privilege = Loc.GetString(_prototypeManager.Index(tag)?.Name ?? "generic-unknown"); + var privilege = Loc.GetString(protoManager.Index(tag)?.Name ?? "generic-unknown"); missingPrivileges.Add(privilege); } @@ -90,13 +93,5 @@ namespace Content.Client.Access.UI } } } - - private void SubmitData() - { - _owner.SubmitData( - - // Iterate over the buttons dictionary, filter by `Pressed`, only get key from the key/value pair - _accessButtons.Where(x => x.Value.Pressed).Select(x => new ProtoId(x.Key)).ToList()); - } } } diff --git a/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs b/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs index 761f52988a..50add43dc9 100644 --- a/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs +++ b/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Access.Systems; using Content.Shared.StatusIcon; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Access.UI @@ -20,16 +21,11 @@ namespace Content.Client.Access.UI { base.Open(); - _window?.Dispose(); - _window = new AgentIDCardWindow(this); - if (State != null) - UpdateState(State); + _window = this.CreateWindow(); - _window.OpenCentered(); - - _window.OnClose += Close; _window.OnNameChanged += OnNameChanged; _window.OnJobChanged += OnJobChanged; + _window.OnJobIconChanged += OnJobIconChanged; } private void OnNameChanged(string newName) @@ -61,14 +57,5 @@ namespace Content.Client.Access.UI _window.SetCurrentJob(cast.CurrentJob); _window.SetAllowedIcons(cast.Icons, cast.CurrentJobIconId); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _window?.Dispose(); - } } } diff --git a/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs b/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs index 6d0b2a184f..071ce41a06 100644 --- a/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs +++ b/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs @@ -17,19 +17,19 @@ namespace Content.Client.Access.UI [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IEntitySystemManager _entitySystem = default!; private readonly SpriteSystem _spriteSystem; - private readonly AgentIDCardBoundUserInterface _bui; private const int JobIconColumnCount = 10; public event Action? OnNameChanged; public event Action? OnJobChanged; - public AgentIDCardWindow(AgentIDCardBoundUserInterface bui) + public event Action>? OnJobIconChanged; + + public AgentIDCardWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); _spriteSystem = _entitySystem.GetEntitySystem(); - _bui = bui; NameLineEdit.OnTextEntered += e => OnNameChanged?.Invoke(e.Text); NameLineEdit.OnFocusExit += e => OnNameChanged?.Invoke(e.Text); @@ -67,7 +67,7 @@ namespace Content.Client.Access.UI }; // Generate buttons textures - TextureRect jobIconTexture = new TextureRect + var jobIconTexture = new TextureRect { Texture = _spriteSystem.Frame0(jobIcon.Icon), TextureScale = new Vector2(2.5f, 2.5f), @@ -75,7 +75,7 @@ namespace Content.Client.Access.UI }; jobIconButton.AddChild(jobIconTexture); - jobIconButton.OnPressed += _ => _bui.OnJobIconChanged(jobIconId); + jobIconButton.OnPressed += _ => OnJobIconChanged?.Invoke(jobIcon.ID); IconGrid.AddChild(jobIconButton); if (jobIconId.Equals(currentJobIconId)) diff --git a/Content.Client/Ame/UI/AmeControllerBoundUserInterface.cs b/Content.Client/Ame/UI/AmeControllerBoundUserInterface.cs index e84cf5d34d..3d65f75189 100644 --- a/Content.Client/Ame/UI/AmeControllerBoundUserInterface.cs +++ b/Content.Client/Ame/UI/AmeControllerBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Ame.Components; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Ame.UI { @@ -16,9 +17,8 @@ namespace Content.Client.Ame.UI { base.Open(); - _window = new AmeWindow(this); - _window.OnClose += Close; - _window.OpenCentered(); + _window = this.CreateWindow(); + _window.OnAmeButton += ButtonPressed; } /// @@ -40,15 +40,5 @@ namespace Content.Client.Ame.UI { SendMessage(new UiButtonPressedMessage(button)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Dispose(); - } - } } } diff --git a/Content.Client/Ame/UI/AmeWindow.xaml.cs b/Content.Client/Ame/UI/AmeWindow.xaml.cs index 8b91ec5966..d6d580bcda 100644 --- a/Content.Client/Ame/UI/AmeWindow.xaml.cs +++ b/Content.Client/Ame/UI/AmeWindow.xaml.cs @@ -1,3 +1,4 @@ +using System.Linq; using Content.Client.UserInterface; using Content.Shared.Ame.Components; using Robust.Client.AutoGenerated; @@ -9,15 +10,17 @@ namespace Content.Client.Ame.UI [GenerateTypedNameReferences] public sealed partial class AmeWindow : DefaultWindow { - public AmeWindow(AmeControllerBoundUserInterface ui) + public event Action? OnAmeButton; + + public AmeWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - EjectButton.OnPressed += _ => ui.ButtonPressed(UiButton.Eject); - ToggleInjection.OnPressed += _ => ui.ButtonPressed(UiButton.ToggleInjection); - IncreaseFuelButton.OnPressed += _ => ui.ButtonPressed(UiButton.IncreaseFuel); - DecreaseFuelButton.OnPressed += _ => ui.ButtonPressed(UiButton.DecreaseFuel); + EjectButton.OnPressed += _ => OnAmeButton?.Invoke(UiButton.Eject); + ToggleInjection.OnPressed += _ => OnAmeButton?.Invoke(UiButton.ToggleInjection); + IncreaseFuelButton.OnPressed += _ => OnAmeButton?.Invoke(UiButton.IncreaseFuel); + DecreaseFuelButton.OnPressed += _ => OnAmeButton?.Invoke(UiButton.DecreaseFuel); } /// @@ -29,7 +32,7 @@ namespace Content.Client.Ame.UI var castState = (AmeControllerBoundUserInterfaceState) state; // Disable all buttons if not powered - if (Contents.Children != null) + if (Contents.Children.Any()) { ButtonHelpers.SetButtonDisabledRecursive(Contents, !castState.HasPower); EjectButton.Disabled = false; @@ -65,8 +68,8 @@ namespace Content.Client.Ame.UI CoreCount.Text = $"{castState.CoreCount}"; InjectionAmount.Text = $"{castState.InjectionAmount}"; // format power statistics to pretty numbers - CurrentPowerSupply.Text = $"{castState.CurrentPowerSupply.ToString("N1")}"; - TargetedPowerSupply.Text = $"{castState.TargetedPowerSupply.ToString("N1")}"; + CurrentPowerSupply.Text = $"{castState.CurrentPowerSupply:N1}"; + TargetedPowerSupply.Text = $"{castState.TargetedPowerSupply:N1}"; } } } diff --git a/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs b/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs index 5764d0a097..5d1985485c 100644 --- a/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs +++ b/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Anomaly; using Content.Shared.Gravity; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Anomaly.Ui; @@ -18,10 +19,8 @@ public sealed class AnomalyGeneratorBoundUserInterface : BoundUserInterface { base.Open(); - _window = new(Owner); - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); + _window.SetEntity(Owner); _window.OnGenerateButtonPressed += () => { @@ -37,18 +36,5 @@ public sealed class AnomalyGeneratorBoundUserInterface : BoundUserInterface return; _window?.UpdateState(msg); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - - _window?.Dispose(); - } - - public void SetPowerSwitch(bool on) - { - SendMessage(new SharedGravityGeneratorComponent.SwitchGeneratorMessage(on)); - } } diff --git a/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs b/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs index 08438e2a1b..82d41192dd 100644 --- a/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs +++ b/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs @@ -18,17 +18,21 @@ public sealed partial class AnomalyGeneratorWindow : FancyWindow public Action? OnGenerateButtonPressed; - public AnomalyGeneratorWindow(EntityUid gen) + public AnomalyGeneratorWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - EntityView.SetEntity(gen); EntityView.SpriteOffset = false; GenerateButton.OnPressed += _ => OnGenerateButtonPressed?.Invoke(); } + public void SetEntity(EntityUid uid) + { + EntityView.SetEntity(uid); + } + public void UpdateState(AnomalyGeneratorUserInterfaceState state) { _cooldownEnd = state.CooldownEndTime; diff --git a/Content.Client/Arcade/BlockGameMenu.cs b/Content.Client/Arcade/BlockGameMenu.cs index eeda2a3102..4a579fc4bf 100644 --- a/Content.Client/Arcade/BlockGameMenu.cs +++ b/Content.Client/Arcade/BlockGameMenu.cs @@ -28,8 +28,6 @@ namespace Content.Client.Arcade private static readonly Vector2 BlockSize = new(15, 15); - private readonly BlockGameBoundUserInterface _owner; - private readonly PanelContainer _mainPanel; private readonly BoxContainer _gameRootContainer; @@ -58,10 +56,11 @@ namespace Content.Client.Arcade private bool _isPlayer = false; private bool _gameOver = false; - public BlockGameMenu(BlockGameBoundUserInterface owner) + public event Action? OnAction; + + public BlockGameMenu() { Title = Loc.GetString("blockgame-menu-title"); - _owner = owner; MinSize = SetSize = new Vector2(410, 490); @@ -176,7 +175,7 @@ namespace Content.Client.Arcade }; _newGameButton.OnPressed += (e) => { - _owner.SendAction(BlockGamePlayerAction.NewGame); + OnAction?.Invoke(BlockGamePlayerAction.NewGame); }; pauseMenuContainer.AddChild(_newGameButton); pauseMenuContainer.AddChild(new Control { MinSize = new Vector2(1, 10) }); @@ -186,7 +185,10 @@ namespace Content.Client.Arcade Text = Loc.GetString("blockgame-menu-button-scoreboard"), TextAlign = Label.AlignMode.Center }; - _scoreBoardButton.OnPressed += (e) => _owner.SendAction(BlockGamePlayerAction.ShowHighscores); + _scoreBoardButton.OnPressed += (e) => + { + OnAction?.Invoke(BlockGamePlayerAction.ShowHighscores); + }; pauseMenuContainer.AddChild(_scoreBoardButton); _unpauseButtonMargin = new Control { MinSize = new Vector2(1, 10), Visible = false }; pauseMenuContainer.AddChild(_unpauseButtonMargin); @@ -199,7 +201,7 @@ namespace Content.Client.Arcade }; _unpauseButton.OnPressed += (e) => { - _owner.SendAction(BlockGamePlayerAction.Unpause); + OnAction?.Invoke(BlockGamePlayerAction.Unpause); }; pauseMenuContainer.AddChild(_unpauseButton); @@ -257,7 +259,7 @@ namespace Content.Client.Arcade }; _finalNewGameButton.OnPressed += (e) => { - _owner.SendAction(BlockGamePlayerAction.NewGame); + OnAction?.Invoke(BlockGamePlayerAction.NewGame); }; gameOverMenuContainer.AddChild(_finalNewGameButton); @@ -327,7 +329,10 @@ namespace Content.Client.Arcade Text = Loc.GetString("blockgame-menu-button-back"), TextAlign = Label.AlignMode.Center }; - _highscoreBackButton.OnPressed += (e) => _owner.SendAction(BlockGamePlayerAction.Pause); + _highscoreBackButton.OnPressed += (e) => + { + OnAction?.Invoke(BlockGamePlayerAction.Pause); + }; menuContainer.AddChild(_highscoreBackButton); menuInnerPanel.AddChild(menuContainer); @@ -473,7 +478,7 @@ namespace Content.Client.Arcade private void TryPause() { - _owner.SendAction(BlockGamePlayerAction.Pause); + OnAction?.Invoke(BlockGamePlayerAction.Pause); } public void SetStarted() @@ -576,19 +581,19 @@ namespace Content.Client.Arcade return; else if (args.Function == ContentKeyFunctions.ArcadeLeft) - _owner.SendAction(BlockGamePlayerAction.StartLeft); + OnAction?.Invoke(BlockGamePlayerAction.StartLeft); else if (args.Function == ContentKeyFunctions.ArcadeRight) - _owner.SendAction(BlockGamePlayerAction.StartRight); + OnAction?.Invoke(BlockGamePlayerAction.StartRight); else if (args.Function == ContentKeyFunctions.ArcadeUp) - _owner.SendAction(BlockGamePlayerAction.Rotate); + OnAction?.Invoke(BlockGamePlayerAction.Rotate); else if (args.Function == ContentKeyFunctions.Arcade3) - _owner.SendAction(BlockGamePlayerAction.CounterRotate); + OnAction?.Invoke(BlockGamePlayerAction.CounterRotate); else if (args.Function == ContentKeyFunctions.ArcadeDown) - _owner.SendAction(BlockGamePlayerAction.SoftdropStart); + OnAction?.Invoke(BlockGamePlayerAction.SoftdropStart); else if (args.Function == ContentKeyFunctions.Arcade2) - _owner.SendAction(BlockGamePlayerAction.Hold); + OnAction?.Invoke(BlockGamePlayerAction.Hold); else if (args.Function == ContentKeyFunctions.Arcade1) - _owner.SendAction(BlockGamePlayerAction.Harddrop); + OnAction?.Invoke(BlockGamePlayerAction.Harddrop); } protected override void KeyBindUp(GUIBoundKeyEventArgs args) @@ -599,11 +604,11 @@ namespace Content.Client.Arcade return; else if (args.Function == ContentKeyFunctions.ArcadeLeft) - _owner.SendAction(BlockGamePlayerAction.EndLeft); + OnAction?.Invoke(BlockGamePlayerAction.EndLeft); else if (args.Function == ContentKeyFunctions.ArcadeRight) - _owner.SendAction(BlockGamePlayerAction.EndRight); + OnAction?.Invoke(BlockGamePlayerAction.EndRight); else if (args.Function == ContentKeyFunctions.ArcadeDown) - _owner.SendAction(BlockGamePlayerAction.SoftdropEnd); + OnAction?.Invoke(BlockGamePlayerAction.SoftdropEnd); } public void UpdateNextBlock(BlockGameBlock[] blocks) diff --git a/Content.Client/Arcade/SpaceVillainArcadeMenu.cs b/Content.Client/Arcade/SpaceVillainArcadeMenu.cs index e5542a5848..1ee4c26818 100644 --- a/Content.Client/Arcade/SpaceVillainArcadeMenu.cs +++ b/Content.Client/Arcade/SpaceVillainArcadeMenu.cs @@ -8,8 +8,6 @@ namespace Content.Client.Arcade { public sealed class SpaceVillainArcadeMenu : DefaultWindow { - public SpaceVillainArcadeBoundUserInterface Owner { get; set; } - private readonly Label _enemyNameLabel; private readonly Label _playerInfoLabel; private readonly Label _enemyInfoLabel; @@ -17,11 +15,13 @@ namespace Content.Client.Arcade private readonly Label _enemyActionLabel; private readonly Button[] _gameButtons = new Button[3]; //used to disable/enable all game buttons - public SpaceVillainArcadeMenu(SpaceVillainArcadeBoundUserInterface owner) + + public event Action? OnPlayerAction; + + public SpaceVillainArcadeMenu() { MinSize = SetSize = new Vector2(300, 225); Title = Loc.GetString("spacevillain-menu-title"); - Owner = owner; var grid = new GridContainer { Columns = 1 }; @@ -47,32 +47,43 @@ namespace Content.Client.Arcade grid.AddChild(_enemyActionLabel); var buttonGrid = new GridContainer { Columns = 3 }; - _gameButtons[0] = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.Attack) + _gameButtons[0] = new Button() { Text = Loc.GetString("spacevillain-menu-button-attack") }; + + _gameButtons[0].OnPressed += + _ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.Attack); buttonGrid.AddChild(_gameButtons[0]); - _gameButtons[1] = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.Heal) + _gameButtons[1] = new Button() { Text = Loc.GetString("spacevillain-menu-button-heal") }; + + _gameButtons[1].OnPressed += + _ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.Heal); buttonGrid.AddChild(_gameButtons[1]); - _gameButtons[2] = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.Recharge) + _gameButtons[2] = new Button() { Text = Loc.GetString("spacevillain-menu-button-recharge") }; + + _gameButtons[2].OnPressed += + _ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.Recharge); buttonGrid.AddChild(_gameButtons[2]); centerContainer = new CenterContainer(); centerContainer.AddChild(buttonGrid); grid.AddChild(centerContainer); - var newGame = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.NewGame) + var newGame = new Button() { Text = Loc.GetString("spacevillain-menu-button-new-game") }; + + newGame.OnPressed += _ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.NewGame); grid.AddChild(newGame); Contents.AddChild(grid); @@ -99,23 +110,5 @@ namespace Content.Client.Arcade _playerActionLabel.Text = message.PlayerActionMessage; _enemyActionLabel.Text = message.EnemyActionMessage; } - - private sealed class ActionButton : Button - { - private readonly SpaceVillainArcadeBoundUserInterface _owner; - private readonly SharedSpaceVillainArcadeComponent.PlayerAction _playerAction; - - public ActionButton(SpaceVillainArcadeBoundUserInterface owner, SharedSpaceVillainArcadeComponent.PlayerAction playerAction) - { - _owner = owner; - _playerAction = playerAction; - OnPressed += Clicked; - } - - private void Clicked(ButtonEventArgs e) - { - _owner.SendAction(_playerAction); - } - } } } diff --git a/Content.Client/Arcade/UI/BlockGameBoundUserInterface.cs b/Content.Client/Arcade/UI/BlockGameBoundUserInterface.cs index 1a3422dec0..8fa8035afd 100644 --- a/Content.Client/Arcade/UI/BlockGameBoundUserInterface.cs +++ b/Content.Client/Arcade/UI/BlockGameBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Arcade; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Arcade.UI; @@ -15,9 +16,7 @@ public sealed class BlockGameBoundUserInterface : BoundUserInterface { base.Open(); - _menu = new BlockGameMenu(this); - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); } protected override void ReceiveMessage(BoundUserInterfaceMessage message) diff --git a/Content.Client/Arcade/UI/SpaceVillainArcadeBoundUserInterface.cs b/Content.Client/Arcade/UI/SpaceVillainArcadeBoundUserInterface.cs index 40bbe8b2d8..c0704530de 100644 --- a/Content.Client/Arcade/UI/SpaceVillainArcadeBoundUserInterface.cs +++ b/Content.Client/Arcade/UI/SpaceVillainArcadeBoundUserInterface.cs @@ -1,4 +1,5 @@ using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.GameObjects; using Robust.Shared.ViewVariables; using static Content.Shared.Arcade.SharedSpaceVillainArcadeComponent; @@ -9,8 +10,6 @@ public sealed class SpaceVillainArcadeBoundUserInterface : BoundUserInterface { [ViewVariables] private SpaceVillainArcadeMenu? _menu; - //public SharedSpaceVillainArcadeComponent SpaceVillainArcade; - public SpaceVillainArcadeBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { SendAction(PlayerAction.RequestData); @@ -25,10 +24,7 @@ public sealed class SpaceVillainArcadeBoundUserInterface : BoundUserInterface { base.Open(); - _menu = new SpaceVillainArcadeMenu(this); - - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); } protected override void ReceiveMessage(BoundUserInterfaceMessage message) @@ -36,12 +32,4 @@ public sealed class SpaceVillainArcadeBoundUserInterface : BoundUserInterface if (message is SpaceVillainArcadeDataUpdateMessage msg) _menu?.UpdateInfo(msg); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - _menu?.Dispose(); - } } diff --git a/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs b/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs index 8f3b507c80..2ae1518835 100644 --- a/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs +++ b/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Atmos; using Content.Shared.Atmos.Monitor; using Content.Shared.Atmos.Monitor.Components; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Log; @@ -20,16 +21,9 @@ public sealed class AirAlarmBoundUserInterface : BoundUserInterface { base.Open(); - _window = new AirAlarmWindow(this); + _window = this.CreateWindow(); + _window.SetEntity(Owner); - if (State != null) - { - UpdateState(State); - } - - _window.OpenCentered(); - - _window.OnClose += Close; _window.AtmosDeviceDataChanged += OnDeviceDataChanged; _window.AtmosDeviceDataCopied += OnDeviceDataCopied; _window.AtmosAlarmThresholdChanged += OnThresholdChanged; diff --git a/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml.cs b/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml.cs index 43be67c9d6..eeec11c766 100644 --- a/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml.cs +++ b/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml.cs @@ -47,7 +47,7 @@ public sealed partial class AirAlarmWindow : FancyWindow private CheckBox _autoMode => AutoModeCheckBox; - public AirAlarmWindow(BoundUserInterface owner) + public AirAlarmWindow() { RobustXamlLoader.Load(this); @@ -95,8 +95,11 @@ public sealed partial class AirAlarmWindow : FancyWindow _sensors.Clear(); ResyncAllRequested!.Invoke(); }; + } - EntityView.SetEntity(owner.Owner); + public void SetEntity(EntityUid uid) + { + EntityView.SetEntity(uid); } public void UpdateState(AirAlarmUIState state) diff --git a/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs b/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs index a5e316a8de..7bf9b396d5 100644 --- a/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Atmos.Piping.Binary.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -21,14 +22,8 @@ namespace Content.Client.Atmos.UI { base.Open(); - _window = new GasCanisterWindow(); + _window = this.CreateWindow(); - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; _window.ReleaseValveCloseButtonPressed += OnReleaseValveClosePressed; _window.ReleaseValveOpenButtonPressed += OnReleaseValveOpenPressed; _window.ReleasePressureSet += OnReleasePressureSet; diff --git a/Content.Client/Atmos/UI/GasFilterBoundUserInterface.cs b/Content.Client/Atmos/UI/GasFilterBoundUserInterface.cs index 1904e2b340..2b8020924c 100644 --- a/Content.Client/Atmos/UI/GasFilterBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasFilterBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Atmos; using Content.Shared.Atmos.Piping.Trinary.Components; using Content.Shared.Localizations; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -28,14 +29,8 @@ namespace Content.Client.Atmos.UI var atmosSystem = EntMan.System(); - _window = new GasFilterWindow(atmosSystem.Gases); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); + _window.PopulateGasList(atmosSystem.Gases); _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed; _window.FilterTransferRateChanged += OnFilterTransferRatePressed; diff --git a/Content.Client/Atmos/UI/GasFilterWindow.xaml.cs b/Content.Client/Atmos/UI/GasFilterWindow.xaml.cs index 28766c688a..62748b5259 100644 --- a/Content.Client/Atmos/UI/GasFilterWindow.xaml.cs +++ b/Content.Client/Atmos/UI/GasFilterWindow.xaml.cs @@ -26,10 +26,9 @@ namespace Content.Client.Atmos.UI public event Action? FilterTransferRateChanged; public event Action? SelectGasPressed; - public GasFilterWindow(IEnumerable gases) + public GasFilterWindow() { RobustXamlLoader.Load(this); - PopulateGasList(gases); ToggleStatusButton.OnPressed += _ => SetFilterStatus(!FilterStatus); ToggleStatusButton.OnPressed += _ => ToggleStatusButtonPressed?.Invoke(); @@ -73,7 +72,7 @@ namespace Content.Client.Atmos.UI SelectGasButton.Disabled = true; } - private void PopulateGasList(IEnumerable gases) + public void PopulateGasList(IEnumerable gases) { GasList.Add(new ItemList.Item(GasList) { @@ -81,7 +80,7 @@ namespace Content.Client.Atmos.UI Text = Loc.GetString("comp-gas-filter-ui-filter-gas-none") }); - foreach (GasPrototype gas in gases) + foreach (var gas in gases) { var gasName = Loc.GetString(gas.Name); GasList.Add(GetGasItem(gas.ID, gasName, GasList)); diff --git a/Content.Client/Atmos/UI/GasMixerBoundUserInteface.cs b/Content.Client/Atmos/UI/GasMixerBoundUserInteface.cs index 709c06517c..392fbf1cd9 100644 --- a/Content.Client/Atmos/UI/GasMixerBoundUserInteface.cs +++ b/Content.Client/Atmos/UI/GasMixerBoundUserInteface.cs @@ -2,7 +2,7 @@ using Content.Shared.Atmos; using Content.Shared.Atmos.Piping.Trinary.Components; using Content.Shared.Localizations; using JetBrains.Annotations; -using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -26,14 +26,7 @@ namespace Content.Client.Atmos.UI { base.Open(); - _window = new GasMixerWindow(); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed; _window.MixerOutputPressureChanged += OnMixerOutputPressurePressed; @@ -83,12 +76,5 @@ namespace Content.Client.Atmos.UI _window.SetOutputPressure(cast.OutputPressure); _window.SetNodePercentages(cast.NodeOne); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } } diff --git a/Content.Client/Atmos/UI/GasPressurePumpBoundUserInterface.cs b/Content.Client/Atmos/UI/GasPressurePumpBoundUserInterface.cs index 6eba2e0d21..220fdbe875 100644 --- a/Content.Client/Atmos/UI/GasPressurePumpBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasPressurePumpBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Atmos.Piping.Binary.Components; using Content.Shared.Localizations; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -26,14 +27,7 @@ namespace Content.Client.Atmos.UI { base.Open(); - _window = new GasPressurePumpWindow(); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed; _window.PumpOutputPressureChanged += OnPumpOutputPressurePressed; @@ -67,12 +61,5 @@ namespace Content.Client.Atmos.UI _window.SetPumpStatus(cast.Enabled); _window.SetOutputPressure(cast.OutputPressure); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } } diff --git a/Content.Client/Atmos/UI/GasThermomachineBoundUserInterface.cs b/Content.Client/Atmos/UI/GasThermomachineBoundUserInterface.cs index 1664c8b9d7..d62be8f4bb 100644 --- a/Content.Client/Atmos/UI/GasThermomachineBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasThermomachineBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Atmos.Piping.Unary.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -31,14 +32,7 @@ namespace Content.Client.Atmos.UI { base.Open(); - _window = new GasThermomachineWindow(); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.ToggleStatusButton.OnPressed += _ => OnToggleStatusButtonPressed(); _window.TemperatureSpinbox.OnValueChanged += _ => OnTemperatureChanged(_window.TemperatureSpinbox.Value); @@ -91,12 +85,5 @@ namespace Content.Client.Atmos.UI true => Loc.GetString("comp-gas-thermomachine-ui-title-heater") }; } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } } diff --git a/Content.Client/Atmos/UI/GasVolumePumpBoundUserInterface.cs b/Content.Client/Atmos/UI/GasVolumePumpBoundUserInterface.cs index 1b39306181..642f34c2f9 100644 --- a/Content.Client/Atmos/UI/GasVolumePumpBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasVolumePumpBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Atmos.Piping.Binary.Components; using Content.Shared.Localizations; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -26,14 +27,7 @@ namespace Content.Client.Atmos.UI { base.Open(); - _window = new GasVolumePumpWindow(); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed; _window.PumpTransferRateChanged += OnPumpTransferRatePressed; @@ -64,16 +58,9 @@ namespace Content.Client.Atmos.UI if (_window == null || state is not GasVolumePumpBoundUserInterfaceState cast) return; - _window.Title = (cast.PumpLabel); + _window.Title = cast.PumpLabel; _window.SetPumpStatus(cast.Enabled); _window.SetTransferRate(cast.TransferRate); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } } diff --git a/Content.Client/Atmos/UI/SpaceHeaterBoundUserInterface.cs b/Content.Client/Atmos/UI/SpaceHeaterBoundUserInterface.cs index 4d8d1191e9..e70426575d 100644 --- a/Content.Client/Atmos/UI/SpaceHeaterBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/SpaceHeaterBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Atmos.Piping.Portable.Components; using JetBrains.Annotations; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; namespace Content.Client.Atmos.UI; @@ -21,14 +22,7 @@ public sealed class SpaceHeaterBoundUserInterface : BoundUserInterface { base.Open(); - _window = new SpaceHeaterWindow(); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.ToggleStatusButton.OnPressed += _ => OnToggleStatusButtonPressed(); _window.IncreaseTempRange.OnPressed += _ => OnTemperatureRangeChanged(_window.TemperatureChangeDelta); diff --git a/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs b/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs index 60fe339069..865dfc478d 100644 --- a/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs +++ b/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs @@ -1,8 +1,7 @@ using Content.Shared.Audio.Jukebox; using Robust.Client.Audio; -using Robust.Client.Player; +using Robust.Client.UserInterface; using Robust.Shared.Audio.Components; -using Robust.Shared.Player; using Robust.Shared.Prototypes; namespace Content.Client.Audio.Jukebox; @@ -23,9 +22,7 @@ public sealed class JukeboxBoundUserInterface : BoundUserInterface { base.Open(); - _menu = new JukeboxMenu(); - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); _menu.OnPlayPressed += args => { @@ -100,19 +97,5 @@ public sealed class JukeboxBoundUserInterface : BoundUserInterface SendMessage(new JukeboxSetTimeMessage(sentTime)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - if (_menu == null) - return; - - _menu.OnClose -= Close; - _menu.Dispose(); - _menu = null; - } } diff --git a/Content.Client/Bed/Cryostorage/CryostorageBoundUserInterface.cs b/Content.Client/Bed/Cryostorage/CryostorageBoundUserInterface.cs index ffab162548..09f3cec8fb 100644 --- a/Content.Client/Bed/Cryostorage/CryostorageBoundUserInterface.cs +++ b/Content.Client/Bed/Cryostorage/CryostorageBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Bed.Cryostorage; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Bed.Cryostorage; @@ -17,9 +18,7 @@ public sealed class CryostorageBoundUserInterface : BoundUserInterface { base.Open(); - _menu = new(); - - _menu.OnClose += Close; + _menu = this.CreateWindow(); _menu.SlotRemoveButtonPressed += (ent, slot) => { @@ -30,8 +29,6 @@ public sealed class CryostorageBoundUserInterface : BoundUserInterface { SendMessage(new CryostorageRemoveItemBuiMessage(ent, hand, CryostorageRemoveItemBuiMessage.RemovalType.Hand)); }; - - _menu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -45,12 +42,4 @@ public sealed class CryostorageBoundUserInterface : BoundUserInterface break; } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Dispose(); - } } diff --git a/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs b/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs index d3365702bc..44c40143d8 100644 --- a/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs +++ b/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Client.Cargo.UI; using Content.Shared.Cargo.Components; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Cargo.BUI; @@ -18,9 +19,7 @@ public sealed class CargoBountyConsoleBoundUserInterface : BoundUserInterface { base.Open(); - _menu = new(); - - _menu.OnClose += Close; + _menu = this.CreateWindow(); _menu.OnLabelButtonPressed += id => { @@ -31,8 +30,6 @@ public sealed class CargoBountyConsoleBoundUserInterface : BoundUserInterface { SendMessage(new BountySkipMessage(id)); }; - - _menu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState message) @@ -44,14 +41,4 @@ public sealed class CargoBountyConsoleBoundUserInterface : BoundUserInterface _menu?.UpdateEntries(state.Bounties, state.UntilNextSkip); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (!disposing) - return; - - _menu?.Dispose(); - } } diff --git a/Content.Client/Cargo/BUI/CargoPalletConsoleBoundUserInterface.cs b/Content.Client/Cargo/BUI/CargoPalletConsoleBoundUserInterface.cs index 20c23a48a0..2461dafb5f 100644 --- a/Content.Client/Cargo/BUI/CargoPalletConsoleBoundUserInterface.cs +++ b/Content.Client/Cargo/BUI/CargoPalletConsoleBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Client.Cargo.UI; using Content.Shared.Cargo.BUI; using Content.Shared.Cargo.Events; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Cargo.BUI; @@ -18,21 +19,9 @@ public sealed class CargoPalletConsoleBoundUserInterface : BoundUserInterface { base.Open(); - _menu = new CargoPalletMenu(); + _menu = this.CreateWindow(); _menu.AppraiseRequested += OnAppraisal; _menu.SellRequested += OnSell; - _menu.OnClose += Close; - - _menu.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (disposing) - { - _menu?.Dispose(); - } } private void OnAppraisal() diff --git a/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs b/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs index 422d03707a..02b721b902 100644 --- a/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs +++ b/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Client.Cargo.UI; using Content.Shared.Cargo.BUI; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Cargo.BUI; @@ -9,6 +10,8 @@ namespace Content.Client.Cargo.BUI; [UsedImplicitly] public sealed class CargoShuttleConsoleBoundUserInterface : BoundUserInterface { + [Dependency] private readonly IPrototypeManager _protoManager = default!; + [ViewVariables] private CargoShuttleMenu? _menu; @@ -19,24 +22,7 @@ public sealed class CargoShuttleConsoleBoundUserInterface : BoundUserInterface protected override void Open() { base.Open(); - var collection = IoCManager.Instance; - - if (collection == null) - return; - - _menu = new CargoShuttleMenu(collection.Resolve(), collection.Resolve().GetEntitySystem()); - _menu.OnClose += Close; - - _menu.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (disposing) - { - _menu?.Dispose(); - } + _menu = this.CreateWindow(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -45,6 +31,6 @@ public sealed class CargoShuttleConsoleBoundUserInterface : BoundUserInterface if (state is not CargoShuttleConsoleBoundUserInterfaceState cargoState) return; _menu?.SetAccountName(cargoState.AccountName); _menu?.SetShuttleName(cargoState.ShuttleName); - _menu?.SetOrders(cargoState.Orders); + _menu?.SetOrders(EntMan.System(), _protoManager, cargoState.Orders); } } diff --git a/Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs b/Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs index c591f917da..43b00089e1 100644 --- a/Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs +++ b/Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs @@ -12,14 +12,9 @@ namespace Content.Client.Cargo.UI [GenerateTypedNameReferences] public sealed partial class CargoShuttleMenu : FancyWindow { - private readonly IPrototypeManager _protoManager; - private readonly SpriteSystem _spriteSystem; - - public CargoShuttleMenu(IPrototypeManager protoManager, SpriteSystem spriteSystem) + public CargoShuttleMenu() { RobustXamlLoader.Load(this); - _protoManager = protoManager; - _spriteSystem = spriteSystem; Title = Loc.GetString("cargo-shuttle-console-menu-title"); } @@ -33,19 +28,19 @@ namespace Content.Client.Cargo.UI ShuttleNameLabel.Text = name; } - public void SetOrders(List orders) + public void SetOrders(SpriteSystem sprites, IPrototypeManager protoManager, List orders) { Orders.DisposeAllChildren(); foreach (var order in orders) { - var product = _protoManager.Index(order.ProductId); + var product = protoManager.Index(order.ProductId); var productName = product.Name; var row = new CargoOrderRow { Order = order, - Icon = { Texture = _spriteSystem.Frame0(product) }, + Icon = { Texture = sprites.Frame0(product) }, ProductName = { Text = Loc.GetString( diff --git a/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs b/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs index 988fea7978..3ef7f0ae73 100644 --- a/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs +++ b/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Chemistry; using Content.Shared.Containers.ItemSlots; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Chemistry.UI { @@ -27,13 +28,8 @@ namespace Content.Client.Chemistry.UI base.Open(); // Setup window layout/elements - _window = new ChemMasterWindow - { - Title = EntMan.GetComponent(Owner).EntityName, - }; - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); + _window.Title = EntMan.GetComponent(Owner).EntityName; // Setup static button actions. _window.InputEjectButton.OnPressed += _ => SendMessage( @@ -75,15 +71,5 @@ namespace Content.Client.Chemistry.UI _window?.UpdateState(castState); // Update window state } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Dispose(); - } - } } } diff --git a/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs b/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs index 99e5a3d395..2ad1b71888 100644 --- a/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs +++ b/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Chemistry; using Content.Shared.Containers.ItemSlots; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Chemistry.UI { @@ -15,9 +16,6 @@ namespace Content.Client.Chemistry.UI [ViewVariables] private ReagentDispenserWindow? _window; - [ViewVariables] - private ReagentDispenserBoundUserInterfaceState? _lastState; - public ReagentDispenserBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -32,14 +30,9 @@ namespace Content.Client.Chemistry.UI base.Open(); // Setup window layout/elements - _window = new() - { - Title = EntMan.GetComponent(Owner).EntityName, - HelpGuidebookIds = EntMan.GetComponent(Owner).Guides - }; - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); + _window.Title = EntMan.GetComponent(Owner).EntityName; + _window.HelpGuidebookIds = EntMan.GetComponent(Owner).Guides; // Setup static button actions. _window.EjectButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(SharedReagentDispenser.OutputSlotName)); @@ -63,19 +56,7 @@ namespace Content.Client.Chemistry.UI base.UpdateState(state); var castState = (ReagentDispenserBoundUserInterfaceState) state; - _lastState = castState; - _window?.UpdateState(castState); //Update window state } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Dispose(); - } - } } } diff --git a/Content.Client/Chemistry/UI/TransferAmountBoundUserInterface.cs b/Content.Client/Chemistry/UI/TransferAmountBoundUserInterface.cs index 35df131312..f1cb27a62a 100644 --- a/Content.Client/Chemistry/UI/TransferAmountBoundUserInterface.cs +++ b/Content.Client/Chemistry/UI/TransferAmountBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Chemistry; using Content.Shared.FixedPoint; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Chemistry.UI { @@ -18,7 +19,7 @@ namespace Content.Client.Chemistry.UI protected override void Open() { base.Open(); - _window = new TransferAmountWindow(); + _window = this.CreateWindow(); _window.ApplyButton.OnPressed += _ => { @@ -28,15 +29,6 @@ namespace Content.Client.Chemistry.UI _window.Close(); } }; - _window.OnClose += Close; - _window.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); } } } diff --git a/Content.Client/CloningConsole/UI/CloningConsoleBoundUserInterface.cs b/Content.Client/CloningConsole/UI/CloningConsoleBoundUserInterface.cs index 26f0994701..62a02f3718 100644 --- a/Content.Client/CloningConsole/UI/CloningConsoleBoundUserInterface.cs +++ b/Content.Client/CloningConsole/UI/CloningConsoleBoundUserInterface.cs @@ -1,6 +1,7 @@ using JetBrains.Annotations; using Robust.Client.GameObjects; using Content.Shared.Cloning.CloningConsole; +using Robust.Client.UserInterface; namespace Content.Client.CloningConsole.UI { @@ -17,13 +18,11 @@ namespace Content.Client.CloningConsole.UI protected override void Open() { base.Open(); - _window = new CloningConsoleWindow - { - Title = Loc.GetString("cloning-console-window-title") - }; - _window.OnClose += Close; + + _window = this.CreateWindow(); + _window.Title = Loc.GetString("cloning-console-window-title"); + _window.CloneButton.OnPressed += _ => SendMessage(new UiButtonPressedMessage(UiButton.Clone)); - _window.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -32,19 +31,5 @@ namespace Content.Client.CloningConsole.UI _window?.Populate((CloningConsoleBoundUserInterfaceState) state); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - if (_window != null) - { - _window.OnClose -= Close; - _window.CloneButton.OnPressed -= _ => SendMessage(new UiButtonPressedMessage(UiButton.Clone)); - } - _window?.Dispose(); - } } } diff --git a/Content.Client/Clothing/UI/ChameleonBoundUserInterface.cs b/Content.Client/Clothing/UI/ChameleonBoundUserInterface.cs index 5b0d5fcf21..83f6ba1566 100644 --- a/Content.Client/Clothing/UI/ChameleonBoundUserInterface.cs +++ b/Content.Client/Clothing/UI/ChameleonBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Clothing.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Clothing.UI; @@ -22,10 +23,8 @@ public sealed class ChameleonBoundUserInterface : BoundUserInterface { base.Open(); - _menu = new ChameleonMenu(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); _menu.OnIdSelected += OnIdSelected; - _menu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -42,15 +41,4 @@ public sealed class ChameleonBoundUserInterface : BoundUserInterface { SendMessage(new ChameleonPrototypeSelectedMessage(selectedId)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _menu?.Close(); - _menu = null; - } - } } diff --git a/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs b/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs index 1c94d32bf8..0310e91eeb 100644 --- a/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs +++ b/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.CCVar; using Content.Shared.Chat; using Content.Shared.Communications; +using Robust.Client.UserInterface; using Robust.Shared.Configuration; using Robust.Shared.Timing; @@ -8,34 +9,11 @@ namespace Content.Client.Communications.UI { public sealed class CommunicationsConsoleBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IConfigurationManager _cfg = default!; [ViewVariables] private CommunicationsConsoleMenu? _menu; - [ViewVariables] - public bool CanAnnounce { get; private set; } - [ViewVariables] - public bool CanBroadcast { get; private set; } - - [ViewVariables] - public bool CanCall { get; private set; } - - [ViewVariables] - public bool CountdownStarted { get; private set; } - - [ViewVariables] - public bool AlertLevelSelectable { get; private set; } - - [ViewVariables] - public string CurrentLevel { get; private set; } = default!; - - [ViewVariables] - private TimeSpan? _expectedCountdownTime; - - public int Countdown => _expectedCountdownTime == null ? 0 : Math.Max((int) _expectedCountdownTime.Value.Subtract(_gameTiming.CurTime).TotalSeconds, 0); - public CommunicationsConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -44,23 +22,25 @@ namespace Content.Client.Communications.UI { base.Open(); - _menu = new CommunicationsConsoleMenu(this); - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); + _menu.OnAnnounce += AnnounceButtonPressed; + _menu.OnBroadcast += BroadcastButtonPressed; + _menu.OnAlertLevel += AlertLevelSelected; + _menu.OnEmergencyLevel += EmergencyShuttleButtonPressed; } public void AlertLevelSelected(string level) { - if (AlertLevelSelectable) + if (_menu!.AlertLevelSelectable) { - CurrentLevel = level; + _menu.CurrentLevel = level; SendMessage(new CommunicationsConsoleSelectAlertLevelMessage(level)); } } public void EmergencyShuttleButtonPressed() { - if (CountdownStarted) + if (_menu!.CountdownStarted) RecallShuttle(); else CallShuttle(); @@ -95,31 +75,23 @@ namespace Content.Client.Communications.UI if (state is not CommunicationsConsoleInterfaceState commsState) return; - CanAnnounce = commsState.CanAnnounce; - CanBroadcast = commsState.CanBroadcast; - CanCall = commsState.CanCall; - _expectedCountdownTime = commsState.ExpectedCountdownEnd; - CountdownStarted = commsState.CountdownStarted; - AlertLevelSelectable = commsState.AlertLevels != null && !float.IsNaN(commsState.CurrentAlertDelay) && commsState.CurrentAlertDelay <= 0; - CurrentLevel = commsState.CurrentAlert; - 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, CurrentLevel); - _menu.AlertLevelButton.Disabled = !AlertLevelSelectable; - _menu.EmergencyShuttleButton.Disabled = !CanCall; - _menu.AnnounceButton.Disabled = !CanAnnounce; - _menu.BroadcastButton.Disabled = !CanBroadcast; + _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; } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - - _menu?.Dispose(); - } } } diff --git a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs index bbca06f519..63868e7a93 100644 --- a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs +++ b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs @@ -1,31 +1,40 @@ -using Content.Client.UserInterface.Controls; -using System.Threading; +using System.Globalization; +using Content.Client.UserInterface.Controls; using Content.Shared.CCVar; using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.XAML; using Robust.Shared.Configuration; +using Robust.Shared.Timing; using Robust.Shared.Utility; -using Timer = Robust.Shared.Timing.Timer; namespace Content.Client.Communications.UI { [GenerateTypedNameReferences] public sealed partial class CommunicationsConsoleMenu : FancyWindow { - private CommunicationsConsoleBoundUserInterface Owner { get; set; } - private readonly CancellationTokenSource _timerCancelTokenSource = new(); - [Dependency] private readonly IConfigurationManager _cfg = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly ILocalizationManager _loc = default!; - public CommunicationsConsoleMenu(CommunicationsConsoleBoundUserInterface owner) + public bool CanAnnounce; + public bool CanBroadcast; + public bool CanCall; + public bool AlertLevelSelectable; + public bool CountdownStarted; + public string CurrentLevel = string.Empty; + public TimeSpan? CountdownEnd; + + public event Action? OnEmergencyLevel; + public event Action? OnAlertLevel; + public event Action? OnAnnounce; + public event Action? OnBroadcast; + + public CommunicationsConsoleMenu() { IoCManager.InjectDependencies(this); RobustXamlLoader.Load(this); - Owner = owner; - - var loc = IoCManager.Resolve(); - MessageInput.Placeholder = new Rope.Leaf(loc.GetString("comms-console-menu-announcement-placeholder")); + MessageInput.Placeholder = new Rope.Leaf(_loc.GetString("comms-console-menu-announcement-placeholder")); var maxAnnounceLength = _cfg.GetCVar(CCVars.ChatMaxAnnouncementLength); MessageInput.OnTextChanged += (args) => @@ -37,33 +46,38 @@ namespace Content.Client.Communications.UI } else { - AnnounceButton.Disabled = !owner.CanAnnounce; + AnnounceButton.Disabled = !CanAnnounce; AnnounceButton.ToolTip = null; } }; - AnnounceButton.OnPressed += (_) => Owner.AnnounceButtonPressed(Rope.Collapse(MessageInput.TextRope)); - AnnounceButton.Disabled = !owner.CanAnnounce; + AnnounceButton.OnPressed += _ => OnAnnounce?.Invoke(Rope.Collapse(MessageInput.TextRope)); + AnnounceButton.Disabled = !CanAnnounce; - BroadcastButton.OnPressed += (_) => Owner.BroadcastButtonPressed(Rope.Collapse(MessageInput.TextRope)); - BroadcastButton.Disabled = !owner.CanBroadcast; + 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) { - Owner.AlertLevelSelected(cast); + OnAlertLevel?.Invoke(cast); } }; - AlertLevelButton.Disabled = !owner.AlertLevelSelectable; - EmergencyShuttleButton.OnPressed += (_) => Owner.EmergencyShuttleButtonPressed(); - EmergencyShuttleButton.Disabled = !owner.CanCall; + AlertLevelButton.Disabled = !AlertLevelSelectable; + + EmergencyShuttleButton.OnPressed += _ => OnEmergencyLevel?.Invoke(); + EmergencyShuttleButton.Disabled = !CanCall; + } + + protected override void FrameUpdate(FrameEventArgs args) + { + base.FrameUpdate(args); UpdateCountdown(); - Timer.SpawnRepeating(1000, UpdateCountdown, _timerCancelTokenSource.Token); } // The current alert could make levels unselectable, so we need to ensure that the UI reacts properly. @@ -105,32 +119,19 @@ namespace Content.Client.Communications.UI public void UpdateCountdown() { - if (!Owner.CountdownStarted) + if (!CountdownStarted) { - CountdownLabel.SetMessage(""); + CountdownLabel.SetMessage(string.Empty); EmergencyShuttleButton.Text = Loc.GetString("comms-console-menu-call-shuttle"); return; } + 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", Owner.Countdown.ToString())); + ("time", diff.TotalSeconds.ToString(CultureInfo.CurrentCulture))); CountdownLabel.SetMessage(infoText); } - - public override void Close() - { - base.Close(); - - _timerCancelTokenSource.Cancel(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - _timerCancelTokenSource.Cancel(); - } } } diff --git a/Content.Client/Computer/ComputerBoundUserInterface.cs b/Content.Client/Computer/ComputerBoundUserInterface.cs index bdbfe03fa1..11c26b252e 100644 --- a/Content.Client/Computer/ComputerBoundUserInterface.cs +++ b/Content.Client/Computer/ComputerBoundUserInterface.cs @@ -1,4 +1,5 @@ using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.CustomControls; namespace Content.Client.Computer @@ -19,10 +20,8 @@ namespace Content.Client.Computer { base.Open(); - _window = (TWindow) _dynamicTypeFactory.CreateInstance(typeof(TWindow)); + _window = this.CreateWindow(); _window.SetupComputerWindow(this); - _window.OnClose += Close; - _window.OpenCentered(); } // Alas, this constructor has to be copied to the subclass. :( @@ -42,16 +41,6 @@ namespace Content.Client.Computer _window.UpdateState((TState) state); } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Dispose(); - } - } - protected override void ReceiveMessage(BoundUserInterfaceMessage message) { _window?.ReceiveMessage(message); diff --git a/Content.Client/Configurable/UI/ConfigurationBoundUserInterface.cs b/Content.Client/Configurable/UI/ConfigurationBoundUserInterface.cs index 4fea44f225..e4966f1ec4 100644 --- a/Content.Client/Configurable/UI/ConfigurationBoundUserInterface.cs +++ b/Content.Client/Configurable/UI/ConfigurationBoundUserInterface.cs @@ -1,5 +1,6 @@ using System.Text.RegularExpressions; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using static Content.Shared.Configurable.ConfigurationComponent; namespace Content.Client.Configurable.UI @@ -9,9 +10,6 @@ namespace Content.Client.Configurable.UI [ViewVariables] private ConfigurationMenu? _menu; - [ViewVariables] - public Regex? Validation { get; internal set; } - public ConfigurationBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -19,10 +17,8 @@ namespace Content.Client.Configurable.UI protected override void Open() { base.Open(); - _menu = new ConfigurationMenu(this); - - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); + _menu.OnConfiguration += SendConfiguration; } protected override void UpdateState(BoundUserInterfaceState state) @@ -30,9 +26,7 @@ namespace Content.Client.Configurable.UI base.UpdateState(state); if (state is not ConfigurationBoundUserInterfaceState configurationState) - { return; - } _menu?.Populate(configurationState); } @@ -41,9 +35,12 @@ namespace Content.Client.Configurable.UI { base.ReceiveMessage(message); + if (_menu == null) + return; + if (message is ValidationUpdateMessage msg) { - Validation = new Regex(msg.ValidationString, RegexOptions.Compiled); + _menu.Validation = new Regex(msg.ValidationString, RegexOptions.Compiled); } } @@ -51,16 +48,5 @@ namespace Content.Client.Configurable.UI { SendMessage(new ConfigurationUpdatedMessage(config)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing && _menu != null) - { - _menu.OnClose -= Close; - _menu.Close(); - } - } } } diff --git a/Content.Client/Configurable/UI/ConfigurationMenu.cs b/Content.Client/Configurable/UI/ConfigurationMenu.cs index cc24af2869..29217eef7b 100644 --- a/Content.Client/Configurable/UI/ConfigurationMenu.cs +++ b/Content.Client/Configurable/UI/ConfigurationMenu.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Numerics; +using System.Text.RegularExpressions; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; @@ -13,23 +14,25 @@ namespace Content.Client.Configurable.UI { public sealed class ConfigurationMenu : DefaultWindow { - public ConfigurationBoundUserInterface Owner { get; } - private readonly BoxContainer _column; private readonly BoxContainer _row; private readonly List<(string name, LineEdit input)> _inputs; - public ConfigurationMenu(ConfigurationBoundUserInterface owner) + [ViewVariables] + public Regex? Validation { get; internal set; } + + public event Action>? OnConfiguration; + + public ConfigurationMenu() { MinSize = SetSize = new Vector2(300, 250); - Owner = owner; _inputs = new List<(string name, LineEdit input)>(); Title = Loc.GetString("configuration-menu-device-title"); - BoxContainer baseContainer = new BoxContainer + var baseContainer = new BoxContainer { Orientation = LayoutOrientation.Vertical, VerticalExpand = true, @@ -116,14 +119,13 @@ namespace Content.Client.Configurable.UI private void OnConfirm(ButtonEventArgs args) { var config = GenerateDictionary(_inputs, "Text"); - - Owner.SendConfiguration(config); + OnConfiguration?.Invoke(config); Close(); } private bool Validate(string value) { - return Owner.Validation == null || Owner.Validation.IsMatch(value); + return Validation?.IsMatch(value) != false; } private Dictionary GenerateDictionary(IEnumerable<(string name, LineEdit input)> inputs, string propertyName) diff --git a/Content.Client/Construction/UI/FlatpackCreatorBoundUserInterface.cs b/Content.Client/Construction/UI/FlatpackCreatorBoundUserInterface.cs index 86f1b8b83c..887492955e 100644 --- a/Content.Client/Construction/UI/FlatpackCreatorBoundUserInterface.cs +++ b/Content.Client/Construction/UI/FlatpackCreatorBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Construction.Components; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Construction.UI { @@ -17,8 +18,8 @@ namespace Content.Client.Construction.UI { base.Open(); - _menu = new FlatpackCreatorMenu(Owner); - _menu.OnClose += Close; + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); _menu.PackButtonPressed += () => { @@ -27,14 +28,5 @@ namespace Content.Client.Construction.UI _menu.OpenCentered(); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _menu?.Dispose(); - } } } diff --git a/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs b/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs index 9f3d5695bb..269694ebf9 100644 --- a/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs +++ b/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs @@ -24,7 +24,7 @@ public sealed partial class FlatpackCreatorMenu : FancyWindow private readonly FlatpackSystem _flatpack; private readonly MaterialStorageSystem _materialStorage; - private readonly EntityUid _owner; + private EntityUid _owner; [ValidatePrototypeId] public const string NoBoardEffectId = "FlatpackerNoBoardEffect"; @@ -33,7 +33,7 @@ public sealed partial class FlatpackCreatorMenu : FancyWindow public event Action? PackButtonPressed; - public FlatpackCreatorMenu(EntityUid uid) + public FlatpackCreatorMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); @@ -42,14 +42,17 @@ public sealed partial class FlatpackCreatorMenu : FancyWindow _flatpack = _entityManager.System(); _materialStorage = _entityManager.System(); - _owner = uid; - PackButton.OnPressed += _ => PackButtonPressed?.Invoke(); - MaterialStorageControl.SetOwner(uid); InsertLabel.SetMarkup(Loc.GetString("flatpacker-ui-insert-board")); } + public void SetEntity(EntityUid uid) + { + _owner = uid; + MaterialStorageControl.SetOwner(uid); + } + protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); diff --git a/Content.Client/Crayon/UI/CrayonBoundUserInterface.cs b/Content.Client/Crayon/UI/CrayonBoundUserInterface.cs index e2c4d51ecd..e5be0b1811 100644 --- a/Content.Client/Crayon/UI/CrayonBoundUserInterface.cs +++ b/Content.Client/Crayon/UI/CrayonBoundUserInterface.cs @@ -2,12 +2,15 @@ using Content.Shared.Crayon; using Content.Shared.Decals; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Crayon.UI { public sealed class CrayonBoundUserInterface : BoundUserInterface { + [Dependency] private readonly IPrototypeManager _protoManager = default!; + [ViewVariables] private CrayonWindow? _menu; @@ -18,15 +21,29 @@ namespace Content.Client.Crayon.UI protected override void Open() { base.Open(); - _menu = new CrayonWindow(this); - - _menu.OnClose += Close; - var prototypeManager = IoCManager.Resolve(); - var crayonDecals = prototypeManager.EnumeratePrototypes().Where(x => x.Tags.Contains("crayon")); - _menu.Populate(crayonDecals); + _menu = this.CreateWindow(); + _menu.OnColorSelected += SelectColor; + _menu.OnSelected += Select; + PopulateCrayons(); _menu.OpenCenteredLeft(); } + private void PopulateCrayons() + { + var crayonDecals = _protoManager.EnumeratePrototypes().Where(x => x.Tags.Contains("crayon")); + _menu?.Populate(crayonDecals); + } + + public override void OnProtoReload(PrototypesReloadedEventArgs args) + { + base.OnProtoReload(args); + + if (!args.WasModified()) + return; + + PopulateCrayons(); + } + protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); @@ -43,16 +60,5 @@ namespace Content.Client.Crayon.UI { SendMessage(new CrayonColorMessage(color)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _menu?.Close(); - _menu = null; - } - } } } diff --git a/Content.Client/Crayon/UI/CrayonWindow.xaml.cs b/Content.Client/Crayon/UI/CrayonWindow.xaml.cs index 2a5801ccf2..b97786cd41 100644 --- a/Content.Client/Crayon/UI/CrayonWindow.xaml.cs +++ b/Content.Client/Crayon/UI/CrayonWindow.xaml.cs @@ -18,18 +18,17 @@ namespace Content.Client.Crayon.UI [GenerateTypedNameReferences] public sealed partial class CrayonWindow : DefaultWindow { - public CrayonBoundUserInterface Owner { get; } - private Dictionary? _decals; private string? _selected; private Color _color; - public CrayonWindow(CrayonBoundUserInterface owner) + public event Action? OnColorSelected; + public event Action? OnSelected; + + public CrayonWindow() { RobustXamlLoader.Load(this); - Owner = owner; - Search.OnTextChanged += _ => RefreshList(); ColorSelector.OnColorChanged += SelectColor; } @@ -38,16 +37,16 @@ namespace Content.Client.Crayon.UI { _color = color; - Owner.SelectColor(color); - + OnColorSelected?.Invoke(color); RefreshList(); } private void RefreshList() { // Clear - Grid.RemoveAllChildren(); - if (_decals == null) return; + Grid.DisposeAllChildren(); + if (_decals == null) + return; var filter = Search.Text; foreach (var (decal, tex) in _decals) @@ -89,7 +88,6 @@ namespace Content.Client.Crayon.UI { if (obj.Button.Name == null) return; - Owner.Select(obj.Button.Name); _selected = obj.Button.Name; RefreshList(); } diff --git a/Content.Client/Disposal/UI/DisposalRouterBoundUserInterface.cs b/Content.Client/Disposal/UI/DisposalRouterBoundUserInterface.cs index e8e77217ea..296e71d3a9 100644 --- a/Content.Client/Disposal/UI/DisposalRouterBoundUserInterface.cs +++ b/Content.Client/Disposal/UI/DisposalRouterBoundUserInterface.cs @@ -1,5 +1,6 @@ using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using static Content.Shared.Disposal.Components.SharedDisposalRouterComponent; namespace Content.Client.Disposal.UI @@ -21,20 +22,16 @@ namespace Content.Client.Disposal.UI { base.Open(); - _window = new DisposalRouterWindow(); - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); _window.Confirm.OnPressed += _ => ButtonPressed(UiAction.Ok, _window.TagInput.Text); _window.TagInput.OnTextEntered += args => ButtonPressed(UiAction.Ok, args.Text); - } private void ButtonPressed(UiAction action, string tag) { SendMessage(new UiActionMessage(action, tag)); - _window?.Close(); + Close(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -48,18 +45,5 @@ namespace Content.Client.Disposal.UI _window?.UpdateState(cast); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Dispose(); - } - } - - } - } diff --git a/Content.Client/Disposal/UI/DisposalTaggerBoundUserInterface.cs b/Content.Client/Disposal/UI/DisposalTaggerBoundUserInterface.cs index 3aeed8dc80..7fc0eb8540 100644 --- a/Content.Client/Disposal/UI/DisposalTaggerBoundUserInterface.cs +++ b/Content.Client/Disposal/UI/DisposalTaggerBoundUserInterface.cs @@ -1,5 +1,6 @@ using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using static Content.Shared.Disposal.Components.SharedDisposalTaggerComponent; namespace Content.Client.Disposal.UI @@ -21,20 +22,17 @@ namespace Content.Client.Disposal.UI { base.Open(); - _window = new DisposalTaggerWindow(); - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); _window.Confirm.OnPressed += _ => ButtonPressed(UiAction.Ok, _window.TagInput.Text); _window.TagInput.OnTextEntered += args => ButtonPressed(UiAction.Ok, args.Text); - } private void ButtonPressed(UiAction action, string tag) { + // TODO: This looks copy-pasted with the other mailing stuff... SendMessage(new UiActionMessage(action, tag)); - _window?.Close(); + Close(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -48,18 +46,5 @@ namespace Content.Client.Disposal.UI _window?.UpdateState(cast); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Dispose(); - } - } - - } - } diff --git a/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs b/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs index cd7ea717ce..9b7e23c03a 100644 --- a/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs +++ b/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Access; using Content.Shared.Doors.Electronics; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Doors.Electronics; @@ -18,6 +19,23 @@ public sealed class DoorElectronicsBoundUserInterface : BoundUserInterface protected override void Open() { base.Open(); + _window = this.CreateWindow(); + _window.OnAccessChanged += UpdateConfiguration; + Reset(); + } + + public override void OnProtoReload(PrototypesReloadedEventArgs args) + { + base.OnProtoReload(args); + + if (!args.WasModified()) + return; + + Reset(); + } + + private void Reset() + { List> accessLevels = new(); foreach (var accessLevel in _prototypeManager.EnumeratePrototypes()) @@ -29,10 +47,7 @@ public sealed class DoorElectronicsBoundUserInterface : BoundUserInterface } accessLevels.Sort(); - - _window = new DoorElectronicsConfigurationMenu(this, accessLevels, _prototypeManager); - _window.OnClose += Close; - _window.OpenCentered(); + _window?.Reset(_prototypeManager, accessLevels); } protected override void UpdateState(BoundUserInterfaceState state) @@ -44,14 +59,6 @@ public sealed class DoorElectronicsBoundUserInterface : BoundUserInterface _window?.UpdateState(castState); } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - - _window?.Dispose(); - } - public void UpdateConfiguration(List> newAccessList) { SendMessage(new DoorElectronicsUpdateConfigurationMessage(newAccessList)); diff --git a/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs b/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs index c01f13a462..2112a56297 100644 --- a/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs +++ b/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs @@ -15,22 +15,23 @@ namespace Content.Client.Doors.Electronics; [GenerateTypedNameReferences] public sealed partial class DoorElectronicsConfigurationMenu : FancyWindow { - private readonly DoorElectronicsBoundUserInterface _owner; - private AccessLevelControl _buttonsList = new(); + private readonly AccessLevelControl _buttonsList = new(); - public DoorElectronicsConfigurationMenu(DoorElectronicsBoundUserInterface ui, List> accessLevels, IPrototypeManager prototypeManager) + public event Action>>? OnAccessChanged; + + public DoorElectronicsConfigurationMenu() { RobustXamlLoader.Load(this); - - _owner = ui; - - _buttonsList.Populate(accessLevels, prototypeManager); AccessLevelControlContainer.AddChild(_buttonsList); + } - foreach (var (id, button) in _buttonsList.ButtonsList) + public void Reset(IPrototypeManager protoManager, List> accessLevels) + { + _buttonsList.Populate(accessLevels, protoManager); + + foreach (var button in _buttonsList.ButtonsList.Values) { - button.OnPressed += _ => _owner.UpdateConfiguration( - _buttonsList.ButtonsList.Where(x => x.Value.Pressed).Select(x => x.Key).ToList()); + button.OnPressed += _ => OnAccessChanged?.Invoke(_buttonsList.ButtonsList.Where(x => x.Value.Pressed).Select(x => x.Key).ToList()); } } diff --git a/Content.Client/Fax/UI/FaxBoundUi.cs b/Content.Client/Fax/UI/FaxBoundUi.cs index a95066a3b5..ca2e834b4f 100644 --- a/Content.Client/Fax/UI/FaxBoundUi.cs +++ b/Content.Client/Fax/UI/FaxBoundUi.cs @@ -25,10 +25,7 @@ public sealed class FaxBoundUi : BoundUserInterface { base.Open(); - _window = new FaxWindow(); - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.FileButtonPressed += OnFileButtonPressed; _window.CopyButtonPressed += OnCopyButtonPressed; _window.SendButtonPressed += OnSendButtonPressed; @@ -104,11 +101,4 @@ public sealed class FaxBoundUi : BoundUserInterface _window.UpdateState(cast); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (disposing) - _window?.Dispose(); - } } diff --git a/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs b/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs index ba49f11ea0..08596b04e6 100644 --- a/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs +++ b/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs @@ -1,6 +1,7 @@ using Robust.Client.GameObjects; using Robust.Shared.Timing; using Content.Shared.Forensics; +using Robust.Client.UserInterface; namespace Content.Client.Forensics { @@ -21,11 +22,9 @@ namespace Content.Client.Forensics protected override void Open() { base.Open(); - _window = new ForensicScannerMenu(); - _window.OnClose += Close; + _window = this.CreateWindow(); _window.Print.OnPressed += _ => Print(); _window.Clear.OnPressed += _ => Clear(); - _window.OpenCentered(); } private void Print() @@ -62,6 +61,7 @@ namespace Content.Client.Forensics _printCooldown = cast.PrintCooldown; + // TODO: Fix this if (cast.PrintReadyAt > _gameTiming.CurTime) Timer.Spawn(cast.PrintReadyAt - _gameTiming.CurTime, () => { @@ -71,14 +71,5 @@ namespace Content.Client.Forensics _window.UpdateState(cast); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _window?.Dispose(); - } } } diff --git a/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs b/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs index fdb3cdbc01..457b70ca7c 100644 --- a/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs +++ b/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Gateway; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Gateway.UI; @@ -17,24 +18,13 @@ public sealed class GatewayBoundUserInterface : BoundUserInterface { base.Open(); - _window = new GatewayWindow(EntMan.GetNetEntity(Owner)); + _window = this.CreateWindow(); + _window.SetEntity(EntMan.GetNetEntity(Owner)); _window.OpenPortal += destination => { SendMessage(new GatewayOpenPortalMessage(destination)); }; - _window.OnClose += Close; - _window?.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (disposing) - { - _window?.Dispose(); - _window = null; - } } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Gateway/UI/GatewayWindow.xaml.cs b/Content.Client/Gateway/UI/GatewayWindow.xaml.cs index 889dd6e175..1c779b2b35 100644 --- a/Content.Client/Gateway/UI/GatewayWindow.xaml.cs +++ b/Content.Client/Gateway/UI/GatewayWindow.xaml.cs @@ -22,7 +22,7 @@ public sealed partial class GatewayWindow : FancyWindow, public event Action? OpenPortal; private List _destinations = new(); - public readonly NetEntity Owner; + public NetEntity Owner; private NetEntity? _current; private TimeSpan _nextReady; @@ -46,16 +46,20 @@ public sealed partial class GatewayWindow : FancyWindow, /// private bool _isCooldownPending = true; - public GatewayWindow(NetEntity netEntity) + public GatewayWindow() { RobustXamlLoader.Load(this); var dependencies = IoCManager.Instance!; _timing = dependencies.Resolve(); - Owner = netEntity; NextUnlockBar.ForegroundStyleBoxOverride = new StyleBoxFlat(Color.FromHex("#C74EBD")); } + public void SetEntity(NetEntity entity) + { + + } + public void UpdateState(GatewayBoundUserInterfaceState state) { _destinations = state.Destinations; diff --git a/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs b/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs index d72da3e812..32b40747d5 100644 --- a/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs +++ b/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs @@ -1,6 +1,6 @@ using Content.Shared.Gravity; using JetBrains.Annotations; -using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Gravity.UI { @@ -18,17 +18,8 @@ namespace Content.Client.Gravity.UI { base.Open(); - _window = new GravityGeneratorWindow(this); - - /* - _window.Switch.OnPressed += _ => - { - SendMessage(new SharedGravityGeneratorComponent.SwitchGeneratorMessage(!IsOn)); - }; - */ - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); + _window.SetEntity(Owner); } protected override void UpdateState(BoundUserInterfaceState state) @@ -39,14 +30,6 @@ namespace Content.Client.Gravity.UI _window?.UpdateState(castState); } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - - _window?.Dispose(); - } - public void SetPowerSwitch(bool on) { SendMessage(new SharedGravityGeneratorComponent.SwitchGeneratorMessage(on)); diff --git a/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs b/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs index 75f8eb479b..6f04133b59 100644 --- a/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs +++ b/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs @@ -12,22 +12,23 @@ namespace Content.Client.Gravity.UI { private readonly ButtonGroup _buttonGroup = new(); - private readonly GravityGeneratorBoundUserInterface _owner; + public event Action? OnPowerSwitch; - public GravityGeneratorWindow(GravityGeneratorBoundUserInterface owner) + public GravityGeneratorWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - _owner = owner; - OnButton.Group = _buttonGroup; OffButton.Group = _buttonGroup; - OnButton.OnPressed += _ => _owner.SetPowerSwitch(true); - OffButton.OnPressed += _ => _owner.SetPowerSwitch(false); + OnButton.OnPressed += _ => OnPowerSwitch?.Invoke(true); + OffButton.OnPressed += _ => OnPowerSwitch?.Invoke(false); + } - EntityView.SetEntity(owner.Owner); + public void SetEntity(EntityUid uid) + { + EntityView.SetEntity(uid); } public void UpdateState(SharedGravityGeneratorComponent.GeneratorState state) diff --git a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs index dc0a3e9fcc..38760f4aa3 100644 --- a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs +++ b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs @@ -1,6 +1,6 @@ using Content.Shared.MedicalScanner; using JetBrains.Annotations; -using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.HealthAnalyzer.UI { @@ -17,12 +17,9 @@ namespace Content.Client.HealthAnalyzer.UI protected override void Open() { base.Open(); - _window = new HealthAnalyzerWindow - { - Title = EntMan.GetComponent(Owner).EntityName, - }; - _window.OnClose += Close; - _window.OpenCentered(); + _window = this.CreateWindow(); + + _window.Title = EntMan.GetComponent(Owner).EntityName; } protected override void ReceiveMessage(BoundUserInterfaceMessage message) @@ -35,17 +32,5 @@ namespace Content.Client.HealthAnalyzer.UI _window.Populate(cast); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - if (_window != null) - _window.OnClose -= Close; - - _window?.Dispose(); - } } } diff --git a/Content.Client/Humanoid/HumanoidMarkingModifierBoundUserInterface.cs b/Content.Client/Humanoid/HumanoidMarkingModifierBoundUserInterface.cs index a8872604a4..53977eb636 100644 --- a/Content.Client/Humanoid/HumanoidMarkingModifierBoundUserInterface.cs +++ b/Content.Client/Humanoid/HumanoidMarkingModifierBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Humanoid; using Content.Shared.Humanoid.Markings; +using Robust.Client.UserInterface; namespace Content.Client.Humanoid; @@ -20,8 +21,7 @@ public sealed class HumanoidMarkingModifierBoundUserInterface : BoundUserInterfa { base.Open(); - _window = new(); - _window.OnClose += Close; + _window = this.CreateWindow(); _window.OnMarkingAdded += SendMarkingSet; _window.OnMarkingRemoved += SendMarkingSet; _window.OnMarkingColorChange += SendMarkingSetNoResend; diff --git a/Content.Client/Instruments/UI/BandMenu.xaml.cs b/Content.Client/Instruments/UI/BandMenu.xaml.cs index 5fb293a194..26cd1369e5 100644 --- a/Content.Client/Instruments/UI/BandMenu.xaml.cs +++ b/Content.Client/Instruments/UI/BandMenu.xaml.cs @@ -11,7 +11,9 @@ public sealed partial class BandMenu : DefaultWindow { private readonly InstrumentBoundUserInterface _owner; - public BandMenu(InstrumentBoundUserInterface owner) : base() + public EntityUid? Master; + + public BandMenu(InstrumentBoundUserInterface owner) { RobustXamlLoader.Load(this); @@ -40,7 +42,7 @@ public sealed partial class BandMenu : DefaultWindow { var uid = entManager.GetEntity(nent); var item = BandList.AddItem(name, null, true, uid); - item.Selected = _owner.Instrument?.Master == uid; + item.Selected = Master == uid; } } } diff --git a/Content.Client/Instruments/UI/ChannelsMenu.xaml.cs b/Content.Client/Instruments/UI/ChannelsMenu.xaml.cs index 2814d41536..c175e67842 100644 --- a/Content.Client/Instruments/UI/ChannelsMenu.xaml.cs +++ b/Content.Client/Instruments/UI/ChannelsMenu.xaml.cs @@ -51,7 +51,7 @@ public sealed partial class ChannelsMenu : DefaultWindow } } - public void Populate() + public void Populate(InstrumentComponent? instrument) { ChannelList.Clear(); @@ -60,7 +60,8 @@ public sealed partial class ChannelsMenu : DefaultWindow var item = ChannelList.AddItem(_owner.Loc.GetString("instrument-component-channel-name", ("number", i)), null, true, i); - item.Selected = !_owner.Instrument?.FilteredChannels[i] ?? false; + + item.Selected = !instrument?.FilteredChannels[i] ?? false; } } } diff --git a/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs b/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs index 0f5729f55b..4816ce8c36 100644 --- a/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs +++ b/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs @@ -24,8 +24,6 @@ namespace Content.Client.Instruments.UI [ViewVariables] private BandMenu? _bandMenu; [ViewVariables] private ChannelsMenu? _channelsMenu; - [ViewVariables] public InstrumentComponent? Instrument { get; private set; } - public InstrumentBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { IoCManager.InjectDependencies(this); @@ -43,14 +41,20 @@ namespace Content.Client.Instruments.UI protected override void Open() { - if (!EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument)) - return; + _instrumentMenu = this.CreateWindow(); + _instrumentMenu.Title = EntMan.GetComponent(Owner).EntityName; - Instrument = instrument; - _instrumentMenu = new InstrumentMenu(this); - _instrumentMenu.OnClose += Close; + _instrumentMenu.OnOpenBand += OpenBandMenu; + _instrumentMenu.OnOpenChannels += OpenChannelsMenu; + _instrumentMenu.OnCloseChannels += CloseChannelsMenu; + _instrumentMenu.OnCloseBands += CloseBandMenu; - _instrumentMenu.OpenCentered(); + _instrumentMenu.SetMIDI(MidiManager.IsAvailable); + + if (EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument)) + { + _instrumentMenu.SetInstrument((Owner, instrument)); + } } protected override void Dispose(bool disposing) @@ -58,7 +62,12 @@ namespace Content.Client.Instruments.UI base.Dispose(disposing); if (!disposing) return; - _instrumentMenu?.Dispose(); + + if (EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument)) + { + _instrumentMenu?.RemoveInstrument(instrument); + } + _bandMenu?.Dispose(); _channelsMenu?.Dispose(); } @@ -72,6 +81,11 @@ namespace Content.Client.Instruments.UI { _bandMenu ??= new BandMenu(this); + if (EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument)) + { + _bandMenu.Master = instrument.Master; + } + // Refresh cache... RefreshBands(); @@ -87,7 +101,9 @@ namespace Content.Client.Instruments.UI public void OpenChannelsMenu() { _channelsMenu ??= new ChannelsMenu(this); - _channelsMenu.Populate(); + EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument); + + _channelsMenu.Populate(instrument); _channelsMenu.OpenCenteredRight(); } diff --git a/Content.Client/Instruments/UI/InstrumentMenu.xaml.cs b/Content.Client/Instruments/UI/InstrumentMenu.xaml.cs index da443e3fb5..fc863648d7 100644 --- a/Content.Client/Instruments/UI/InstrumentMenu.xaml.cs +++ b/Content.Client/Instruments/UI/InstrumentMenu.xaml.cs @@ -1,7 +1,10 @@ using System.IO; using System.Numerics; using System.Threading.Tasks; +using Content.Client.Interactable; +using Content.Shared.ActionBlocker; using Robust.Client.AutoGenerated; +using Robust.Client.Player; using Robust.Client.UserInterface; using Robust.Client.UserInterface.CustomControls; using Robust.Client.UserInterface.XAML; @@ -16,33 +19,23 @@ namespace Content.Client.Instruments.UI [GenerateTypedNameReferences] public sealed partial class InstrumentMenu : DefaultWindow { - private readonly InstrumentBoundUserInterface _owner; + [Dependency] private readonly IEntityManager _entManager = default!; + [Dependency] private readonly IFileDialogManager _dialogs = default!; + [Dependency] private readonly IPlayerManager _player = default!; private bool _isMidiFileDialogueWindowOpen; - public InstrumentMenu(InstrumentBoundUserInterface owner) + public event Action? OnOpenBand; + public event Action? OnOpenChannels; + public event Action? OnCloseBands; + public event Action? OnCloseChannels; + + public EntityUid Entity; + + public InstrumentMenu() { RobustXamlLoader.Load(this); - - _owner = owner; - - if (_owner.Instrument != null) - { - _owner.Instrument.OnMidiPlaybackEnded += InstrumentOnMidiPlaybackEnded; - Title = _owner.Entities.GetComponent(_owner.Owner).EntityName; - LoopButton.Disabled = !_owner.Instrument.IsMidiOpen; - LoopButton.Pressed = _owner.Instrument.LoopMidi; - ChannelsButton.Disabled = !_owner.Instrument.IsRendererAlive; - StopButton.Disabled = !_owner.Instrument.IsMidiOpen; - PlaybackSlider.MouseFilter = _owner.Instrument.IsMidiOpen ? MouseFilterMode.Pass : MouseFilterMode.Ignore; - } - - if (!_owner.MidiManager.IsAvailable) - { - UnavailableOverlay.Visible = true; - // We return early as to not give the buttons behavior. - return; - } + IoCManager.InjectDependencies(this); InputButton.OnToggled += MidiInputButtonOnOnToggled; BandButton.OnPressed += BandButtonOnPressed; @@ -57,12 +50,34 @@ namespace Content.Client.Instruments.UI MinSize = SetSize = new Vector2(400, 150); } + public void SetInstrument(Entity entity) + { + Entity = entity; + var component = entity.Comp; + component.OnMidiPlaybackEnded += InstrumentOnMidiPlaybackEnded; + LoopButton.Disabled = !component.IsMidiOpen; + LoopButton.Pressed = component.LoopMidi; + ChannelsButton.Disabled = !component.IsRendererAlive; + StopButton.Disabled = !component.IsMidiOpen; + PlaybackSlider.MouseFilter = component.IsMidiOpen ? MouseFilterMode.Pass : MouseFilterMode.Ignore; + } + + public void RemoveInstrument(InstrumentComponent component) + { + component.OnMidiPlaybackEnded -= InstrumentOnMidiPlaybackEnded; + } + + public void SetMIDI(bool available) + { + UnavailableOverlay.Visible = !available; + } + private void BandButtonOnPressed(ButtonEventArgs obj) { if (!PlayCheck()) return; - _owner.OpenBandMenu(); + OnOpenBand?.Invoke(); } private void BandButtonOnToggled(ButtonToggledEventArgs obj) @@ -70,12 +85,15 @@ namespace Content.Client.Instruments.UI if (obj.Pressed) return; - _owner.Instruments.SetMaster(_owner.Owner, null); + if (_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument)) + { + _entManager.System().SetMaster(Entity, instrument.Master); + } } private void ChannelsButtonOnPressed(ButtonEventArgs obj) { - _owner.OpenChannelsMenu(); + OnOpenChannels?.Invoke(); } private void InstrumentOnMidiPlaybackEnded() @@ -85,8 +103,10 @@ namespace Content.Client.Instruments.UI public void MidiPlaybackSetButtonsDisabled(bool disabled) { - if(disabled) - _owner.CloseChannelsMenu(); + if (disabled) + { + OnCloseChannels?.Invoke(); + } LoopButton.Disabled = disabled; StopButton.Disabled = disabled; @@ -100,7 +120,7 @@ namespace Content.Client.Instruments.UI if (_isMidiFileDialogueWindowOpen) return; - _owner.CloseBandMenu(); + OnCloseBands?.Invoke(); var filters = new FileDialogFilters(new FileDialogFilters.Group("mid", "midi")); @@ -108,7 +128,7 @@ namespace Content.Client.Instruments.UI // or focus the previously-opened window. _isMidiFileDialogueWindowOpen = true; - await using var file = await _owner.FileDialogManager.OpenFile(filters); + await using var file = await _dialogs.OpenFile(filters); _isMidiFileDialogueWindowOpen = false; @@ -129,9 +149,18 @@ namespace Content.Client.Instruments.UI await file.CopyToAsync(memStream); - if (_owner.Instrument is not {} instrument - || !_owner.Instruments.OpenMidi(_owner.Owner, memStream.GetBuffer().AsSpan(0, (int) memStream.Length), instrument)) + if (!_entManager.TryGetComponent(Entity, out var instrument)) + { return; + } + + if (!_entManager.System() + .OpenMidi(Entity, + memStream.GetBuffer().AsSpan(0, (int) memStream.Length), + instrument)) + { + return; + } MidiPlaybackSetButtonsDisabled(false); if (InputButton.Pressed) @@ -140,7 +169,7 @@ namespace Content.Client.Instruments.UI private void MidiInputButtonOnOnToggled(ButtonToggledEventArgs obj) { - _owner.CloseBandMenu(); + OnCloseBands?.Invoke(); if (obj.Pressed) { @@ -148,109 +177,99 @@ namespace Content.Client.Instruments.UI return; MidiStopButtonOnPressed(null); - if(_owner.Instrument is {} instrument) - _owner.Instruments.OpenInput(_owner.Owner, instrument); + + if (_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument)) + _entManager.System().OpenInput(Entity, instrument); } - else if (_owner.Instrument is { } instrument) + else { - _owner.Instruments.CloseInput(_owner.Owner, false, instrument); - _owner.CloseChannelsMenu(); + _entManager.System().CloseInput(Entity, false); + OnCloseChannels?.Invoke(); } } private bool PlayCheck() { // TODO all of these checks should also be done server-side. - - var instrumentEnt = _owner.Owner; - var instrument = _owner.Instrument; - - if (instrument == null) + if (!_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument)) return false; - var localEntity = _owner.PlayerManager.LocalEntity; + var localEntity = _player.LocalEntity; // If we don't have a player or controlled entity, we return. if (localEntity == null) return false; // By default, allow an instrument to play itself and skip all other checks - if (localEntity == instrumentEnt) + if (localEntity == Entity) return true; - var container = _owner.Entities.System(); + var container = _entManager.System(); // If we're a handheld instrument, we might be in a container. Get it just in case. - container.TryGetContainingContainer(instrumentEnt, out var conMan); + container.TryGetContainingContainer(Entity, out var conMan); // If the instrument is handheld and we're not holding it, we return. - if ((instrument.Handheld && (conMan == null || conMan.Owner != localEntity))) + if (instrument.Handheld && (conMan == null || conMan.Owner != localEntity)) return false; - if (!_owner.ActionBlocker.CanInteract(localEntity.Value, instrumentEnt)) + if (!_entManager.System().CanInteract(localEntity.Value, Entity)) return false; // We check that we're in range unobstructed just in case. - return _owner.Interactions.InRangeUnobstructed(localEntity.Value, instrumentEnt); + return _entManager.System().InRangeUnobstructed(localEntity.Value, Entity); } private void MidiStopButtonOnPressed(ButtonEventArgs? obj) { MidiPlaybackSetButtonsDisabled(true); - if (_owner.Instrument is not {} instrument) - return; - - _owner.Instruments.CloseMidi(_owner.Owner, false, instrument); - _owner.CloseChannelsMenu(); + _entManager.System().CloseMidi(Entity, false); + OnCloseChannels?.Invoke(); } private void MidiLoopButtonOnOnToggled(ButtonToggledEventArgs obj) { - if (_owner.Instrument == null) - return; + var instrument = _entManager.System(); - _owner.Instrument.LoopMidi = obj.Pressed; - _owner.Instruments.UpdateRenderer(_owner.Owner, _owner.Instrument); + if (_entManager.TryGetComponent(Entity, out InstrumentComponent? instrumentComp)) + { + instrumentComp.LoopMidi = obj.Pressed; + } + + instrument.UpdateRenderer(Entity); } private void PlaybackSliderSeek(Range _) { // Do not seek while still grabbing. - if (PlaybackSlider.Grabbed || _owner.Instrument is not {} instrument) + if (PlaybackSlider.Grabbed) return; - _owner.Instruments.SetPlayerTick(_owner.Owner, (int)Math.Ceiling(PlaybackSlider.Value), instrument); + _entManager.System().SetPlayerTick(Entity, (int)Math.Ceiling(PlaybackSlider.Value)); } private void PlaybackSliderKeyUp(GUIBoundKeyEventArgs args) { - if (args.Function != EngineKeyFunctions.UIClick || _owner.Instrument is not {} instrument) + if (args.Function != EngineKeyFunctions.UIClick) return; - _owner.Instruments.SetPlayerTick(_owner.Owner, (int)Math.Ceiling(PlaybackSlider.Value), instrument); - } - - public override void Close() - { - base.Close(); - _owner.CloseBandMenu(); - _owner.CloseChannelsMenu(); + _entManager.System().SetPlayerTick(Entity, (int)Math.Ceiling(PlaybackSlider.Value)); } protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); - if (_owner.Instrument == null) + if (!_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument)) return; - var hasMaster = _owner.Instrument.Master != null; + var hasMaster = instrument.Master != null; BandButton.ToggleMode = hasMaster; BandButton.Pressed = hasMaster; - BandButton.Disabled = _owner.Instrument.IsMidiOpen || _owner.Instrument.IsInputOpen; - ChannelsButton.Disabled = !_owner.Instrument.IsRendererAlive; + BandButton.Disabled = instrument.IsMidiOpen || instrument.IsInputOpen; + ChannelsButton.Disabled = !instrument.IsRendererAlive; - if (!_owner.Instrument.IsMidiOpen) + if (!instrument.IsMidiOpen) { PlaybackSlider.MaxValue = 1; PlaybackSlider.SetValueWithoutEvent(0); @@ -260,8 +279,8 @@ namespace Content.Client.Instruments.UI if (PlaybackSlider.Grabbed) return; - PlaybackSlider.MaxValue = _owner.Instrument.PlayerTotalTick; - PlaybackSlider.SetValueWithoutEvent(_owner.Instrument.PlayerTick); + PlaybackSlider.MaxValue = instrument.PlayerTotalTick; + PlaybackSlider.SetValueWithoutEvent(instrument.PlayerTick); } } } diff --git a/Content.Client/Inventory/StrippableBoundUserInterface.cs b/Content.Client/Inventory/StrippableBoundUserInterface.cs index 7e50eb1c68..132c5ed654 100644 --- a/Content.Client/Inventory/StrippableBoundUserInterface.cs +++ b/Content.Client/Inventory/StrippableBoundUserInterface.cs @@ -41,7 +41,7 @@ namespace Content.Client.Inventory public const string HiddenPocketEntityId = "StrippingHiddenEntity"; [ViewVariables] - private readonly StrippingMenu? _strippingMenu; + private StrippingMenu? _strippingMenu; [ViewVariables] private readonly EntityUid _virtualHiddenEntity; @@ -51,33 +51,30 @@ namespace Content.Client.Inventory _examine = EntMan.System(); _inv = EntMan.System(); _cuffable = EntMan.System(); - - // TODO update name when identity changes - var title = Loc.GetString("strippable-bound-user-interface-stripping-menu-title", ("ownerName", Identity.Name(Owner, EntMan))); - _strippingMenu = new StrippingMenu(title, this); - _strippingMenu.OnClose += Close; - - // TODO use global entity - // BUIs are opened and closed while applying comp sates, so spawning entities here is probably not the best idea. _virtualHiddenEntity = EntMan.SpawnEntity(HiddenPocketEntityId, MapCoordinates.Nullspace); } protected override void Open() { base.Open(); + + _strippingMenu = this.CreateWindow(); + _strippingMenu.OnDirty += UpdateMenu; + _strippingMenu.Title = Loc.GetString("strippable-bound-user-interface-stripping-menu-title", ("ownerName", Identity.Name(Owner, EntMan))); + _strippingMenu?.OpenCenteredLeft(); } protected override void Dispose(bool disposing) { - base.Dispose(disposing); - - EntMan.DeleteEntity(_virtualHiddenEntity); - if (!disposing) return; - _strippingMenu?.Dispose(); + if (_strippingMenu != null) + _strippingMenu.OnDirty -= UpdateMenu; + + EntMan.DeleteEntity(_virtualHiddenEntity); + base.Dispose(disposing); } public void DirtyMenu() diff --git a/Content.Client/Kitchen/UI/GrinderMenu.xaml.cs b/Content.Client/Kitchen/UI/GrinderMenu.xaml.cs index f97d8a7330..7884268c42 100644 --- a/Content.Client/Kitchen/UI/GrinderMenu.xaml.cs +++ b/Content.Client/Kitchen/UI/GrinderMenu.xaml.cs @@ -12,42 +12,34 @@ namespace Content.Client.Kitchen.UI [GenerateTypedNameReferences] public sealed partial class GrinderMenu : FancyWindow { - private readonly IEntityManager _entityManager; - private readonly IPrototypeManager _prototypeManager; - private readonly ReagentGrinderBoundUserInterface _owner; + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; private readonly Dictionary _chamberVisualContents = new(); - public GrinderMenu(ReagentGrinderBoundUserInterface owner, IEntityManager entityManager, IPrototypeManager prototypeManager) + public event Action? OnToggleAuto; + public event Action? OnGrind; + public event Action? OnJuice; + public event Action? OnEjectAll; + public event Action? OnEjectBeaker; + public event Action? OnEjectChamber; + + public GrinderMenu() { RobustXamlLoader.Load(this); - _entityManager = entityManager; - _prototypeManager = prototypeManager; - _owner = owner; - AutoModeButton.OnPressed += owner.ToggleAutoMode; - GrindButton.OnPressed += owner.StartGrinding; - JuiceButton.OnPressed += owner.StartJuicing; - ChamberContentBox.EjectButton.OnPressed += owner.EjectAll; - BeakerContentBox.EjectButton.OnPressed += owner.EjectBeaker; + IoCManager.InjectDependencies(this); + AutoModeButton.OnPressed += _ => OnToggleAuto?.Invoke(); + GrindButton.OnPressed += _ => OnGrind?.Invoke(); + JuiceButton.OnPressed += _ => OnJuice?.Invoke(); + ChamberContentBox.EjectButton.OnPressed += _ => OnEjectAll?.Invoke(); + BeakerContentBox.EjectButton.OnPressed += _ => OnEjectBeaker?.Invoke(); ChamberContentBox.BoxContents.OnItemSelected += OnChamberBoxContentsItemSelected; BeakerContentBox.BoxContents.SelectMode = ItemList.ItemListSelectMode.None; } private void OnChamberBoxContentsItemSelected(ItemList.ItemListSelectedEventArgs args) { - _owner.EjectChamberContent(_chamberVisualContents[args.ItemIndex]); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - _chamberVisualContents.Clear(); - GrindButton.OnPressed -= _owner.StartGrinding; - JuiceButton.OnPressed -= _owner.StartJuicing; - ChamberContentBox.EjectButton.OnPressed -= _owner.EjectAll; - BeakerContentBox.EjectButton.OnPressed -= _owner.EjectBeaker; - ChamberContentBox.BoxContents.OnItemSelected -= OnChamberBoxContentsItemSelected; + OnEjectChamber?.Invoke(_chamberVisualContents[args.ItemIndex]); } public void UpdateState(ReagentGrinderInterfaceState state) diff --git a/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs b/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs index 7e7dd2d693..643ac47054 100644 --- a/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs +++ b/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Kitchen.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; using Robust.Client.Graphics; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Timing; @@ -19,28 +20,15 @@ namespace Content.Client.Kitchen.UI [ViewVariables] private readonly Dictionary _reagents = new(); - [Dependency] private readonly IGameTiming _gameTiming = default!; - - public MicrowaveUpdateUserInterfaceState currentState = default!; - - private IEntityManager _entManager; public MicrowaveBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { - _entManager = IoCManager.Resolve(); - } - - public TimeSpan GetCurrentTime() - { - return _gameTiming.CurTime; } protected override void Open() { base.Open(); - _menu = new MicrowaveMenu(this); - _menu.OpenCentered(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); _menu.StartButton.OnPressed += _ => SendPredictedMessage(new MicrowaveStartCookMessage()); _menu.EjectButton.OnPressed += _ => SendPredictedMessage(new MicrowaveEjectMessage()); _menu.IngredientsList.OnItemSelected += args => @@ -74,38 +62,23 @@ namespace Content.Client.Kitchen.UI }; } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (!disposing) - { - return; - } - - _solids.Clear(); - _menu?.Dispose(); - } - protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); - if (state is not MicrowaveUpdateUserInterfaceState cState) + if (state is not MicrowaveUpdateUserInterfaceState cState || _menu == null) { return; } + _menu.IsBusy = cState.IsMicrowaveBusy; + _menu.CurrentCooktimeEnd = cState.CurrentCookTimeEnd; - _menu?.ToggleBusyDisableOverlayPanel(cState.IsMicrowaveBusy || cState.ContainedSolids.Length == 0); - currentState = cState; - + _menu.ToggleBusyDisableOverlayPanel(cState.IsMicrowaveBusy || cState.ContainedSolids.Length == 0); // TODO move this to a component state and ensure the net ids. - RefreshContentsDisplay(_entManager.GetEntityArray(cState.ContainedSolids)); - - if (_menu == null) return; + RefreshContentsDisplay(EntMan.GetEntityArray(cState.ContainedSolids)); //Set the cook time info label - var cookTime = cState.ActiveButtonIndex == 0 + var cookTime = cState.ActiveButtonIndex == 0 ? Loc.GetString("microwave-menu-instant-button") : cState.CurrentCookTime.ToString(); diff --git a/Content.Client/Kitchen/UI/MicrowaveMenu.xaml.cs b/Content.Client/Kitchen/UI/MicrowaveMenu.xaml.cs index b292e9f146..13029e3846 100644 --- a/Content.Client/Kitchen/UI/MicrowaveMenu.xaml.cs +++ b/Content.Client/Kitchen/UI/MicrowaveMenu.xaml.cs @@ -9,22 +9,21 @@ namespace Content.Client.Kitchen.UI [GenerateTypedNameReferences] public sealed partial class MicrowaveMenu : FancyWindow { - public sealed class MicrowaveCookTimeButton : Button - { - public uint CookTime; - } + [Dependency] private readonly IGameTiming _timing = default!; public event Action? OnCookTimeSelected; public ButtonGroup CookTimeButtonGroup { get; } - private readonly MicrowaveBoundUserInterface _owner; - public MicrowaveMenu(MicrowaveBoundUserInterface owner) + public bool IsBusy; + public TimeSpan CurrentCooktimeEnd; + + public MicrowaveMenu() { RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); CookTimeButtonGroup = new ButtonGroup(); InstantCookButton.Group = CookTimeButtonGroup; - _owner = owner; InstantCookButton.OnPressed += args => { OnCookTimeSelected?.Invoke(args, 0); @@ -65,14 +64,20 @@ namespace Content.Client.Kitchen.UI protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); - if(!_owner.currentState.IsMicrowaveBusy) + + if (!IsBusy) return; - if(_owner.currentState.CurrentCookTimeEnd > _owner.GetCurrentTime()) + if (CurrentCooktimeEnd > _timing.CurTime) { CookTimeInfoLabel.Text = Loc.GetString("microwave-bound-user-interface-cook-time-label", - ("time",_owner.currentState.CurrentCookTimeEnd.Subtract(_owner.GetCurrentTime()).Seconds)); + ("time", CurrentCooktimeEnd.Subtract(_timing.CurTime).Seconds)); } } + + public sealed class MicrowaveCookTimeButton : Button + { + public uint CookTime; + } } } diff --git a/Content.Client/Kitchen/UI/ReagentGrinderBoundUserInterface.cs b/Content.Client/Kitchen/UI/ReagentGrinderBoundUserInterface.cs index e6f108b305..bc4cc75b4d 100644 --- a/Content.Client/Kitchen/UI/ReagentGrinderBoundUserInterface.cs +++ b/Content.Client/Kitchen/UI/ReagentGrinderBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Containers.ItemSlots; using Content.Shared.Kitchen; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Prototypes; @@ -8,8 +9,6 @@ namespace Content.Client.Kitchen.UI { public sealed class ReagentGrinderBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [ViewVariables] private GrinderMenu? _menu; @@ -21,20 +20,13 @@ namespace Content.Client.Kitchen.UI { base.Open(); - _menu = new GrinderMenu(this, EntMan, _prototypeManager); - _menu.OpenCentered(); - _menu.OnClose += Close; - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - { - return; - } - - _menu?.Dispose(); + _menu = this.CreateWindow(); + _menu.OnToggleAuto += ToggleAutoMode; + _menu.OnGrind += StartGrinding; + _menu.OnJuice += StartJuicing; + _menu.OnEjectAll += EjectAll; + _menu.OnEjectBeaker += EjectBeaker; + _menu.OnEjectChamber += EjectChamberContent; } protected override void UpdateState(BoundUserInterfaceState state) @@ -52,27 +44,27 @@ namespace Content.Client.Kitchen.UI _menu?.HandleMessage(message); } - public void ToggleAutoMode(BaseButton.ButtonEventArgs args) + public void ToggleAutoMode() { SendMessage(new ReagentGrinderToggleAutoModeMessage()); } - public void StartGrinding(BaseButton.ButtonEventArgs? _ = null) + public void StartGrinding() { SendMessage(new ReagentGrinderStartMessage(GrinderProgram.Grind)); } - public void StartJuicing(BaseButton.ButtonEventArgs? _ = null) + public void StartJuicing() { SendMessage(new ReagentGrinderStartMessage(GrinderProgram.Juice)); } - public void EjectAll(BaseButton.ButtonEventArgs? _ = null) + public void EjectAll() { SendMessage(new ReagentGrinderEjectChamberAllMessage()); } - public void EjectBeaker(BaseButton.ButtonEventArgs? _ = null) + public void EjectBeaker() { SendMessage(new ItemSlotButtonPressedEvent(SharedReagentGrinder.BeakerSlotId)); } diff --git a/Content.Client/Labels/UI/HandLabelerBoundUserInterface.cs b/Content.Client/Labels/UI/HandLabelerBoundUserInterface.cs index 555f1ff09e..6b65612341 100644 --- a/Content.Client/Labels/UI/HandLabelerBoundUserInterface.cs +++ b/Content.Client/Labels/UI/HandLabelerBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Labels; using Content.Shared.Labels.Components; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Labels.UI { @@ -23,13 +24,8 @@ namespace Content.Client.Labels.UI { base.Open(); - _window = new HandLabelerWindow(); - if (State != null) - UpdateState(State); + _window = this.CreateWindow(); - _window.OpenCentered(); - - _window.OnClose += Close; _window.OnLabelChanged += OnLabelChanged; Reload(); } @@ -51,13 +47,5 @@ namespace Content.Client.Labels.UI _window.SetCurrentLabel(component.AssignedLabel); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } - } diff --git a/Content.Client/Lathe/UI/LatheBoundUserInterface.cs b/Content.Client/Lathe/UI/LatheBoundUserInterface.cs index 6e6d1b9176..a599f79152 100644 --- a/Content.Client/Lathe/UI/LatheBoundUserInterface.cs +++ b/Content.Client/Lathe/UI/LatheBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Lathe; using Content.Shared.Research.Components; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Lathe.UI { @@ -17,9 +18,9 @@ namespace Content.Client.Lathe.UI { base.Open(); - _menu = new LatheMenu(this); - _menu.OnClose += Close; - + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); + _menu.OpenCenteredRight(); _menu.OnServerListButtonPressed += _ => { @@ -30,8 +31,6 @@ namespace Content.Client.Lathe.UI { SendMessage(new LatheQueueRecipeMessage(recipe, amount)); }; - - _menu.OpenCenteredRight(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -50,13 +49,5 @@ namespace Content.Client.Lathe.UI break; } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Dispose(); - } } } diff --git a/Content.Client/Lathe/UI/LatheMenu.xaml.cs b/Content.Client/Lathe/UI/LatheMenu.xaml.cs index f2f52b67b5..6f530b76c7 100644 --- a/Content.Client/Lathe/UI/LatheMenu.xaml.cs +++ b/Content.Client/Lathe/UI/LatheMenu.xaml.cs @@ -1,3 +1,4 @@ +using System.Buffers; using System.Linq; using System.Text; using Content.Client.Materials; @@ -22,7 +23,6 @@ public sealed partial class LatheMenu : DefaultWindow [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - private EntityUid _owner; private readonly SpriteSystem _spriteSystem; private readonly LatheSystem _lathe; private readonly MaterialStorageSystem _materialStorage; @@ -36,9 +36,10 @@ public sealed partial class LatheMenu : DefaultWindow public ProtoId? CurrentCategory; - public LatheMenu(LatheBoundUserInterface owner) + public EntityUid Entity; + + public LatheMenu() { - _owner = owner.Owner; RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); @@ -46,8 +47,6 @@ public sealed partial class LatheMenu : DefaultWindow _lathe = _entityManager.System(); _materialStorage = _entityManager.System(); - Title = _entityManager.GetComponent(owner.Owner).EntityName; - SearchBar.OnTextChanged += _ => { PopulateRecipes(); @@ -60,8 +59,13 @@ public sealed partial class LatheMenu : DefaultWindow FilterOption.OnItemSelected += OnItemSelected; ServerListButton.OnPressed += a => OnServerListButtonPressed?.Invoke(a); + } - if (_entityManager.TryGetComponent(owner.Owner, out var latheComponent)) + public void SetEntity(EntityUid uid) + { + Entity = uid; + + if (_entityManager.TryGetComponent(Entity, out var latheComponent)) { if (!latheComponent.DynamicRecipes.Any()) { @@ -69,7 +73,7 @@ public sealed partial class LatheMenu : DefaultWindow } } - MaterialsList.SetOwner(owner.Owner); + MaterialsList.SetOwner(Entity); } /// @@ -102,13 +106,15 @@ public sealed partial class LatheMenu : DefaultWindow var sortedRecipesToShow = recipesToShow.OrderBy(p => p.Name); RecipeList.Children.Clear(); + _entityManager.TryGetComponent(Entity, out LatheComponent? lathe); + foreach (var prototype in sortedRecipesToShow) { EntityPrototype? recipeProto = null; - if (_prototypeManager.TryIndex(prototype.Result, out EntityPrototype? entityProto) && entityProto != null) + if (_prototypeManager.TryIndex(prototype.Result, out EntityPrototype? entityProto)) recipeProto = entityProto; - var canProduce = _lathe.CanProduce(_owner, prototype, quantity); + var canProduce = _lathe.CanProduce(Entity, prototype, quantity, component: lathe); var control = new RecipeControl(prototype, () => GenerateTooltipText(prototype), canProduce, recipeProto); control.OnButtonPressed += s => @@ -124,19 +130,20 @@ public sealed partial class LatheMenu : DefaultWindow private string GenerateTooltipText(LatheRecipePrototype prototype) { StringBuilder sb = new(); + var multiplier = _entityManager.GetComponent(Entity).MaterialUseMultiplier; foreach (var (id, amount) in prototype.RequiredMaterials) { if (!_prototypeManager.TryIndex(id, out var proto)) continue; - var adjustedAmount = SharedLatheSystem.AdjustMaterial(amount, prototype.ApplyMaterialDiscount, _entityManager.GetComponent(_owner).MaterialUseMultiplier); + var adjustedAmount = SharedLatheSystem.AdjustMaterial(amount, prototype.ApplyMaterialDiscount, multiplier); var sheetVolume = _materialStorage.GetSheetVolume(proto); var unit = Loc.GetString(proto.Unit); var sheets = adjustedAmount / (float) sheetVolume; - var availableAmount = _materialStorage.GetMaterialAmount(_owner, id); + var availableAmount = _materialStorage.GetMaterialAmount(Entity, id); var missingAmount = Math.Max(0, adjustedAmount - availableAmount); var missingSheets = missingAmount / (float) sheetVolume; diff --git a/Content.Client/MachineLinking/UI/SignalTimerBoundUserInterface.cs b/Content.Client/MachineLinking/UI/SignalTimerBoundUserInterface.cs index 09bdedfd94..11abe8c245 100644 --- a/Content.Client/MachineLinking/UI/SignalTimerBoundUserInterface.cs +++ b/Content.Client/MachineLinking/UI/SignalTimerBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.MachineLinking; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Timing; namespace Content.Client.MachineLinking.UI; @@ -19,19 +20,14 @@ public sealed class SignalTimerBoundUserInterface : BoundUserInterface { base.Open(); - _window = new SignalTimerWindow(this); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); + _window.OnStartTimer += StartTimer; _window.OnCurrentTextChanged += OnTextChanged; _window.OnCurrentDelayMinutesChanged += OnDelayChanged; _window.OnCurrentDelaySecondsChanged += OnDelayChanged; } - public void OnStartTimer() + public void StartTimer() { SendMessage(new SignalTimerStartMessage()); } @@ -48,11 +44,6 @@ public sealed class SignalTimerBoundUserInterface : BoundUserInterface SendMessage(new SignalTimerDelayChangedMessage(_window.GetDelay())); } - public TimeSpan GetCurrentTime() - { - return _gameTiming.CurTime; - } - /// /// Update the UI state based on server-sent info /// @@ -72,11 +63,4 @@ public sealed class SignalTimerBoundUserInterface : BoundUserInterface _window.SetTimerStarted(cast.TimerStarted); _window.SetHasAccess(cast.HasAccess); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } diff --git a/Content.Client/MachineLinking/UI/SignalTimerWindow.xaml.cs b/Content.Client/MachineLinking/UI/SignalTimerWindow.xaml.cs index b62595595e..6133abfcb7 100644 --- a/Content.Client/MachineLinking/UI/SignalTimerWindow.xaml.cs +++ b/Content.Client/MachineLinking/UI/SignalTimerWindow.xaml.cs @@ -9,42 +9,44 @@ namespace Content.Client.MachineLinking.UI; [GenerateTypedNameReferences] public sealed partial class SignalTimerWindow : DefaultWindow { + [Dependency] private readonly IGameTiming _timing = default!; + private const int MaxTextLength = 5; public event Action? OnCurrentTextChanged; public event Action? OnCurrentDelayMinutesChanged; public event Action? OnCurrentDelaySecondsChanged; - private readonly SignalTimerBoundUserInterface _owner; - private TimeSpan? _triggerTime; private bool _timerStarted; - public SignalTimerWindow(SignalTimerBoundUserInterface owner) + public event Action? OnStartTimer; + + public SignalTimerWindow() { RobustXamlLoader.Load(this); - - _owner = owner; + IoCManager.InjectDependencies(this); CurrentTextEdit.OnTextChanged += e => OnCurrentTextChange(e.Text); CurrentDelayEditMinutes.OnTextChanged += e => OnCurrentDelayMinutesChange(e.Text); CurrentDelayEditSeconds.OnTextChanged += e => OnCurrentDelaySecondsChange(e.Text); - StartTimer.OnPressed += _ => OnStartTimer(); + StartTimer.OnPressed += _ => StartTimerWeh(); } - public void OnStartTimer() + private void StartTimerWeh() { if (!_timerStarted) { _timerStarted = true; - _triggerTime = _owner.GetCurrentTime() + GetDelay(); + _triggerTime = _timing.CurTime + GetDelay(); } else { SetTimerStarted(false); } - _owner.OnStartTimer(); + + OnStartTimer?.Invoke(); } protected override void FrameUpdate(FrameEventArgs args) @@ -54,9 +56,9 @@ public sealed partial class SignalTimerWindow : DefaultWindow if (!_timerStarted || _triggerTime == null) return; - if (_owner.GetCurrentTime() < _triggerTime.Value) + if (_timing.CurTime < _triggerTime.Value) { - StartTimer.Text = TextScreenSystem.TimeToString(_triggerTime.Value - _owner.GetCurrentTime()); + StartTimer.Text = TextScreenSystem.TimeToString(_triggerTime.Value - _timing.CurTime); } else { diff --git a/Content.Client/MagicMirror/MagicMirrorBoundUserInterface.cs b/Content.Client/MagicMirror/MagicMirrorBoundUserInterface.cs index f6979bf8d7..0a87948ff6 100644 --- a/Content.Client/MagicMirror/MagicMirrorBoundUserInterface.cs +++ b/Content.Client/MagicMirror/MagicMirrorBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Humanoid.Markings; using Content.Shared.MagicMirror; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.MagicMirror; @@ -17,7 +18,7 @@ public sealed class MagicMirrorBoundUserInterface : BoundUserInterface { base.Open(); - _window = new(); + _window = this.CreateWindow(); _window.OnHairSelected += tuple => SelectHair(MagicMirrorCategory.Hair, tuple.id, tuple.slot); _window.OnHairColorChanged += args => ChangeColor(MagicMirrorCategory.Hair, args.marking, args.slot); @@ -29,9 +30,6 @@ public sealed class MagicMirrorBoundUserInterface : BoundUserInterface args => ChangeColor(MagicMirrorCategory.FacialHair, args.marking, args.slot); _window.OnFacialHairSlotAdded += delegate () { AddSlot(MagicMirrorCategory.FacialHair); }; _window.OnFacialHairSlotRemoved += args => RemoveSlot(MagicMirrorCategory.FacialHair, args); - - _window.OnClose += Close; - _window.OpenCentered(); } private void SelectHair(MagicMirrorCategory category, string marking, int slot) @@ -65,14 +63,5 @@ public sealed class MagicMirrorBoundUserInterface : BoundUserInterface _window.UpdateState(data); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _window?.Dispose(); - } } diff --git a/Content.Client/MassMedia/Ui/NewsWriterBoundUserInterface.cs b/Content.Client/MassMedia/Ui/NewsWriterBoundUserInterface.cs index 80eca82e32..22e5bc452a 100644 --- a/Content.Client/MassMedia/Ui/NewsWriterBoundUserInterface.cs +++ b/Content.Client/MassMedia/Ui/NewsWriterBoundUserInterface.cs @@ -1,6 +1,7 @@ using JetBrains.Annotations; using Content.Shared.MassMedia.Systems; using Content.Shared.MassMedia.Components; +using Robust.Client.UserInterface; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -9,8 +10,6 @@ namespace Content.Client.MassMedia.Ui; [UsedImplicitly] public sealed class NewsWriterBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IGameTiming _gameTiming = default!; - [ViewVariables] private NewsWriterMenu? _menu; @@ -21,10 +20,7 @@ public sealed class NewsWriterBoundUserInterface : BoundUserInterface protected override void Open() { - _menu = new NewsWriterMenu(_gameTiming); - - _menu.OpenCentered(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); _menu.ArticleEditorPanel.PublishButtonPressed += OnPublishButtonPressed; _menu.DeleteButtonPressed += OnDeleteButtonPressed; @@ -32,16 +28,6 @@ public sealed class NewsWriterBoundUserInterface : BoundUserInterface SendMessage(new NewsWriterArticlesRequestMessage()); } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _menu?.Close(); - _menu?.Dispose(); - } - protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); diff --git a/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs b/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs index e2d57935e3..c059ce785a 100644 --- a/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs +++ b/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs @@ -10,17 +10,17 @@ namespace Content.Client.MassMedia.Ui; [GenerateTypedNameReferences] public sealed partial class NewsWriterMenu : FancyWindow { - private readonly IGameTiming _gameTiming; + [Dependency] private readonly IGameTiming _gameTiming = default!; private TimeSpan? _nextPublish; public event Action? DeleteButtonPressed; - public NewsWriterMenu(IGameTiming gameTiming) + public NewsWriterMenu() { RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); - _gameTiming = gameTiming; ContentsContainer.RectClipContent = false; // Customize scrollbar width and margin. This is not possible in xaml diff --git a/Content.Client/Mech/Ui/MechBoundUserInterface.cs b/Content.Client/Mech/Ui/MechBoundUserInterface.cs index 4172bdc90f..2130a8c609 100644 --- a/Content.Client/Mech/Ui/MechBoundUserInterface.cs +++ b/Content.Client/Mech/Ui/MechBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Mech; using Content.Shared.Mech.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Mech.Ui; @@ -20,9 +21,8 @@ public sealed class MechBoundUserInterface : BoundUserInterface { base.Open(); - _menu = new(Owner); - - _menu.OnClose += Close; + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); _menu.OpenCenteredLeft(); _menu.OnRemoveButtonPressed += uid => @@ -60,16 +60,6 @@ public sealed class MechBoundUserInterface : BoundUserInterface } } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (!disposing) - return; - - _menu?.Close(); - } - public UIFragment? GetEquipmentUi(EntityUid? uid) { var component = EntMan.GetComponentOrNull(uid); diff --git a/Content.Client/Mech/Ui/MechMenu.xaml.cs b/Content.Client/Mech/Ui/MechMenu.xaml.cs index fad7648808..6f39bc386e 100644 --- a/Content.Client/Mech/Ui/MechMenu.xaml.cs +++ b/Content.Client/Mech/Ui/MechMenu.xaml.cs @@ -16,14 +16,15 @@ public sealed partial class MechMenu : FancyWindow public event Action? OnRemoveButtonPressed; - public MechMenu(EntityUid mech) + public MechMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); + } - _mech = mech; - - MechView.SetEntity(mech); + public void SetEntity(EntityUid uid) + { + MechView.SetEntity(uid); } public void UpdateMechStats() diff --git a/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs b/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs index 3978880987..b1f239cd78 100644 --- a/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs +++ b/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs @@ -1,4 +1,5 @@ using Content.Shared.Medical.CrewMonitoring; +using Robust.Client.UserInterface; namespace Content.Client.Medical.CrewMonitoring; @@ -14,7 +15,7 @@ public sealed class CrewMonitoringBoundUserInterface : BoundUserInterface protected override void Open() { EntityUid? gridUid = null; - string stationName = string.Empty; + var stationName = string.Empty; if (EntMan.TryGetComponent(Owner, out var xform)) { @@ -26,10 +27,8 @@ public sealed class CrewMonitoringBoundUserInterface : BoundUserInterface } } - _menu = new CrewMonitoringWindow(stationName, gridUid); - - _menu.OpenCentered(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); + _menu.Set(stationName, gridUid); } protected override void UpdateState(BoundUserInterfaceState state) @@ -44,13 +43,4 @@ public sealed class CrewMonitoringBoundUserInterface : BoundUserInterface break; } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _menu?.Dispose(); - } } diff --git a/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs b/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs index 863412e553..e861864c14 100644 --- a/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs +++ b/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs @@ -23,22 +23,27 @@ namespace Content.Client.Medical.CrewMonitoring; [GenerateTypedNameReferences] public sealed partial class CrewMonitoringWindow : FancyWindow { - private readonly IEntityManager _entManager; - private readonly IPrototypeManager _prototypeManager; + [Dependency] private readonly IEntityManager _entManager = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; private readonly SpriteSystem _spriteSystem; private NetEntity? _trackedEntity; private bool _tryToScrollToListFocus; private Texture? _blipTexture; - public CrewMonitoringWindow(string stationName, EntityUid? mapUid) + public CrewMonitoringWindow() { RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); - _entManager = IoCManager.Resolve(); - _prototypeManager = IoCManager.Resolve(); _spriteSystem = _entManager.System(); + NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap; + + } + + public void Set(string stationName, EntityUid? mapUid) + { _blipTexture = _spriteSystem.Frame0(new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_circle.png"))); if (_entManager.TryGetComponent(mapUid, out var xform)) @@ -49,8 +54,6 @@ public sealed partial class CrewMonitoringWindow : FancyWindow StationName.AddStyleClass("LabelBig"); StationName.Text = stationName; - - NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap; NavMap.ForceNavMapUpdate(); } diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorBoundUserInterface.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorBoundUserInterface.cs index 80c98f143b..f85220a926 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorBoundUserInterface.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Client.NetworkConfigurator.Systems; using Content.Shared.DeviceNetwork; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; namespace Content.Client.NetworkConfigurator; @@ -35,14 +36,12 @@ public sealed class NetworkConfiguratorBoundUserInterface : BoundUserInterface switch (UiKey) { case NetworkConfiguratorUiKey.List: - _listMenu = new NetworkConfiguratorListMenu(this); - _listMenu.OnClose += Close; + _listMenu = this.CreateWindow(); _listMenu.ClearButton.OnPressed += _ => OnClearButtonPressed(); - _listMenu.OpenCenteredRight(); + _listMenu.OnRemoveAddress += OnRemoveButtonPressed; break; case NetworkConfiguratorUiKey.Configure: - _configurationMenu = new NetworkConfiguratorConfigurationMenu(); - _configurationMenu.OnClose += Close; + _configurationMenu = this.CreateWindow(); _configurationMenu.Set.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Set); _configurationMenu.Add.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Add); //_configurationMenu.Edit.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Edit); @@ -50,12 +49,24 @@ public sealed class NetworkConfiguratorBoundUserInterface : BoundUserInterface _configurationMenu.Copy.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Copy); _configurationMenu.Show.OnPressed += OnShowPressed; _configurationMenu.Show.Pressed = _netConfig.ConfiguredListIsTracked(Owner); - _configurationMenu.OpenCentered(); + _configurationMenu.OnRemoveAddress += OnRemoveButtonPressed; break; case NetworkConfiguratorUiKey.Link: - _linkMenu = new NetworkConfiguratorLinkMenu(this); - _linkMenu.OnClose += Close; - _linkMenu.OpenCentered(); + _linkMenu = this.CreateWindow(); + _linkMenu.OnLinkDefaults += args => + { + SendMessage(new NetworkConfiguratorLinksSaveMessage(args)); + }; + + _linkMenu.OnToggleLink += (left, right) => + { + SendMessage(new NetworkConfiguratorToggleLinkMessage(left, right)); + }; + + _linkMenu.OnClearLinks += () => + { + SendMessage(new NetworkConfiguratorClearLinksMessage()); + }; break; } } @@ -83,16 +94,6 @@ public sealed class NetworkConfiguratorBoundUserInterface : BoundUserInterface } } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - - _linkMenu?.Dispose(); - _listMenu?.Dispose(); - _configurationMenu?.Dispose(); - } - private void OnClearButtonPressed() { SendMessage(new NetworkConfiguratorClearDevicesMessage()); diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorConfigurationMenu.xaml.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorConfigurationMenu.xaml.cs index 19d04cd346..fcd2f75918 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorConfigurationMenu.xaml.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorConfigurationMenu.xaml.cs @@ -9,17 +9,23 @@ namespace Content.Client.NetworkConfigurator; [GenerateTypedNameReferences] public sealed partial class NetworkConfiguratorConfigurationMenu : FancyWindow { + public event Action? OnRemoveAddress; + public NetworkConfiguratorConfigurationMenu() { RobustXamlLoader.Load(this); Clear.StyleClasses.Add(StyleBase.ButtonOpenLeft); Clear.StyleClasses.Add(StyleNano.StyleClassButtonColorRed); + DeviceList.OnRemoveAddress += args => + { + OnRemoveAddress?.Invoke(args); + }; } public void UpdateState(DeviceListUserInterfaceState state) { - DeviceList.UpdateState(null, state.DeviceList); + DeviceList.UpdateState(state.DeviceList, false); Count.Text = Loc.GetString("network-configurator-ui-count-label", ("count", state.DeviceList.Count)); } diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorDeviceList.xaml.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorDeviceList.xaml.cs index 8cfa97dc6c..e75c60058c 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorDeviceList.xaml.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorDeviceList.xaml.cs @@ -7,17 +7,19 @@ namespace Content.Client.NetworkConfigurator; [GenerateTypedNameReferences] public sealed partial class NetworkConfiguratorDeviceList : ScrollContainer { - public void UpdateState(NetworkConfiguratorBoundUserInterface? ui, HashSet<(string address, string name)> devices) + public event Action? OnRemoveAddress; + + public void UpdateState(HashSet<(string address, string name)> devices, bool ui) { DeviceList.RemoveAllChildren(); foreach (var device in devices) { - DeviceList.AddChild(BuildDeviceListRow(ui, device)); + DeviceList.AddChild(BuildDeviceListRow(device, ui)); } } - private static BoxContainer BuildDeviceListRow(NetworkConfiguratorBoundUserInterface? ui, (string address, string name) savedDevice) + private BoxContainer BuildDeviceListRow((string address, string name) savedDevice, bool ui) { var row = new BoxContainer() { @@ -48,10 +50,10 @@ public sealed partial class NetworkConfiguratorDeviceList : ScrollContainer row.AddChild(name); row.AddChild(address); - if (ui != null) + if (ui) { row.AddChild(removeButton); - removeButton.OnPressed += _ => ui.OnRemoveButtonPressed(savedDevice.address); + removeButton.OnPressed += _ => OnRemoveAddress?.Invoke(savedDevice.address); } return row; diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs index c04b42f249..8cdffd16af 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs @@ -18,20 +18,20 @@ public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow private readonly LinksRender _links; - private readonly List _sources = new(); private readonly List _sinks = new(); - private readonly NetworkConfiguratorBoundUserInterface _userInterface; - private (ButtonPosition position, string id, int index)? _selectedButton; private List<(string left, string right)>? _defaults; - public NetworkConfiguratorLinkMenu(NetworkConfiguratorBoundUserInterface userInterface) + public event Action? OnClearLinks; + public event Action? OnToggleLink; + public event Action>? OnLinkDefaults; + + public NetworkConfiguratorLinkMenu() { - _userInterface = userInterface; RobustXamlLoader.Load(this); var footerStyleBox = new StyleBoxFlat() @@ -52,7 +52,7 @@ public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow ButtonOk.OnPressed += _ => Close(); ButtonLinkDefault.OnPressed += _ => LinkDefaults(); - ButtonClear.OnPressed += _ => _userInterface.SendMessage(new NetworkConfiguratorClearLinksMessage()); + ButtonClear.OnPressed += _ => OnClearLinks?.Invoke(); } public void UpdateState(DeviceLinkUserInterfaceState linkState) @@ -98,7 +98,7 @@ public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow if (_defaults == default) return; - _userInterface.SendMessage(new NetworkConfiguratorLinksSaveMessage(_defaults)); + OnLinkDefaults?.Invoke(_defaults); } private Button CreateButton(ButtonPosition position, string name, string description, string id, int index) @@ -138,7 +138,7 @@ public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow var left = _selectedButton.Value.position == ButtonPosition.Left ? _selectedButton.Value.id : id; var right = _selectedButton.Value.position == ButtonPosition.Left ? id : _selectedButton.Value.id; - _userInterface.SendMessage(new NetworkConfiguratorToggleLinkMessage(left, right)); + OnToggleLink?.Invoke(left, right); args.Button.Pressed = false; diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorListMenu.xaml.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorListMenu.xaml.cs index fb4aec1974..6294facaee 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorListMenu.xaml.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorListMenu.xaml.cs @@ -9,17 +9,20 @@ namespace Content.Client.NetworkConfigurator; [GenerateTypedNameReferences] public sealed partial class NetworkConfiguratorListMenu : FancyWindow { - private readonly NetworkConfiguratorBoundUserInterface _ui; - public NetworkConfiguratorListMenu(NetworkConfiguratorBoundUserInterface ui) + public event Action? OnRemoveAddress; + + public NetworkConfiguratorListMenu() { RobustXamlLoader.Load(this); - - _ui = ui; + DeviceList.OnRemoveAddress += args => + { + OnRemoveAddress?.Invoke(args); + }; } public void UpdateState(NetworkConfiguratorUserInterfaceState state) { DeviceCountLabel.Text = Loc.GetString("network-configurator-ui-count-label", ("count", state.DeviceList.Count)); - DeviceList.UpdateState(_ui, state.DeviceList); + DeviceList.UpdateState(state.DeviceList, true); } } diff --git a/Content.Client/Nuke/NukeBoundUserInterface.cs b/Content.Client/Nuke/NukeBoundUserInterface.cs index 59fbc5b319..2e15042373 100644 --- a/Content.Client/Nuke/NukeBoundUserInterface.cs +++ b/Content.Client/Nuke/NukeBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Containers.ItemSlots; using Content.Shared.Nuke; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Nuke { @@ -11,15 +12,13 @@ namespace Content.Client.Nuke [ViewVariables] private NukeMenu? _menu; - public NukeBoundUserInterface([NotNull] EntityUid owner, [NotNull] Enum uiKey) : base(owner, uiKey) + public NukeBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } protected override void Open() { - _menu = new NukeMenu(); - _menu.OpenCentered(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); _menu.OnKeypadButtonPressed += i => { @@ -62,15 +61,5 @@ namespace Content.Client.Nuke break; } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _menu?.Close(); - _menu?.Dispose(); - } } } diff --git a/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs b/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs index ec055b3240..ad4f1a75d4 100644 --- a/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs +++ b/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Chat; using Content.Shared.NukeOps; using JetBrains.Annotations; +using Robust.Client.UserInterface; using Robust.Shared.Configuration; using Robust.Shared.Timing; @@ -11,8 +12,6 @@ namespace Content.Client.NukeOps; public sealed class WarDeclaratorBoundUserInterface : BoundUserInterface { [Dependency] private readonly IConfigurationManager _cfg = default!; - [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly ILocalizationManager _localizationManager = default!; [ViewVariables] private WarDeclaratorWindow? _window; @@ -23,13 +22,7 @@ public sealed class WarDeclaratorBoundUserInterface : BoundUserInterface { base.Open(); - _window = new WarDeclaratorWindow(_gameTiming, _localizationManager); - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.OnActivated += OnWarDeclaratorActivated; } @@ -42,13 +35,6 @@ public sealed class WarDeclaratorBoundUserInterface : BoundUserInterface _window?.UpdateState(cast); } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (disposing) - _window?.Dispose(); - } - private void OnWarDeclaratorActivated(string message) { var maxLength = _cfg.GetCVar(CCVars.ChatMaxAnnouncementLength); diff --git a/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs b/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs index b4a3f1c7fa..aeceae1327 100644 --- a/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs +++ b/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs @@ -11,7 +11,8 @@ namespace Content.Client.NukeOps; [GenerateTypedNameReferences] public sealed partial class WarDeclaratorWindow : FancyWindow { - private readonly IGameTiming _gameTiming; + [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly ILocalizationManager _localizationManager = default!; public event Action? OnActivated; @@ -19,15 +20,13 @@ public sealed partial class WarDeclaratorWindow : FancyWindow private TimeSpan _shuttleDisabledTime; private WarConditionStatus _status; - public WarDeclaratorWindow(IGameTiming gameTiming, ILocalizationManager localizationManager) + public WarDeclaratorWindow() { RobustXamlLoader.Load(this); - _gameTiming = gameTiming; - WarButton.OnPressed += (_) => OnActivated?.Invoke(Rope.Collapse(MessageEdit.TextRope)); - MessageEdit.Placeholder = new Rope.Leaf(localizationManager.GetString("war-declarator-message-placeholder")); + MessageEdit.Placeholder = new Rope.Leaf(_localizationManager.GetString("war-declarator-message-placeholder")); } protected override void FrameUpdate(FrameEventArgs args) diff --git a/Content.Client/PDA/PdaBoundUserInterface.cs b/Content.Client/PDA/PdaBoundUserInterface.cs index f8f4c67076..37ce9c4280 100644 --- a/Content.Client/PDA/PdaBoundUserInterface.cs +++ b/Content.Client/PDA/PdaBoundUserInterface.cs @@ -24,14 +24,13 @@ namespace Content.Client.PDA if (_menu == null) CreateMenu(); - - _menu?.OpenCenteredLeft(); } private void CreateMenu() { - _menu = new PdaMenu(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); + _menu.OpenCenteredLeft(); + _menu.FlashLightToggleButton.OnToggled += _ => { SendMessage(new PdaToggleFlashlightMessage()); @@ -96,7 +95,6 @@ namespace Content.Client.PDA _menu?.UpdateState(updateState); } - protected override void AttachCartridgeUI(Control cartridgeUIFragment, string? title) { _menu?.ProgramView.AddChild(cartridgeUIFragment); @@ -118,15 +116,6 @@ namespace Content.Client.PDA _menu?.UpdateAvailablePrograms(programs); } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _menu?.Dispose(); - } - private PdaBorderColorComponent? GetBorderColorComponent() { return EntMan.GetComponentOrNull(Owner); diff --git a/Content.Client/PDA/Ringer/RingerBoundUserInterface.cs b/Content.Client/PDA/Ringer/RingerBoundUserInterface.cs index a0688523f1..170a296ac2 100644 --- a/Content.Client/PDA/Ringer/RingerBoundUserInterface.cs +++ b/Content.Client/PDA/Ringer/RingerBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.PDA; using Content.Shared.PDA.Ringer; using JetBrains.Annotations; +using Robust.Client.UserInterface; using Robust.Shared.Timing; namespace Content.Client.PDA.Ringer @@ -18,9 +19,8 @@ namespace Content.Client.PDA.Ringer protected override void Open() { base.Open(); - _menu = new RingtoneMenu(); + _menu = this.CreateWindow(); _menu.OpenToLeft(); - _menu.OnClose += Close; _menu.TestRingerButton.OnPressed += _ => { diff --git a/Content.Client/Paper/UI/PaperBoundUserInterface.cs b/Content.Client/Paper/UI/PaperBoundUserInterface.cs index 4b0ac868f0..f3ad1e347e 100644 --- a/Content.Client/Paper/UI/PaperBoundUserInterface.cs +++ b/Content.Client/Paper/UI/PaperBoundUserInterface.cs @@ -1,4 +1,5 @@ using JetBrains.Annotations; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Utility; using static Content.Shared.Paper.SharedPaperComponent; @@ -19,16 +20,13 @@ public sealed class PaperBoundUserInterface : BoundUserInterface { base.Open(); - _window = new PaperWindow(); - _window.OnClose += Close; - _window.OnSaved += Input_OnTextEntered; + _window = this.CreateWindow(); + _window.OnSaved += InputOnTextEntered; if (EntMan.TryGetComponent(Owner, out var visuals)) { _window.InitVisuals(Owner, visuals); } - - _window.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -37,7 +35,7 @@ public sealed class PaperBoundUserInterface : BoundUserInterface _window?.Populate((PaperBoundUserInterfaceState) state); } - private void Input_OnTextEntered(string text) + private void InputOnTextEntered(string text) { SendMessage(new PaperInputTextMessage(text)); @@ -47,11 +45,4 @@ public sealed class PaperBoundUserInterface : BoundUserInterface _window.Input.CursorPosition = new TextEdit.CursorPos(0, TextEdit.LineBreakBias.Top); } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } diff --git a/Content.Client/Paper/UI/PaperWindow.xaml.cs b/Content.Client/Paper/UI/PaperWindow.xaml.cs index 7a5fd65264..f7cace642c 100644 --- a/Content.Client/Paper/UI/PaperWindow.xaml.cs +++ b/Content.Client/Paper/UI/PaperWindow.xaml.cs @@ -17,6 +17,7 @@ namespace Content.Client.Paper.UI public sealed partial class PaperWindow : BaseWindow { [Dependency] private readonly IInputManager _inputManager = default!; + [Dependency] private readonly IResourceCache _resCache = default!; private static Color DefaultTextColor = new(25, 25, 25); @@ -85,11 +86,10 @@ namespace Content.Client.Paper.UI // Randomize the placement of any stamps based on the entity UID // so that there's some variety in different papers. StampDisplay.PlacementSeed = (int)entity; - var resCache = IoCManager.Resolve(); // Initialize the background: PaperBackground.ModulateSelfOverride = visuals.BackgroundModulate; - var backgroundImage = visuals.BackgroundImagePath != null? resCache.GetResource(visuals.BackgroundImagePath) : null; + var backgroundImage = visuals.BackgroundImagePath != null? _resCache.GetResource(visuals.BackgroundImagePath) : null; if (backgroundImage != null) { var backgroundImageMode = visuals.BackgroundImageTile ? StyleBoxTexture.StretchMode.Tile : StyleBoxTexture.StretchMode.Stretch; @@ -127,7 +127,7 @@ namespace Content.Client.Paper.UI PaperContent.ModulateSelfOverride = visuals.ContentImageModulate; WrittenTextLabel.ModulateSelfOverride = visuals.FontAccentColor; - var contentImage = visuals.ContentImagePath != null ? resCache.GetResource(visuals.ContentImagePath) : null; + var contentImage = visuals.ContentImagePath != null ? _resCache.GetResource(visuals.ContentImagePath) : null; if (contentImage != null) { // Setup the paper content texture, but keep a reference to it, as we can't set diff --git a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs index cde5ba9ef7..ff1eae36f5 100644 --- a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs +++ b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Singularity.Components; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.ParticleAccelerator.UI { @@ -16,9 +17,10 @@ namespace Content.Client.ParticleAccelerator.UI { base.Open(); - _menu = new ParticleAcceleratorControlMenu(this); - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); + _menu.OnOverallState += SendEnableMessage; + _menu.OnPowerState += SendPowerStateMessage; + _menu.OnScanPartsRequested += SendScanPartsMessage; } public void SendEnableMessage(bool enable) @@ -40,13 +42,5 @@ namespace Content.Client.ParticleAccelerator.UI { _menu?.DataUpdate((ParticleAcceleratorUIState) state); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - _menu?.Dispose(); - _menu = null; - } } } diff --git a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs index c69e027137..05a296edf3 100644 --- a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs +++ b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs @@ -18,9 +18,10 @@ namespace Content.Client.ParticleAccelerator.UI { public sealed class ParticleAcceleratorControlMenu : BaseWindow { - private readonly ShaderInstance _greyScaleShader; + [Dependency] private readonly IPrototypeManager _protoManager = default!; + [Dependency] private readonly IResourceCache _cache = default!; - private readonly ParticleAcceleratorBoundUserInterface _owner; + private readonly ShaderInstance _greyScaleShader; private readonly Label _drawLabel; private readonly FastNoiseLite _drawNoiseGenerator; @@ -50,19 +51,22 @@ namespace Content.Client.ParticleAccelerator.UI private bool _shouldContinueAnimating; private int _maxStrength = 3; - public ParticleAcceleratorControlMenu(ParticleAcceleratorBoundUserInterface owner) - { - SetSize = new Vector2(400, 320); - _greyScaleShader = IoCManager.Resolve().Index("Greyscale").Instance(); + public event Action? OnOverallState; + public event Action? OnPowerState; + public event Action? OnScanPartsRequested; + + public ParticleAcceleratorControlMenu() + { + IoCManager.InjectDependencies(this); + SetSize = new Vector2(400, 320); + _greyScaleShader = _protoManager.Index("Greyscale").Instance(); - _owner = owner; _drawNoiseGenerator = new(); _drawNoiseGenerator.SetFractalType(FastNoiseLite.FractalType.FBm); _drawNoiseGenerator.SetFrequency(0.5f); - var resourceCache = IoCManager.Resolve(); - var font = resourceCache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); - var panelTex = resourceCache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); + var font = _cache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); + var panelTex = _cache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); MouseFilter = MouseFilterMode.Stop; @@ -112,7 +116,8 @@ namespace Content.Client.ParticleAccelerator.UI Text = Loc.GetString("particle-accelerator-control-menu-off-button"), StyleClasses = { StyleBase.ButtonOpenRight }, }; - _offButton.OnPressed += args => owner.SendEnableMessage(false); + + _offButton.OnPressed += args => OnOverallState?.Invoke(false); _onButton = new Button { @@ -120,7 +125,7 @@ namespace Content.Client.ParticleAccelerator.UI Text = Loc.GetString("particle-accelerator-control-menu-on-button"), StyleClasses = { StyleBase.ButtonOpenLeft }, }; - _onButton.OnPressed += args => owner.SendEnableMessage(true); + _onButton.OnPressed += args => OnOverallState?.Invoke(true); var closeButton = new TextureButton { @@ -316,7 +321,7 @@ namespace Content.Client.ParticleAccelerator.UI } }); - _scanButton.OnPressed += args => _owner.SendScanPartsMessage(); + _scanButton.OnPressed += args => OnScanPartsRequested?.Invoke(); _alarmControl.AnimationCompleted += s => { @@ -332,7 +337,7 @@ namespace Content.Client.ParticleAccelerator.UI PASegmentControl Segment(string name) { - return new(this, resourceCache, name); + return new(this, _cache, name); } UpdateUI(false, false, false, false); @@ -368,7 +373,7 @@ namespace Content.Client.ParticleAccelerator.UI } _stateSpinBox.SetButtonDisabled(true); - _owner.SendPowerStateMessage(newState); + OnPowerState?.Invoke(newState); } protected override DragMode GetDragModeFor(Vector2 relativeMousePos) diff --git a/Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs b/Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs index 3ebcf7cbce..0df6787170 100644 --- a/Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs +++ b/Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Pinpointer; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Pinpointer.UI; @@ -16,19 +17,16 @@ public sealed class NavMapBeaconBoundUserInterface : BoundUserInterface protected override void Open() { base.Open(); - _window = new NavMapBeaconWindow(Owner); - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); + + if (EntMan.TryGetComponent(Owner, out NavMapBeaconComponent? beacon)) + { + _window.SetEntity(Owner, beacon); + } _window.OnApplyButtonPressed += (label, enabled, color) => { SendMessage(new NavMapBeaconConfigureBuiMessage(label, enabled, color)); }; } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - _window?.Dispose(); - } } diff --git a/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs b/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs index 968fe188f7..b77f1af047 100644 --- a/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs +++ b/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs @@ -10,36 +10,35 @@ namespace Content.Client.Pinpointer.UI; [GenerateTypedNameReferences] public sealed partial class NavMapBeaconWindow : FancyWindow { - [Dependency] private readonly IEntityManager _entityManager = default!; - private string? _defaultLabel; private bool _defaultEnabled; private Color _defaultColor; public event Action? OnApplyButtonPressed; - public NavMapBeaconWindow(EntityUid beaconEntity) + public NavMapBeaconWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - if (!_entityManager.TryGetComponent(beaconEntity, out var navMap)) - return; + + VisibleButton.OnPressed += args => UpdateVisibleButton(args.Button.Pressed); + LabelLineEdit.OnTextChanged += OnTextChanged; + ColorSelector.OnColorChanged += _ => TryEnableApplyButton(); + + TryEnableApplyButton(); + ApplyButton.OnPressed += OnApplyPressed; + } + + public void SetEntity(EntityUid uid, NavMapBeaconComponent navMap) + { _defaultLabel = navMap.Text; _defaultEnabled = navMap.Enabled; _defaultColor = navMap.Color; UpdateVisibleButton(navMap.Enabled); - VisibleButton.OnPressed += args => UpdateVisibleButton(args.Button.Pressed); - LabelLineEdit.Text = navMap.Text ?? string.Empty; - LabelLineEdit.OnTextChanged += OnTextChanged; - ColorSelector.Color = navMap.Color; - ColorSelector.OnColorChanged += _ => TryEnableApplyButton(); - - TryEnableApplyButton(); - ApplyButton.OnPressed += OnApplyPressed; } private void UpdateVisibleButton(bool value) diff --git a/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs b/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs index 1483e75e73..7417fafede 100644 --- a/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs +++ b/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs @@ -1,4 +1,4 @@ -using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Pinpointer.UI; @@ -14,7 +14,6 @@ public sealed class StationMapBoundUserInterface : BoundUserInterface protected override void Open() { base.Open(); - _window?.Close(); EntityUid? gridUid = null; if (EntMan.TryGetComponent(Owner, out var xform)) @@ -22,14 +21,8 @@ public sealed class StationMapBoundUserInterface : BoundUserInterface gridUid = xform.GridUid; } - _window = new StationMapWindow(gridUid, Owner); - _window.OpenCentered(); - _window.OnClose += Close; - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - _window?.Dispose(); + _window = this.CreateWindow(); + _window.Title = EntMan.GetComponent(Owner).EntityName; + _window.Set(gridUid, Owner); } } diff --git a/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs b/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs index 1b01fe4e30..7cbb8b7d0d 100644 --- a/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs +++ b/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs @@ -9,19 +9,18 @@ namespace Content.Client.Pinpointer.UI; [GenerateTypedNameReferences] public sealed partial class StationMapWindow : FancyWindow { - public StationMapWindow(EntityUid? mapUid, EntityUid? trackedEntity) + public StationMapWindow() { RobustXamlLoader.Load(this); + } + + public void Set(EntityUid? mapUid, EntityUid? trackedEntity) + { NavMapScreen.MapUid = mapUid; if (trackedEntity != null) NavMapScreen.TrackedCoordinates.Add(new EntityCoordinates(trackedEntity.Value, Vector2.Zero), (true, Color.Cyan)); - if (IoCManager.Resolve().TryGetComponent(mapUid, out var metadata)) - { - Title = metadata.EntityName; - } - NavMapScreen.ForceNavMapUpdate(); } } diff --git a/Content.Client/Pinpointer/UI/UntrackedMapBoundUserInterface.cs b/Content.Client/Pinpointer/UI/UntrackedMapBoundUserInterface.cs index 57965b030a..a3ca6f65da 100644 --- a/Content.Client/Pinpointer/UI/UntrackedMapBoundUserInterface.cs +++ b/Content.Client/Pinpointer/UI/UntrackedMapBoundUserInterface.cs @@ -1,4 +1,4 @@ -using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Pinpointer.UI; @@ -14,22 +14,15 @@ public sealed class UntrackedStationMapBoundUserInterface : BoundUserInterface protected override void Open() { base.Open(); - _window?.Close(); EntityUid? gridUid = null; + // TODO: What this just looks like it's been copy-pasted wholesale from StationMapBoundUserInterface? if (EntMan.TryGetComponent(Owner, out var xform)) { gridUid = xform.GridUid; } - _window = new StationMapWindow(gridUid, null); - _window.OpenCentered(); - _window.OnClose += Close; - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - _window?.Dispose(); + _window = this.CreateWindow(); + _window.Set(gridUid, Owner); } } diff --git a/Content.Client/Power/APC/ApcBoundUserInterface.cs b/Content.Client/Power/APC/ApcBoundUserInterface.cs index fbcbf01156..759a5949ba 100644 --- a/Content.Client/Power/APC/ApcBoundUserInterface.cs +++ b/Content.Client/Power/APC/ApcBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.APC; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Power.APC { @@ -19,9 +20,8 @@ namespace Content.Client.Power.APC { base.Open(); - _menu = new ApcMenu(this); - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); + _menu.OnBreaker += BreakerPressed; } protected override void UpdateState(BoundUserInterfaceState state) @@ -36,15 +36,5 @@ namespace Content.Client.Power.APC { SendMessage(new ApcToggleMainBreakerMessage()); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _menu?.Dispose(); - } - } } } diff --git a/Content.Client/Power/APC/UI/ApcMenu.xaml.cs b/Content.Client/Power/APC/UI/ApcMenu.xaml.cs index dbf68ea07b..2f61ea63a8 100644 --- a/Content.Client/Power/APC/UI/ApcMenu.xaml.cs +++ b/Content.Client/Power/APC/UI/ApcMenu.xaml.cs @@ -17,13 +17,19 @@ namespace Content.Client.Power.APC.UI [GenerateTypedNameReferences] public sealed partial class ApcMenu : FancyWindow { - public ApcMenu(ApcBoundUserInterface owner) + public event Action? OnBreaker; + + public ApcMenu() { IoCManager.InjectDependencies(this); RobustXamlLoader.Load(this); - EntityView.SetEntity(owner.Owner); - BreakerButton.OnPressed += _ => owner.BreakerPressed(); + BreakerButton.OnPressed += _ => OnBreaker?.Invoke(); + } + + public void SetEntity(EntityUid entity) + { + EntityView.SetEntity(entity); } public void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Power/Generator/GeneratorWindow.xaml.cs b/Content.Client/Power/Generator/GeneratorWindow.xaml.cs index bd5b75de1d..e975e5d466 100644 --- a/Content.Client/Power/Generator/GeneratorWindow.xaml.cs +++ b/Content.Client/Power/Generator/GeneratorWindow.xaml.cs @@ -9,35 +9,39 @@ namespace Content.Client.Power.Generator; [GenerateTypedNameReferences] public sealed partial class GeneratorWindow : FancyWindow { - private readonly EntityUid _entity; - [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly ILocalizationManager _loc = default!; - private readonly SharedPowerSwitchableSystem _switchable; - private readonly FuelGeneratorComponent? _component; - private PortableGeneratorComponentBuiState? _lastState; + private EntityUid _entity; - public GeneratorWindow(PortableGeneratorBoundUserInterface bui, EntityUid entity) + public float? MaximumPower; + + public event Action? OnPower; + public event Action? OnState; + public event Action? OnSwitchOutput; + public event Action? OnEjectFuel; + + public GeneratorWindow() { - _entity = entity; RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - _entityManager.TryGetComponent(entity, out _component); - _switchable = _entityManager.System(); - - EntityView.SetEntity(entity); TargetPower.IsValid += IsValid; TargetPower.ValueChanged += (args) => { - bui.SetTargetPower(args.Value); + OnPower?.Invoke(args.Value); }; - StartButton.OnPressed += _ => bui.Start(); - StopButton.OnPressed += _ => bui.Stop(); - OutputSwitchButton.OnPressed += _ => bui.SwitchOutput(); - FuelEject.OnPressed += _ => bui.EjectFuel(); + StartButton.OnPressed += _ => OnState?.Invoke(true); + StopButton.OnPressed += _ => OnState?.Invoke(false); + OutputSwitchButton.OnPressed += _ => OnSwitchOutput?.Invoke(); + FuelEject.OnPressed += _ => OnEjectFuel?.Invoke(); + } + + public void SetEntity(EntityUid entity) + { + _entity = entity; + EntityView.SetEntity(entity); } private bool IsValid(int arg) @@ -45,7 +49,7 @@ public sealed partial class GeneratorWindow : FancyWindow if (arg < 0) return false; - if (arg > (_lastState?.MaximumPower / 1000.0f ?? 0)) + if (arg > (MaximumPower / 1000.0f ?? 0)) return false; return true; @@ -53,16 +57,17 @@ public sealed partial class GeneratorWindow : FancyWindow public void Update(PortableGeneratorComponentBuiState state) { - if (_component == null) + MaximumPower = state.MaximumPower; + + if (!_entityManager.TryGetComponent(_entity, out FuelGeneratorComponent? component)) return; - _lastState = state; if (!TargetPower.LineEditControl.HasKeyboardFocus()) TargetPower.OverrideValue((int)(state.TargetPower / 1000.0f)); - var efficiency = SharedGeneratorSystem.CalcFuelEfficiency(state.TargetPower, state.OptimalPower, _component); + var efficiency = SharedGeneratorSystem.CalcFuelEfficiency(state.TargetPower, state.OptimalPower, component); Efficiency.Text = efficiency.ToString("P1"); - var burnRate = _component.OptimalBurnRate / efficiency; + var burnRate = component.OptimalBurnRate / efficiency; var left = state.RemainingFuel / burnRate; Eta.Text = Loc.GetString( @@ -102,14 +107,15 @@ public sealed partial class GeneratorWindow : FancyWindow } var canSwitch = _entityManager.TryGetComponent(_entity, out PowerSwitchableComponent? switchable); + var switcher = _entityManager.System(); OutputSwitchLabel.Visible = canSwitch; OutputSwitchButton.Visible = canSwitch; if (switchable != null) { - var voltage = _switchable.VoltageString(_switchable.GetVoltage(_entity, switchable)); + var voltage = switcher.VoltageString(switcher.GetVoltage(_entity, switchable)); OutputSwitchLabel.Text = Loc.GetString("portable-generator-ui-current-output", ("voltage", voltage)); - var nextVoltage = _switchable.VoltageString(_switchable.GetNextVoltage(_entity, switchable)); + var nextVoltage = switcher.VoltageString(switcher.GetNextVoltage(_entity, switchable)); OutputSwitchButton.Text = Loc.GetString("power-switchable-switch-voltage", ("voltage", nextVoltage)); OutputSwitchButton.Disabled = state.On; } diff --git a/Content.Client/Power/Generator/PortableGeneratorBoundUserInterface.cs b/Content.Client/Power/Generator/PortableGeneratorBoundUserInterface.cs index 30679d71fd..550e1041b6 100644 --- a/Content.Client/Power/Generator/PortableGeneratorBoundUserInterface.cs +++ b/Content.Client/Power/Generator/PortableGeneratorBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Power.Generator; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Power.Generator; @@ -16,10 +17,25 @@ public sealed class PortableGeneratorBoundUserInterface : BoundUserInterface protected override void Open() { base.Open(); - _window = new GeneratorWindow(this, Owner); + _window = this.CreateWindow(); + _window.SetEntity(Owner); + _window.OnState += args => + { + if (args) + { + Start(); + } + else + { + Stop(); + } + }; + + _window.OnPower += SetTargetPower; + _window.OnEjectFuel += EjectFuel; + _window.OnSwitchOutput += SwitchOutput; _window.OpenCenteredLeft(); - _window.OnClose += Close; } protected override void UpdateState(BoundUserInterfaceState state) @@ -30,11 +46,6 @@ public sealed class PortableGeneratorBoundUserInterface : BoundUserInterface _window?.Update(msg); } - protected override void Dispose(bool disposing) - { - _window?.Dispose(); - } - public void SetTargetPower(int target) { SendMessage(new PortableGeneratorSetTargetPowerMessage(target)); diff --git a/Content.Client/Power/PowerMonitoringConsoleBoundUserInterface.cs b/Content.Client/Power/PowerMonitoringConsoleBoundUserInterface.cs index dc1dcd03ef..cbc343c06c 100644 --- a/Content.Client/Power/PowerMonitoringConsoleBoundUserInterface.cs +++ b/Content.Client/Power/PowerMonitoringConsoleBoundUserInterface.cs @@ -1,4 +1,5 @@ using Content.Shared.Power; +using Robust.Client.UserInterface; namespace Content.Client.Power; @@ -11,9 +12,9 @@ public sealed class PowerMonitoringConsoleBoundUserInterface : BoundUserInterfac protected override void Open() { - _menu = new PowerMonitoringWindow(this, Owner); - _menu.OpenCentered(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); + _menu.SendPowerMonitoringConsoleMessageAction += SendPowerMonitoringConsoleMessage; } protected override void UpdateState(BoundUserInterfaceState state) @@ -22,9 +23,6 @@ public sealed class PowerMonitoringConsoleBoundUserInterface : BoundUserInterfac var castState = (PowerMonitoringConsoleBoundInterfaceState) state; - if (castState == null) - return; - EntMan.TryGetComponent(Owner, out var xform); _menu?.ShowEntites (castState.TotalSources, @@ -40,13 +38,4 @@ public sealed class PowerMonitoringConsoleBoundUserInterface : BoundUserInterfac { SendMessage(new PowerMonitoringConsoleMessage(netEntity, group)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _menu?.Dispose(); - } } diff --git a/Content.Client/Power/PowerMonitoringWindow.xaml.Widgets.cs b/Content.Client/Power/PowerMonitoringWindow.xaml.Widgets.cs index 74752ddc53..d995299207 100644 --- a/Content.Client/Power/PowerMonitoringWindow.xaml.Widgets.cs +++ b/Content.Client/Power/PowerMonitoringWindow.xaml.Widgets.cs @@ -32,7 +32,7 @@ public sealed partial class PowerMonitoringWindow if (windowEntry == null) return; - // Update sources and loads + // Update sources and loads UpdateEntrySourcesOrLoads(masterContainer, windowEntry.SourcesContainer, focusSources, _sourceIcon); UpdateEntrySourcesOrLoads(masterContainer, windowEntry.LoadsContainer, focusLoads, _loadIconPath); @@ -134,7 +134,7 @@ public sealed partial class PowerMonitoringWindow subEntry.Button.OnButtonUp += args => { ButtonAction(subEntry, masterContainer); }; } - if (!_entManager.TryGetComponent(_owner, out var console)) + if (!_entManager.TryGetComponent(Entity, out var console)) return; // Update all children @@ -379,7 +379,7 @@ public sealed class PowerMonitoringWindowEntry : PowerMonitoringWindowBaseEntry AddChild(MainContainer); - // Grid container to hold the list of sources when selected + // Grid container to hold the list of sources when selected SourcesContainer = new BoxContainer() { Orientation = LayoutOrientation.Vertical, diff --git a/Content.Client/Power/PowerMonitoringWindow.xaml.cs b/Content.Client/Power/PowerMonitoringWindow.xaml.cs index 81fe1f4d04..e304325248 100644 --- a/Content.Client/Power/PowerMonitoringWindow.xaml.cs +++ b/Content.Client/Power/PowerMonitoringWindow.xaml.cs @@ -15,13 +15,12 @@ namespace Content.Client.Power; [GenerateTypedNameReferences] public sealed partial class PowerMonitoringWindow : FancyWindow { - private readonly IEntityManager _entManager; + [Dependency] private IEntityManager _entManager = default!; private readonly SpriteSystem _spriteSystem; - private readonly IGameTiming _gameTiming; + [Dependency] private IGameTiming _gameTiming = default!; private const float BlinkFrequency = 1f; - private EntityUid? _owner; private NetEntity? _focusEntity; public event Action? SendPowerMonitoringConsoleMessageAction; @@ -34,40 +33,14 @@ public sealed partial class PowerMonitoringWindow : FancyWindow { PowerMonitoringConsoleGroup.APC, (new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_triangle.png")), Color.LimeGreen) }, }; - public PowerMonitoringWindow(PowerMonitoringConsoleBoundUserInterface userInterface, EntityUid? owner) + public EntityUid Entity; + + public PowerMonitoringWindow() { RobustXamlLoader.Load(this); - _entManager = IoCManager.Resolve(); - _gameTiming = IoCManager.Resolve(); + IoCManager.InjectDependencies(this); _spriteSystem = _entManager.System(); - _owner = owner; - - // Pass owner to nav map - NavMap.Owner = _owner; - - // Set nav map grid uid - var stationName = Loc.GetString("power-monitoring-window-unknown-location"); - - if (_entManager.TryGetComponent(owner, out var xform)) - { - NavMap.MapUid = xform.GridUid; - - // Assign station name - if (_entManager.TryGetComponent(xform.GridUid, out var stationMetaData)) - stationName = stationMetaData.EntityName; - - var msg = new FormattedMessage(); - msg.AddMarkup(Loc.GetString("power-monitoring-window-station-name", ("stationName", stationName))); - - StationName.SetMessage(msg); - } - - else - { - StationName.SetMessage(stationName); - NavMap.Visible = false; - } // Set trackable entity selected action NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap; @@ -88,9 +61,37 @@ public sealed partial class PowerMonitoringWindow : FancyWindow ShowHVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.HighVoltage); ShowMVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.MediumVoltage); ShowLVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.Apc); + } - // Set power monitoring message action - SendPowerMonitoringConsoleMessageAction += userInterface.SendPowerMonitoringConsoleMessage; + public void SetEntity(EntityUid uid) + { + Entity = uid; + + // Pass owner to nav map + NavMap.Owner = uid; + + // Set nav map grid uid + var stationName = Loc.GetString("power-monitoring-window-unknown-location"); + + if (_entManager.TryGetComponent(uid, out var xform)) + { + NavMap.MapUid = xform.GridUid; + + // Assign station name + if (_entManager.TryGetComponent(xform.GridUid, out var stationMetaData)) + stationName = stationMetaData.EntityName; + + var msg = new FormattedMessage(); + msg.AddMarkupOrThrow(Loc.GetString("power-monitoring-window-station-name", ("stationName", stationName))); + + StationName.SetMessage(msg); + } + + else + { + StationName.SetMessage(stationName); + NavMap.Visible = false; + } } private void OnTabChanged(int tab) @@ -113,10 +114,7 @@ public sealed partial class PowerMonitoringWindow : FancyWindow PowerMonitoringConsoleEntry[] focusLoads, EntityCoordinates? monitorCoords) { - if (_owner == null) - return; - - if (!_entManager.TryGetComponent(_owner.Value, out var console)) + if (!_entManager.TryGetComponent(Entity, out var console)) return; // Update power status text @@ -161,13 +159,13 @@ public sealed partial class PowerMonitoringWindow : FancyWindow } // Show monitor location - var mon = _entManager.GetNetEntity(_owner); + var mon = _entManager.GetNetEntity(Entity); - if (monitorCoords != null && mon != null) + if (monitorCoords != null && mon.IsValid()) { var texture = _spriteSystem.Frame0(new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_circle.png"))); var blip = new NavMapBlip(monitorCoords.Value, texture, Color.Cyan, true, false); - NavMap.TrackedEntities[mon.Value] = blip; + NavMap.TrackedEntities[mon] = blip; } // If the entry group doesn't match the current tab, the data is out dated, do not use it @@ -239,7 +237,7 @@ public sealed partial class PowerMonitoringWindow : FancyWindow if (netEntity == null) return; - if (!_entManager.TryGetComponent(_owner, out var console)) + if (!_entManager.TryGetComponent(Entity, out var console)) return; if (!console.PowerMonitoringDeviceMetaData.TryGetValue(netEntity.Value, out var metaData)) @@ -266,7 +264,7 @@ public sealed partial class PowerMonitoringWindow : FancyWindow { AutoScrollToFocus(); - // Warning sign pulse + // Warning sign pulse var lit = _gameTiming.RealTime.TotalSeconds % BlinkFrequency > BlinkFrequency / 2f; SystemWarningPanel.Modulate = lit ? Color.White : new Color(178, 178, 178); } diff --git a/Content.Client/RCD/RCDMenu.xaml.cs b/Content.Client/RCD/RCDMenu.xaml.cs index 3eb0397a69..f0d27d6b1f 100644 --- a/Content.Client/RCD/RCDMenu.xaml.cs +++ b/Content.Client/RCD/RCDMenu.xaml.cs @@ -20,31 +20,37 @@ public sealed partial class RCDMenu : RadialMenu [Dependency] private readonly IPrototypeManager _protoManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; - private readonly SpriteSystem _spriteSystem; - private readonly SharedPopupSystem _popup; + private SharedPopupSystem _popup; + private SpriteSystem _sprites; public event Action>? SendRCDSystemMessageAction; private EntityUid _owner; - public RCDMenu(EntityUid owner, RCDMenuBoundUserInterface bui) + public RCDMenu() { IoCManager.InjectDependencies(this); RobustXamlLoader.Load(this); - _spriteSystem = _entManager.System(); _popup = _entManager.System(); + _sprites = _entManager.System(); - _owner = owner; + OnChildAdded += AddRCDMenuButtonOnClickActions; + } + public void SetEntity(EntityUid uid) + { + _owner = uid; + Refresh(); + } + + public void Refresh() + { // Find the main radial container var main = FindControl("Main"); - if (main == null) - return; - // Populate secondary radial containers - if (!_entManager.TryGetComponent(owner, out var rcd)) + if (!_entManager.TryGetComponent(_owner, out var rcd)) return; foreach (var protoId in rcd.AvailablePrototypes) @@ -56,14 +62,10 @@ public sealed partial class RCDMenu : RadialMenu continue; var parent = FindControl(proto.Category); - - if (parent == null) - continue; - var tooltip = Loc.GetString(proto.SetName); if ((proto.Mode == RcdMode.ConstructTile || proto.Mode == RcdMode.ConstructObject) && - proto.Prototype != null && _protoManager.TryIndex(proto.Prototype, out var entProto)) + proto.Prototype != null && _protoManager.TryIndex(proto.Prototype, out var entProto, logError: false)) { tooltip = Loc.GetString(entProto.Name); } @@ -84,7 +86,7 @@ public sealed partial class RCDMenu : RadialMenu { VerticalAlignment = VAlignment.Center, HorizontalAlignment = HAlignment.Center, - Texture = _spriteSystem.Frame0(proto.Sprite), + Texture = _sprites.Frame0(proto.Sprite), TextureScale = new Vector2(2f, 2f), }; @@ -112,11 +114,9 @@ public sealed partial class RCDMenu : RadialMenu // Set up menu actions foreach (var child in Children) + { AddRCDMenuButtonOnClickActions(child); - - OnChildAdded += AddRCDMenuButtonOnClickActions; - - SendRCDSystemMessageAction += bui.SendRCDSystemMessage; + } } private static string OopsConcat(string a, string b) @@ -153,7 +153,7 @@ public sealed partial class RCDMenu : RadialMenu var name = Loc.GetString(proto.SetName); if (proto.Prototype != null && - _protoManager.TryIndex(proto.Prototype, out var entProto)) + _protoManager.TryIndex(proto.Prototype, out var entProto, logError: false)) name = entProto.Name; msg = Loc.GetString("rcd-component-change-build-mode", ("name", name)); diff --git a/Content.Client/RCD/RCDMenuBoundUserInterface.cs b/Content.Client/RCD/RCDMenuBoundUserInterface.cs index a37dbcecf8..1dd03626ae 100644 --- a/Content.Client/RCD/RCDMenuBoundUserInterface.cs +++ b/Content.Client/RCD/RCDMenuBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.RCD.Components; using JetBrains.Annotations; using Robust.Client.Graphics; using Robust.Client.Input; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.RCD; @@ -24,8 +25,9 @@ public sealed class RCDMenuBoundUserInterface : BoundUserInterface { base.Open(); - _menu = new(Owner, this); - _menu.OnClose += Close; + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); + _menu.SendRCDSystemMessageAction += SendRCDSystemMessage; // Open the menu, centered on the mouse var vpSize = _displayManager.ScreenSize; @@ -34,16 +36,8 @@ public sealed class RCDMenuBoundUserInterface : BoundUserInterface public void SendRCDSystemMessage(ProtoId protoId) { - // A predicted message cannot be used here as the RCD UI is closed immediately + // A predicted message cannot be used here as the RCD UI is closed immediately // after this message is sent, which will stop the server from receiving it SendMessage(new RCDSystemMessage(protoId)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - - _menu?.Dispose(); - } } diff --git a/Content.Client/Radio/Ui/IntercomBoundUserInterface.cs b/Content.Client/Radio/Ui/IntercomBoundUserInterface.cs index 7b3e39aa08..401e7edd44 100644 --- a/Content.Client/Radio/Ui/IntercomBoundUserInterface.cs +++ b/Content.Client/Radio/Ui/IntercomBoundUserInterface.cs @@ -1,6 +1,8 @@ using Content.Shared.Radio; using Content.Shared.Radio.Components; using JetBrains.Annotations; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Radio.Ui; @@ -19,9 +21,12 @@ public sealed class IntercomBoundUserInterface : BoundUserInterface { base.Open(); - var comp = EntMan.GetComponent(Owner); + _menu = this.CreateWindow(); - _menu = new((Owner, comp)); + if (EntMan.TryGetComponent(Owner, out IntercomComponent? intercom)) + { + _menu.Update((Owner, intercom)); + } _menu.OnMicPressed += enabled => { @@ -35,17 +40,6 @@ public sealed class IntercomBoundUserInterface : BoundUserInterface { SendMessage(new SelectIntercomChannelMessage(channel)); }; - - _menu.OnClose += Close; - _menu.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Close(); } public void Update(Entity ent) diff --git a/Content.Client/Radio/Ui/IntercomMenu.xaml.cs b/Content.Client/Radio/Ui/IntercomMenu.xaml.cs index 2e08913051..20d2e4a3e5 100644 --- a/Content.Client/Radio/Ui/IntercomMenu.xaml.cs +++ b/Content.Client/Radio/Ui/IntercomMenu.xaml.cs @@ -18,15 +18,13 @@ public sealed partial class IntercomMenu : FancyWindow private readonly List _channels = new(); - public IntercomMenu(Entity entity) + public IntercomMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); MicButton.OnPressed += args => OnMicPressed?.Invoke(args.Button.Pressed); SpeakerButton.OnPressed += args => OnSpeakerPressed?.Invoke(args.Button.Pressed); - - Update(entity); } public void Update(Entity entity) diff --git a/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs b/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs index c14a8c5bd0..9641adb5b2 100644 --- a/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs +++ b/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs @@ -1,5 +1,7 @@ using Content.Shared.Research; using Content.Shared.Research.Components; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Research.UI { @@ -16,10 +18,7 @@ namespace Content.Client.Research.UI { base.Open(); - _menu = new(); - - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); _menu.OnServerButtonPressed += () => { @@ -31,14 +30,6 @@ namespace Content.Client.Research.UI }; } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Close(); - } - protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); diff --git a/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs b/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs index a0a2b58e88..288445e4de 100644 --- a/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs +++ b/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs @@ -1,4 +1,6 @@ using Content.Shared.Research.Components; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Research.UI { @@ -15,10 +17,9 @@ namespace Content.Client.Research.UI protected override void Open() { base.Open(); - - _menu = new ResearchClientServerSelectionMenu(this); - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); + _menu.OnServerSelected += SelectServer; + _menu.OnServerDeselected += DeselectServer; } public void SelectServer(int serverId) @@ -37,12 +38,5 @@ namespace Content.Client.Research.UI if (state is not ResearchClientBoundInterfaceState rState) return; _menu?.Populate(rState.ServerCount, rState.ServerNames, rState.ServerIds, rState.SelectedServerId); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _menu?.Dispose(); - } } } diff --git a/Content.Client/Research/UI/ResearchClientServerSelectionMenu.xaml.cs b/Content.Client/Research/UI/ResearchClientServerSelectionMenu.xaml.cs index ceaa965e59..d10f8b39f4 100644 --- a/Content.Client/Research/UI/ResearchClientServerSelectionMenu.xaml.cs +++ b/Content.Client/Research/UI/ResearchClientServerSelectionMenu.xaml.cs @@ -13,27 +13,26 @@ namespace Content.Client.Research.UI private int[] _serverIds = Array.Empty(); private int _selectedServerId = -1; - private ResearchClientBoundUserInterface Owner { get; } + public event Action? OnServerSelected; + public event Action? OnServerDeselected; - public ResearchClientServerSelectionMenu(ResearchClientBoundUserInterface owner) + public ResearchClientServerSelectionMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - Owner = owner; - Servers.OnItemSelected += OnItemSelected; Servers.OnItemDeselected += OnItemDeselected; } public void OnItemSelected(ItemList.ItemListSelectedEventArgs itemListSelectedEventArgs) { - Owner.SelectServer(_serverIds[itemListSelectedEventArgs.ItemIndex]); + OnServerSelected?.Invoke(_serverIds[itemListSelectedEventArgs.ItemIndex]); } public void OnItemDeselected(ItemList.ItemListDeselectedEventArgs itemListDeselectedEventArgs) { - Owner.DeselectServer(); + OnServerDeselected?.Invoke(); } public void Populate(int serverCount, string[] serverNames, int[] serverIds, int selectedServerId) diff --git a/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs b/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs index 2a9782045b..2895ada61f 100644 --- a/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs +++ b/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs @@ -1,5 +1,8 @@ using Content.Shared.Research.Components; +using Content.Shared.Research.Prototypes; using JetBrains.Annotations; +using Robust.Client.UserInterface; +using Robust.Shared.Prototypes; namespace Content.Client.Research.UI; @@ -19,7 +22,8 @@ public sealed class ResearchConsoleBoundUserInterface : BoundUserInterface var owner = Owner; - _consoleMenu = new ResearchConsoleMenu(owner); + _consoleMenu = this.CreateWindow(); + _consoleMenu.SetEntity(owner); _consoleMenu.OnTechnologyCardPressed += id => { @@ -30,10 +34,20 @@ public sealed class ResearchConsoleBoundUserInterface : BoundUserInterface { SendMessage(new ConsoleServerSelectionMessage()); }; + } - _consoleMenu.OnClose += Close; + public override void OnProtoReload(PrototypesReloadedEventArgs args) + { + base.OnProtoReload(args); - _consoleMenu.OpenCentered(); + if (!args.WasModified()) + return; + + if (State is not ResearchConsoleBoundInterfaceState rState) + return; + + _consoleMenu?.UpdatePanels(rState); + _consoleMenu?.UpdateInformationPanel(rState); } protected override void UpdateState(BoundUserInterfaceState state) @@ -45,12 +59,4 @@ public sealed class ResearchConsoleBoundUserInterface : BoundUserInterface _consoleMenu?.UpdatePanels(castState); _consoleMenu?.UpdateInformationPanel(castState); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _consoleMenu?.Dispose(); - } } diff --git a/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs b/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs index 77ebe6740c..eafbe75fbb 100644 --- a/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs +++ b/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs @@ -25,14 +25,13 @@ public sealed partial class ResearchConsoleMenu : FancyWindow [Dependency] private readonly IEntityManager _entity = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly IPlayerManager _player = default!; - private readonly TechnologyDatabaseComponent? _technologyDatabase; private readonly ResearchSystem _research; private readonly SpriteSystem _sprite; private readonly AccessReaderSystem _accessReader; - public readonly EntityUid Entity; + public EntityUid Entity; - public ResearchConsoleMenu(EntityUid entity) + public ResearchConsoleMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); @@ -40,21 +39,23 @@ public sealed partial class ResearchConsoleMenu : FancyWindow _research = _entity.System(); _sprite = _entity.System(); _accessReader = _entity.System(); - Entity = entity; ServerButton.OnPressed += _ => OnServerButtonPressed?.Invoke(); - - _entity.TryGetComponent(entity, out _technologyDatabase); } - public void UpdatePanels(ResearchConsoleBoundInterfaceState state) + public void SetEntity(EntityUid entity) + { + Entity = entity; + } + + public void UpdatePanels(ResearchConsoleBoundInterfaceState state) { TechnologyCardsContainer.Children.Clear(); var availableTech = _research.GetAvailableTechnologies(Entity); SyncTechnologyList(AvailableCardsContainer, availableTech); - if (_technologyDatabase == null) + if (!_entity.TryGetComponent(Entity, out TechnologyDatabaseComponent? database)) return; // i can't figure out the spacing so here you go @@ -66,7 +67,7 @@ public sealed partial class ResearchConsoleMenu : FancyWindow var hasAccess = _player.LocalEntity is not { } local || !_entity.TryGetComponent(Entity, out var access) || _accessReader.IsAllowed(local, Entity, access); - foreach (var techId in _technologyDatabase.CurrentTechnologyCards) + foreach (var techId in database.CurrentTechnologyCards) { var tech = _prototype.Index(techId); var cardControl = new TechnologyCardControl(tech, _prototype, _sprite, _research.GetTechnologyDescription(tech, includeTier: false), state.Points, hasAccess); @@ -74,7 +75,7 @@ public sealed partial class ResearchConsoleMenu : FancyWindow TechnologyCardsContainer.AddChild(cardControl); } - var unlockedTech = _technologyDatabase.UnlockedTechnologies.Select(x => _prototype.Index(x)); + var unlockedTech = database.UnlockedTechnologies.Select(x => _prototype.Index(x)); SyncTechnologyList(UnlockedCardsContainer, unlockedTech); } @@ -85,14 +86,14 @@ public sealed partial class ResearchConsoleMenu : FancyWindow ("points", state.Points))); ResearchAmountLabel.SetMessage(amountMsg); - if (_technologyDatabase == null) + if (!_entity.TryGetComponent(Entity, out TechnologyDatabaseComponent? database)) return; var disciplineText = Loc.GetString("research-discipline-none"); var disciplineColor = Color.Gray; - if (_technologyDatabase.MainDiscipline != null) + if (database.MainDiscipline != null) { - var discipline = _prototype.Index(_technologyDatabase.MainDiscipline); + var discipline = _prototype.Index(database.MainDiscipline); disciplineText = Loc.GetString(discipline.Name); disciplineColor = discipline.Color; } @@ -103,10 +104,10 @@ public sealed partial class ResearchConsoleMenu : FancyWindow MainDisciplineLabel.SetMessage(msg); TierDisplayContainer.Children.Clear(); - foreach (var disciplineId in _technologyDatabase.SupportedDisciplines) + foreach (var disciplineId in database.SupportedDisciplines) { var discipline = _prototype.Index(disciplineId); - var tier = _research.GetHighestDisciplineTier(_technologyDatabase, discipline); + var tier = _research.GetHighestDisciplineTier(database, discipline); // don't show tiers with no available tech if (tier == 0) diff --git a/Content.Client/Robotics/UI/RoboticsConsoleBoundUserInterface.cs b/Content.Client/Robotics/UI/RoboticsConsoleBoundUserInterface.cs index 6185979eee..9a5159880f 100644 --- a/Content.Client/Robotics/UI/RoboticsConsoleBoundUserInterface.cs +++ b/Content.Client/Robotics/UI/RoboticsConsoleBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Robotics; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Robotics.UI; @@ -16,7 +17,9 @@ public sealed class RoboticsConsoleBoundUserInterface : BoundUserInterface { base.Open(); - _window = new RoboticsConsoleWindow(Owner); + _window = this.CreateWindow(); + _window.SetEntity(Owner); + _window.OnDisablePressed += address => { SendMessage(new RoboticsConsoleDisableMessage(address)); @@ -25,9 +28,6 @@ public sealed class RoboticsConsoleBoundUserInterface : BoundUserInterface { SendMessage(new RoboticsConsoleDestroyMessage(address)); }; - _window.OnClose += Close; - - _window.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -37,14 +37,6 @@ public sealed class RoboticsConsoleBoundUserInterface : BoundUserInterface if (state is not RoboticsConsoleState cast) return; - _window?.UpdateState(cast); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - _window?.Dispose(); + _window.UpdateState(cast); } } diff --git a/Content.Client/Robotics/UI/RoboticsConsoleWindow.xaml.cs b/Content.Client/Robotics/UI/RoboticsConsoleWindow.xaml.cs index fc7b234bcc..87d7e62c39 100644 --- a/Content.Client/Robotics/UI/RoboticsConsoleWindow.xaml.cs +++ b/Content.Client/Robotics/UI/RoboticsConsoleWindow.xaml.cs @@ -23,11 +23,12 @@ public sealed partial class RoboticsConsoleWindow : FancyWindow public Action? OnDisablePressed; public Action? OnDestroyPressed; - private Entity _console; private string? _selected; private Dictionary _cyborgs = new(); - public RoboticsConsoleWindow(EntityUid console) + public EntityUid Entity; + + public RoboticsConsoleWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); @@ -35,9 +36,6 @@ public sealed partial class RoboticsConsoleWindow : FancyWindow _lock = _entMan.System(); _sprite = _entMan.System(); - _console = (console, _entMan.GetComponent(console), null); - _entMan.TryGetComponent(_console, out _console.Comp2); - Cyborgs.OnItemSelected += args => { if (Cyborgs[args.ItemIndex].Metadata is not string address) @@ -66,6 +64,11 @@ public sealed partial class RoboticsConsoleWindow : FancyWindow DestroyButton.StyleClasses.Add(StyleBase.ButtonCaution); } + public void SetEntity(EntityUid uid) + { + Entity = uid; + } + public void UpdateState(RoboticsConsoleState state) { _cyborgs = state.Cyborgs; @@ -81,7 +84,7 @@ public sealed partial class RoboticsConsoleWindow : FancyWindow PopulateData(); - var locked = _lock.IsLocked((_console, _console.Comp2)); + var locked = _lock.IsLocked(Entity); DangerZone.Visible = !locked; LockedMessage.Visible = locked; } @@ -135,13 +138,19 @@ public sealed partial class RoboticsConsoleWindow : FancyWindow // how the turntables DisableButton.Disabled = !(data.HasBrain && data.CanDisable); - DestroyButton.Disabled = _timing.CurTime < _console.Comp1.NextDestroy; } protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); - DestroyButton.Disabled = _timing.CurTime < _console.Comp1.NextDestroy; + if (_entMan.TryGetComponent(Entity, out RoboticsConsoleComponent? console)) + { + DestroyButton.Disabled = _timing.CurTime < console.NextDestroy; + } + else + { + DestroyButton.Disabled = true; + } } } diff --git a/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs b/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs index 8f1723d1f2..663bde15b0 100644 --- a/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs +++ b/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs @@ -30,17 +30,9 @@ public sealed class SalvageExpeditionConsoleBoundUserInterface : BoundUserInterf protected override void Open() { base.Open(); - _window = new OfferingWindow(); + _window = this.CreateWindow(); _window.Title = Loc.GetString("salvage-expedition-window-title"); - _window.OnClose += Close; - _window?.OpenCenteredLeft(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - _window?.Dispose(); - _window = null; + _window.OpenCenteredLeft(); } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Salvage/UI/SalvageMagnetBoundUserInterface.cs b/Content.Client/Salvage/UI/SalvageMagnetBoundUserInterface.cs index eafb692733..a248126a85 100644 --- a/Content.Client/Salvage/UI/SalvageMagnetBoundUserInterface.cs +++ b/Content.Client/Salvage/UI/SalvageMagnetBoundUserInterface.cs @@ -21,13 +21,9 @@ public sealed class SalvageMagnetBoundUserInterface : BoundUserInterface { base.Open(); - if (_window is null) - { - _window = new OfferingWindow(); - _window.Title = Loc.GetString("salvage-magnet-window-title"); - _window.OnClose += Close; - _window.OpenCenteredLeft(); - } + _window = this.CreateWindow(); + _window.Title = Loc.GetString("salvage-magnet-window-title"); + _window.OpenCenteredLeft(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -112,15 +108,4 @@ public sealed class SalvageMagnetBoundUserInterface : BoundUserInterface _window.AddOption(option); } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Close(); - _window?.Dispose(); - } - } } diff --git a/Content.Client/Shuttles/BUI/IFFConsoleBoundUserInterface.cs b/Content.Client/Shuttles/BUI/IFFConsoleBoundUserInterface.cs index 086369aa26..b8b4fb8a74 100644 --- a/Content.Client/Shuttles/BUI/IFFConsoleBoundUserInterface.cs +++ b/Content.Client/Shuttles/BUI/IFFConsoleBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Shuttles.BUIStates; using Content.Shared.Shuttles.Events; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Shuttles.BUI; @@ -20,8 +21,7 @@ public sealed class IFFConsoleBoundUserInterface : BoundUserInterface { base.Open(); - _window = new IFFConsoleWindow(); - _window.OnClose += Close; + _window = this.CreateWindow(); _window.ShowIFF += SendIFFMessage; _window.ShowVessel += SendVesselMessage; _window.OpenCenteredLeft(); diff --git a/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs b/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs index 4bd44a47a8..f75759b042 100644 --- a/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs +++ b/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Client.Shuttles.UI; using Content.Shared.Shuttles.BUIStates; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using RadarConsoleWindow = Content.Client.Shuttles.UI.RadarConsoleWindow; namespace Content.Client.Shuttles.BUI; @@ -20,18 +21,7 @@ public sealed class RadarConsoleBoundUserInterface : BoundUserInterface { base.Open(); - _window = new RadarConsoleWindow(); - _window.OnClose += Close; - _window.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (disposing) - { - _window?.Dispose(); - } + _window = this.CreateWindow(); } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs b/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs index af7b6055c8..e677181419 100644 --- a/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs +++ b/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Client.Shuttles.UI; using Content.Shared.Shuttles.BUIStates; using Content.Shared.Shuttles.Events; using JetBrains.Annotations; +using Robust.Client.UserInterface; using Robust.Shared.Map; namespace Content.Client.Shuttles.BUI; @@ -19,9 +20,7 @@ public sealed class ShuttleConsoleBoundUserInterface : BoundUserInterface protected override void Open() { base.Open(); - _window = new ShuttleConsoleWindow(); - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); _window.RequestFTL += OnFTLRequest; _window.RequestBeaconFTL += OnFTLBeaconRequest; diff --git a/Content.Client/Silicons/Borgs/BorgBoundUserInterface.cs b/Content.Client/Silicons/Borgs/BorgBoundUserInterface.cs index 3cc2a35d79..ed9bf40a48 100644 --- a/Content.Client/Silicons/Borgs/BorgBoundUserInterface.cs +++ b/Content.Client/Silicons/Borgs/BorgBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Silicons.Borgs; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Silicons.Borgs; @@ -18,9 +19,8 @@ public sealed class BorgBoundUserInterface : BoundUserInterface { base.Open(); - var owner = Owner; - - _menu = new BorgMenu(owner); + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); _menu.BrainButtonPressed += () => { @@ -41,10 +41,6 @@ public sealed class BorgBoundUserInterface : BoundUserInterface { SendMessage(new BorgRemoveModuleBuiMessage(EntMan.GetNetEntity(module))); }; - - _menu.OnClose += Close; - - _menu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -55,12 +51,4 @@ public sealed class BorgBoundUserInterface : BoundUserInterface return; _menu?.UpdateState(msg); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Dispose(); - } } diff --git a/Content.Client/Silicons/Borgs/BorgMenu.xaml b/Content.Client/Silicons/Borgs/BorgMenu.xaml index 7d8fd9fe57..4cc2e41a8f 100644 --- a/Content.Client/Silicons/Borgs/BorgMenu.xaml +++ b/Content.Client/Silicons/Borgs/BorgMenu.xaml @@ -10,7 +10,7 @@ VerticalExpand="True"> - + diff --git a/Content.Client/Silicons/Borgs/BorgMenu.xaml.cs b/Content.Client/Silicons/Borgs/BorgMenu.xaml.cs index 474a83b453..f6a861aa05 100644 --- a/Content.Client/Silicons/Borgs/BorgMenu.xaml.cs +++ b/Content.Client/Silicons/Borgs/BorgMenu.xaml.cs @@ -21,25 +21,33 @@ public sealed partial class BorgMenu : FancyWindow public Action? NameChanged; public Action? RemoveModuleButtonPressed; - private readonly BorgChassisComponent? _chassis; - public readonly EntityUid Entity; public float AccumulatedTime; private string _lastValidName; private List _modules = new(); - public BorgMenu(EntityUid entity) + public EntityUid Entity; + + public BorgMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); + _lastValidName = NameLineEdit.Text; + + EjectBatteryButton.OnPressed += _ => EjectBatteryButtonPressed?.Invoke(); + BrainButton.OnPressed += _ => BrainButtonPressed?.Invoke(); + + NameLineEdit.OnTextChanged += OnNameChanged; + NameLineEdit.OnTextEntered += OnNameEntered; + NameLineEdit.OnFocusExit += OnNameFocusExit; + + UpdateBrainButton(); + } + + public void SetEntity(EntityUid entity) + { Entity = entity; - - if (_entity.TryGetComponent(Entity, out var chassis)) - _chassis = chassis; - BorgSprite.SetEntity(entity); - ChargeBar.MaxValue = 1f; - ChargeBar.Value = 1f; if (_entity.TryGetComponent(Entity, out var nameIdentifierComponent)) { @@ -55,17 +63,6 @@ public sealed partial class BorgMenu : FancyWindow NameIdentifierLabel.Visible = false; NameLineEdit.Text = _entity.GetComponent(Entity).EntityName; } - - _lastValidName = NameLineEdit.Text; - - EjectBatteryButton.OnPressed += _ => EjectBatteryButtonPressed?.Invoke(); - BrainButton.OnPressed += _ => BrainButtonPressed?.Invoke(); - - NameLineEdit.OnTextChanged += OnNameChanged; - NameLineEdit.OnTextEntered += OnNameEntered; - NameLineEdit.OnFocusExit += OnNameFocusExit; - - UpdateBrainButton(); } protected override void FrameUpdate(FrameEventArgs args) @@ -89,7 +86,7 @@ public sealed partial class BorgMenu : FancyWindow private void UpdateBrainButton() { - if (_chassis?.BrainEntity is { } brain) + if (_entity.TryGetComponent(Entity, out BorgChassisComponent? chassis) && chassis.BrainEntity is { } brain) { BrainButton.Text = _entity.GetComponent(brain).EntityName; BrainView.Visible = true; @@ -108,17 +105,17 @@ public sealed partial class BorgMenu : FancyWindow private void UpdateModulePanel() { - if (_chassis == null) + if (!_entity.TryGetComponent(Entity, out BorgChassisComponent? chassis)) return; ModuleCounter.Text = Loc.GetString("borg-ui-module-counter", - ("actual", _chassis.ModuleCount), - ("max", _chassis.MaxModules)); + ("actual", chassis.ModuleCount), + ("max", chassis.MaxModules)); - if (_chassis.ModuleContainer.Count == _modules.Count) + if (chassis.ModuleContainer.Count == _modules.Count) { var isSame = true; - foreach (var module in _chassis.ModuleContainer.ContainedEntities) + foreach (var module in chassis.ModuleContainer.ContainedEntities) { if (_modules.Contains(module)) continue; @@ -132,7 +129,7 @@ public sealed partial class BorgMenu : FancyWindow ModuleContainer.Children.Clear(); _modules.Clear(); - foreach (var module in _chassis.ModuleContainer.ContainedEntities) + foreach (var module in chassis.ModuleContainer.ContainedEntities) { var control = new BorgModuleControl(module, _entity); control.RemoveButtonPressed += () => diff --git a/Content.Client/Silicons/Laws/Ui/SiliconLawBoundUserInterface.cs b/Content.Client/Silicons/Laws/Ui/SiliconLawBoundUserInterface.cs index d150735fa1..56216b9184 100644 --- a/Content.Client/Silicons/Laws/Ui/SiliconLawBoundUserInterface.cs +++ b/Content.Client/Silicons/Laws/Ui/SiliconLawBoundUserInterface.cs @@ -2,6 +2,7 @@ using System.Linq; using Content.Shared.Silicons.Laws; using Content.Shared.Silicons.Laws.Components; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Silicons.Laws.Ui; @@ -22,18 +23,7 @@ public sealed class SiliconLawBoundUserInterface : BoundUserInterface { base.Open(); - _menu = new(); - - _menu.OnClose += Close; - _menu.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Close(); + _menu = this.CreateWindow(); } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs b/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs index e8442d2390..7d6a6cf2a5 100644 --- a/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs +++ b/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs @@ -1,6 +1,6 @@ using Content.Shared.SprayPainter; using Content.Shared.SprayPainter.Components; -using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; namespace Content.Client.SprayPainter.UI; @@ -10,9 +10,6 @@ public sealed class SprayPainterBoundUserInterface : BoundUserInterface [ViewVariables] private SprayPainterWindow? _window; - [ViewVariables] - private SprayPainterSystem? _painter; - public SprayPainterBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -21,27 +18,15 @@ public sealed class SprayPainterBoundUserInterface : BoundUserInterface { base.Open(); - if (!EntMan.TryGetComponent(Owner, out var comp)) - return; + _window = this.CreateWindow(); - _window = new SprayPainterWindow(); - - _painter = EntMan.System(); - - _window.OnClose += Close; _window.OnSpritePicked = OnSpritePicked; _window.OnColorPicked = OnColorPicked; - _window.Populate(_painter.Entries, comp.Index, comp.PickedColor, comp.ColorPalette); - - _window.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - _window?.Dispose(); + if (EntMan.TryGetComponent(Owner, out SprayPainterComponent? comp)) + { + _window.Populate(EntMan.System().Entries, comp.Index, comp.PickedColor, comp.ColorPalette); + } } private void OnSpritePicked(ItemList.ItemListSelectedEventArgs args) diff --git a/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs b/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs index 720a2efb9d..e7bab71e38 100644 --- a/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs +++ b/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs @@ -1,4 +1,5 @@ using Content.Shared.StationRecords; +using Robust.Client.UserInterface; namespace Content.Client.StationRecords; @@ -15,15 +16,12 @@ public sealed class GeneralStationRecordConsoleBoundUserInterface : BoundUserInt { base.Open(); - _window = new(); + _window = this.CreateWindow(); _window.OnKeySelected += key => SendMessage(new SelectStationRecord(key)); _window.OnFiltersChanged += (type, filterValue) => SendMessage(new SetStationRecordFilter(type, filterValue)); _window.OnDeleted += id => SendMessage(new DeleteStationRecord(id)); - _window.OnClose += Close; - - _window.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -35,11 +33,4 @@ public sealed class GeneralStationRecordConsoleBoundUserInterface : BoundUserInt _window?.UpdateState(cast); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - _window?.Close(); - } } diff --git a/Content.Client/Store/Ui/StoreBoundUserInterface.cs b/Content.Client/Store/Ui/StoreBoundUserInterface.cs index 0010aedd96..7ed67f7b5d 100644 --- a/Content.Client/Store/Ui/StoreBoundUserInterface.cs +++ b/Content.Client/Store/Ui/StoreBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Store; using JetBrains.Annotations; using System.Linq; using Content.Shared.Store.Components; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Store.Ui; @@ -26,13 +27,10 @@ public sealed class StoreBoundUserInterface : BoundUserInterface protected override void Open() { - _menu = new StoreMenu(); + _menu = this.CreateWindow(); if (EntMan.TryGetComponent(Owner, out var store)) _menu.Title = Loc.GetString(store.Name); - _menu.OpenCentered(); - _menu.OnClose += Close; - _menu.OnListingButtonPressed += (_, listing) => { SendMessage(new StoreBuyListingMessage(listing)); @@ -77,15 +75,6 @@ public sealed class StoreBoundUserInterface : BoundUserInterface } } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Close(); - _menu?.Dispose(); - } - private void UpdateListingsWithSearchFilter() { if (_menu == null) diff --git a/Content.Client/Strip/StrippingMenu.cs b/Content.Client/Strip/StrippingMenu.cs index eea867b794..1c46b4be35 100644 --- a/Content.Client/Strip/StrippingMenu.cs +++ b/Content.Client/Strip/StrippingMenu.cs @@ -1,4 +1,3 @@ -using Content.Client.Inventory; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; using Robust.Shared.Timing; @@ -11,14 +10,12 @@ namespace Content.Client.Strip public LayoutContainer InventoryContainer = new(); public BoxContainer HandsContainer = new() { Orientation = LayoutOrientation.Horizontal }; public BoxContainer SnareContainer = new(); - private StrippableBoundUserInterface _bui; public bool Dirty = true; - public StrippingMenu(string title, StrippableBoundUserInterface bui) - { - Title = title; - _bui = bui; + public event Action? OnDirty; + public StrippingMenu() + { var box = new BoxContainer() { Orientation = LayoutOrientation.Vertical, Margin = new Thickness(0, 8) }; Contents.AddChild(box); box.AddChild(SnareContainer); @@ -39,7 +36,7 @@ namespace Content.Client.Strip return; Dirty = false; - _bui.UpdateMenu(); + OnDirty?.Invoke(); } } } diff --git a/Content.Client/SurveillanceCamera/UI/SurveillanceCameraMonitorBoundUi.cs b/Content.Client/SurveillanceCamera/UI/SurveillanceCameraMonitorBoundUi.cs index 9132dd6ed5..e3646c00cc 100644 --- a/Content.Client/SurveillanceCamera/UI/SurveillanceCameraMonitorBoundUi.cs +++ b/Content.Client/SurveillanceCamera/UI/SurveillanceCameraMonitorBoundUi.cs @@ -1,6 +1,7 @@ using Content.Client.Eye; using Content.Shared.SurveillanceCamera; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.SurveillanceCamera.UI; @@ -25,20 +26,12 @@ public sealed class SurveillanceCameraMonitorBoundUserInterface : BoundUserInter { base.Open(); - _window = new SurveillanceCameraMonitorWindow(); - - if (State != null) - { - UpdateState(State); - } - - _window.OpenCentered(); + _window = this.CreateWindow(); _window.CameraSelected += OnCameraSelected; _window.SubnetOpened += OnSubnetRequest; _window.CameraRefresh += OnCameraRefresh; _window.SubnetRefresh += OnSubnetRefresh; - _window.OnClose += Close; _window.CameraSwitchTimer += OnCameraSwitchTimer; _window.CameraDisconnect += OnCameraDisconnect; } diff --git a/Content.Client/Thief/ThiefBackpackBoundUserInterface.cs b/Content.Client/Thief/ThiefBackpackBoundUserInterface.cs index 37384daafe..0631d98993 100644 --- a/Content.Client/Thief/ThiefBackpackBoundUserInterface.cs +++ b/Content.Client/Thief/ThiefBackpackBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Thief; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Thief; @@ -15,21 +16,9 @@ public sealed class ThiefBackpackBoundUserInterface : BoundUserInterface { base.Open(); - _window = new ThiefBackpackMenu(this); - _window.OnClose += Close; - _window.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - if (_window != null) - _window.OnClose -= Close; - - _window?.Dispose(); + _window = this.CreateWindow(); + _window.OnApprove += SendApprove; + _window.OnSetChange += SendChangeSelected; } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Thief/ThiefBackpackMenu.xaml.cs b/Content.Client/Thief/ThiefBackpackMenu.xaml.cs index 543772c704..aaee357617 100644 --- a/Content.Client/Thief/ThiefBackpackMenu.xaml.cs +++ b/Content.Client/Thief/ThiefBackpackMenu.xaml.cs @@ -12,46 +12,42 @@ public sealed partial class ThiefBackpackMenu : FancyWindow [Dependency] private readonly IEntitySystemManager _sysMan = default!; private readonly SpriteSystem _spriteSystem; - private readonly ThiefBackpackBoundUserInterface _owner; + public event Action? OnApprove; + public event Action? OnSetChange; - public ThiefBackpackMenu(ThiefBackpackBoundUserInterface owner) + public ThiefBackpackMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); _spriteSystem = _sysMan.GetEntitySystem(); - _owner = owner; - - ApproveButton.OnButtonDown += (args) => + ApproveButton.OnPressed += args => { - _owner.SendApprove(); + OnApprove?.Invoke(); }; } public void UpdateState(ThiefBackpackBoundUserInterfaceState state) { - SetsGrid.RemoveAllChildren(); - int count = 0; - int selectedNumber = 0; - foreach (var set in state.Sets) + SetsGrid.DisposeAllChildren(); + var selectedNumber = 0; + foreach (var (set, info) in state.Sets) { - var child = new ThiefBackpackSet(set.Value, _spriteSystem); + var child = new ThiefBackpackSet(info, _spriteSystem); child.SetButton.OnButtonDown += (args) => { - _owner.SendChangeSelected(set.Key); + OnSetChange?.Invoke(set); }; SetsGrid.AddChild(child); - count++; - - if (set.Value.Selected) + if (info.Selected) selectedNumber++; } Description.Text = Loc.GetString("thief-backpack-window-description", ("maxCount", state.MaxSelectedSets)); SelectedSets.Text = Loc.GetString("thief-backpack-window-selected", ("selectedCount", selectedNumber), ("maxCount", state.MaxSelectedSets)); - ApproveButton.Disabled = selectedNumber == state.MaxSelectedSets ? false : true; + ApproveButton.Disabled = selectedNumber != state.MaxSelectedSets; } } diff --git a/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankBoundUserInterface.cs b/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankBoundUserInterface.cs index 4702f8f365..4ae74a5d65 100644 --- a/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankBoundUserInterface.cs +++ b/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankBoundUserInterface.cs @@ -1,5 +1,7 @@ using Content.Shared.Atmos.Components; using JetBrains.Annotations; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.UserInterface.Systems.Atmos.GasTank { @@ -13,7 +15,7 @@ namespace Content.Client.UserInterface.Systems.Atmos.GasTank { } - public void SetOutputPressure(in float value) + public void SetOutputPressure(float value) { SendMessage(new GasTankSetPressureMessage { @@ -29,9 +31,10 @@ namespace Content.Client.UserInterface.Systems.Atmos.GasTank protected override void Open() { base.Open(); - _window = new GasTankWindow(this, EntMan.GetComponent(Owner).EntityName); - _window.OnClose += Close; - _window.OpenCentered(); + _window = this.CreateWindow(); + _window.SetTitle(EntMan.GetComponent(Owner).EntityName); + _window.OnOutputPressure += SetOutputPressure; + _window.OnToggleInternals += ToggleInternals; } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankWindow.cs b/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankWindow.cs index c23850a650..fd5624ad8a 100644 --- a/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankWindow.cs +++ b/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankWindow.cs @@ -15,23 +15,29 @@ namespace Content.Client.UserInterface.Systems.Atmos.GasTank; public sealed class GasTankWindow : BaseWindow { + [Dependency] private readonly IResourceCache _cache = default!; + private readonly RichTextLabel _lblPressure; private readonly FloatSpinBox _spbPressure; private readonly RichTextLabel _lblInternals; private readonly Button _btnInternals; + private readonly Label _topLabel; - public GasTankWindow(GasTankBoundUserInterface owner, string uidName) + public event Action? OnOutputPressure; + public event Action? OnToggleInternals; + + public GasTankWindow() { + IoCManager.InjectDependencies(this); Control contentContainer; BoxContainer topContainer; TextureButton btnClose; - var resourceCache = IoCManager.Resolve(); var rootContainer = new LayoutContainer { Name = "GasTankRoot" }; AddChild(rootContainer); MouseFilter = MouseFilterMode.Stop; - var panelTex = resourceCache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); + var panelTex = _cache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); var back = new StyleBoxTexture { Texture = panelTex, @@ -78,7 +84,17 @@ public sealed class GasTankWindow LayoutContainer.SetAnchorPreset(topContainerWrap, LayoutContainer.LayoutPreset.Wide); - var font = resourceCache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); + var font = _cache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); + + _topLabel = new Label + { + FontOverride = font, + FontColorOverride = StyleNano.NanoGold, + VerticalAlignment = VAlignment.Center, + HorizontalExpand = true, + HorizontalAlignment = HAlignment.Left, + Margin = new Thickness(0, 0, 20, 0), + }; var topRow = new BoxContainer { @@ -86,16 +102,7 @@ public sealed class GasTankWindow Margin = new Thickness(4, 2, 12, 2), Children = { - (new Label - { - Text = uidName, - FontOverride = font, - FontColorOverride = StyleNano.NanoGold, - VerticalAlignment = VAlignment.Center, - HorizontalExpand = true, - HorizontalAlignment = HAlignment.Left, - Margin = new Thickness(0, 0, 20, 0), - }), + _topLabel, (btnClose = new TextureButton { StyleClasses = {DefaultWindow.StyleClassWindowCloseButton}, @@ -168,17 +175,22 @@ public sealed class GasTankWindow // Handlers _spbPressure.OnValueChanged += args => { - owner.SetOutputPressure(args.Value); + OnOutputPressure?.Invoke(args.Value); }; _btnInternals.OnPressed += args => { - owner.ToggleInternals(); + OnToggleInternals?.Invoke(); }; btnClose.OnPressed += _ => Close(); } + public void SetTitle(string name) + { + _topLabel.Text = name; + } + public void UpdateState(GasTankBoundUserInterfaceState state) { _lblPressure.SetMarkup(Loc.GetString("gas-tank-window-tank-pressure-text", ("tankPressure", $"{state.TankPressure:0.##}"))); diff --git a/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs b/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs index 17ddba77ff..eafab84ed6 100644 --- a/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs +++ b/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Client.VendingMachines.UI; using Content.Shared.VendingMachines; using Robust.Client.UserInterface.Controls; using System.Linq; +using Robust.Client.UserInterface; namespace Content.Client.VendingMachines { @@ -28,15 +29,14 @@ namespace Content.Client.VendingMachines _cachedInventory = vendingMachineSys.GetAllInventory(Owner); - _menu = new VendingMachineMenu { Title = EntMan.GetComponent(Owner).EntityName }; + _menu = this.CreateWindow(); + _menu.OpenCenteredLeft(); + _menu.Title = EntMan.GetComponent(Owner).EntityName; - _menu.OnClose += Close; _menu.OnItemSelected += OnItemSelected; _menu.OnSearchChanged += OnSearchChanged; _menu.Populate(_cachedInventory, out _cachedFilteredIndex); - - _menu.OpenCenteredLeft(); } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs b/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs index f700c6663b..891804674d 100644 --- a/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs +++ b/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs @@ -1,12 +1,13 @@ using Content.Shared.VoiceMask; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.VoiceMask; public sealed class VoiceMaskBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IPrototypeManager _proto = default!; + [Dependency] private readonly IPrototypeManager _protomanager = default!; [ViewVariables] private VoiceMaskNameChangeWindow? _window; @@ -19,12 +20,11 @@ public sealed class VoiceMaskBoundUserInterface : BoundUserInterface { base.Open(); - _window = new(_proto); + _window = this.CreateWindow(); + _window.ReloadVerbs(_protomanager); - _window.OpenCentered(); _window.OnNameChange += OnNameSelected; _window.OnVerbChange += verb => SendMessage(new VoiceMaskChangeVerbMessage(verb)); - _window.OnClose += Close; } private void OnNameSelected(string name) diff --git a/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs b/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs index 16a28f9d9b..0dc41f807a 100644 --- a/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs +++ b/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs @@ -17,7 +17,7 @@ public sealed partial class VoiceMaskNameChangeWindow : FancyWindow private string? _verb; - public VoiceMaskNameChangeWindow(IPrototypeManager proto) + public VoiceMaskNameChangeWindow() { RobustXamlLoader.Load(this); @@ -32,12 +32,10 @@ public sealed partial class VoiceMaskNameChangeWindow : FancyWindow SpeechVerbSelector.SelectId(args.Id); }; - ReloadVerbs(proto); - AddVerbs(); } - private void ReloadVerbs(IPrototypeManager proto) + public void ReloadVerbs(IPrototypeManager proto) { foreach (var verb in proto.EnumeratePrototypes()) { diff --git a/Content.Client/Weapons/Melee/UI/MeleeSpeechBoundUserInterface.cs b/Content.Client/Weapons/Melee/UI/MeleeSpeechBoundUserInterface.cs index f3e0c0a539..3f01808c42 100644 --- a/Content.Client/Weapons/Melee/UI/MeleeSpeechBoundUserInterface.cs +++ b/Content.Client/Weapons/Melee/UI/MeleeSpeechBoundUserInterface.cs @@ -1,5 +1,6 @@ using Robust.Client.GameObjects; using Content.Shared.Speech.Components; +using Robust.Client.UserInterface; namespace Content.Client.Weapons.Melee.UI; @@ -19,17 +20,10 @@ public sealed class MeleeSpeechBoundUserInterface : BoundUserInterface { base.Open(); - _window = new MeleeSpeechWindow(); - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.OnBattlecryEntered += OnBattlecryChanged; } - private void OnBattlecryChanged(string newBattlecry) { SendMessage(new MeleeSpeechBattlecryChangedMessage(newBattlecry)); diff --git a/Content.Client/Wires/UI/WiresBoundUserInterface.cs b/Content.Client/Wires/UI/WiresBoundUserInterface.cs index 5a8869a204..edf1a2d377 100644 --- a/Content.Client/Wires/UI/WiresBoundUserInterface.cs +++ b/Content.Client/Wires/UI/WiresBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Wires; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Wires.UI { @@ -15,10 +16,8 @@ namespace Content.Client.Wires.UI protected override void Open() { base.Open(); - - _menu = new WiresMenu(this); - _menu.OnClose += Close; - _menu.OpenCenteredLeft(); + _menu = this.CreateWindow(); + _menu.OnAction += PerformAction; } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Wires/UI/WiresMenu.cs b/Content.Client/Wires/UI/WiresMenu.cs index 7bccc20861..eccc548297 100644 --- a/Content.Client/Wires/UI/WiresMenu.cs +++ b/Content.Client/Wires/UI/WiresMenu.cs @@ -1,4 +1,3 @@ -using System; using System.Numerics; using Content.Client.Examine; using Content.Client.Resources; @@ -12,10 +11,6 @@ using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; using Robust.Shared.Animations; using Robust.Shared.Input; -using Robust.Shared.IoC; -using Robust.Shared.Localization; -using Robust.Shared.Maths; -using Robust.Shared.Random; using static Robust.Client.UserInterface.Controls.BoxContainer; namespace Content.Client.Wires.UI @@ -24,8 +19,6 @@ namespace Content.Client.Wires.UI { [Dependency] private readonly IResourceCache _resourceCache = default!; - public WiresBoundUserInterface Owner { get; } - private readonly Control _wiresHBox; private readonly Control _topContainer; private readonly Control _statusContainer; @@ -35,11 +28,12 @@ namespace Content.Client.Wires.UI public TextureButton CloseButton { get; set; } - public WiresMenu(WiresBoundUserInterface owner) + public event Action? OnAction; + + public WiresMenu() { IoCManager.InjectDependencies(this); - Owner = owner; var rootContainer = new LayoutContainer {Name = "WireRoot"}; AddChild(rootContainer); @@ -257,12 +251,12 @@ namespace Content.Client.Wires.UI control.WireClicked += () => { - Owner.PerformAction(wire.Id, wire.IsCut ? WiresAction.Mend : WiresAction.Cut); + OnAction?.Invoke(wire.Id, wire.IsCut ? WiresAction.Mend : WiresAction.Cut); }; control.ContactsClicked += () => { - Owner.PerformAction(wire.Id, WiresAction.Pulse); + OnAction?.Invoke(wire.Id, WiresAction.Pulse); }; } diff --git a/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleBoundUserInterface.cs b/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleBoundUserInterface.cs index 2538caf6eb..c7a74815b6 100644 --- a/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleBoundUserInterface.cs +++ b/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Xenoarchaeology.Equipment; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Xenoarchaeology.Ui; @@ -18,10 +19,7 @@ public sealed class AnalysisConsoleBoundUserInterface : BoundUserInterface { base.Open(); - _consoleMenu = new AnalysisConsoleMenu(); - - _consoleMenu.OnClose += Close; - _consoleMenu.OpenCentered(); + _consoleMenu = this.CreateWindow(); _consoleMenu.OnServerSelectionButtonPressed += () => {