WuhuIslandTesting/Library/PackageCache/com.unity.addressables@1.21.12/Editor/GUI/GUIElements/Ribbon.cs

250 lines
9.3 KiB
C#
Raw Normal View History

2025-01-07 02:06:59 +01:00
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
[assembly: UxmlNamespacePrefix("UnityEditor.AddressableAssets.GUIElements", "AddressablesGUI")]
namespace UnityEditor.AddressableAssets.GUIElements
{
internal class Ribbon : VisualElement
{
static class Content
{
// Technically Rbbon is a UI controll that could be more agnostic of this specific implementation for the Memory Profiler.
// While this content may be reused in other places of the Memory Profiler and therefore makes sense to be located on TextContent,
// keeping a Content class here makes it easier to keep things separated and helps when copying it out into other tools.
public static readonly string OpenManualTooltip = GUIUtility.OpenManualTooltip;
}
static class Styles
{
public static readonly string HelpIconButtonClass = GUIUtility.HelpIconButtonClass;
public static readonly string MenuIconButtonClass = GUIUtility.MenuIconButtonClass;
}
Align m_Alignment;
public Align Alignment
{
get { return m_Alignment; }
private set
{
switch (value)
{
case Align.Auto:
case Align.FlexStart:
m_Alignment = value;
SetLeftAligned();
break;
case Align.Center:
m_Alignment = value;
SetCenterAligned();
break;
case Align.FlexEnd:
case Align.Stretch:
default:
Debug.LogError("Ribbons can only be left of center aligned");
break;
}
}
}
public bool ShowHelpButton { get; private set; }
public bool ShowMenuButton { get; private set; }
public int InitialOption { get; private set; }
public int m_CurrentOption = 0;
public int CurrentOption
{
get { return m_CurrentOption; }
set { m_CurrentOption = value; RefreshButtonToggleStates(); }
}
public override VisualElement contentContainer
{
get { return m_Content; }
}
public event Action<int> Clicked = delegate { };
public event Action HelpClicked = delegate { };
public event Action MenuClicked = delegate { };
VisualElement m_Root;
VisualElement m_Content;
VisualElement m_Container;
List<RibbonButton> m_Buttons = new List<RibbonButton>();
VisualElement m_OptionsAndInfos;
Button m_Menu;
Button m_Help;
const string k_ContainerClassCenterAligned = "ribbon__container--centered";
const string k_ClassCenterAligned = "ribbon--centered";
const string k_ContainerClassLeftAligned = "ribbon__container--left-aligned";
const string k_ClassLeftAligned = "ribbon--left-aligned";
public Ribbon()
{
VisualTreeAsset ribbonViewTree = AssetDatabase.LoadAssetAtPath(GUIUtility.RibbonUxmlPath, typeof(VisualTreeAsset)) as VisualTreeAsset;
m_Root = ribbonViewTree.Clone();
// clear out the style sheets defined in the template uxml file so they can be applied from here in the order of: 1. theming, 2. base
m_Root.styleSheets.Clear();
var themeStyle = AssetDatabase.LoadAssetAtPath(EditorGUIUtility.isProSkin ? GUIUtility.RibbonDarkUssPath : GUIUtility.RibbonLightUssPath, typeof(StyleSheet)) as StyleSheet;
m_Root.styleSheets.Add(themeStyle);
var ribbonStyle = AssetDatabase.LoadAssetAtPath(GUIUtility.RibbonUssPath, typeof(StyleSheet)) as StyleSheet;
m_Root.styleSheets.Add(ribbonStyle);
hierarchy.Add(m_Root);
style.flexShrink = 0;
m_Container = m_Root.Q("ribbon__container");
m_Content = m_Root.Q("ribbon__buttons");
m_OptionsAndInfos = m_Root.Q("options-and-info");
m_Menu = m_OptionsAndInfos.Q<Button>("", Styles.MenuIconButtonClass);
m_Help = m_OptionsAndInfos.Q<Button>("", Styles.HelpIconButtonClass);
m_Help.tooltip = Content.OpenManualTooltip;
m_CurrentOption = InitialOption;
Setup();
}
void Init()
{
m_CurrentOption = InitialOption;
Setup();
}
public void Setup()
{
GatherElements();
if (m_Buttons.Count > 0)
{
UnregisterCallback<GeometryChangedEvent>(OnPostDisplaySetup);
SetupElements();
}
else
RegisterCallback<GeometryChangedEvent>(OnPostDisplaySetup);
}
void GatherElements()
{
m_Buttons.Clear();
if (m_Content == null)
return;
for (int i = 0; i < m_Content.childCount; i++)
{
if (m_Content[i] is RibbonButton)
{
m_Buttons.Add(m_Content[i] as RibbonButton);
}
}
}
void OnPostDisplaySetup(GeometryChangedEvent evt)
{
GatherElements();
if (m_Buttons.Count > 0)
{
UnregisterCallback<GeometryChangedEvent>(OnPostDisplaySetup);
SetupElements();
}
}
void SetupElements()
{
if (m_Alignment == Align.Center)
SetCenterAligned();
else
SetLeftAligned();
GUIUtility.SetVisibility(m_Help, ShowHelpButton);
m_Help.clickable.clicked += HelpClicked;
GUIUtility.SetVisibility(m_Menu, ShowMenuButton);
m_Menu.clickable.clicked += MenuClicked;
RefreshButtonToggleStates();
for (int i = 0; i < m_Buttons.Count; i++)
{
// copy index value to local scope before enclosing to ensure it isn't Count-1
int buttonIndex = i;
m_Buttons[i].clickable.clicked += () => ButtonClicked(buttonIndex);
}
}
void RefreshButtonToggleStates()
{
m_CurrentOption = Mathf.Clamp(m_CurrentOption, 0, Mathf.Max(0, m_Buttons.Count - 1));
for (int i = 0; i < m_Buttons.Count; i++)
{
m_Buttons[i].Toggled = i == m_CurrentOption;
}
}
public void ButtonClicked(int index)
{
m_CurrentOption = index;
RefreshButtonToggleStates();
Clicked(index);
}
void SetCenterAligned()
{
m_Container.SwitchClasses(classToAdd: k_ContainerClassCenterAligned, classToRemove: k_ContainerClassLeftAligned);
m_Content.SwitchClasses(classToAdd: k_ClassCenterAligned, classToRemove: k_ClassLeftAligned);
}
void SetLeftAligned()
{
m_Container.SwitchClasses(classToAdd: k_ContainerClassLeftAligned, classToRemove: k_ContainerClassCenterAligned);
m_Content.SwitchClasses(classToAdd: k_ClassLeftAligned, classToRemove: k_ClassCenterAligned);
}
/// <summary>
/// Instantiates a <see cref="Ribbon"/> using the data read from a UXML file.
/// </summary>
public new class UxmlFactory : UxmlFactory<Ribbon, UxmlTraits> { }
/// <summary>
/// Defines <see cref="UxmlTraits"/> for the <see cref="Ribbon"/>.
/// </summary>
public new class UxmlTraits : VisualElement.UxmlTraits
{
UxmlEnumAttributeDescription<Align> m_Align = new UxmlEnumAttributeDescription<Align> { name = "alignment", defaultValue = Align.Center };
UxmlBoolAttributeDescription m_ShowHelp = new UxmlBoolAttributeDescription { name = "show-help-button", defaultValue = false };
UxmlBoolAttributeDescription m_ShowMenu = new UxmlBoolAttributeDescription { name = "show-menu-button", defaultValue = false };
UxmlIntAttributeDescription m_InitialOption = new UxmlIntAttributeDescription { name = "initial-option", defaultValue = 0 };
public override IEnumerable<UxmlChildElementDescription> uxmlChildElementsDescription
{
get
{
// can only contain ribbon buttons
yield return new UxmlChildElementDescription(typeof(RibbonButton));
}
}
public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
{
base.Init(ve, bag, cc);
var ribbon = ((Ribbon)ve);
var align = m_Align.GetValueFromBag(bag, cc);
var help = m_ShowHelp.GetValueFromBag(bag, cc);
var menu = m_ShowMenu.GetValueFromBag(bag, cc);
var initialOption = m_InitialOption.GetValueFromBag(bag, cc);
ribbon.Alignment = align;
ribbon.ShowHelpButton = help;
ribbon.ShowMenuButton = menu;
ribbon.InitialOption = initialOption;
((Ribbon)ve).Init();
}
}
}
}