Files
tbd-station-14/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs
slarticodefast a13d5916bf Fix admin objects tab (#39832)
fix objects tab
2025-08-22 15:37:51 -07:00

225 lines
8.1 KiB
C#

using Content.Client.Administration.Managers;
using Content.Client.Station;
using Content.Client.UserInterface.Controls;
using Robust.Client.AutoGenerated;
using Robust.Client.Console;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Map.Components;
namespace Content.Client.Administration.UI.Tabs.ObjectsTab;
[GenerateTypedNameReferences]
public sealed partial class ObjectsTab : Control
{
[Dependency] private readonly IClientAdminManager _admin = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IClientConsoleHost _console = default!;
private readonly Color _altColor = Color.FromHex("#292B38");
private readonly Color _defaultColor = Color.FromHex("#2F2F3B");
private bool _ascending;
private ObjectsTabHeader.Header _headerClicked = ObjectsTabHeader.Header.ObjectName;
private readonly List<ObjectsTabSelection> _selections = [];
public event Action<GUIBoundKeyEventArgs, ListData>? OnEntryKeyBindDown;
public ObjectsTab()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
ObjectTypeOptions.OnItemSelected += ev =>
{
ObjectTypeOptions.SelectId(ev.Id);
RefreshObjectList(_selections[ev.Id]);
};
foreach (var type in Enum.GetValues<ObjectsTabSelection>())
{
_selections.Add(type);
ObjectTypeOptions.AddItem(GetLocalizedEnumValue(type));
}
ListHeader.OnHeaderClicked += HeaderClicked;
SearchList.SearchBar = SearchLineEdit;
SearchList.GenerateItem += GenerateButton;
SearchList.DataFilterCondition += DataFilterCondition;
SearchList.ItemKeyBindDown += (args, data) => OnEntryKeyBindDown?.Invoke(args, data);
RefreshListButton.OnPressed += _ => RefreshObjectList();
var defaultSelection = ObjectsTabSelection.Grids;
ObjectTypeOptions.SelectId((int)defaultSelection);
RefreshObjectList(defaultSelection);
}
private void TeleportTo(NetEntity nent)
{
var selection = _selections[ObjectTypeOptions.SelectedId];
switch (selection)
{
case ObjectsTabSelection.Grids:
{
// directly teleport to the entity
_console.ExecuteCommand($"tpto {nent}");
}
break;
case ObjectsTabSelection.Maps:
{
// teleport to the map, not to the map entity (which is in nullspace)
if (!_entityManager.TryGetEntity(nent, out var map) || !_entityManager.TryGetComponent<MapComponent>(map, out var mapComp))
break;
_console.ExecuteCommand($"tp 0 0 {mapComp.MapId}");
break;
}
case ObjectsTabSelection.Stations:
{
// teleport to the station's largest grid, not to the station entity (which is in nullspace)
if (!_entityManager.TryGetEntity(nent, out var station))
break;
var largestGrid = _entityManager.EntitySysManager.GetEntitySystem<StationSystem>().GetLargestGrid(station.Value);
if (largestGrid == null)
break;
_console.ExecuteCommand($"tpto {largestGrid.Value}");
break;
}
default:
throw new NotImplementedException();
}
}
private void Delete(NetEntity nent)
{
_console.ExecuteCommand($"delete {nent}");
RefreshObjectList();
}
public void RefreshObjectList()
{
RefreshObjectList(_selections[ObjectTypeOptions.SelectedId]);
}
private void RefreshObjectList(ObjectsTabSelection selection)
{
var entities = new List<(string Name, NetEntity Entity)>();
switch (selection)
{
case ObjectsTabSelection.Stations:
entities.AddRange(_entityManager.EntitySysManager.GetEntitySystem<StationSystem>().GetStationNames());
break;
case ObjectsTabSelection.Grids:
{
var query = _entityManager.AllEntityQueryEnumerator<MapGridComponent, MetaDataComponent>();
while (query.MoveNext(out var uid, out _, out var metadata))
entities.Add((metadata.EntityName, _entityManager.GetNetEntity(uid)));
break;
}
case ObjectsTabSelection.Maps:
{
var query = _entityManager.AllEntityQueryEnumerator<MapComponent, MetaDataComponent>();
while (query.MoveNext(out var uid, out _, out var metadata))
entities.Add((metadata.EntityName, _entityManager.GetNetEntity(uid)));
break;
}
default:
throw new ArgumentOutOfRangeException(nameof(selection), selection, null);
}
entities.Sort((a, b) =>
{
var valueA = GetComparableValue(a, _headerClicked);
var valueB = GetComparableValue(b, _headerClicked);
return _ascending
? Comparer<object>.Default.Compare(valueA, valueB)
: Comparer<object>.Default.Compare(valueB, valueA);
});
var listData = new List<ObjectsListData>();
for (var index = 0; index < entities.Count; index++)
{
var info = entities[index];
listData.Add(new ObjectsListData(info,
$"{info.Name} {info.Entity}",
index % 2 == 0 ? _altColor : _defaultColor));
}
SearchList.PopulateList(listData);
}
private void GenerateButton(ListData data, ListContainerButton button)
{
if (data is not ObjectsListData { Info: var info, BackgroundColor: var backgroundColor })
return;
var entry = new ObjectsTabEntry(_admin, info.Name, info.Entity, new StyleBoxFlat { BackgroundColor = backgroundColor });
entry.OnTeleport += TeleportTo;
entry.OnDelete += Delete;
button.ToolTip = $"{info.Name}, {info.Entity}";
button.AddChild(entry);
button.StyleClasses.Clear();
}
private bool DataFilterCondition(string filter, ListData listData)
{
if (listData is not ObjectsListData { FilteringString: var filteringString })
return false;
// If the filter is empty, do not filter out any entries
if (string.IsNullOrEmpty(filter))
return true;
return filteringString.Contains(filter, StringComparison.CurrentCultureIgnoreCase);
}
private object GetComparableValue((string Name, NetEntity Entity) entity, ObjectsTabHeader.Header header)
{
return header switch
{
ObjectsTabHeader.Header.ObjectName => entity.Name,
ObjectsTabHeader.Header.EntityID => entity.Entity.ToString(),
_ => entity.Name,
};
}
private void HeaderClicked(ObjectsTabHeader.Header header)
{
if (_headerClicked == header)
{
_ascending = !_ascending;
}
else
{
_headerClicked = header;
_ascending = true;
}
ListHeader.UpdateHeaderSymbols(_headerClicked, _ascending);
RefreshObjectList();
}
private string GetLocalizedEnumValue(ObjectsTabSelection selection)
{
return selection switch
{
ObjectsTabSelection.Grids => Loc.GetString("object-tab-object-type-grids"),
ObjectsTabSelection.Maps => Loc.GetString("object-tab-object-type-maps"),
ObjectsTabSelection.Stations => Loc.GetString("object-tab-object-type-stations"),
_ => throw new ArgumentOutOfRangeException(nameof(selection), selection, null),
};
}
private enum ObjectsTabSelection
{
Grids,
Maps,
Stations,
}
}
public record ObjectsListData((string Name, NetEntity Entity) Info, string FilteringString, Color BackgroundColor)
: ListData;