Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Content.Shared.Backmen.Supermatter.Consoles;

namespace Content.Client.Backmen.Supermatter.Consoles;

public sealed class SupermatterConsoleBoundUserInterface : BoundUserInterface
{
[ViewVariables]
private SupermatterConsoleWindow? _menu;

public SupermatterConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}

protected override void Open()
{
base.Open();

_menu = new SupermatterConsoleWindow(this, Owner);
_menu.OpenCentered();
_menu.OnClose += Close;
}

protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);

var castState = (SupermatterConsoleBoundInterfaceState) state;
_menu?.UpdateUI(castState.Supermatters, castState.FocusData);
}

public void SendFocusChangeMessage(NetEntity? netEntity) =>
SendMessage(new SupermatterConsoleFocusChangeMessage(netEntity));

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;

_menu?.Dispose();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:ui="clr-namespace:Content.Client.Pinpointer.UI"
xmlns:controls="using:Content.Client.UserInterface.Controls"
Title="{Loc 'supermatter-console-window-title'}"
Resizable="True"
SetSize="700 550"
MinSize="700 550">
<BoxContainer Orientation="Vertical">
<!-- Main display -->
<BoxContainer Orientation="Horizontal" VerticalExpand="True" HorizontalExpand="True">
<!-- Supermatter list -->
<BoxContainer Orientation="Vertical" VerticalExpand="True" HorizontalExpand="True" Margin="10 0 10 10">
<!-- Supermatters (entries added by C# code) -->
<BoxContainer VerticalExpand="True" HorizontalExpand="True" Margin="0 10 0 0">
<ScrollContainer HorizontalExpand="True">
<BoxContainer Name="SupermattersTable" Orientation="Vertical" VerticalExpand="True" HorizontalExpand="True" Margin="0 0 0 10" />
</ScrollContainer>
</BoxContainer>
</BoxContainer>
</BoxContainer>

<!-- Footer -->
<BoxContainer Orientation="Vertical">
<PanelContainer StyleClasses="LowDivider" />
<BoxContainer Orientation="Horizontal" Margin="10 2 5 0" VerticalAlignment="Bottom">
<Label Text="{Loc 'supermatter-console-window-flavor-left'}" StyleClasses="WindowFooterText" />
<Label Text="{Loc 'supermatter-console-window-flavor-right'}" StyleClasses="WindowFooterText"
HorizontalAlignment="Right" HorizontalExpand="True" Margin="0 0 5 0" />
<TextureRect StyleClasses="NTLogoDark" Stretch="KeepAspectCentered"
VerticalAlignment="Center" HorizontalAlignment="Right" SetSize="19 19"/>
</BoxContainer>
</BoxContainer>
</BoxContainer>
</controls:FancyWindow>
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Client.Message;
using Content.Client.UserInterface.Controls;
using Content.Shared.Backmen.Supermatter.Consoles;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

namespace Content.Client.Backmen.Supermatter.Consoles;

[GenerateTypedNameReferences]
public sealed partial class SupermatterConsoleWindow : FancyWindow
{
private readonly IEntityManager _entManager;

private readonly EntityUid? _owner;
private NetEntity? _trackedEntity;

private SupermatterConsoleEntry[]? _supermatters;

public event Action<NetEntity?>? SendFocusChangeMessageAction;

private bool _autoScrollActive;
private bool _autoScrollAwaitsUpdate;

public SupermatterConsoleWindow(SupermatterConsoleBoundUserInterface userInterface, EntityUid? owner)
{
RobustXamlLoader.Load(this);
_entManager = IoCManager.Resolve<IEntityManager>();

_owner = owner;
SendFocusChangeMessageAction += userInterface.SendFocusChangeMessage;
}

public void UpdateUI(SupermatterConsoleEntry[] supermatters, SupermatterFocusData? focusData)
{
if (_owner == null
|| !_entManager.TryGetComponent<SupermatterConsoleComponent>(_owner.Value, out var console))
return;

if (_trackedEntity != focusData?.NetEntity)
{
SendFocusChangeMessageAction?.Invoke(_trackedEntity);
focusData = null;
}

_supermatters = supermatters;

var supermattersCount = _supermatters.Length;

while (SupermattersTable.ChildCount > supermattersCount)
SupermattersTable.RemoveChild(SupermattersTable.GetChild(SupermattersTable.ChildCount - 1));

for (var index = 0; index < _supermatters.Length; index++)
{
var entry = _supermatters[index];
UpdateUIEntry(entry, index, SupermattersTable, console, focusData);
}

if (supermattersCount == 0)
{
var label = new RichTextLabel
{
HorizontalExpand = true,
VerticalExpand = true,
HorizontalAlignment = HAlignment.Center,
VerticalAlignment = VAlignment.Center,
};

label.SetMarkup(Loc.GetString("supermatter-console-window-no-supermatters"));
SupermattersTable.AddChild(label);
}

if (_autoScrollAwaitsUpdate)
{
_autoScrollActive = true;
_autoScrollAwaitsUpdate = false;
}
}

private void UpdateUIEntry(
SupermatterConsoleEntry entry,
int index,
Control table,
SupermatterConsoleComponent console,
SupermatterFocusData? focusData = null)
{
if (index >= table.ChildCount)
{
var newEntryContainer = new SupermatterEntryContainer(entry.NetEntity);

newEntryContainer.FocusButton.OnButtonUp += _ =>
{
_trackedEntity = _trackedEntity == newEntryContainer.NetEntity
? null
: newEntryContainer.NetEntity;

SendFocusChangeMessageAction?.Invoke(_trackedEntity);
};

table.AddChild(newEntryContainer);
}

var tableChild = table.GetChild(index);

if (tableChild is not SupermatterEntryContainer)
{
table.RemoveChild(tableChild);
UpdateUIEntry(entry, index, table, console, focusData);
return;
}

var entryContainer = (SupermatterEntryContainer) tableChild;
entryContainer.UpdateEntry(entry, entry.NetEntity == _trackedEntity, focusData);
}

protected override void FrameUpdate(FrameEventArgs args) =>
AutoScrollToFocus();

private void AutoScrollToFocus()
{
if (!_autoScrollActive)
return;

var scroll = SupermattersTable.Parent as ScrollContainer;
if (scroll == null
|| !TryGetVerticalScrollbar(scroll, out var vScrollbar)
|| !TryGetNextScrollPosition(out var nextScrollPosition))
return;

vScrollbar.ValueTarget = nextScrollPosition.Value;

if (MathHelper.CloseToPercent(vScrollbar.Value, vScrollbar.ValueTarget))
_autoScrollActive = false;
}

private static bool TryGetVerticalScrollbar(ScrollContainer scroll, [NotNullWhen(true)] out VScrollBar? vScrollBar)
{
vScrollBar = null;

foreach (var child in scroll.Children)
{
if (child is not VScrollBar castChild)
continue;

vScrollBar = castChild;
return true;
}

return false;
}

private bool TryGetNextScrollPosition([NotNullWhen(true)] out float? nextScrollPosition)
{
nextScrollPosition = null;

var scroll = SupermattersTable.Parent as ScrollContainer;
if (scroll == null)
return false;

var container = scroll.Children.ElementAt(0) as BoxContainer;
if (container == null || !container.Children.Any())
return false;

if (!container.Children.Any(x => x.Height > 0))
return false;

nextScrollPosition = 0;

foreach (var control in container.Children)
{
if (control is not SupermatterEntryContainer entry)
continue;

if (entry.NetEntity == _trackedEntity)
return true;

nextScrollPosition += control.Height;
}

nextScrollPosition = null;
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<BoxContainer xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
Orientation="Vertical" HorizontalExpand ="True" Margin="0 0 0 3">

<Button Name="FocusButton" VerticalExpand="True" HorizontalExpand="True" StyleClasses="OpenLeft" Access="Public">
<BoxContainer HorizontalExpand="True" VerticalExpand="True" Orientation="Horizontal">
<!-- Supermatter sprite -->
<TextureRect Name="SupermatterSprite" SetWidth="32" SetHeight="48" TexturePath="/Textures/Interface/Supermatter/supermatter.png" Margin="6 2" />
<!-- Supermatter name -->
<Label Name="SupermatterNameLabel" Text="???" HorizontalExpand="True" HorizontalAlignment="Left" Margin="5 0" />

<!-- Supermatter status -->

</BoxContainer>
</Button>

<!-- Panel that appears on selecting the device -->
<PanelContainer Name="FocusContainer" HorizontalExpand="True" Margin="1 -1 1 0" ReservesSpace="False" Visible="False" Access="Public">
<PanelContainer.PanelOverride>
<gfx:StyleBoxFlat BackgroundColor="#25252a"/>
</PanelContainer.PanelOverride>
<BoxContainer HorizontalExpand="True" VerticalExpand="True" Orientation="Horizontal" Margin="6 3">

<!-- Engine details -->
<BoxContainer HorizontalExpand="True" VerticalExpand="True" Orientation="Vertical" Margin="0 0 6 0">
<!-- Integrity display -->
<BoxContainer HorizontalExpand="True" Orientation="Horizontal" Margin="0 1">
<Label Name="IntegrityLabel" Text="{Loc 'supermatter-console-window-label-integrity'}" HorizontalExpand="True" HorizontalAlignment="Left" />
<PanelContainer Name="IntegrityBarBorder" SetWidth="150" SetHeight="24">
<ProgressBar Name="IntegrityBar" MinValue="0" MaxValue="100" HorizontalExpand="True" VerticalExpand="True" Margin="1">
<Label Name="IntegrityBarLabel" HorizontalAlignment="Right" Margin="0 0 4 0" />
</ProgressBar>
</PanelContainer>
</BoxContainer>

<!-- Internal energy display -->
<BoxContainer HorizontalExpand="True" Orientation="Horizontal" Margin="0 1">
<Label Name="PowerLabel" Text="{Loc 'supermatter-console-window-label-power'}" HorizontalExpand="True" HorizontalAlignment="Left" />
<PanelContainer Name="PowerBarBorder" SetWidth="150" SetHeight="24">
<ProgressBar Name="PowerBar" MinValue="0" MaxValue="5000" HorizontalExpand="True" VerticalExpand="True" Margin="1">
<Label Name="PowerBarLabel" HorizontalAlignment="Right" Margin="0 0 4 0" />
</ProgressBar>
</PanelContainer>
</BoxContainer>

<!-- Radiation display -->
<BoxContainer HorizontalExpand="True" Orientation="Horizontal" Margin="0 1">
<Label Name="RadiationLabel" Text="{Loc 'supermatter-console-window-label-radiation'}" HorizontalExpand="True" HorizontalAlignment="Left" />
<PanelContainer Name="RadiationBarBorder" SetWidth="150" SetHeight="24">
<ProgressBar Name="RadiationBar" MinValue="0" MaxValue="30" HorizontalExpand="True" VerticalExpand="True" Margin="1">
<Label Name="RadiationBarLabel" HorizontalAlignment="Right" Margin="0 0 4 0" />
</ProgressBar>
</PanelContainer>
</BoxContainer>

<!-- Absorbed moles display -->
<BoxContainer HorizontalExpand="True" Orientation="Horizontal" Margin="0 1">
<Label Name="MolesLabel" Text="{Loc 'supermatter-console-window-label-moles'}" HorizontalExpand="True" HorizontalAlignment="Left" />
<PanelContainer Name="MolesBarBorder" SetWidth="150" SetHeight="24">
<ProgressBar Name="MolesBar" MinValue="0" MaxValue="100" HorizontalExpand="True" VerticalExpand="True" Margin="1">
<Label Name="MolesBarLabel" HorizontalAlignment="Right" Margin="0 0 4 0" />
</ProgressBar>
</PanelContainer>
</BoxContainer>

<!-- Temperature display -->
<BoxContainer HorizontalExpand="True" Orientation="Horizontal" Margin="0 1">
<Label Name="TemperatureLabel" Text="{Loc 'supermatter-console-window-label-temperature'}" HorizontalExpand="True" HorizontalAlignment="Left" />
<PanelContainer Name="TemperatureBarBorder" SetWidth="150" SetHeight="24">
<ProgressBar Name="TemperatureBar" MinValue="0" MaxValue="1000" HorizontalExpand="True" VerticalExpand="True" Margin="1">
<Label Name="TemperatureBarLabel" HorizontalAlignment="Right" Margin="0 0 4 0" />
</ProgressBar>
</PanelContainer>
</BoxContainer>

<!-- Temperature limit display -->
<BoxContainer HorizontalExpand="True" Orientation="Horizontal" Margin="0 1">
<Label Name="TemperatureLimitLabel" Text="{Loc 'supermatter-console-window-label-temperature-limit'}" HorizontalExpand="True" HorizontalAlignment="Left" />
<Label Name="TemperatureLimitBarLabel" HorizontalAlignment="Left" SetWidth="150" />
</BoxContainer>

<!-- Waste multiplier display -->
<BoxContainer HorizontalExpand="True" Orientation="Horizontal" Margin="0 1">
<Label Name="WasteLabel" Text="{Loc 'supermatter-console-window-label-waste'}" HorizontalExpand="True" HorizontalAlignment="Left" />
<PanelContainer Name="WasteBarBorder" SetWidth="150" SetHeight="24">
<ProgressBar Name="WasteBar" MinValue="0" MaxValue="10" HorizontalExpand="True" VerticalExpand="True" Margin="1">
<Label Name="WasteBarLabel" HorizontalAlignment="Right" Margin="0 0 4 0" />
</ProgressBar>
</PanelContainer>
</BoxContainer>

<!-- Absorption ratio display -->
<BoxContainer HorizontalExpand="True" Orientation="Horizontal" Margin="0 1">
<Label Name="AbsorptionLabel" Text="{Loc 'supermatter-console-window-label-absorption'}" HorizontalExpand="True" HorizontalAlignment="Left" />
<Label Name="AbsorptionBarLabel" HorizontalAlignment="Left" SetWidth="150" />
</BoxContainer>
</BoxContainer>

<!-- Gas details (entries added by C# code) -->
<BoxContainer Name="GasTable" HorizontalExpand="True" VerticalExpand="True" Orientation="Vertical" Margin="6 0 0 0" />
</BoxContainer>
</PanelContainer>

</BoxContainer>
Loading
Loading