Skip to content
Open
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
11 changes: 6 additions & 5 deletions .github/workflows/reuse-updater.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# SPDX-FileCopyrightText: 2025 Aiden
# SPDX-FileCopyrightText: 2025 Aidenkrz
# SPDX-FileCopyrightText: 2025 Redrover1760
# SPDX-FileCopyrightText: 2025 sleepyyapril
# SPDX-FileCopyrightText: 2025 Aiden <28298836+Aidenkrz@users.noreply.github.com>
# SPDX-FileCopyrightText: 2025 Aidenkrz <28298836+Aidenkrz@users.noreply.github.com>
# SPDX-FileCopyrightText: 2025 Lachryphage (GitHub)
# SPDX-FileCopyrightText: 2025 ReboundQ3 <ReboundQ3@gmail.com>
# SPDX-FileCopyrightText: 2025 sleepyyapril <flyingkarii@gmail.com>
#
# SPDX-License-Identifier: AGPL-3.0-or-later

Expand Down Expand Up @@ -51,7 +53,7 @@ jobs:
echo "Error fetching PR files from GitHub API."
exit 1
fi

if ! echo "$PR_FILES_JSON" | jq -e . > /dev/null; then
echo "Warning: Received empty or invalid JSON from GitHub API for PR files."
PR_FILES="" # Set PR_FILES to empty to avoid errors below
Expand Down Expand Up @@ -114,4 +116,3 @@ jobs:
skip_dirty_check: false
skip_fetch: true


20 changes: 20 additions & 0 deletions Content.Client/Options/UI/Tabs/AudioTab.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
// SPDX-FileCopyrightText: 2021 20kdc <asdd2808@gmail.com>
// SPDX-FileCopyrightText: 2021 Visne <39844191+Visne@users.noreply.github.com>
// SPDX-FileCopyrightText: 2022 Jessica M <jessica@jessicamaybe.com>
// SPDX-FileCopyrightText: 2022 Moony <moonheart08@users.noreply.github.com>
// SPDX-FileCopyrightText: 2022 ike709 <ike709@github.com>
// SPDX-FileCopyrightText: 2022 ike709 <ike709@users.noreply.github.com>
// SPDX-FileCopyrightText: 2022 mirrorcult <lunarautomaton6@gmail.com>
// SPDX-FileCopyrightText: 2022 theashtronaut <112137107+theashtronaut@users.noreply.github.com>
// SPDX-FileCopyrightText: 2022 wrexbe <81056464+wrexbe@users.noreply.github.com>
// SPDX-FileCopyrightText: 2023 Pieter-Jan Briers <pieterjan.briers@gmail.com>
// SPDX-FileCopyrightText: 2023 metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
// SPDX-FileCopyrightText: 2024 Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
// SPDX-FileCopyrightText: 2025 Lachryphage (GitHub)
// SPDX-FileCopyrightText: 2025 ReboundQ3 <ReboundQ3@gmail.com>
// SPDX-FileCopyrightText: 2025 c4llv07e <igor@c4llv07e.xyz>
// SPDX-FileCopyrightText: 2025 hivehum <ketchupfaced@gmail.com>
//
// SPDX-License-Identifier: MIT

using Content.Client.Administration.Managers;
using Content.Client.Audio;
using Content.Shared._EE.CCVar;
using Content.Shared.CCVar;
using Robust.Client.Audio;
using Robust.Client.AutoGenerated;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-FileCopyrightText: 2025 Lachryphage (GitHub)
// SPDX-FileCopyrightText: 2025 ReboundQ3 <ReboundQ3@gmail.com>
// SPDX-FileCopyrightText: 2025 hivehum <ketchupfaced@gmail.com>
//
// SPDX-License-Identifier: MIT

using Content.Client._EE.Supermatter.Systems;
using Content.Shared._EE.Supermatter.Components;

namespace Content.Client._EE.Supermatter.Components;

[RegisterComponent]
[Access(typeof(SupermatterVisualizerSystem))]
public sealed partial class SupermatterVisualsComponent : Component
{
[DataField("crystal", required: true)]
public Dictionary<SupermatterCrystalState, PrototypeLayerData> CrystalVisuals = default!;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// SPDX-FileCopyrightText: 2025 Lachryphage (GitHub)
// SPDX-FileCopyrightText: 2025 ReboundQ3 <ReboundQ3@gmail.com>
// SPDX-FileCopyrightText: 2025 V <97265903+formlessnameless@users.noreply.github.com>
// SPDX-FileCopyrightText: 2025 hivehum <ketchupfaced@gmail.com>
// SPDX-FileCopyrightText: 2025 mqole <113324899+mqole@users.noreply.github.com>
//
// SPDX-License-Identifier: MIT

using Content.Shared._EE.Supermatter.Components;

namespace Content.Client._EE.Supermatter.Consoles;

public sealed class SupermatterConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey)
{
[ViewVariables]
private SupermatterConsoleWindow? _menu;

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);

if (_menu == null || state is not SupermatterConsoleBoundInterfaceState msg)
return;

_menu?.UpdateUI(msg.Supermatters, msg.FocusData);
}

public void SendFocusChangeMessage(NetEntity? netEntity)
{
SendMessage(new SupermatterConsoleFocusChangeMessage(netEntity));
}

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

_menu?.Parent?.RemoveChild(_menu);
}
}
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="clr-namespace:Content.Client.UserInterface.Controls"
Title="{Loc 'supermatter-console-window-title'}"
Resizable="True"
SetSize="700 400"
MinSize="700 400">
<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,217 @@
// SPDX-FileCopyrightText: 2025 Lachryphage (GitHub)
// SPDX-FileCopyrightText: 2025 ReboundQ3 <ReboundQ3@gmail.com>
// SPDX-FileCopyrightText: 2025 V <97265903+formlessnameless@users.noreply.github.com>
// SPDX-FileCopyrightText: 2025 hivehum <ketchupfaced@gmail.com>
// SPDX-FileCopyrightText: 2025 mqole <113324899+mqole@users.noreply.github.com>
//
// SPDX-License-Identifier: MIT

using Content.Client.Message;
using Content.Client.UserInterface.Controls;
using Content.Shared._EE.Supermatter.Components;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Timing;
using System.Diagnostics.CodeAnalysis;
using System.Linq;

namespace Content.Client._EE.Supermatter.Consoles;

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

private readonly EntityUid? _owner;
private NetEntity? _trackedEntity;
private SupermatterConsoleEntry[]? _supermatters = null;

public event Action<NetEntity?>? SendFocusChangeMessageAction;

private bool _autoScrollActive = false;
private bool _autoScrollAwaitsUpdate = false;

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

// Set the tracked supermatter for persistence
if (_entManager.TryGetComponent<SupermatterConsoleComponent>(_owner, out var console))
_trackedEntity = console.FocusSupermatter;

// Set supermatter monitoring message action
SendFocusChangeMessageAction += userInterface.SendFocusChangeMessage;
}

public void UpdateUI(SupermatterConsoleEntry[] supermatters, SupermatterFocusData? focusData)
{
if (_owner == null)
return;

if (!_entManager.TryGetComponent<SupermatterConsoleComponent>(_owner.Value, out var console))
return;

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

// Retain supermatter data for use inbetween updates
_supermatters = supermatters;

// Clear excess children from the tables
var supermattersCount = _supermatters.Length;

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

// Update all entries in each table
for (var index = 0; index < _supermatters.Length; index++)
{
var entry = _supermatters.ElementAt(index);
UpdateUIEntry(entry, index, SupermattersTable, console, focusData);
}

// If no alerts are active, display a message
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);
}

// Auto-scroll re-enable
if (_autoScrollAwaitsUpdate)
{
_autoScrollActive = true;
_autoScrollAwaitsUpdate = false;
}
}

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

// On click
newEntryContainer.FocusButton.OnButtonUp += args =>
{
if (_trackedEntity == newEntryContainer.NetEntity)
_trackedEntity = null;
else
_trackedEntity = newEntryContainer.NetEntity;

// Send message to console that the focus has changed
SendFocusChangeMessageAction?.Invoke(_trackedEntity);
};

// Add the entry to the current table
table.AddChild(newEntryContainer);
}

// Update values and UI elements
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;

if (SupermattersTable.Parent is not ScrollContainer scroll)
return;

if (!TryGetVerticalScrollbar(scroll, out var vScrollbar))
return;

if (!TryGetNextScrollPosition(out float? 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;

if (SupermattersTable.Parent is not ScrollContainer scroll)
return false;

if (scroll.Children.ElementAt(0) is not BoxContainer container ||
!container.Children.Any())
return false;

// Exit if the heights of the children haven't been initialized yet
if (!container.Children.Any(x => x.Height > 0))
return false;

nextScrollPosition = 0;

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

if (((SupermatterEntryContainer)control).NetEntity == _trackedEntity)
return true;

nextScrollPosition += control.Height;
}

// Failed to find control
nextScrollPosition = null;

return false;
}
}
Loading
Loading