#if UNITY_EDITOR
using System;
using JetBrains.Annotations;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Phantom.XRMOD.UnityFusion.Editor
{
///
/// Utility class for getting and setting component tooltips.
///
internal static class ComponentTooltip
{
private static readonly Dictionary tooltips = new();
private static readonly Dictionary xmlDocumentationSummaries = new()
{
{ typeof(Transform), "Position, rotation and scale of an object." },
{ typeof(MeshFilter), "A class to access the Mesh of the mesh filter." },
{ typeof(Light), "Script interface for light components." },
{ typeof(MeshCollider), "A mesh collider allows you to do collision detection between meshes and primitives." }
};
private static readonly HashSet hasOverride = new();
internal static bool HasOverride([NotNull] Component component)
=> hasOverride.Contains(component);
internal static void Set([NotNull] Component component, [CanBeNull] string tooltip, ModifyOptions modifyOptions)
{
if(string.IsNullOrEmpty(tooltip))
{
tooltips.Remove(component);
hasOverride.Remove(component);
if(modifyOptions.IsUpdatingContainerAllowed())
{
UpdateNameContainer(component, modifyOptions);
}
return;
static void UpdateNameContainer(Component component, ModifyOptions modifyOptions)
{
if(modifyOptions.IsDelayed())
{
EditorApplication.delayCall += ()=> UpdateNameContainer(component, modifyOptions.Immediately());
}
if(!NameContainer.TryGet(component, out var nameContainer))
{
return;
}
if(ComponentName.IsNullEmptyOrDefault(component, nameContainer.NameOverride) && modifyOptions.IsRemovingNameContainerAllowed())
{
nameContainer.Remove(modifyOptions);
}
else
{
nameContainer.TooltipOverride = "";
}
}
}
hasOverride.Add(component);
tooltips[component] = tooltip;
if(modifyOptions.IsUpdatingContainerAllowed())
{
NameContainer.TryGetOrCreate(component, modifyOptions, nameContainer =>
{
nameContainer.TooltipOverride = tooltip;
}, null, tooltip);
}
}
internal static string Get([NotNull] Component component)
{
if(tooltips.TryGetValue(component, out string tooltip))
{
return tooltip;
}
return GetDefault(component);
}
internal static string GetDefault(Component component)
{
var componentType = component.GetType();
// TODO: Is it bad that the tooltip gets discarded here? do we need to then call this twice to also get the tooltip?
// Maybe not, if it's only updated on mouse enter for example. Investigate!
var (_, _, tooltip) = HeaderContentUtility.GetCustomHeaderContent(component, componentType);
return !tooltip.IsDefault ? tooltip : GetXmlDocumentationSummary(component);
}
internal static string GetXmlDocumentationSummary(Component component)
{
var type = component.GetType();
if(xmlDocumentationSummaries.TryGetValue(type, out string summary))
{
return summary;
}
if(component is not MonoBehaviour monoBehaviour || !MonoScriptSummaryParser.TryParseSummary(monoBehaviour, out summary))
{
DLLSummaryParser.TryParseSummary(type, out summary);
}
summary ??= "";
xmlDocumentationSummaries[type] = summary;
return summary;
}
}
}
#endif