You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
298 lines
6.6 KiB
298 lines
6.6 KiB
2 years ago
|
using UnityEngine;
|
||
|
using UnityEngine.Events;
|
||
|
using UnityEngine.UI;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Linq;
|
||
|
using System;
|
||
|
|
||
|
namespace UIWidgets
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// TabSelectEvent.
|
||
|
/// </summary>
|
||
|
[Serializable]
|
||
|
public class TabSelectEvent : UnityEvent<int>
|
||
|
{
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Tabs.
|
||
|
/// http://ilih.ru/images/unity-assets/UIWidgets/Tabs.png
|
||
|
/// </summary>
|
||
|
[AddComponentMenu("UI/UIWidgets/Tabs")]
|
||
|
public class Tabs : MonoBehaviour
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// The container for tab toggle buttons.
|
||
|
/// </summary>
|
||
|
[SerializeField]
|
||
|
public Transform Container;
|
||
|
|
||
|
/// <summary>
|
||
|
/// The default tab button.
|
||
|
/// </summary>
|
||
|
[SerializeField]
|
||
|
public Button DefaultTabButton;
|
||
|
|
||
|
/// <summary>
|
||
|
/// The active tab button.
|
||
|
/// </summary>
|
||
|
[SerializeField]
|
||
|
public Button ActiveTabButton;
|
||
|
|
||
|
[SerializeField]
|
||
|
Tab[] tabObjects = new Tab[]{};
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets or sets the tab objects.
|
||
|
/// </summary>
|
||
|
/// <value>The tab objects.</value>
|
||
|
public Tab[] TabObjects {
|
||
|
get {
|
||
|
return tabObjects;
|
||
|
}
|
||
|
set {
|
||
|
tabObjects = value;
|
||
|
UpdateButtons();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The name of the default tab.
|
||
|
/// </summary>
|
||
|
[SerializeField]
|
||
|
[Tooltip("Tab name which will be active by default, if not specified will be opened first Tab.")]
|
||
|
public string DefaultTabName = string.Empty;
|
||
|
|
||
|
/// <summary>
|
||
|
/// If true does not deactivate hidden tabs.
|
||
|
/// </summary>
|
||
|
[SerializeField]
|
||
|
[Tooltip("If true does not deactivate hidden tabs.")]
|
||
|
public bool KeepTabsActive = false;
|
||
|
|
||
|
/// <summary>
|
||
|
/// OnTabSelect event.
|
||
|
/// </summary>
|
||
|
[SerializeField]
|
||
|
public TabSelectEvent OnTabSelect = new TabSelectEvent();
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets or sets the selected tab.
|
||
|
/// </summary>
|
||
|
/// <value>The selected tab.</value>
|
||
|
public Tab SelectedTab {
|
||
|
get;
|
||
|
protected set;
|
||
|
}
|
||
|
|
||
|
List<Button> defaultButtons = new List<Button>();
|
||
|
List<Button> activeButtons = new List<Button>();
|
||
|
List<UnityAction> callbacks = new List<UnityAction>();
|
||
|
|
||
|
/// <summary>
|
||
|
/// Start this instance.
|
||
|
/// </summary>
|
||
|
public 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();
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Updates the buttons.
|
||
|
/// </summary>
|
||
|
void UpdateButtons()
|
||
|
{
|
||
|
if (tabObjects.Length==0)
|
||
|
{
|
||
|
throw new ArgumentException("TabObjects array is empty. Fill it.");
|
||
|
}
|
||
|
|
||
|
RemoveCallbacks();
|
||
|
|
||
|
CreateButtons();
|
||
|
|
||
|
AddCallbacks();
|
||
|
|
||
|
if (DefaultTabName!="")
|
||
|
{
|
||
|
if (IsExistsTabName(DefaultTabName))
|
||
|
{
|
||
|
SelectTab(DefaultTabName);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Debug.LogWarning(string.Format("Tab with specified DefaultTabName \"{0}\" not found. Opened first Tab.", DefaultTabName), this);
|
||
|
SelectTab(tabObjects[0].Name);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SelectTab(tabObjects[0].Name);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool IsExistsTabName(string tabName)
|
||
|
{
|
||
|
return tabObjects.Any(x => x.Name==tabName);
|
||
|
}
|
||
|
|
||
|
void AddCallback(Tab tab, int index)
|
||
|
{
|
||
|
var tabName = tab.Name;
|
||
|
UnityAction callback = () => SelectTab(tabName);
|
||
|
callbacks.Add(callback);
|
||
|
|
||
|
defaultButtons[index].onClick.AddListener(callbacks[index]);
|
||
|
}
|
||
|
|
||
|
void AddCallbacks()
|
||
|
{
|
||
|
tabObjects.ForEach(AddCallback);
|
||
|
}
|
||
|
|
||
|
void RemoveCallback(Tab 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();
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Selects the tab.
|
||
|
/// </summary>
|
||
|
/// <param name="tabName">Tab name.</param>
|
||
|
public void SelectTab(string tabName)
|
||
|
{
|
||
|
var index = Array.FindIndex(tabObjects, x => x.Name==tabName);
|
||
|
if (index==-1)
|
||
|
{
|
||
|
throw new ArgumentException(string.Format("Tab with name \"{0}\" not found.", tabName));
|
||
|
}
|
||
|
|
||
|
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);
|
||
|
|
||
|
SelectedTab = tabObjects[index];
|
||
|
OnTabSelect.Invoke(index);
|
||
|
}
|
||
|
|
||
|
void DeactivateTab(Tab tab)
|
||
|
{
|
||
|
tab.TabObject.SetActive(false);
|
||
|
}
|
||
|
|
||
|
void ActivateButton(Button button)
|
||
|
{
|
||
|
button.gameObject.SetActive(true);
|
||
|
}
|
||
|
|
||
|
void DeactivateButton(Button button)
|
||
|
{
|
||
|
button.gameObject.SetActive(false);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Creates the buttons.
|
||
|
/// </summary>
|
||
|
void CreateButtons()
|
||
|
{
|
||
|
if (tabObjects.Length > defaultButtons.Count)
|
||
|
{
|
||
|
for (var i = defaultButtons.Count; i < tabObjects.Length; i++)
|
||
|
{
|
||
|
var defaultButton = Instantiate(DefaultTabButton) as Button;
|
||
|
defaultButton.transform.SetParent(Container, false);
|
||
|
|
||
|
//Utilites.FixInstantiated(DefaultTabButton, defaultButton);
|
||
|
|
||
|
defaultButtons.Add(defaultButton);
|
||
|
|
||
|
var activeButton = Instantiate(ActiveTabButton) as Button;
|
||
|
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(SetButtonName);
|
||
|
activeButtons.ForEach(SetButtonName);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Sets the name of the button.
|
||
|
/// </summary>
|
||
|
/// <param name="button">Button.</param>
|
||
|
/// <param name="index">Index.</param>
|
||
|
protected virtual void SetButtonName(Button button, int index)
|
||
|
{
|
||
|
var tab_button = button.GetComponent<TabButtonComponent>();
|
||
|
if (tab_button==null)
|
||
|
{
|
||
|
button.gameObject.SetActive(true);
|
||
|
button.GetComponentInChildren<Text>().text = TabObjects[index].Name;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
tab_button.SetButtonData(TabObjects[index]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|