]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Make vending machine use EntityPrototypeView (#30064)
authorWinkarst <74284083+Winkarst-cpu@users.noreply.github.com>
Thu, 22 Aug 2024 14:40:39 +0000 (17:40 +0300)
committerGitHub <noreply@github.com>
Thu, 22 Aug 2024 14:40:39 +0000 (10:40 -0400)
* Make vendor machines use EntityPrototypeView

* Update

* 1

* Kill me

* For the love of god!!!

Content.Client/VendingMachines/UI/VendingMachineItem.xaml [new file with mode: 0644]
Content.Client/VendingMachines/UI/VendingMachineItem.xaml.cs [new file with mode: 0644]
Content.Client/VendingMachines/UI/VendingMachineMenu.xaml
Content.Client/VendingMachines/UI/VendingMachineMenu.xaml.cs
Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs

diff --git a/Content.Client/VendingMachines/UI/VendingMachineItem.xaml b/Content.Client/VendingMachines/UI/VendingMachineItem.xaml
new file mode 100644 (file)
index 0000000..a665b72
--- /dev/null
@@ -0,0 +1,16 @@
+<BoxContainer xmlns="https://spacestation14.io"
+            Orientation="Horizontal"
+            HorizontalExpand="True"
+            SeparationOverride="4">
+    <EntityPrototypeView
+            Name="ItemPrototype"
+            Margin="4 4"
+            HorizontalAlignment="Center"
+            VerticalAlignment="Center"
+            MinSize="32 32"
+            />
+    <Label Name="NameLabel"
+            SizeFlagsStretchRatio="3"
+            HorizontalExpand="True"
+            ClipText="True"/>
+</BoxContainer>
diff --git a/Content.Client/VendingMachines/UI/VendingMachineItem.xaml.cs b/Content.Client/VendingMachines/UI/VendingMachineItem.xaml.cs
new file mode 100644 (file)
index 0000000..a721293
--- /dev/null
@@ -0,0 +1,19 @@
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+using Robust.Shared.Prototypes;
+
+namespace Content.Client.VendingMachines.UI;
+
+[GenerateTypedNameReferences]
+public sealed partial class VendingMachineItem : BoxContainer
+{
+    public VendingMachineItem(EntProtoId entProto, string text)
+    {
+        RobustXamlLoader.Load(this);
+
+        ItemPrototype.SetPrototype(entProto);
+
+        NameLabel.Text = text;
+    }
+}
index 1fcb1a7898cda7d8fe9b58b2abacb4f417388ef8..f43f4bdc3629b734d8e16e898929b98bb06d2c00 100644 (file)
@@ -2,17 +2,10 @@
     xmlns="https://spacestation14.io"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
-    xmlns:style="clr-namespace:Content.Client.Stylesheets">
-    <BoxContainer Orientation="Vertical">
-        <LineEdit Name="SearchBar" PlaceHolder="{Loc 'vending-machine-component-search-filter'}" HorizontalExpand="True"  Margin ="4 4" Access="Public"/>
-        <ItemList Name="VendingContents"
-                  SizeFlagsStretchRatio="8"
-                  VerticalExpand="True"
-                  ItemSeparation="2"
-                  Margin="4 0"
-                  SelectMode="Button"
-                  StyleClasses="transparentBackgroundItemList">
-        </ItemList>
+    xmlns:co="clr-namespace:Content.Client.UserInterface.Controls">
+    <BoxContainer Name="MainContainer" Orientation="Vertical">
+        <LineEdit Name="SearchBar" PlaceHolder="{Loc 'vending-machine-component-search-filter'}" HorizontalExpand="True"  Margin ="4 4"/>
+        <co:SearchListContainer Name="VendingContents" VerticalExpand="True" Margin="4 0"/>
          <!-- Footer -->
         <BoxContainer Orientation="Vertical">
             <PanelContainer StyleClasses="LowDivider" />
index ac51cdbac5e6f368707f514b3d24a863343afc06..efe6ef8e9ab35df6e94af35b1afd5abf312922cf 100644 (file)
@@ -1,14 +1,13 @@
 using System.Numerics;
 using Content.Shared.VendingMachines;
 using Robust.Client.AutoGenerated;
-using Robust.Client.GameObjects;
-using Robust.Client.Graphics;
 using Robust.Client.UserInterface.Controls;
 using Robust.Client.UserInterface.XAML;
 using Robust.Shared.Prototypes;
 using FancyWindow = Content.Client.UserInterface.Controls.FancyWindow;
-using Content.Shared.IdentityManagement;
-using Robust.Shared.Timing;
+using Robust.Client.UserInterface;
+using Content.Client.UserInterface.Controls;
+using Robust.Client.Graphics;
 
 namespace Content.Client.VendingMachines.UI
 {
@@ -16,12 +15,10 @@ namespace Content.Client.VendingMachines.UI
     public sealed partial class VendingMachineMenu : FancyWindow
     {
         [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
-        [Dependency] private readonly IEntityManager _entityManager = default!;
 
-        private readonly Dictionary<EntProtoId, EntityUid> _dummies = [];
+        public event Action<GUIBoundKeyEventArgs, ListData>? OnItemSelected;
 
-        public event Action<ItemList.ItemListSelectedEventArgs>? OnItemSelected;
-        public event Action<string>? OnSearchChanged;
+        private readonly StyleBoxFlat _styleBox = new() { BackgroundColor = new Color(70, 73, 102) };
 
         public VendingMachineMenu()
         {
@@ -29,106 +26,90 @@ namespace Content.Client.VendingMachines.UI
             RobustXamlLoader.Load(this);
             IoCManager.InjectDependencies(this);
 
-            SearchBar.OnTextChanged += _ =>
-            {
-                OnSearchChanged?.Invoke(SearchBar.Text);
-            };
-
-            VendingContents.OnItemSelected += args =>
-            {
-                OnItemSelected?.Invoke(args);
-            };
+            VendingContents.SearchBar = SearchBar;
+            VendingContents.DataFilterCondition += DataFilterCondition;
+            VendingContents.GenerateItem += GenerateButton;
+            VendingContents.ItemKeyBindDown += (args, data) => OnItemSelected?.Invoke(args, data);
         }
 
-        protected override void Dispose(bool disposing)
+        private bool DataFilterCondition(string filter, ListData data)
         {
-            base.Dispose(disposing);
+            if (data is not VendorItemsListData { ItemText: var text })
+                return false;
+
+            if (string.IsNullOrEmpty(filter))
+                return true;
+
+            return text.Contains(filter, StringComparison.CurrentCultureIgnoreCase);
+        }
 
-            // Don't clean up dummies during disposal or we'll just have to spawn them again
-            if (!disposing)
+        private void GenerateButton(ListData data, ListContainerButton button)
+        {
+            if (data is not VendorItemsListData { ItemProtoID: var protoID, ItemText: var text })
                 return;
 
-            // Delete any dummy items we spawned
-            foreach (var entity in _dummies.Values)
-            {
-                _entityManager.QueueDeleteEntity(entity);
-            }
-            _dummies.Clear();
+            button.AddChild(new VendingMachineItem(protoID, text));
+
+            button.ToolTip = text;
+            button.StyleBoxOverride = _styleBox;
         }
 
         /// <summary>
         /// Populates the list of available items on the vending machine interface
         /// and sets icons based on their prototypes
         /// </summary>
-        public void Populate(List<VendingMachineInventoryEntry> inventory, out List<int> filteredInventory,  string? filter = null)
+        public void Populate(List<VendingMachineInventoryEntry> inventory)
         {
-            filteredInventory = new();
-
-            if (inventory.Count == 0)
+            if (inventory.Count == 0 && VendingContents.Visible)
             {
-                VendingContents.Clear();
-                var outOfStockText = Loc.GetString("vending-machine-component-try-eject-out-of-stock");
-                VendingContents.AddItem(outOfStockText);
-                SetSizeAfterUpdate(outOfStockText.Length, VendingContents.Count);
-                return;
-            }
+                SearchBar.Visible = false;
+                VendingContents.Visible = false;
 
-            while (inventory.Count != VendingContents.Count)
-            {
-                if (inventory.Count > VendingContents.Count)
-                    VendingContents.AddItem(string.Empty);
-                else
-                    VendingContents.RemoveAt(VendingContents.Count - 1);
+                var outOfStockLabel = new Label()
+                {
+                    Text = Loc.GetString("vending-machine-component-try-eject-out-of-stock"),
+                    Margin = new Thickness(4, 4),
+                    HorizontalExpand = true,
+                    VerticalAlignment = VAlignment.Stretch,
+                    HorizontalAlignment = HAlignment.Center
+                };
+
+                MainContainer.AddChild(outOfStockLabel);
+
+                SetSizeAfterUpdate(outOfStockLabel.Text.Length, 0);
+
+                return;
             }
 
             var longestEntry = string.Empty;
-            var spriteSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<SpriteSystem>();
+            var listData = new List<VendorItemsListData>();
 
-            var filterCount = 0;
             for (var i = 0; i < inventory.Count; i++)
             {
                 var entry = inventory[i];
-                var vendingItem = VendingContents[i - filterCount];
-                vendingItem.Text = string.Empty;
-                vendingItem.Icon = null;
-
-                if (!_dummies.TryGetValue(entry.ID, out var dummy))
-                {
-                    dummy = _entityManager.Spawn(entry.ID);
-                    _dummies.Add(entry.ID, dummy);
-                }
-
-                var itemName = Identity.Name(dummy, _entityManager);
-                Texture? icon = null;
-                if (_prototypeManager.TryIndex<EntityPrototype>(entry.ID, out var prototype))
-                {
-                    icon = spriteSystem.GetPrototypeIcon(prototype).Default;
-                }
 
-                // search filter
-                if (!string.IsNullOrEmpty(filter) &&
-                    !itemName.ToLowerInvariant().Contains(filter.Trim().ToLowerInvariant()))
-                {
-                    VendingContents.Remove(vendingItem);
-                    filterCount++;
+                if (!_prototypeManager.TryIndex(entry.ID, out var prototype))
                     continue;
-                }
 
-                if (itemName.Length > longestEntry.Length)
-                    longestEntry = itemName;
+                var itemText = $"{prototype.Name} [{entry.Amount}]";
 
-                vendingItem.Text = $"{itemName} [{entry.Amount}]";
-                vendingItem.Icon = icon;
-                filteredInventory.Add(i);
+                if (itemText.Length > longestEntry.Length)
+                    longestEntry = itemText;
+
+                listData.Add(new VendorItemsListData(prototype.ID, itemText, i));
             }
 
+            VendingContents.PopulateList(listData);
+
             SetSizeAfterUpdate(longestEntry.Length, inventory.Count);
         }
 
         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, 400),
                 Math.Clamp(contentCount * 50, 150, 350));
         }
     }
 }
+
+public record VendorItemsListData(EntProtoId ItemProtoID, string ItemText, int ItemIndex) : ListData;
index eafab84ed6381b0f7605326b048f70eba200ff2a..797360d1712dadaaf584a84c4f7d7aa5fe32a7f9 100644 (file)
@@ -1,6 +1,9 @@
+using Content.Client.UserInterface.Controls;
 using Content.Client.VendingMachines.UI;
 using Content.Shared.VendingMachines;
+using Robust.Client.UserInterface;
 using Robust.Client.UserInterface.Controls;
+using Robust.Shared.Input;
 using System.Linq;
 using Robust.Client.UserInterface;
 
@@ -14,9 +17,6 @@ namespace Content.Client.VendingMachines
         [ViewVariables]
         private List<VendingMachineInventoryEntry> _cachedInventory = new();
 
-        [ViewVariables]
-        private List<int> _cachedFilteredIndex = new();
-
         public VendingMachineBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
         {
         }
@@ -34,9 +34,10 @@ namespace Content.Client.VendingMachines
             _menu.Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName;
 
             _menu.OnItemSelected += OnItemSelected;
-            _menu.OnSearchChanged += OnSearchChanged;
 
-            _menu.Populate(_cachedInventory, out _cachedFilteredIndex);
+            _menu.Populate(_cachedInventory);
+
+            _menu.OpenCenteredLeft();
         }
 
         protected override void UpdateState(BoundUserInterfaceState state)
@@ -48,15 +49,21 @@ namespace Content.Client.VendingMachines
 
             _cachedInventory = newState.Inventory;
 
-            _menu?.Populate(_cachedInventory, out _cachedFilteredIndex, _menu.SearchBar.Text);
+            _menu?.Populate(_cachedInventory);
         }
 
-        private void OnItemSelected(ItemList.ItemListSelectedEventArgs args)
+        private void OnItemSelected(GUIBoundKeyEventArgs args, ListData data)
         {
+            if (args.Function != EngineKeyFunctions.UIClick)
+                return;
+
+            if (data is not VendorItemsListData { ItemIndex: var itemIndex })
+                return;
+
             if (_cachedInventory.Count == 0)
                 return;
 
-            var selectedItem = _cachedInventory.ElementAtOrDefault(_cachedFilteredIndex.ElementAtOrDefault(args.ItemIndex));
+            var selectedItem = _cachedInventory.ElementAtOrDefault(itemIndex);
 
             if (selectedItem == null)
                 return;
@@ -77,10 +84,5 @@ namespace Content.Client.VendingMachines
             _menu.OnClose -= Close;
             _menu.Dispose();
         }
-
-        private void OnSearchChanged(string? filter)
-        {
-            _menu?.Populate(_cachedInventory, out _cachedFilteredIndex, filter);
-        }
     }
 }