using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.UIElements; #if UNITY_EDITOR using UnityEditor; #endif namespace NEG.Utils.UiToolkits { public class MultiSelectChips : VisualElement { private readonly List spawnedItems = new(); private readonly VisualTreeAsset itemPrefab; private ICollection itemsSource; private Label label; private VisualElement realItemsParent; public MultiSelectChips() { #if UNITY_EDITOR string path = AssetDatabase.GUIDToAssetPath(AssetDatabase.FindAssets($"t:Script {nameof(MultiSelectChips)}")[0]); path = path.Remove(path.LastIndexOf('/')); SetVisuals(AssetDatabase.LoadAssetAtPath($"{path}/Resources/MultiSelectChips.uxml")); itemPrefab = AssetDatabase.LoadAssetAtPath($"{path}/Resources/MultiSelectChipItem.uxml"); #else SetVisuals(Resources.Load("MultiSelectChips.uxml")); itemPrefab = Resources.Load("MultiSelectChipItem.uxml"); #endif } public string LabelText { get => label.text; set { if (!string.IsNullOrEmpty(value)) { if (label == null) InitLabel(); label.text = value; } else if (label != null) { label.RemoveFromHierarchy(); label = null; } } } public ICollection ItemsSource { get => itemsSource; set { itemsSource = value; UpdateItems(); } } public event Action OnTryingToRemoveItem; public event Action OnTryingToAddItem; public void UpdateItems() { if (itemPrefab == null || itemsSource == null || realItemsParent == null) return; var itemsToDestroy = new List(spawnedItems); itemsToDestroy.RemoveAll(x => itemsSource.Contains(x.ChipItem)); foreach (var item in itemsToDestroy) { realItemsParent.Remove(item.VisualElement); spawnedItems.Remove(item); } List itemsToAdd = new(itemsSource); foreach (var item in spawnedItems) if (itemsToAdd.Contains(item.ChipItem)) itemsToAdd.Remove(item.ChipItem); foreach (var item in itemsToAdd) { VisualElement chipItemVisuals = itemPrefab.Instantiate(); realItemsParent.Insert(0, chipItemVisuals); spawnedItems.Add(new MultiSelectChipItem(chipItemVisuals, item, this)); } } public void TryRemoveItem(IMultiSelectChipItem item) => OnTryingToRemoveItem?.Invoke(item); private void InitLabel() { label = new Label { pickingMode = PickingMode.Ignore }; Insert(0, label); } private void SetVisuals(VisualTreeAsset treeAsset) { realItemsParent = treeAsset.Instantiate(); Add(realItemsParent); var button = realItemsParent.Q