Fix Admin Object tab sorting and search - Part 2 (#28681)
* admin Object tab sorting and searchable * Fix for showing disconnected players on player admin tab * Fix namespace and search bar location. * Change linq to loop. * No more Linq to sort * Fix item click vv menu * Added refresh button and refresh on opening tab. * Clear spaces. * Move tab magic numbers to enums * Get rid of old unused xaml * Fix code style issues and button event type. * Merge in baby jail * More style cleanup and move cast around. * Make the localization a little more easy to read, same loc var names. * Missed Loc for label * Fix class field order * Over zelous delete. * Small updates. * Min syntax issues fix
This commit is contained in:
@@ -3,8 +3,8 @@ using Robust.Client.AutoGenerated;
|
|||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
|
|
||||||
namespace Content.Client.Administration.UI
|
namespace Content.Client.Administration.UI;
|
||||||
{
|
|
||||||
[GenerateTypedNameReferences]
|
[GenerateTypedNameReferences]
|
||||||
public sealed partial class AdminMenuWindow : DefaultWindow
|
public sealed partial class AdminMenuWindow : DefaultWindow
|
||||||
{
|
{
|
||||||
@@ -15,18 +15,26 @@ namespace Content.Client.Administration.UI
|
|||||||
MinSize = new Vector2(650, 250);
|
MinSize = new Vector2(650, 250);
|
||||||
Title = Loc.GetString("admin-menu-title");
|
Title = Loc.GetString("admin-menu-title");
|
||||||
RobustXamlLoader.Load(this);
|
RobustXamlLoader.Load(this);
|
||||||
MasterTabContainer.SetTabTitle(0, Loc.GetString("admin-menu-admin-tab"));
|
MasterTabContainer.SetTabTitle((int) TabIndex.Admin, Loc.GetString("admin-menu-admin-tab"));
|
||||||
MasterTabContainer.SetTabTitle(1, Loc.GetString("admin-menu-adminbus-tab"));
|
MasterTabContainer.SetTabTitle((int) TabIndex.Adminbus, Loc.GetString("admin-menu-adminbus-tab"));
|
||||||
MasterTabContainer.SetTabTitle(2, Loc.GetString("admin-menu-atmos-tab"));
|
MasterTabContainer.SetTabTitle((int) TabIndex.Atmos, Loc.GetString("admin-menu-atmos-tab"));
|
||||||
MasterTabContainer.SetTabTitle(3, Loc.GetString("admin-menu-round-tab"));
|
MasterTabContainer.SetTabTitle((int) TabIndex.Round, Loc.GetString("admin-menu-round-tab"));
|
||||||
MasterTabContainer.SetTabTitle(4, Loc.GetString("admin-menu-server-tab"));
|
MasterTabContainer.SetTabTitle((int) TabIndex.Server, Loc.GetString("admin-menu-server-tab"));
|
||||||
MasterTabContainer.SetTabTitle(5, Loc.GetString("admin-menu-panic-bunker-tab"));
|
MasterTabContainer.SetTabTitle((int) TabIndex.PanicBunker, Loc.GetString("admin-menu-panic-bunker-tab"));
|
||||||
/*
|
/*
|
||||||
* TODO: Remove baby jail code once a more mature gateway process is established. This code is only being issued as a stopgap to help with potential tiding in the immediate future.
|
* TODO: Remove baby jail code once a more mature gateway process is established. This code is only being issued as a stopgap to help with potential tiding in the immediate future.
|
||||||
*/
|
*/
|
||||||
MasterTabContainer.SetTabTitle(6, Loc.GetString("admin-menu-baby-jail-tab"));
|
MasterTabContainer.SetTabTitle((int) TabIndex.BabyJail, Loc.GetString("admin-menu-baby-jail-tab"));
|
||||||
MasterTabContainer.SetTabTitle(7, Loc.GetString("admin-menu-players-tab"));
|
MasterTabContainer.SetTabTitle((int) TabIndex.Players, Loc.GetString("admin-menu-players-tab"));
|
||||||
MasterTabContainer.SetTabTitle(8, Loc.GetString("admin-menu-objects-tab"));
|
MasterTabContainer.SetTabTitle((int) TabIndex.Objects, Loc.GetString("admin-menu-objects-tab"));
|
||||||
|
MasterTabContainer.OnTabChanged += OnTabChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnTabChanged(int tabIndex)
|
||||||
|
{
|
||||||
|
var tabEnum = (TabIndex)tabIndex;
|
||||||
|
if (tabEnum == TabIndex.Objects)
|
||||||
|
ObjectsTabControl.RefreshObjectList();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
@@ -35,6 +43,17 @@ namespace Content.Client.Administration.UI
|
|||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
OnDisposed = null;
|
OnDisposed = null;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private enum TabIndex
|
||||||
|
{
|
||||||
|
Admin = 0,
|
||||||
|
Adminbus,
|
||||||
|
Atmos,
|
||||||
|
Round,
|
||||||
|
Server,
|
||||||
|
PanicBunker,
|
||||||
|
BabyJail,
|
||||||
|
Players,
|
||||||
|
Objects,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,12 +4,11 @@
|
|||||||
xmlns:co="clr-namespace:Content.Client.UserInterface.Controls">
|
xmlns:co="clr-namespace:Content.Client.UserInterface.Controls">
|
||||||
<BoxContainer Orientation="Vertical">
|
<BoxContainer Orientation="Vertical">
|
||||||
<BoxContainer Orientation="Horizontal">
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label HorizontalExpand="True" SizeFlagsStretchRatio="0.50"
|
<Label Text="{Loc object-tab-object-type}" />
|
||||||
Text="{Loc object-tab-object-type}" />
|
<OptionButton Name="ObjectTypeOptions" HorizontalAlignment="Left" />
|
||||||
<LineEdit Name="SearchLineEdit" PlaceHolder="{Loc object-tab-object-search}" HorizontalExpand="True" SizeFlagsStretchRatio="1"/>
|
<LineEdit Name="SearchLineEdit" PlaceHolder="{Loc object-tab-object-search}" HorizontalExpand="True"
|
||||||
<OptionButton Name="ObjectTypeOptions" HorizontalExpand="True" SizeFlagsStretchRatio="0.25"/>
|
SizeFlagsStretchRatio="1" />
|
||||||
</BoxContainer>
|
<Button Name="RefreshListButton" Text="{Loc object-tab-refresh-button}" ToggleMode="False" />
|
||||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
<cc:HSeparator />
|
<cc:HSeparator />
|
||||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True">
|
<BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True">
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Content.Client.UserInterface.Controls;
|
|||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
using Robust.Shared.Map.Components;
|
using Robust.Shared.Map.Components;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
@@ -15,17 +16,14 @@ public sealed partial class ObjectsTab : Control
|
|||||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
[Dependency] private readonly IGameTiming _timing = default!;
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
|
|
||||||
private readonly List<ObjectsTabEntry> _objects = new();
|
|
||||||
private readonly List<ObjectsTabSelection> _selections = new();
|
|
||||||
private bool _ascending = false; // Set to false for descending order by default
|
|
||||||
private ObjectsTabHeader.Header _headerClicked = ObjectsTabHeader.Header.ObjectName;
|
|
||||||
private readonly Color _altColor = Color.FromHex("#292B38");
|
private readonly Color _altColor = Color.FromHex("#292B38");
|
||||||
private readonly Color _defaultColor = Color.FromHex("#2F2F3B");
|
private readonly Color _defaultColor = Color.FromHex("#2F2F3B");
|
||||||
|
|
||||||
public event Action<GUIBoundKeyEventArgs, ListData>? OnEntryKeyBindDown;
|
private bool _ascending;
|
||||||
|
private ObjectsTabHeader.Header _headerClicked = ObjectsTabHeader.Header.ObjectName;
|
||||||
|
|
||||||
private readonly TimeSpan _updateFrequency = TimeSpan.FromSeconds(2);
|
private readonly List<ObjectsTabSelection> _selections = [];
|
||||||
private TimeSpan _nextUpdate;
|
public event Action<GUIBoundKeyEventArgs, ListData>? OnEntryKeyBindDown;
|
||||||
|
|
||||||
public ObjectsTab()
|
public ObjectsTab()
|
||||||
{
|
{
|
||||||
@@ -38,40 +36,25 @@ public sealed partial class ObjectsTab : Control
|
|||||||
RefreshObjectList(_selections[ev.Id]);
|
RefreshObjectList(_selections[ev.Id]);
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var type in Enum.GetValues(typeof(ObjectsTabSelection)))
|
foreach (var type in Enum.GetValues<ObjectsTabSelection>())
|
||||||
{
|
{
|
||||||
_selections.Add((ObjectsTabSelection)type!);
|
_selections.Add(type);
|
||||||
ObjectTypeOptions.AddItem(Loc.GetString($"object-tab-object-type-{((Enum.GetName((ObjectsTabSelection)type))!.ToString().ToLower())}"));
|
ObjectTypeOptions.AddItem(GetLocalizedEnumValue(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
ListHeader.OnHeaderClicked += HeaderClicked;
|
ListHeader.OnHeaderClicked += HeaderClicked;
|
||||||
SearchList.SearchBar = SearchLineEdit;
|
SearchList.SearchBar = SearchLineEdit;
|
||||||
SearchList.GenerateItem += GenerateButton;
|
SearchList.GenerateItem += GenerateButton;
|
||||||
SearchList.DataFilterCondition += DataFilterCondition;
|
SearchList.DataFilterCondition += DataFilterCondition;
|
||||||
|
SearchList.ItemKeyBindDown += (args, data) => OnEntryKeyBindDown?.Invoke(args, data);
|
||||||
|
RefreshListButton.OnPressed += _ => RefreshObjectList();
|
||||||
|
|
||||||
RefreshObjectList();
|
|
||||||
// Set initial selection and refresh the list to apply the initial sort order
|
|
||||||
var defaultSelection = ObjectsTabSelection.Grids;
|
var defaultSelection = ObjectsTabSelection.Grids;
|
||||||
ObjectTypeOptions.SelectId((int)defaultSelection); // Set the default selection
|
ObjectTypeOptions.SelectId((int) defaultSelection);
|
||||||
RefreshObjectList(defaultSelection); // Refresh the list with the default selection
|
RefreshObjectList(defaultSelection);
|
||||||
|
|
||||||
// Initialize the next update time
|
|
||||||
_nextUpdate = TimeSpan.Zero;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void FrameUpdate(FrameEventArgs args)
|
public void RefreshObjectList()
|
||||||
{
|
|
||||||
base.FrameUpdate(args);
|
|
||||||
|
|
||||||
if (_timing.CurTime < _nextUpdate)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_nextUpdate = _timing.CurTime + _updateFrequency;
|
|
||||||
|
|
||||||
RefreshObjectList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RefreshObjectList()
|
|
||||||
{
|
{
|
||||||
RefreshObjectList(_selections[ObjectTypeOptions.SelectedId]);
|
RefreshObjectList(_selections[ObjectTypeOptions.SelectedId]);
|
||||||
}
|
}
|
||||||
@@ -101,6 +84,7 @@ public sealed partial class ObjectsTab : Control
|
|||||||
{
|
{
|
||||||
entities.Add((metadata.EntityName, _entityManager.GetNetEntity(uid)));
|
entities.Add((metadata.EntityName, _entityManager.GetNetEntity(uid)));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -111,14 +95,18 @@ public sealed partial class ObjectsTab : Control
|
|||||||
{
|
{
|
||||||
var valueA = GetComparableValue(a, _headerClicked);
|
var valueA = GetComparableValue(a, _headerClicked);
|
||||||
var valueB = GetComparableValue(b, _headerClicked);
|
var valueB = GetComparableValue(b, _headerClicked);
|
||||||
return _ascending ? Comparer<object>.Default.Compare(valueA, valueB) : Comparer<object>.Default.Compare(valueB, valueA);
|
return _ascending
|
||||||
|
? Comparer<object>.Default.Compare(valueA, valueB)
|
||||||
|
: Comparer<object>.Default.Compare(valueB, valueA);
|
||||||
});
|
});
|
||||||
|
|
||||||
var listData = new List<ObjectsListData>();
|
var listData = new List<ObjectsListData>();
|
||||||
for (int index = 0; index < entities.Count; index++)
|
for (var index = 0; index < entities.Count; index++)
|
||||||
{
|
{
|
||||||
var info = entities[index];
|
var info = entities[index];
|
||||||
listData.Add(new ObjectsListData(info, $"{info.Name} {info.Entity}", index % 2 == 0 ? _altColor : _defaultColor));
|
listData.Add(new ObjectsListData(info,
|
||||||
|
$"{info.Name} {info.Entity}",
|
||||||
|
index % 2 == 0 ? _altColor : _defaultColor));
|
||||||
}
|
}
|
||||||
|
|
||||||
SearchList.PopulateList(listData);
|
SearchList.PopulateList(listData);
|
||||||
@@ -129,10 +117,11 @@ public sealed partial class ObjectsTab : Control
|
|||||||
if (data is not ObjectsListData { Info: var info, BackgroundColor: var backgroundColor })
|
if (data is not ObjectsListData { Info: var info, BackgroundColor: var backgroundColor })
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var entry = new ObjectsTabEntry(info.Name, info.Entity, new StyleBoxFlat { BackgroundColor = backgroundColor });
|
var entry = new ObjectsTabEntry(info.Name,
|
||||||
|
info.Entity,
|
||||||
|
new StyleBoxFlat { BackgroundColor = backgroundColor });
|
||||||
button.ToolTip = $"{info.Name}, {info.Entity}";
|
button.ToolTip = $"{info.Name}, {info.Entity}";
|
||||||
|
|
||||||
button.OnKeyBindDown += args => OnEntryKeyBindDown?.Invoke(args, data);
|
|
||||||
button.AddChild(entry);
|
button.AddChild(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +143,7 @@ public sealed partial class ObjectsTab : Control
|
|||||||
{
|
{
|
||||||
ObjectsTabHeader.Header.ObjectName => entity.Name,
|
ObjectsTabHeader.Header.ObjectName => entity.Name,
|
||||||
ObjectsTabHeader.Header.EntityID => entity.Entity.ToString(),
|
ObjectsTabHeader.Header.EntityID => entity.Entity.ToString(),
|
||||||
_ => entity.Name
|
_ => entity.Name,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,6 +163,17 @@ public sealed partial class ObjectsTab : Control
|
|||||||
RefreshObjectList();
|
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
|
private enum ObjectsTabSelection
|
||||||
{
|
{
|
||||||
Grids,
|
Grids,
|
||||||
@@ -182,4 +182,5 @@ public sealed partial class ObjectsTab : Control
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public record ObjectsListData((string Name, NetEntity Entity) Info, string FilteringString, Color BackgroundColor) : ListData;
|
public record ObjectsListData((string Name, NetEntity Entity) Info, string FilteringString, Color BackgroundColor)
|
||||||
|
: ListData;
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ public sealed class AdminUIController : UIController,
|
|||||||
|
|
||||||
if (function == EngineKeyFunctions.UIClick)
|
if (function == EngineKeyFunctions.UIClick)
|
||||||
_conHost.ExecuteCommand($"vv {uid}");
|
_conHost.ExecuteCommand($"vv {uid}");
|
||||||
else if (function == EngineKeyFunctions.UseSecondary)
|
else if (function == EngineKeyFunctions.UIRightClick)
|
||||||
_verb.OpenVerbMenu(uid, true);
|
_verb.OpenVerbMenu(uid, true);
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -7,3 +7,4 @@ object-tab-object-search = Search...
|
|||||||
object-tab-object-type-grids = Grids
|
object-tab-object-type-grids = Grids
|
||||||
object-tab-object-type-maps = Maps
|
object-tab-object-type-maps = Maps
|
||||||
object-tab-object-type-stations = Stations
|
object-tab-object-type-stations = Stations
|
||||||
|
object-tab-refresh-button = Refresh
|
||||||
|
|||||||
Reference in New Issue
Block a user