Adds a search bar to vending machines (#20326)

* Adds a search bar to vending machines

* fix indentation

* whitespace again

---------

Co-authored-by: ike709 <ike709@github.com>
This commit is contained in:
ike709
2023-09-20 12:40:41 -07:00
committed by GitHub
parent 9441f6b53a
commit 3ee729f3fd
4 changed files with 37 additions and 10 deletions

View File

@@ -1,6 +1,9 @@
<DefaultWindow xmlns="https://spacestation14.io"> <DefaultWindow xmlns="https://spacestation14.io">
<ItemList Name="VendingContents" <BoxContainer Orientation="Vertical">
SizeFlagsStretchRatio="8" <LineEdit Name="SearchBar" PlaceHolder="{Loc 'vending-machine-component-search-filter'}" HorizontalExpand="True" Margin ="0 4"/>
VerticalExpand="True"> <ItemList Name="VendingContents"
</ItemList> SizeFlagsStretchRatio="8"
VerticalExpand="True">
</ItemList>
</BoxContainer>
</DefaultWindow> </DefaultWindow>

View File

@@ -17,6 +17,7 @@ namespace Content.Client.VendingMachines.UI
[Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
public event Action<ItemList.ItemListSelectedEventArgs>? OnItemSelected; public event Action<ItemList.ItemListSelectedEventArgs>? OnItemSelected;
public event Action<string>? OnSearchChanged;
public VendingMachineMenu() public VendingMachineMenu()
{ {
@@ -24,8 +25,14 @@ namespace Content.Client.VendingMachines.UI
RobustXamlLoader.Load(this); RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this); IoCManager.InjectDependencies(this);
SearchBar.OnTextChanged += _ =>
{
OnSearchChanged?.Invoke(SearchBar.Text);
};
VendingContents.OnItemSelected += args => VendingContents.OnItemSelected += args =>
{ {
SearchBar.Text = string.Empty;
OnItemSelected?.Invoke(args); OnItemSelected?.Invoke(args);
}; };
} }
@@ -34,14 +41,14 @@ namespace Content.Client.VendingMachines.UI
/// Populates the list of available items on the vending machine interface /// Populates the list of available items on the vending machine interface
/// and sets icons based on their prototypes /// and sets icons based on their prototypes
/// </summary> /// </summary>
public void Populate(List<VendingMachineInventoryEntry> inventory) public void Populate(List<VendingMachineInventoryEntry> inventory, string? filter = null)
{ {
if (inventory.Count == 0) if (inventory.Count == 0)
{ {
VendingContents.Clear(); VendingContents.Clear();
var outOfStockText = Loc.GetString("vending-machine-component-try-eject-out-of-stock"); var outOfStockText = Loc.GetString("vending-machine-component-try-eject-out-of-stock");
VendingContents.AddItem(outOfStockText); VendingContents.AddItem(outOfStockText);
SetSizeAfterUpdate(outOfStockText.Length); SetSizeAfterUpdate(outOfStockText.Length, VendingContents.Count);
return; return;
} }
@@ -56,10 +63,11 @@ namespace Content.Client.VendingMachines.UI
var longestEntry = string.Empty; var longestEntry = string.Empty;
var spriteSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<SpriteSystem>(); var spriteSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<SpriteSystem>();
var filterCount = 0;
for (var i = 0; i < inventory.Count; i++) for (var i = 0; i < inventory.Count; i++)
{ {
var entry = inventory[i]; var entry = inventory[i];
var vendingItem = VendingContents[i]; var vendingItem = VendingContents[i - filterCount];
vendingItem.Text = string.Empty; vendingItem.Text = string.Empty;
vendingItem.Icon = null; vendingItem.Icon = null;
@@ -71,6 +79,15 @@ namespace Content.Client.VendingMachines.UI
icon = spriteSystem.GetPrototypeIcon(prototype).Default; icon = spriteSystem.GetPrototypeIcon(prototype).Default;
} }
// search filter
if (!string.IsNullOrEmpty(filter) &&
!itemName.ToLowerInvariant().Contains(filter.Trim().ToLowerInvariant()))
{
VendingContents.Remove(vendingItem);
filterCount++;
continue;
}
if (itemName.Length > longestEntry.Length) if (itemName.Length > longestEntry.Length)
longestEntry = itemName; longestEntry = itemName;
@@ -78,13 +95,13 @@ namespace Content.Client.VendingMachines.UI
vendingItem.Icon = icon; vendingItem.Icon = icon;
} }
SetSizeAfterUpdate(longestEntry.Length); SetSizeAfterUpdate(longestEntry.Length, inventory.Count);
} }
private void SetSizeAfterUpdate(int longestEntryLength) private void SetSizeAfterUpdate(int longestEntryLength, int contentCount)
{ {
SetSize = new Vector2(Math.Clamp((longestEntryLength + 2) * 12, 250, 300), SetSize = new Vector2(Math.Clamp((longestEntryLength + 2) * 12, 250, 300),
Math.Clamp(VendingContents.Count * 50, 150, 350)); Math.Clamp(contentCount * 50, 150, 350));
} }
} }
} }

View File

@@ -30,6 +30,7 @@ namespace Content.Client.VendingMachines
_menu.OnClose += Close; _menu.OnClose += Close;
_menu.OnItemSelected += OnItemSelected; _menu.OnItemSelected += OnItemSelected;
_menu.OnSearchChanged += OnSearchChanged;
_menu.Populate(_cachedInventory); _menu.Populate(_cachedInventory);
@@ -74,5 +75,10 @@ namespace Content.Client.VendingMachines
_menu.OnClose -= Close; _menu.OnClose -= Close;
_menu.Dispose(); _menu.Dispose();
} }
private void OnSearchChanged(string? filter)
{
_menu?.Populate(_cachedInventory, filter);
}
} }
} }

View File

@@ -3,3 +3,4 @@
vending-machine-component-try-eject-invalid-item = Invalid item vending-machine-component-try-eject-invalid-item = Invalid item
vending-machine-component-try-eject-out-of-stock = Out of stock vending-machine-component-try-eject-out-of-stock = Out of stock
vending-machine-component-try-eject-access-denied = Access denied vending-machine-component-try-eject-access-denied = Access denied
vending-machine-component-search-filter = Search...