using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using System.Collections.Generic; using System.Linq; using System; namespace UIWidgets { /// /// Base class for creating own tabs. /// public class TabsCustom : MonoBehaviour where TTab : Tab where TButton : TabButton { /// /// The container for tab toggle buttons. /// [SerializeField] public Transform Container; /// /// The default tab button. /// [SerializeField] public TButton DefaultTabButton; /// /// The active tab button. /// [SerializeField] public TButton ActiveTabButton; [SerializeField] TTab[] tabObjects = new TTab[]{}; /// /// Gets or sets the tab objects. /// /// The tab objects. public TTab[] TabObjects { get { return tabObjects; } set { tabObjects = value; UpdateButtons(); } } /// /// The name of the default tab. /// [SerializeField] [Tooltip("Tab name which will be active by default, if not specified will be opened first Tab.")] public string DefaultTabName = string.Empty; /// /// If true does not deactivate hidden tabs. /// [SerializeField] [Tooltip("If true does not deactivate hidden tabs.")] public bool KeepTabsActive = false; /// /// OnTabSelect event. /// [SerializeField] public TabSelectEvent OnTabSelect = new TabSelectEvent(); /// /// Gets or sets the selected tab. /// /// The selected tab. public TTab SelectedTab { get; protected set; } List defaultButtons = new List(); List activeButtons = new List(); List callbacks = new List(); bool isStarted; /// /// Start this instance. /// public void Start() { if (isStarted) { return ; } isStarted = true; 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(); } /// /// Updates the buttons. /// void UpdateButtons() { if (tabObjects.Length==0) { throw new ArgumentException("TabObjects array is empty. Fill it."); } RemoveCallbacks(); CreateButtons(); AddCallbacks(); if (DefaultTabName!="") { var tab = GetTabByName(DefaultTabName); if (tab!=null) { SelectTab(tab); } else { Debug.LogWarning(string.Format("Tab with specified DefaultTabName \"{0}\" not found. Opened first Tab.", DefaultTabName), this); SelectTab(tabObjects[0]); } } else { SelectTab(tabObjects[0]); } } TTab GetTabByName(string tabName) { return tabObjects.FirstOrDefault(x => x.Name==tabName); } void AddCallback(TTab tab, int index) { UnityAction callback = () => SelectTab(tab); callbacks.Add(callback); defaultButtons[index].onClick.AddListener(callbacks[index]); } void AddCallbacks() { tabObjects.ForEach(AddCallback); } void RemoveCallback(TTab tab, int index) { if ((tab!=null) && (index < callbacks.Count)) { defaultButtons[index].onClick.RemoveListener(callbacks[index]); } } void RemoveCallbacks() { if (callbacks.Count > 0) { tabObjects.ForEach(RemoveCallback); callbacks.Clear(); } } void OnDestroy() { RemoveCallbacks(); } /// /// Selects the tab. /// /// Tab name. public void SelectTab(string tabName) { var tab = GetTabByName(tabName); if (tab!=null) { SelectTab(tab); } else { Debug.LogWarning(string.Format("Tab with specified name \"{0}\" not found.", tabName), this); } } /// /// Selects the tab. /// /// Tab. public void SelectTab(TTab tab) { var index = Array.IndexOf(tabObjects, tab); if (index==-1) { throw new ArgumentException(string.Format("Tab with name \"{0}\" not found.", tab.Name)); } SelectedTab = tabObjects[index]; if (KeepTabsActive) { tabObjects[index].TabObject.transform.SetAsLastSibling(); } else { tabObjects.ForEach(DeactivateTab); tabObjects[index].TabObject.SetActive(true); } defaultButtons.ForEach(ActivateButton); defaultButtons[index].gameObject.SetActive(false); activeButtons.ForEach(DeactivateButton); activeButtons[index].gameObject.SetActive(true); OnTabSelect.Invoke(index); } void DeactivateTab(TTab tab) { tab.TabObject.SetActive(false); } void ActivateButton(TButton button) { button.gameObject.SetActive(true); } void DeactivateButton(TButton button) { button.gameObject.SetActive(false); } /// /// Creates the buttons. /// void CreateButtons() { if (tabObjects.Length > defaultButtons.Count) { for (var i = defaultButtons.Count; i < tabObjects.Length; i++) { var defaultButton = Instantiate(DefaultTabButton) as TButton; defaultButton.transform.SetParent(Container, false); //Utilites.FixInstantiated(DefaultTabButton, defaultButton); defaultButtons.Add(defaultButton); var activeButton = Instantiate(ActiveTabButton) as TButton; activeButton.transform.SetParent(Container, false); //Utilites.FixInstantiated(ActiveTabButton, activeButton); activeButtons.Add(activeButton); } } //del existing ui elements if necessary if (tabObjects.Length < defaultButtons.Count) { for (var i = defaultButtons.Count; i > tabObjects.Length; i--) { Destroy(defaultButtons[i]); Destroy(activeButtons[i]); defaultButtons.RemoveAt(i); activeButtons.RemoveAt(i); } } defaultButtons.ForEach(SetButtonData); activeButtons.ForEach(SetButtonData); } /// /// Sets the name of the button. /// /// Button. /// Index. protected virtual void SetButtonData(TButton button, int index) { //button.SetData(tabObjects[index]); } } }