198 lines
6.4 KiB
C#
198 lines
6.4 KiB
C#
|
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
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// The name as displayed in the tab button
|
||
|
/// Should be serialized.
|
||
|
/// </summary>
|
||
|
string Name { get; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// 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.
|
||
|
/// </summary>
|
||
|
VisualElement RootVisualElement { get; set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// Sets the tab view visible or not.
|
||
|
/// </summary>
|
||
|
/// <param name="visible">If true, visible.</param>
|
||
|
void SetVisible(bool visible);
|
||
|
|
||
|
/// <summary>
|
||
|
/// If true the Tab can be selected by the user.
|
||
|
/// </summary>
|
||
|
bool IsEnabled => true;
|
||
|
|
||
|
/// <summary>
|
||
|
/// Tooltip which will be shown on the Tab Button.
|
||
|
/// </summary>
|
||
|
string ToolTip => "";
|
||
|
|
||
|
/// <summary>
|
||
|
/// Refreshes the UI Elements according to latest data.
|
||
|
/// If the UI is not created yet, it does it.
|
||
|
/// </summary>
|
||
|
void Refresh();
|
||
|
|
||
|
/// <summary>
|
||
|
/// Unregister all events and clear UI Elements
|
||
|
/// </summary>
|
||
|
void Clear();
|
||
|
|
||
|
/// <summary>
|
||
|
/// The Multiplayer Center Analytics provider.
|
||
|
/// </summary>
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 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.
|
||
|
/// </summary>
|
||
|
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;
|
||
|
}
|
||
|
}
|
||
|
}
|