Device network DeviceLists and the NetworkConfigurator (Makes air alarms usable) (#7697)

* Implement DeviceList
Implement NetworkConfigurator
I sould really get into the habit of making smaller commits

* Remove ApcNetworkComponent from vents, scrubbers anf firelocks

* Change BeforeBroadcastAttemptEvent#Recepients to readonly IReadonlySet and add a ModifiedRecepients field

* Address revievs in NetworkConfigurationSystem

* Fix red and green button styles

* Change NetworkConfiguratorSystem#UpdateState to remove saved entites that don't exist anymore

* Add AtmosDevices device net id

* Add const strings for style classes
Fix wrong margin for NetworkConfiguratorConfigurationMenu

* Hello? Github?

* Add access check before opening the configuration ui

* Address reviews

* Fix call to access reader

* You shall not live again IgnoreComponent

* Fix interaction verb check

* Fix configuration window not closing when target gets deleted / out of range

* Change device is already saved message to say 'network device: ... is already saves'

* Apply suggestions from code review

Co-authored-by: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com>

* Fix applied suggestion

Co-authored-by: wrexbe <81056464+wrexbe@users.noreply.github.com>
Co-authored-by: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com>
This commit is contained in:
Julian Giebel
2022-06-10 03:28:24 +02:00
committed by GitHub
parent 0fc8c0ef5e
commit f4be8b5793
20 changed files with 836 additions and 14 deletions

View File

@@ -0,0 +1,73 @@
using Content.Shared.DeviceNetwork;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
namespace Content.Client.NetworkConfigurator;
public sealed class NetworkConfiguratorBoundUserInterface : BoundUserInterface
{
private NetworkConfiguratorListMenu? _listMenu;
private NetworkConfiguratorConfigurationMenu? _configurationMenu;
public NetworkConfiguratorBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
{
}
public void OnRemoveButtonPressed(string address)
{
SendMessage(new NetworkConfiguratorRemoveDeviceMessage(address));
}
protected override void Open()
{
base.Open();
switch (UiKey)
{
case NetworkConfiguratorUiKey.List:
_listMenu = new NetworkConfiguratorListMenu(this);
_listMenu.OnClose += Close;
_listMenu.ClearButton.OnPressed += _ => OnClearButtonPressed();
_listMenu.OpenCentered();
break;
case NetworkConfiguratorUiKey.Configure:
_configurationMenu = new NetworkConfiguratorConfigurationMenu();
_configurationMenu.OnClose += Close;
_configurationMenu.Set.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Set);
_configurationMenu.Add.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Add);
//_configurationMenu.Edit.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Edit);
_configurationMenu.Clear.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Clear);
_configurationMenu.Copy.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Copy);
_configurationMenu.Show.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Show);
_configurationMenu.OpenCentered();
break;
}
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
var castState = (NetworkConfiguratorUserInterfaceState) state;
_listMenu?.UpdateState(castState);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing) return;
_listMenu?.Dispose();
_configurationMenu?.Dispose();
}
private void OnClearButtonPressed()
{
SendMessage(new NetworkConfiguratorClearDevicesMessage());
}
private void OnConfigButtonPressed(NetworkConfiguratorButtonKey buttonKey)
{
SendMessage(new NetworkConfiguratorButtonPressedMessage(buttonKey));
}
}

View File

@@ -0,0 +1,17 @@
<ui:FancyWindow xmlns="https://spacestation14.io"
xmlns:ui="clr-namespace:Content.Client.UserInterface"
Title="Network Configurator" MinSize="350 100">
<BoxContainer Orientation="Vertical" VerticalExpand="True" HorizontalExpand="True">
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="8 8 8 1">
<Button Name="Set" Text="Set" Access="Public" ToolTip="{Loc 'network-configurator-tooltip-set'}" HorizontalExpand="True" StyleClasses="ButtonSquare"/>
<Button Name="Add" Text="Add" Access="Public" ToolTip="{Loc 'network-configurator-tooltip-add'}" HorizontalExpand="True" StyleClasses="ButtonSquare"/>
<!-- Edit might not be needed -->
<!--<Button Name="Edit" Text="Edit" Access="Public" ToolTip="{Loc 'network-configurator-tooltip-edit'}" HorizontalExpand="True" StyleClasses="ButtonSquare"/>-->
<Button Name="Clear" Text="Clear" Access="Public" ToolTip="{Loc 'network-configurator-tooltip-clear'}" HorizontalExpand="True"/>
</BoxContainer>
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="8 0 8 8">
<Button Name="Copy" Text="Copy" Access="Public" ToolTip="{Loc 'network-configurator-tooltip-copy'}" HorizontalExpand="True" StyleClasses="OpenRight"/>
<Button Name="Show" Text="Show" Access="Public" Disabled="True" ToolTip="{Loc 'network-configurator-tooltip-show'}" HorizontalExpand="True" StyleClasses="ButtonSquare"/>
</BoxContainer>
</BoxContainer>
</ui:FancyWindow>

View File

@@ -0,0 +1,22 @@
using Content.Client.Stylesheets;
using Content.Client.UserInterface;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Client.Graphics;
namespace Content.Client.NetworkConfigurator;
[GenerateTypedNameReferences]
public sealed partial class NetworkConfiguratorConfigurationMenu : FancyWindow
{
public NetworkConfiguratorConfigurationMenu()
{
RobustXamlLoader.Load(this);
Clear.StyleClasses.Add(StyleBase.ButtonOpenLeft);
Clear.StyleClasses.Add(StyleNano.StyleClassButtonColorRed);
}
}

View File

@@ -0,0 +1,18 @@
<ui:FancyWindow xmlns="https://spacestation14.io"
xmlns:ui="clr-namespace:Content.Client.UserInterface"
Title="Network Configurator" MinSize="220 400">
<BoxContainer Orientation="Vertical" VerticalExpand="True">
<ScrollContainer HorizontalExpand="True" VerticalExpand="True">
<Control VerticalExpand="True">
<PanelContainer StyleClasses="PanelBackgroundBaseDark"></PanelContainer>
<BoxContainer Orientation="Vertical" Name="DeviceList" VerticalExpand="True" SeparationOverride="4">
</BoxContainer>
</Control>
</ScrollContainer>
<BoxContainer Orientation="Horizontal" Margin="8 8 8 8">
<Label Name="DeviceCountLabel" Margin="16 0 0 0" MaxWidth="64"></Label>
<Control HorizontalExpand="True" />
<Button Name="ClearButton" Access="Public" Text="{Loc 'network-configurator-ui-clear-button'}"></Button>
</BoxContainer>
</BoxContainer>
</ui:FancyWindow>

View File

@@ -0,0 +1,67 @@
using Content.Client.UserInterface;
using Content.Shared.DeviceNetwork;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
namespace Content.Client.NetworkConfigurator;
[GenerateTypedNameReferences]
public sealed partial class NetworkConfiguratorListMenu : FancyWindow
{
private readonly NetworkConfiguratorBoundUserInterface _ui;
public NetworkConfiguratorListMenu(NetworkConfiguratorBoundUserInterface ui)
{
RobustXamlLoader.Load(this);
_ui = ui;
}
public void UpdateState(NetworkConfiguratorUserInterfaceState state)
{
DeviceCountLabel.Text = Loc.GetString("network-configurator-ui-count-label", ("count", state.DeviceList.Count));
DeviceList.RemoveAllChildren();
foreach (var savedDevice in state.DeviceList)
{
DeviceList.AddChild(BuildDeviceListRow(savedDevice));
}
}
private BoxContainer BuildDeviceListRow((string address, string name) savedDevice)
{
var row = new BoxContainer()
{
Orientation = BoxContainer.LayoutOrientation.Horizontal,
Margin = new Thickness(8)
};
var name = new Label()
{
Text = savedDevice.name[..Math.Min(11, savedDevice.name.Length)],
SetWidth = 84
};
var address = new Label()
{
Text = savedDevice.address,
HorizontalExpand = true,
Align = Label.AlignMode.Center
};
var removeButton = new TextureButton()
{
StyleClasses = { "CrossButtonRed" },
VerticalAlignment = VAlignment.Center,
Scale = new Vector2(0.5f, 0.5f)
};
removeButton.OnPressed += _ => _ui.OnRemoveButtonPressed(savedDevice.address);
row.AddChild(name);
row.AddChild(address);
row.AddChild(removeButton);
return row;
}
}

View File

@@ -39,6 +39,7 @@ namespace Content.Client.Stylesheets
}
}
public sealed class StyleNano : StyleBase
{
public const string StyleClassBorderedWindowPanel = "BorderedWindowPanel";
@@ -93,6 +94,9 @@ namespace Content.Client.Stylesheets
public static readonly Color ButtonColorCautionPressed = Color.FromHex("#3e6c45");
public static readonly Color ButtonColorCautionDisabled = Color.FromHex("#602a2a");
public static readonly Color ButtonColorGoodDefault = Color.FromHex("#3E6C45");
public static readonly Color ButtonColorGoodHovered = Color.FromHex("#31843E");
// Context menu button colors
public static readonly Color ButtonColorContext = Color.FromHex("#1119");
public static readonly Color ButtonColorContextHover = Color.DarkSlateGray;
@@ -112,6 +116,14 @@ namespace Content.Client.Stylesheets
public const string StyleClassItemStatus = "ItemStatus";
//Background
public const string StyleClassBackgroundBaseDark = "PanelBackgroundBaseDark";
//Buttons
public const string StyleClassCrossButtonRed = "CrossButtonRed";
public const string StyleClassButtonColorRed = "ButtonColorRed";
public const string StyleClassButtonColorGreen = "ButtonColorGreen";
public override Stylesheet Stylesheet { get; }
public StyleNano(IResourceCache resCache) : base(resCache)
@@ -461,7 +473,7 @@ namespace Content.Client.Stylesheets
var directionIconArrowTex = resCache.GetTexture("/Textures/Interface/VerbIcons/drop.svg.192dpi.png");
var directionIconQuestionTex = resCache.GetTexture("/Textures/Interface/VerbIcons/information.svg.192dpi.png");
var directionIconHereTex = resCache.GetTexture("/Textures/Interface/VerbIcons/dot.svg.192dpi.png");
Stylesheet = new Stylesheet(BaseRules.Concat(new[]
{
// Window title.
@@ -1294,8 +1306,47 @@ namespace Content.Client.Stylesheets
.Prop("panel", new StyleBoxTexture(BaseButtonOpenLeft) { Padding = default })
.Prop(Control.StylePropertyModulateSelf, Color.FromHex("#1F1F23")),
Element<PanelContainer>().Class("Inset")
.Prop("panel", insetBack),
Element<PanelContainer>().Class("WindowHeadingBackgroundLight")
.Prop("panel", new StyleBoxTexture(BaseButtonOpenLeft) { Padding = default }),
//The lengths you have to go through to change a background color smh
Element<PanelContainer>().Class("PanelBackgroundBaseDark")
.Prop("panel", new StyleBoxTexture(BaseButtonOpenBoth) { Padding = default })
.Prop(Control.StylePropertyModulateSelf, Color.FromHex("#1F1F23")),
// X Texture button ---
Element<TextureButton>().Class("CrossButtonRed")
.Prop(TextureButton.StylePropertyTexture, resCache.GetTexture("/Textures/Interface/Nano/cross.svg.png"))
.Prop(Control.StylePropertyModulateSelf, DangerousRedFore),
Element<TextureButton>().Class("CrossButtonRed").Pseudo(TextureButton.StylePseudoClassHover)
.Prop(Control.StylePropertyModulateSelf, Color.FromHex("#7F3636")),
Element<TextureButton>().Class("CrossButtonRed").Pseudo(TextureButton.StylePseudoClassHover)
.Prop(Control.StylePropertyModulateSelf, Color.FromHex("#753131")),
// ---
// Red Button ---
Element<Button>().Class("ButtonColorRed")
.Prop(Control.StylePropertyModulateSelf, ButtonColorDefaultRed),
Element<Button>().Class("ButtonColorRed").Pseudo(ContainerButton.StylePseudoClassNormal)
.Prop(Control.StylePropertyModulateSelf, ButtonColorDefaultRed),
Element<Button>().Class("ButtonColorRed").Pseudo(ContainerButton.StylePseudoClassHover)
.Prop(Control.StylePropertyModulateSelf, ButtonColorHoveredRed),
// ---
// Green Button ---
Element<Button>().Class("ButtonColorGreen")
.Prop(Control.StylePropertyModulateSelf, ButtonColorGoodDefault),
Element<Button>().Class("ButtonColorGreen").Pseudo(ContainerButton.StylePseudoClassNormal)
.Prop(Control.StylePropertyModulateSelf, ButtonColorGoodDefault),
Element<Button>().Class("ButtonColorGreen").Pseudo(ContainerButton.StylePseudoClassHover)
.Prop(Control.StylePropertyModulateSelf, ButtonColorGoodHovered),
// ---
Element<Label>().Class("StatusFieldTitle")
.Prop("font-color", NanoGold),