using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; namespace UIWidgets { public class TabsCustom : MonoBehaviour where TTab : Tab where TButton : TabButton { [SerializeField] public Transform Container; [SerializeField] public TButton DefaultTabButton; [SerializeField] public TButton ActiveTabButton; [SerializeField] private TTab[] tabObjects = new TTab[0]; [Tooltip("If true does not deactivate hidden tabs.")] [SerializeField] public bool KeepTabsActive; [SerializeField] public TabSelectEvent OnTabSelect = new TabSelectEvent(); private List defaultButtons = new List(); private List activeButtons = new List(); private List callbacks = new List(); public TTab[] TabObjects { get { return tabObjects; } set { tabObjects = value; UpdateButtons(); } } public TTab SelectedTab { get; protected set; } private void Start() { if (Container == null) { throw new NullReferenceException("Container is null. Set object of type GameObject to Container."); } if (DefaultTabButton == null) { throw new NullReferenceException("DefaultTabButton is null. Set object of type GameObject to DefaultTabButton."); } if (ActiveTabButton == null) { throw new NullReferenceException("ActiveTabButton is null. Set object of type GameObject to ActiveTabButton."); } DefaultTabButton.gameObject.SetActive(false); ActiveTabButton.gameObject.SetActive(false); UpdateButtons(); } private void UpdateButtons() { if (tabObjects.Length == 0) { throw new ArgumentException("TabObjects array is empty. Fill it."); } RemoveCallbacks(); CreateButtons(); AddCallbacks(); SelectTab(tabObjects[0]); } private void AddCallback(TTab tab, int index) { UnityAction item = delegate { SelectTab(tab); }; callbacks.Add(item); TButton val = defaultButtons[index]; val.onClick.AddListener(callbacks[index]); } private void AddCallbacks() { tabObjects.ForEach(AddCallback); } private void RemoveCallback(TTab tab, int index) { if (tab != null && index < callbacks.Count) { TButton val = defaultButtons[index]; val.onClick.RemoveListener(callbacks[index]); } } private void RemoveCallbacks() { if (callbacks.Count > 0) { tabObjects.ForEach(RemoveCallback); callbacks.Clear(); } } private void OnDestroy() { RemoveCallbacks(); } public void SelectTab(TTab tab) { int num = Array.IndexOf(tabObjects, tab); if (num == -1) { throw new ArgumentException(string.Format("Tab with name \"{0}\" not found.", tab.Name)); } SelectedTab = tabObjects[num]; if (KeepTabsActive) { tabObjects[num].TabObject.transform.SetAsLastSibling(); } else { tabObjects.ForEach(DeactivateTab); tabObjects[num].TabObject.SetActive(true); } defaultButtons.ForEach(ActivateButton); TButton val = defaultButtons[num]; val.gameObject.SetActive(false); activeButtons.ForEach(DeactivateButton); TButton val2 = activeButtons[num]; val2.gameObject.SetActive(true); OnTabSelect.Invoke(num); } private void DeactivateTab(TTab tab) { tab.TabObject.SetActive(false); } private void ActivateButton(TButton button) { button.gameObject.SetActive(true); } private void DeactivateButton(TButton button) { button.gameObject.SetActive(false); } private void CreateButtons() { if (tabObjects.Length > defaultButtons.Count) { for (int i = defaultButtons.Count; i < tabObjects.Length; i++) { TButton item = UnityEngine.Object.Instantiate(DefaultTabButton); item.transform.SetParent(Container, false); defaultButtons.Add(item); TButton item2 = UnityEngine.Object.Instantiate(ActiveTabButton); item2.transform.SetParent(Container, false); activeButtons.Add(item2); } } if (tabObjects.Length < defaultButtons.Count) { for (int num = defaultButtons.Count; num > tabObjects.Length; num--) { UnityEngine.Object.Destroy(defaultButtons[num]); UnityEngine.Object.Destroy(activeButtons[num]); defaultButtons.RemoveAt(num); activeButtons.RemoveAt(num); } } defaultButtons.ForEach(SetButtonData); activeButtons.ForEach(SetButtonData); } protected virtual void SetButtonData(TButton button, int index) { } } }