module-navigation-tool/Editor/Toolbar/Tools/ToolUICanvasPicker.cs

116 lines
3.7 KiB
C#

using System.Collections.Generic;
using JetBrains.Annotations;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using UTools = UnityEditor.Tools;
#if UNITY_2021_1_OR_NEWER
using UnityEditor.SceneManagement;
#else
using UnityEditor.Experimental.SceneManagement;
#endif
namespace Module.NavigationTool.Editor.Tools
{
[UsedImplicitly]
internal sealed class ToolUICanvasPicker : AbstractToolbarDrawer
{
public override bool Enabled => (UTools.visibleLayers & (1 << LayerMask.NameToLayer("UI"))) != 0;
public override EToolbarPlacement Placement => EToolbarPlacement.Left;
private static bool IS_DIRTY = true;
private static string[] OPTIONS = new string[0];
private static int[] INSTANCE_IDS = new int[0];
private static void Initialize()
{
if (!IS_DIRTY)
return;
PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
Canvas[] canvases = prefabStage != null ? prefabStage.prefabContentsRoot.GetComponentsInParent<Canvas>() : Object.FindObjectsOfType<Canvas>();
var list = new List<Canvas>(canvases.Length);
var listNames = new List<string>(canvases.Length);
var listIds = new List<int>(canvases.Length);
listNames.Add("Select");
listIds.Add(-1);
for (var i = 0; i < canvases.Length; i++)
{
Canvas root = canvases[i].rootCanvas;
if (list.Contains(root))
continue;
list.Add(root);
listNames.Add(root.name);
listIds.Add(root.GetInstanceID());
}
OPTIONS = listNames.ToArray();
INSTANCE_IDS = listIds.ToArray();
IS_DIRTY = false;
}
public override void Update()
{
Initialize();
}
protected override void Draw(Rect rect)
{
// Note: To fix an issue, where instantiated canvases wouldn't be detected, due to no events for canvas additions/removals exist in Unity API (at the moment)
if (Event.current.type == EventType.MouseDown)
{
IS_DIRTY = true;
Initialize();
}
int temp = EditorGUI.Popup(rect, 0, OPTIONS, styles.popup);
if (temp != 0 && OPTIONS.Length != 1)
Focus(INSTANCE_IDS[temp]);
}
public override float CalculateWidth()
{
return 100.0f;
}
private static void Focus(int instanceId)
{
Object obj = EditorUtility.InstanceIDToObject(instanceId);
var canvas = obj as Canvas;
if (canvas == null)
{
if (obj != null)
Debug.LogWarning("Failed to find Canvas component on object", obj);
return;
}
Selection.activeObject = canvas;
Bounds bounds = InternalEditorUtility.CalculateSelectionBounds(false, true, true);
Vector3 point = bounds.center;
Quaternion direction = canvas.transform.rotation;
float size = Mathf.Max(bounds.extents.x, bounds.extents.y);
bool ortho = canvas.renderMode == RenderMode.ScreenSpaceOverlay;
for (var i = 0; i < SceneView.sceneViews.Count; i++)
{
var view = (SceneView)SceneView.sceneViews[i];
view.in2DMode = false;
view.LookAt(point, direction, size, ortho, false);
}
}
public static void SetAsDirty()
{
IS_DIRTY = true;
}
}
}