ObjectsTab.xaml.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. using Content.Client.Administration.Managers;
  2. using Content.Client.Station;
  3. using Content.Client.UserInterface.Controls;
  4. using Robust.Client.AutoGenerated;
  5. using Robust.Client.Console;
  6. using Robust.Client.Graphics;
  7. using Robust.Client.UserInterface;
  8. using Robust.Client.UserInterface.XAML;
  9. using Robust.Shared.Map.Components;
  10. namespace Content.Client.Administration.UI.Tabs.ObjectsTab;
  11. [GenerateTypedNameReferences]
  12. public sealed partial class ObjectsTab : Control
  13. {
  14. [Dependency] private readonly IClientAdminManager _admin = default!;
  15. [Dependency] private readonly IEntityManager _entityManager = default!;
  16. [Dependency] private readonly IClientConsoleHost _console = default!;
  17. private readonly Color _altColor = Color.FromHex("#292B38");
  18. private readonly Color _defaultColor = Color.FromHex("#2F2F3B");
  19. private bool _ascending;
  20. private ObjectsTabHeader.Header _headerClicked = ObjectsTabHeader.Header.ObjectName;
  21. private readonly List<ObjectsTabSelection> _selections = [];
  22. public event Action<GUIBoundKeyEventArgs, ListData>? OnEntryKeyBindDown;
  23. public ObjectsTab()
  24. {
  25. RobustXamlLoader.Load(this);
  26. IoCManager.InjectDependencies(this);
  27. ObjectTypeOptions.OnItemSelected += ev =>
  28. {
  29. ObjectTypeOptions.SelectId(ev.Id);
  30. RefreshObjectList(_selections[ev.Id]);
  31. };
  32. foreach (var type in Enum.GetValues<ObjectsTabSelection>())
  33. {
  34. _selections.Add(type);
  35. ObjectTypeOptions.AddItem(GetLocalizedEnumValue(type));
  36. }
  37. ListHeader.OnHeaderClicked += HeaderClicked;
  38. SearchList.SearchBar = SearchLineEdit;
  39. SearchList.GenerateItem += GenerateButton;
  40. SearchList.DataFilterCondition += DataFilterCondition;
  41. SearchList.ItemKeyBindDown += (args, data) => OnEntryKeyBindDown?.Invoke(args, data);
  42. RefreshListButton.OnPressed += _ => RefreshObjectList();
  43. var defaultSelection = ObjectsTabSelection.Grids;
  44. ObjectTypeOptions.SelectId((int)defaultSelection);
  45. RefreshObjectList(defaultSelection);
  46. }
  47. private void TeleportTo(NetEntity nent)
  48. {
  49. _console.ExecuteCommand($"tpto {nent}");
  50. }
  51. private void Delete(NetEntity nent)
  52. {
  53. _console.ExecuteCommand($"delete {nent}");
  54. }
  55. public void RefreshObjectList()
  56. {
  57. RefreshObjectList(_selections[ObjectTypeOptions.SelectedId]);
  58. }
  59. private void RefreshObjectList(ObjectsTabSelection selection)
  60. {
  61. var entities = new List<(string Name, NetEntity Entity)>();
  62. switch (selection)
  63. {
  64. case ObjectsTabSelection.Stations:
  65. entities.AddRange(_entityManager.EntitySysManager.GetEntitySystem<StationSystem>().Stations);
  66. break;
  67. case ObjectsTabSelection.Grids:
  68. {
  69. var query = _entityManager.AllEntityQueryEnumerator<MapGridComponent, MetaDataComponent>();
  70. while (query.MoveNext(out var uid, out _, out var metadata))
  71. {
  72. entities.Add((metadata.EntityName, _entityManager.GetNetEntity(uid)));
  73. }
  74. break;
  75. }
  76. case ObjectsTabSelection.Maps:
  77. {
  78. var query = _entityManager.AllEntityQueryEnumerator<MapComponent, MetaDataComponent>();
  79. while (query.MoveNext(out var uid, out _, out var metadata))
  80. {
  81. entities.Add((metadata.EntityName, _entityManager.GetNetEntity(uid)));
  82. }
  83. break;
  84. }
  85. default:
  86. throw new ArgumentOutOfRangeException(nameof(selection), selection, null);
  87. }
  88. entities.Sort((a, b) =>
  89. {
  90. var valueA = GetComparableValue(a, _headerClicked);
  91. var valueB = GetComparableValue(b, _headerClicked);
  92. return _ascending
  93. ? Comparer<object>.Default.Compare(valueA, valueB)
  94. : Comparer<object>.Default.Compare(valueB, valueA);
  95. });
  96. var listData = new List<ObjectsListData>();
  97. for (var index = 0; index < entities.Count; index++)
  98. {
  99. var info = entities[index];
  100. listData.Add(new ObjectsListData(info,
  101. $"{info.Name} {info.Entity}",
  102. index % 2 == 0 ? _altColor : _defaultColor));
  103. }
  104. SearchList.PopulateList(listData);
  105. }
  106. private void GenerateButton(ListData data, ListContainerButton button)
  107. {
  108. if (data is not ObjectsListData { Info: var info, BackgroundColor: var backgroundColor })
  109. return;
  110. var entry = new ObjectsTabEntry(_admin, info.Name, info.Entity, new StyleBoxFlat { BackgroundColor = backgroundColor });
  111. entry.OnTeleport += TeleportTo;
  112. entry.OnDelete += Delete;
  113. button.ToolTip = $"{info.Name}, {info.Entity}";
  114. button.AddChild(entry);
  115. }
  116. private bool DataFilterCondition(string filter, ListData listData)
  117. {
  118. if (listData is not ObjectsListData { FilteringString: var filteringString })
  119. return false;
  120. // If the filter is empty, do not filter out any entries
  121. if (string.IsNullOrEmpty(filter))
  122. return true;
  123. return filteringString.Contains(filter, StringComparison.CurrentCultureIgnoreCase);
  124. }
  125. private object GetComparableValue((string Name, NetEntity Entity) entity, ObjectsTabHeader.Header header)
  126. {
  127. return header switch
  128. {
  129. ObjectsTabHeader.Header.ObjectName => entity.Name,
  130. ObjectsTabHeader.Header.EntityID => entity.Entity.ToString(),
  131. _ => entity.Name,
  132. };
  133. }
  134. private void HeaderClicked(ObjectsTabHeader.Header header)
  135. {
  136. if (_headerClicked == header)
  137. {
  138. _ascending = !_ascending;
  139. }
  140. else
  141. {
  142. _headerClicked = header;
  143. _ascending = true;
  144. }
  145. ListHeader.UpdateHeaderSymbols(_headerClicked, _ascending);
  146. RefreshObjectList();
  147. }
  148. private string GetLocalizedEnumValue(ObjectsTabSelection selection)
  149. {
  150. return selection switch
  151. {
  152. ObjectsTabSelection.Grids => Loc.GetString("object-tab-object-type-grids"),
  153. ObjectsTabSelection.Maps => Loc.GetString("object-tab-object-type-maps"),
  154. ObjectsTabSelection.Stations => Loc.GetString("object-tab-object-type-stations"),
  155. _ => throw new ArgumentOutOfRangeException(nameof(selection), selection, null),
  156. };
  157. }
  158. private enum ObjectsTabSelection
  159. {
  160. Grids,
  161. Maps,
  162. Stations,
  163. }
  164. }
  165. public record ObjectsListData((string Name, NetEntity Entity) Info, string FilteringString, Color BackgroundColor)
  166. : ListData;