Files
2026-02-21 16:45:37 +08:00

194 lines
4.4 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace UIWidgets
{
public class TabsCustom<TTab, TButton> : 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<TButton> defaultButtons = new List<TButton>();
private List<TButton> activeButtons = new List<TButton>();
private List<UnityAction> callbacks = new List<UnityAction>();
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)
{
}
}
}