using System;
using Unity.Multiplayer.Center.Analytics;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace Unity.Multiplayer.Center.Window
{
// Note: there is a TabView API in UI Toolkit, but only starting from 2023.2
internal interface ITabView
{
///
/// The name as displayed in the tab button
/// Should be serialized.
///
string Name { get; }
///
/// The root visual element of the tab view.
/// The setter will only be used if the root visual element is null when the tab is created.
///
VisualElement RootVisualElement { get; set; }
///
/// Sets the tab view visible or not.
///
/// If true, visible.
void SetVisible(bool visible);
///
/// If true the Tab can be selected by the user.
///
bool IsEnabled => true;
///
/// Tooltip which will be shown on the Tab Button.
///
string ToolTip => "";
///
/// Refreshes the UI Elements according to latest data.
/// If the UI is not created yet, it does it.
///
void Refresh();
///
/// Unregister all events and clear UI Elements
///
void Clear();
///
/// The Multiplayer Center Analytics provider.
///
IMultiplayerCenterAnalytics MultiplayerCenterAnalytics { get; set; }
}
[Serializable]
internal class TabGroup
{
const string k_TabViewName = "tab-view";
const string k_TabZoneName = "tab-zone";
const string k_TabButtonUssClass = "tab-button";
// The container for all the tabs
const string k_TabsContainerUssClass ="tabs-container";
// Gets applied to the root of each tab
const string k_TabContentUssClass = "tab-content";
[field: SerializeField]
public int CurrentTab { get; private set; } = -1;
public int ViewCount => m_TabViews?.Length ?? 0;
VisualElement[] m_TabButtons;
[SerializeReference]
ITabView[] m_TabViews;
public VisualElement Root { get; private set; }
VisualElement m_MainContainer;
IMultiplayerCenterAnalytics m_MultiplayerCenterAnalytics;
internal IMultiplayerCenterAnalytics MultiplayerCenterAnalytics
{
get => m_MultiplayerCenterAnalytics;
set
{
m_MultiplayerCenterAnalytics = value;
foreach (var tabView in m_TabViews)
{
if(tabView != null)
tabView.MultiplayerCenterAnalytics = value;
}
}
}
public TabGroup(IMultiplayerCenterAnalytics analytics, ITabView[] tabViews, int defaultIndex = 0)
{
m_TabViews = tabViews;
CurrentTab = defaultIndex;
MultiplayerCenterAnalytics = analytics;
}
public void SetSelected(int index, bool force = false)
{
// Select the first tab, if the requested tab is not enabled.
// This assumes the first tab is always enabled.
if (!m_TabViews[index].IsEnabled)
index = 0;
if (index == CurrentTab && !force)
return;
if (CurrentTab >= 0 && CurrentTab < m_TabViews.Length)
{
m_TabButtons[CurrentTab].RemoveFromClassList("selected");
m_TabViews[CurrentTab].SetVisible(false);
}
EditorPrefs.SetInt(PlayerSettings.productName + "_MultiplayerCenter_TabIndex", index);
CurrentTab = index;
m_TabViews[CurrentTab].Refresh();
m_TabButtons[CurrentTab].AddToClassList("selected");
m_TabViews[CurrentTab].SetVisible(true);
}
///
/// Instantiates the visual elements for all the tabs.
/// Use this to create the tabs for the first time the UI is shown or after a domain reload.
///
public void CreateTabs()
{
Root ??= new VisualElement();
m_MainContainer ??= new VisualElement();
if (Root.Q(k_TabZoneName) != null)
Root.Q(k_TabZoneName).RemoveFromHierarchy();
var tabZone = new VisualElement() {name = k_TabZoneName};
Root.Add(tabZone);
Root.name = k_TabViewName;
m_TabButtons = new VisualElement[m_TabViews.Length];
for (var i = 0; i < m_TabViews.Length; i++)
{
var tabView = m_TabViews[i];
var index = i; // copy for closure
var tabButton = new Button(() => SetSelected(index));
tabButton.enabledSelf = tabView.IsEnabled;
tabButton.tooltip = tabView.ToolTip;
tabButton.AddToClassList(k_TabButtonUssClass);
tabButton.text = tabView.Name;
tabZone.Add(tabButton);
m_TabButtons[i] = tabButton;
tabView.RootVisualElement ??= new VisualElement();
tabView.RootVisualElement.AddToClassList(k_TabContentUssClass);
tabView.RootVisualElement.style.display = DisplayStyle.None;
m_MainContainer.Add(m_TabViews[i].RootVisualElement);
}
m_MainContainer.AddToClassList(k_TabsContainerUssClass);
Root.Add(m_MainContainer);
CurrentTab = EditorPrefs.GetInt(PlayerSettings.productName + "_MultiplayerCenter_TabIndex", 0);
}
static void SetVisible(VisualElement e, bool visible)
{
e.style.display = visible ? DisplayStyle.Flex : DisplayStyle.None;
}
public void Clear()
{
if(m_TabViews == null)
return;
foreach (var tabView in m_TabViews)
{
tabView?.Clear();
}
}
public bool TabsAreValid()
{
if (m_TabViews == null)
return false;
foreach (var tab in m_TabViews)
{
if (tab == null)
return false;
}
return true;
}
}
}