266 lines
10 KiB
C#
266 lines
10 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEditor;
|
|
using UnityEngine.SceneManagement;
|
|
using Object = UnityEngine.Object;
|
|
using System.Linq;
|
|
using AssetUsageFinder.Styles;
|
|
using UnityEditor.SceneManagement;
|
|
|
|
namespace AssetUsageFinder {
|
|
class DependencyWindow : EditorWindow {
|
|
Vector2 _scrollPos;
|
|
[SerializeField] DependencyAbstractFinder _data;
|
|
[SerializeField] protected FindModeEnum _findMode;
|
|
bool _expandFiles = true;
|
|
bool _expandScenes = true;
|
|
static GUIContent _sceneIcon;
|
|
Rect _popupButtonRect;
|
|
PrevClick _click;
|
|
List<Action> _postponedActions;
|
|
|
|
[Serializable]
|
|
public class Style {
|
|
public ContentStylePair LookupBtn = new ContentStylePair();
|
|
public GUIStyle TabBreadcrumb0 = new GUIStyle();
|
|
public GUIStyle TabBreadcrumb1 = new GUIStyle();
|
|
public GUIStyle RowMainAssetBtn = new GUIStyle();
|
|
public Vector2 Size = new Vector2(250f, 800f);
|
|
public GUIStyle RowLabel = new GUIStyle();
|
|
|
|
public static Style FindSelf() {
|
|
var res = AufUtils.FirstOfType<WindowStyleAsset>();
|
|
return EditorGUIUtility.isProSkin ? res.Pro : res.Personal;
|
|
}
|
|
}
|
|
|
|
public static Style StyleInstance => Globals<Style>.GetOrCreate(Style.FindSelf);
|
|
|
|
void OnEnable() {
|
|
_postponedActions = new List<Action>();
|
|
}
|
|
|
|
void BreadCrumbs() {
|
|
var parents = _data.Parents();
|
|
parents.Reverse();
|
|
var w = 0f;
|
|
{
|
|
using (new EditorGUILayout.VerticalScope()) {
|
|
EditorGUILayout.BeginHorizontal();
|
|
for (var i = 0; i < parents.Count; i++) {
|
|
var parent = parents[i];
|
|
var style = i == 0 ? StyleInstance.TabBreadcrumb0 : StyleInstance.TabBreadcrumb1;
|
|
|
|
var styleWidth = style.CalcSize(parent.TabContent).x;
|
|
if (w > EditorGUIUtility.currentViewWidth - styleWidth) {
|
|
w = 0f;
|
|
EditorGUILayout.EndHorizontal();
|
|
EditorGUILayout.BeginHorizontal();
|
|
}
|
|
|
|
w += styleWidth;
|
|
|
|
if (i == parents.Count - 1) {
|
|
var res = GUILayout.Toggle(true, parent.TabContent, style);
|
|
if (!res)
|
|
EditorGUIUtility.PingObject(parent.Target.Target);
|
|
}
|
|
else if (GUILayout.Button(parent.TabContent, style)) {
|
|
EditorGUIUtility.PingObject(parent.Target.Target);
|
|
_postponedActions.Add(() => { Init(parent); });
|
|
}
|
|
}
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Update() {
|
|
if (!_postponedActions.Any()) return;
|
|
foreach (var a in _postponedActions)
|
|
a();
|
|
_postponedActions.Clear();
|
|
}
|
|
|
|
void OnGUI() {
|
|
if (_postponedActions == null || _data == null || (Event.current != null && Event.current.keyCode == KeyCode.Escape)) {
|
|
_postponedActions = new List<Action>();
|
|
_postponedActions.Add(() => Close());
|
|
return;
|
|
}
|
|
|
|
EditorGUILayout.BeginVertical();
|
|
{
|
|
BreadCrumbs();
|
|
_scrollPos = EditorGUILayout.BeginScrollView(_scrollPos);
|
|
{
|
|
EditorGUILayout.Space();
|
|
ShowDependencies(_data.Dependencies);
|
|
}
|
|
EditorGUILayout.EndScrollView();
|
|
}
|
|
EditorGUILayout.EndVertical();
|
|
EditorGUILayout.Space();
|
|
Footer();
|
|
}
|
|
|
|
void Footer() {
|
|
if (Event.current.type != EventType.Repaint) return;
|
|
_popupButtonRect = GUILayoutUtility.GetLastRect();
|
|
_popupButtonRect.position += position.position;
|
|
}
|
|
|
|
public void Init(DependencyAbstractFinder d) {
|
|
_data = d;
|
|
// _labelMaxWidth = CalculateContentMaxWidth(EditorStyles.label, _data.Dependencies.SelectMany(dd => dd.Properties.Select(p => p.Content)));
|
|
|
|
// var t = new[] {_data.Target.Root};
|
|
// if (_data.Target.Nested.TryGet(out var nested))
|
|
|
|
titleContent = new GUIContent($"{FindMode.GetWindowTitleByFindMode(_findMode)}");
|
|
titleContent.tooltip = _data.Title;
|
|
}
|
|
|
|
void ShowDependencies(ResultRow[] dependencies) {
|
|
var nDeps = dependencies.Count();
|
|
_expandFiles = EditorGUILayout.Foldout(_expandFiles, $"{FindMode.GetContentByFindMode(_findMode)}: [{nDeps}]");
|
|
|
|
if (_findMode == FindModeEnum.File) {
|
|
if (_data.Target.Scene.IsValid() && !_data.Target.Scene.isLoaded)
|
|
return;
|
|
}
|
|
|
|
if (_expandFiles) {
|
|
if (nDeps > 0) {
|
|
foreach (var dependency in dependencies)
|
|
if (dependency != null && dependency.SerializedObject != null && dependency.SerializedObject.targetObject != null)
|
|
DrawRow(dependency);
|
|
else
|
|
this.Close();
|
|
}
|
|
else {
|
|
EditorGUILayout.LabelField("No file dependencies found.");
|
|
}
|
|
}
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
var fileDep = _data as FileDependencyFinder;
|
|
|
|
if (fileDep == null)
|
|
return;
|
|
|
|
if (fileDep.ScenePaths == null) {
|
|
fileDep.ScenePaths = DependencyFinderEngine.GetScenesThatContain(_data.Target.Target)
|
|
.Select(p => new FileDependencyFinder.Pair {Path = p, NicifiedPath = p.Replace("Assets/", string.Empty)}).ToArray();
|
|
}
|
|
|
|
var nScenes = fileDep.ScenePaths.Count();
|
|
_expandScenes = EditorGUILayout.Foldout(_expandScenes, $"In Scenes: [{nScenes}]");
|
|
|
|
if (!_expandScenes) return;
|
|
if (nScenes > 0) {
|
|
foreach (var p in fileDep.ScenePaths) {
|
|
using (new EditorGUILayout.HorizontalScope()) {
|
|
SceneIcon.text = p.NicifiedPath;
|
|
|
|
if (GUILayout.Button(SceneIcon, EditorStyles.label, GUILayout.Height(16f), GUILayout.MaxWidth(20f + p.NicifiedPath.Length * 7f)))
|
|
EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath<SceneAsset>(p.Path));
|
|
|
|
if (!GUILayout.Button("Open scene & search"))
|
|
continue;
|
|
|
|
var sceneToOpen = SceneManager.GetSceneByPath(p.Path);
|
|
if (sceneToOpen.isLoaded) {
|
|
GuiManager.OpenSceneWindow(_data.Target.Target, p.Path);
|
|
}
|
|
else {
|
|
var currentScene = EditorSceneManager.GetActiveScene();
|
|
|
|
if (currentScene.isDirty && EditorUtility.DisplayDialog(
|
|
$"Unsaved changes",
|
|
$"You are going to open and search in scene [{p.Path}]\n" +
|
|
$"but you have unsaved changes at the scene [{currentScene.name}]",
|
|
$"Stay at current scene and cancel search", $"Discard changes and search"))
|
|
return;
|
|
|
|
EditorSceneManager.OpenScene(p.Path);
|
|
GuiManager.OpenSceneWindow(_data.Target.Target, p.Path);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
EditorGUILayout.LabelField("No scene dependencies found.");
|
|
}
|
|
}
|
|
|
|
struct PrevClick {
|
|
Object _target;
|
|
float _timeClicked;
|
|
|
|
public PrevClick(Object target) {
|
|
_target = target;
|
|
_timeClicked = Time.realtimeSinceStartup;
|
|
}
|
|
|
|
const float DoubleClickTime = 0.5f;
|
|
|
|
public bool IsDoubleClick(Object o) {
|
|
return _target == o && Time.realtimeSinceStartup - _timeClicked < DoubleClickTime;
|
|
}
|
|
}
|
|
|
|
void DrawRow(ResultRow dependency) {
|
|
var id = dependency.Main.GetInstanceID();
|
|
|
|
using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) {
|
|
using (new EditorGUILayout.HorizontalScope()) {
|
|
if (GUILayout.Button(dependency.LabelContent, StyleInstance.RowMainAssetBtn)) {
|
|
if (_click.IsDoubleClick(dependency.Main))
|
|
Selection.activeObject = dependency.Main;
|
|
else {
|
|
EditorGUIUtility.PingObject(dependency.Main);
|
|
}
|
|
|
|
_click = new PrevClick(dependency.Main);
|
|
}
|
|
|
|
if (GUILayout.Button(StyleInstance.LookupBtn.Content, StyleInstance.LookupBtn.Style)) {
|
|
_postponedActions.Add(() =>
|
|
Init(_data.Nest(dependency.Main)));
|
|
}
|
|
}
|
|
|
|
dependency.SerializedObject.Update();
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
|
|
if (dependency.Target) {
|
|
foreach (var prop in dependency.Properties) {
|
|
using (new EditorGUILayout.HorizontalScope()) {
|
|
var locked = prop.Property.objectReferenceValue is MonoScript;
|
|
var f = GUI.enabled;
|
|
|
|
if (locked) GUI.enabled = false;
|
|
|
|
EditorGUILayout.LabelField(prop.Content, StyleInstance.RowLabel, GUILayout.MaxWidth(this.position.width *.8f));
|
|
EditorGUILayout.PropertyField(prop.Property, GUIContent.none, true, GUILayout.MinWidth(this.position.width *.2f));
|
|
|
|
if (locked) GUI.enabled = f;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
dependency.SerializedObject.ApplyModifiedProperties();
|
|
}
|
|
}
|
|
|
|
static GUIContent SceneIcon {
|
|
get { return _sceneIcon ?? (_sceneIcon = new GUIContent(AssetPreview.GetMiniTypeThumbnail(typeof(SceneAsset)))); }
|
|
}
|
|
}
|
|
} |