using UnityEngine; using System; using System.Collections.Generic; namespace Projectiles.UI { public class UIList : UIListBase { } public abstract class UIListBase : UIBehaviour where TListItem: UIListItemBase where RContent: MonoBehaviour { // PUBLIC MEMBERS public event Action UpdateContent; public event Action SelectionChanged; public int Selection { get { return _selection; } set { SetSelection(value, false); } } public int Count => _dataCount; // PRIVATE MEMBERS [SerializeField] private bool _allowSelection = true; [SerializeField] private bool _allowDeselection = true; [SerializeField] private TListItem _itemInstance; private List _items = new List(32); private int _dataCount; private int _selection = -1; // PUBLIC METHODS public void Refresh(int dataCount, bool notifySelection = true) { _dataCount = dataCount; UpdateItems(); if (_selection >= _dataCount) { SetSelection(_allowDeselection == false && _dataCount > 0 ? 0 : -1, notifySelection, true); } else if(_selection < 0 && _allowDeselection == false && _dataCount > 0) { SetSelection(0, notifySelection, true); } else { SetSelection(_selection, false, true); } } public void Clear(bool destroyItems = true) { _dataCount = 0; if (destroyItems == true) { _itemInstance.SetActive(false); for (int i = 1; i < _items.Count; i++) { Destroy(_items[i].gameObject); } _items.Clear(); } else { UpdateItems(); } if (_selection >= 0) { SetSelection(-1, true); } } // MONOBEHAVIOR protected void Awake() { if (_dataCount == 0) { _itemInstance.SetActive(false); } } // PRIVATE METHODS private void SetSelection(int selection, bool notify, bool force = false) { if (_allowSelection == false) return; if (selection >= _dataCount) return; if (selection == _selection && force == false) return; if (selection < 0) { selection = -1; } _selection = selection; for (int i = 0; i < _dataCount; i++) { var item = _items[i]; item.IsSelected = item.Id == _selection; } if (notify == true) { SelectionChanged?.Invoke(_selection); } } private void UpdateItems() { bool selectable = _itemInstance.IsSelectable; var parent = _itemInstance.transform.parent; for (int i = _items.Count; i < _dataCount; i++) { var newItem = i == 0 ? _itemInstance : Instantiate(_itemInstance, parent); newItem.Id = i; if (selectable == true) { newItem.Clicked -= OnItemClicked; newItem.Clicked += OnItemClicked; } _items.Add(newItem); } for (int i = 0; i < _items.Count; i++) { var item = _items[i]; if (i < _dataCount) { UpdateContent?.Invoke(i, item.Content); item.SetActive(true); } else { item.SetActive(false); } } } private void OnItemClicked(int id) { if (id == _selection && _allowDeselection == false) return; SetSelection(id == _selection ? -1 : id, true); } } }