using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; namespace UIWidgets { [AddComponentMenu("UI/ListViewGameObjects", 255)] public class ListViewGameObjects : ListViewBase { [SerializeField] private List objects = new List(); private List> callbacksEnter = new List>(); private List> callbacksExit = new List>(); public Func, IEnumerable> SortFunc; public ListViewGameObjectsEvent OnSelectObject = new ListViewGameObjectsEvent(); public ListViewGameObjectsEvent OnDeselectObject = new ListViewGameObjectsEvent(); public ListViewGameObjectsEvent OnPointerEnterObject = new ListViewGameObjectsEvent(); public ListViewGameObjectsEvent OnPointerExitObject = new ListViewGameObjectsEvent(); [NonSerialized] private bool isStartedListViewGameObjects; public List Objects { get { return new List(objects); } private set { UpdateItems(value); } } private void Awake() { Start(); } public override void Start() { if (!isStartedListViewGameObjects) { isStartedListViewGameObjects = true; base.Start(); DestroyGameObjects = true; UpdateItems(); OnSelect.AddListener(OnSelectCallback); OnDeselect.AddListener(OnDeselectCallback); } } private void OnSelectCallback(int index, ListViewItem item) { OnSelectObject.Invoke(index, objects[index]); } private void OnDeselectCallback(int index, ListViewItem item) { OnDeselectObject.Invoke(index, objects[index]); } private void OnPointerEnterCallback(int index) { OnPointerEnterObject.Invoke(index, objects[index]); } private void OnPointerExitCallback(int index) { OnPointerExitObject.Invoke(index, objects[index]); } public override void UpdateItems() { UpdateItems(objects); } public virtual int Add(GameObject item) { List list = Objects; list.Add(item); UpdateItems(list); return objects.IndexOf(item); } public virtual int Remove(GameObject item) { int num = objects.IndexOf(item); if (num == -1) { return num; } List list = Objects; list.Remove(item); UpdateItems(list); return num; } private void RemoveCallback(ListViewItem item, int index) { if (!(item == null)) { if (index < callbacksEnter.Count) { item.onPointerEnter.RemoveListener(callbacksEnter[index]); } if (index < callbacksExit.Count) { item.onPointerExit.RemoveListener(callbacksExit[index]); } } } private void RemoveCallbacks() { base.Items.ForEach(RemoveCallback); callbacksEnter.Clear(); callbacksExit.Clear(); } private void AddCallbacks() { base.Items.ForEach(AddCallback); } private void AddCallback(ListViewItem item, int index) { callbacksEnter.Add(delegate { OnPointerEnterCallback(index); }); callbacksExit.Add(delegate { OnPointerExitCallback(index); }); item.onPointerEnter.AddListener(callbacksEnter[index]); item.onPointerExit.AddListener(callbacksExit[index]); } private List SortItems(IEnumerable newItems) { IEnumerable enumerable = newItems; if (SortFunc != null) { enumerable = SortFunc(enumerable); } return enumerable.ToList(); } public override void Clear() { if (DestroyGameObjects) { objects.ForEach(UnityEngine.Object.Destroy); } UpdateItems(new List()); } private void UpdateItems(List newItems) { RemoveCallbacks(); newItems = SortItems(newItems); List second = (from x in base.SelectedIndicies select (objects.Count <= x) ? (-1) : newItems.IndexOf(objects[x]) into x where x != -1 select x).ToList(); base.SelectedIndicies.Except(second).ForEach(base.Deselect); objects = newItems; base.Items = newItems.Convert((GameObject x) => x.GetComponent() ?? x.AddComponent()); base.SelectedIndicies = second; AddCallbacks(); } protected override void OnDestroy() { OnSelect.RemoveListener(OnSelectCallback); OnDeselect.RemoveListener(OnDeselectCallback); RemoveCallbacks(); base.OnDestroy(); } } }