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]);
}
}
}