// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#if GT_USE_UGUI
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using UEditor = UnityEditor.Editor;
namespace Microsoft.MixedReality.GraphicsTools.Editor
{
///
/// Helper class to show warnings on canvas renderer components.
///
[CanEditMultipleObjects]
[CustomEditor(typeof(CanvasRenderer))]
public class CanvasRendererInspector : UEditor
{
private readonly List materialsToFix = new List();
private readonly List graphicsToFix = new List();
private Type canvasEditorType = null;
private UEditor internalEditor = null;
private void OnEnable()
{
canvasEditorType = Type.GetType("UnityEditor.CanvasRendererEditor, UnityEditor");
if (canvasEditorType != null)
{
internalEditor = CreateEditor(targets, canvasEditorType);
}
}
private void OnDisable()
{
if (canvasEditorType != null)
{
MethodInfo onDisable = canvasEditorType.GetMethod("OnDisable", BindingFlags.Instance | BindingFlags.NonPublic);
if (onDisable != null)
{
onDisable.Invoke(internalEditor, null);
}
DestroyImmediate(internalEditor);
}
}
///
/// Renders a custom inspector GUI that displays warnings and mitigation options to the user.
///
public override void OnInspectorGUI()
{
GetMaterialsWhichDontSupportCanvas(targets, materialsToFix);
if (materialsToFix.Count != 0)
{
EditorGUILayout.HelpBox($"The {typeof(CanvasRenderer).Name} is using a {typeof(Material).Name} which is using the {StandardShaderUtility.GraphicsToolsStandardShaderName} instead of the {StandardShaderUtility.GraphicsToolsStandardCanvasShaderName} shader. The {StandardShaderUtility.GraphicsToolsStandardCanvasShaderName} is required for some shader features to function.", MessageType.Warning);
if (GUILayout.Button($"Change {typeof(Shader).Name} to {StandardShaderUtility.GraphicsToolsStandardCanvasShaderName}"))
{
Undo.RecordObjects(materialsToFix.ToArray(), "Change Shader");
foreach (var material in materialsToFix)
{
material.shader = StandardShaderUtility.GraphicsToolsStandardCanvasShader;
}
}
}
GetGraphicsWhichRequireScaleMeshEffect(targets, graphicsToFix);
EditorGUILayout.Space();
if (graphicsToFix.Count != 0)
{
EditorGUILayout.HelpBox($"This gameobject requires a {typeof(ScaleMeshEffect).Name} component to work with the {StandardShaderUtility.GraphicsToolsStandardCanvasShaderName} or {StandardShaderUtility.GraphicsToolsStandardShaderName} shader.", MessageType.Warning);
if (GUILayout.Button($"Add {typeof(ScaleMeshEffect).Name}(s)"))
{
foreach (var graphic in graphicsToFix)
{
Undo.AddComponent(graphic.gameObject);
}
}
}
EditorGUILayout.Space();
if (internalEditor != null)
{
internalEditor.OnInspectorGUI();
}
}
private static void GetMaterialsWhichDontSupportCanvas(UnityEngine.Object[] targets, List output)
{
output.Clear();
foreach (UnityEngine.Object target in targets)
{
CanvasRenderer[] renderers = (target as CanvasRenderer).GetComponents();
foreach (var renderer in renderers)
{
var material = renderer.GetMaterial();
if (material != null && material.shader == StandardShaderUtility.GraphicsToolsStandardShader)
{
output.Add(material);
}
}
}
}
private static void GetGraphicsWhichRequireScaleMeshEffect(UnityEngine.Object[] targets, List output)
{
output.Clear();
foreach (UnityEngine.Object target in targets)
{
Graphic[] graphics = (target as CanvasRenderer).GetComponents();
foreach (Graphic graphic in graphics)
{
if (StandardShaderUtility.IsUsingGraphicsToolsStandardShader(graphic.material) && graphic.GetComponent() == null)
{
output.Add(graphic);
}
}
}
}
}
}
#endif // GT_USE_UGUI