using System;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
using Codice.Client.Common.Threading;
using Codice.LogWrapper;
using Unity.PlasticSCM.Editor.AssetsOverlays.Cache;
using Unity.PlasticSCM.Editor.AssetUtils;
using Object = UnityEngine.Object;
namespace Unity.PlasticSCM.Editor.AssetsOverlays
{
internal static class DrawHierarchyOverlay
{
internal interface IGetAssetPathFromInstance
{
bool TryGetAssetPath(UnityObjectInstance instance, out string assetPath);
}
internal static IGetAssetPathFromInstance GetSubSceneAssetPath;
internal static void Enable(
string wkPath,
IAssetStatusCache assetStatusCache)
{
if (mIsEnabled)
return;
mLog.Debug("Enable");
mWkPath = wkPath;
mAssetStatusCache = assetStatusCache;
mIsEnabled = true;
#if UNITY_6000_4_OR_NEWER
EditorApplication.hierarchyWindowItemByEntityIdOnGUI += OnHierarchyGUIByEntityId;
#else
EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyGUI;
#endif
RepaintEditor.HierarchyWindow();
}
internal static void Disable()
{
mLog.Debug("Disable");
mIsEnabled = false;
#if UNITY_6000_4_OR_NEWER
EditorApplication.hierarchyWindowItemByEntityIdOnGUI -= OnHierarchyGUIByEntityId;
#else
EditorApplication.hierarchyWindowItemOnGUI -= OnHierarchyGUI;
#endif
RepaintEditor.HierarchyWindow();
mWkPath = null;
mAssetStatusCache = null;
}
#if UNITY_6000_4_OR_NEWER
static void OnHierarchyGUIByEntityId(EntityId entityId, Rect selectionRect)
{
OnHierarchyGUI(UnityObjectInstance.FromEntityId(entityId), selectionRect);
}
#else
static void OnHierarchyGUI(int instanceId, Rect selectionRect)
{
OnHierarchyGUI(UnityObjectInstance.FromInstanceId(instanceId), selectionRect);
}
#endif
static void OnHierarchyGUI(UnityObjectInstance instance, Rect selectionRect)
{
if (Event.current.type != EventType.Repaint)
return;
try
{
string assetPath = GetAssetPathFromInstance(instance);
if (assetPath == null)
return;
string assetFullPath = AssetsPath.GetFullPathUnderWorkspace.ForAsset(mWkPath, assetPath);
if (assetFullPath == null)
return;
DrawOverlayForAsset(assetFullPath, selectionRect, mAssetStatusCache);
}
catch (Exception ex)
{
ExceptionsHandler.LogException(typeof(DrawHierarchyOverlay).Name, ex);
}
}
static string GetAssetPathFromInstance(UnityObjectInstance instance)
{
string sceneAssetPath;
if (TryGetAssetPathForScene(instance, out sceneAssetPath))
{
return sceneAssetPath;
}
string subSceneAssetPath;
if (TryGetAssetPathForSubScene(instance, out subSceneAssetPath))
{
return subSceneAssetPath;
}
string prefabAssetPath;
if (TryGetAssetPathForPrefab(instance, out prefabAssetPath))
{
return prefabAssetPath;
}
return null;
}
static bool TryGetAssetPathForScene(UnityObjectInstance instance, out string assetPath)
{
assetPath = null;
if (instance.FindObject() != null)
return false;
assetPath = FindScenePathForHandle(instance);
return assetPath != null;
}
static string FindScenePathForHandle(UnityObjectInstance instance)
{
for (int i = 0; i < SceneManager.sceneCount; i++)
{
Scene scene = SceneManager.GetSceneAt(i);
if (instance.MatchesScene(scene) && scene.path != null)
{
return scene.path;
}
}
return null;
}
static bool TryGetAssetPathForSubScene(UnityObjectInstance instance, out string assetPath)
{
assetPath = null;
string subSceneAssetPath;
if (GetSubSceneAssetPath != null &&
GetSubSceneAssetPath.TryGetAssetPath(instance, out subSceneAssetPath))
{
assetPath = subSceneAssetPath;
}
return assetPath != null;
}
static bool TryGetAssetPathForPrefab(UnityObjectInstance instance, out string assetPath)
{
assetPath = null;
PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
if (prefabStage == null)
return false;
Object hierarchyObject = instance.FindObject();
if (hierarchyObject == null)
return false;
if (prefabStage.prefabContentsRoot == hierarchyObject)
assetPath = prefabStage.assetPath;
return assetPath != null;
}
static void DrawOverlayForAsset(
string assetFullPath,
Rect selectionRect,
IAssetStatusCache assetStatusCache)
{
AssetStatus assetStatus = assetStatusCache.GetStatus(assetFullPath);
string tooltipText = AssetOverlay.GetTooltipText(
assetStatus,
assetStatusCache.GetLockStatusData(assetFullPath));
DrawAssetOverlayIcon.ForStatus(
selectionRect,
assetStatus,
tooltipText);
}
static bool mIsEnabled;
static IAssetStatusCache mAssetStatusCache;
static string mWkPath;
static readonly ILog mLog = PlasticApp.GetLogger("DrawHierarchyOverlay");
}
}