mirror of
https://github.com/DCFApixels/DragonECS-Unity.git
synced 2025-09-17 17:34:34 +08:00
315 lines
14 KiB
C#
315 lines
14 KiB
C#
#if UNITY_EDITOR
|
|
using DCFApixels.DragonECS.Unity.Editors;
|
|
using DCFApixels.DragonECS.Unity.Internal;
|
|
using System.Linq;
|
|
using UnityEditor;
|
|
using UnityEditor.SceneManagement;
|
|
using UnityEditorInternal;
|
|
using UnityEngine;
|
|
|
|
namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
|
|
{
|
|
internal class RefRepairerWindow : EditorWindow
|
|
{
|
|
public const string TITLE = "Reference Repairer";
|
|
[MenuItem("Tools/" + EcsConsts.FRAMEWORK_NAME + "/" + TITLE)]
|
|
public static void Open()
|
|
{
|
|
_isNoFound = false;
|
|
var wnd = GetWindow<RefRepairerWindow>();
|
|
wnd.titleContent = new GUIContent(TITLE);
|
|
wnd.minSize = new Vector2(140f, 140f);
|
|
wnd.Show();
|
|
}
|
|
|
|
private MissingRefContainer _missingRefContainer = new MissingRefContainer();
|
|
private MissingsResolvingData[] _cachedMissingsResolvingDatas = null;
|
|
private MissingsResolvingData _selectedMissingsResolvingData = null;
|
|
private ReorderableList _reorderableResolvingDataList;
|
|
|
|
private float _lineWidth = 0f;
|
|
private float _arrowWidth = 0f;
|
|
|
|
private void InitList()
|
|
{
|
|
if (_reorderableResolvingDataList == null)
|
|
{
|
|
_reorderableResolvingDataList = new ReorderableList(_cachedMissingsResolvingDatas, typeof(MissingsResolvingData), false, false, false, false);
|
|
_reorderableResolvingDataList.headerHeight = 0;
|
|
_reorderableResolvingDataList.footerHeight = 0;
|
|
|
|
_reorderableResolvingDataList.elementHeightCallback += OnReorderableResolvingDataListGetHeight;
|
|
_reorderableResolvingDataList.drawElementBackgroundCallback += OnReorderableResolvingDataListDrawElement;
|
|
_reorderableResolvingDataList.drawElementCallback += OnReorderableClearDrawElement;
|
|
_reorderableResolvingDataList.showDefaultBackground = false;
|
|
}
|
|
_reorderableResolvingDataList.list = _cachedMissingsResolvingDatas;
|
|
|
|
_lineWidth = GUI.skin.label.CalcSize(UnityEditorUtility.GetLabel("Namespace:")).x;
|
|
_arrowWidth = GUI.skin.button.CalcSize(UnityEditorUtility.GetLabel("->")).x;
|
|
}
|
|
|
|
private readonly Color _activedColor = new Color(0f, 0.6f, 1f, 0.36f);
|
|
private readonly Color _dragColor = new Color(0f, 0.60f, 1f, 0.16f);
|
|
private float OnReorderableResolvingDataListGetHeight(int index)
|
|
{
|
|
return (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing) * 3f + EditorGUIUtility.standardVerticalSpacing;
|
|
}
|
|
private void OnReorderableClearDrawElement(Rect rect, int index, bool isActive, bool isFocused) { }
|
|
private void OnReorderableResolvingDataListDrawElement(Rect rect, int index, bool isActive, bool isFocused)
|
|
{
|
|
if (index < 0 || index >= _cachedMissingsResolvingDatas.Length) { return; }
|
|
ref var data = ref _cachedMissingsResolvingDatas[index];
|
|
|
|
using (EcsGUI.SetAlpha(0))
|
|
{
|
|
if (GUI.Button(rect, ""))
|
|
{
|
|
_selectedMissingsResolvingData = _cachedMissingsResolvingDatas[index];
|
|
}
|
|
}
|
|
|
|
if (isActive)
|
|
{
|
|
EditorGUI.DrawRect(rect, _activedColor);
|
|
}
|
|
if (EcsGUI.HitTest(rect))
|
|
{
|
|
EditorGUI.DrawRect(rect, _dragColor);
|
|
}
|
|
|
|
rect = rect.AddPadding(EditorGUIUtility.standardVerticalSpacing, 0);
|
|
Rect infoRect;
|
|
(infoRect, rect) = rect.HorizontalSliceLeft(20f);
|
|
if (data.IsResolved)
|
|
{
|
|
GUI.Label(infoRect, UnityEditorUtility.GetLabel(Icons.Instance.PassIcon, "Valid type"));
|
|
}
|
|
else if (data.IsEmpty)
|
|
{
|
|
GUI.Label(infoRect, UnityEditorUtility.GetLabel(Icons.Instance.WarningIcon, "Is empty"));
|
|
}
|
|
else
|
|
{
|
|
GUI.Label(infoRect, UnityEditorUtility.GetLabel(Icons.Instance.ErrorIcon, "Type not found"));
|
|
}
|
|
|
|
rect.height = EditorGUIUtility.singleLineHeight;
|
|
rect = rect.Move(0, EditorGUIUtility.standardVerticalSpacing);
|
|
DrawLine(rect, "Name:", data.OldTypeData.ClassName, data.NewTypeData.ClassName);
|
|
rect = rect.Move(0, EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing);
|
|
DrawLine(rect, "Namespace:", data.OldTypeData.NamespaceName, data.NewTypeData.NamespaceName);
|
|
rect = rect.Move(0, EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing);
|
|
DrawLine(rect, "Assembly:", data.OldTypeData.AssemblyName, data.NewTypeData.AssemblyName);
|
|
|
|
rect.yMin = rect.yMax - 2f;
|
|
rect = rect.Move(0, EditorGUIUtility.standardVerticalSpacing * 2f);
|
|
rect.xMin -= infoRect.width;
|
|
//EditorGUI.DrawRect(rect, new Color(0, 0, 0, 0.3f));
|
|
}
|
|
private void DrawLine(Rect rect, string name, string oldStr, string newStr)
|
|
{
|
|
Rect nameRect, oldRect, arrowRect, newRect;
|
|
|
|
(nameRect, rect) = rect.HorizontalSliceLeft(_lineWidth);
|
|
float tmp = (rect.width - _arrowWidth) / 2f;
|
|
(oldRect, rect) = rect.HorizontalSliceLeft(tmp);
|
|
(arrowRect, rect) = rect.HorizontalSliceLeft(_arrowWidth);
|
|
(newRect, rect) = rect.HorizontalSliceLeft(tmp);
|
|
|
|
GUI.Label(nameRect, name);
|
|
EditorGUI.DrawRect(oldRect, new Color(0, 0, 0, 0.16f));
|
|
GUI.Label(oldRect, oldStr);
|
|
using (EcsGUI.SetAlignment(GUI.skin.label, TextAnchor.MiddleCenter))
|
|
{
|
|
GUI.Label(arrowRect, "->");
|
|
}
|
|
EditorGUI.DrawRect(newRect, new Color(0, 0, 0, 0.16f));
|
|
GUI.Label(newRect, newStr);
|
|
}
|
|
private string DrawEditableLine(Rect rect, string name, string oldStr, string newStr)
|
|
{
|
|
Rect nameRect, oldRect, arrowRect, newRect;
|
|
|
|
(nameRect, rect) = rect.HorizontalSliceLeft(_lineWidth);
|
|
float tmp = (rect.width - _arrowWidth) / 2f;
|
|
(oldRect, rect) = rect.HorizontalSliceLeft(tmp);
|
|
(arrowRect, rect) = rect.HorizontalSliceLeft(_arrowWidth);
|
|
(newRect, rect) = rect.HorizontalSliceLeft(tmp);
|
|
|
|
GUI.Label(nameRect, name);
|
|
GUI.TextField(oldRect, oldStr);
|
|
if (GUI.Button(arrowRect.AddPadding(2.5f, 0), "->"))
|
|
{
|
|
newStr = oldStr;
|
|
}
|
|
return EditorGUI.TextField(newRect, newStr);
|
|
}
|
|
|
|
|
|
private Vector2 _scrollViewPosition;
|
|
private static bool _isNoFound = false;
|
|
private GUIStyle _panel;
|
|
|
|
private void OnGUI()
|
|
{
|
|
//if (_panel == null)
|
|
{
|
|
_panel = new GUIStyle();
|
|
_panel.padding = new RectOffset(5, 5, 5, 5);
|
|
}
|
|
using (EcsGUI.Layout.BeginVertical(_panel))
|
|
{
|
|
const string LIST_EMPTY_MESSAGE = "List of Missings is Empty";
|
|
const string COLLECT_BUTTON = "Collect Missings";
|
|
if (_missingRefContainer.IsEmplty)
|
|
{
|
|
GUILayout.Label("", GUILayout.ExpandHeight(true), GUILayout.ExpandWidth(true));
|
|
using (EcsGUI.SetFontSize(14))
|
|
using (EcsGUI.SetFontSize(GUI.skin.button, 14))
|
|
using (EcsGUI.SetAlignment(value: TextAnchor.MiddleCenter))
|
|
{
|
|
Vector2 center = GUILayoutUtility.GetLastRect().center;
|
|
Vector2 labelSize = GUI.skin.label.CalcSize(UnityEditorUtility.GetLabel(LIST_EMPTY_MESSAGE));
|
|
Vector2 buttonSize = GUI.skin.button.CalcSize(UnityEditorUtility.GetLabel(COLLECT_BUTTON));
|
|
labelSize *= 1.2f;
|
|
buttonSize *= 1.2f;
|
|
Rect r;
|
|
r = new Rect(Vector2.zero, labelSize);
|
|
r.center = center;
|
|
r.y -= labelSize.y / 2f;
|
|
GUI.Label(r, LIST_EMPTY_MESSAGE);
|
|
r = new Rect(Vector2.zero, buttonSize);
|
|
r.center = center;
|
|
r.y += buttonSize.y / 2f;
|
|
if (Event.current.type == EventType.MouseDown && EcsGUI.HitTest(r))
|
|
{
|
|
_isNoFound = false;
|
|
}
|
|
if (GUI.Button(r, COLLECT_BUTTON, GUI.skin.button))
|
|
{
|
|
if (TryInit())
|
|
{
|
|
_missingRefContainer.Collect();
|
|
_cachedMissingsResolvingDatas = _missingRefContainer.MissingsResolvingDatas.Values.ToArray();
|
|
InitList();
|
|
if (_missingRefContainer.IsEmplty)
|
|
{
|
|
_isNoFound = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
GUIContent label = UnityEditorUtility.GetLabel("Missing references not found in the project.");
|
|
labelSize = GUI.skin.label.CalcSize(label);
|
|
r.y += labelSize.y * 1.1f;
|
|
r.xMin -= labelSize.x / 2f;
|
|
r.xMax += labelSize.x / 2f;
|
|
if (_isNoFound)
|
|
{
|
|
GUI.Label(r, label);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (_missingRefContainer.MissingsResolvingDatas.Count != _cachedMissingsResolvingDatas.Length)
|
|
{
|
|
_cachedMissingsResolvingDatas = _missingRefContainer.MissingsResolvingDatas.Values.ToArray();
|
|
InitList();
|
|
}
|
|
|
|
var bc = EcsGUI.SetBackgroundColor(Color.black, 0.5f);
|
|
using (EcsGUI.Layout.BeginVertical(EditorStyles.helpBox))
|
|
{
|
|
bc.Dispose();
|
|
_scrollViewPosition = GUILayout.BeginScrollView(_scrollViewPosition, GUILayout.ExpandHeight(true));
|
|
_reorderableResolvingDataList.DoLayoutList();
|
|
GUILayout.EndScrollView();
|
|
}
|
|
GUILayout.Space(4f);
|
|
|
|
using (EcsGUI.Layout.BeginVertical(GUILayout.ExpandHeight(false)))
|
|
{
|
|
//GUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.ExpandHeight(false));
|
|
|
|
var data = _selectedMissingsResolvingData;
|
|
Rect rect = GUILayoutUtility.GetRect(
|
|
EditorGUIUtility.currentViewWidth,
|
|
(EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing) * 3f + EditorGUIUtility.standardVerticalSpacing * 2f)
|
|
.AddPadding(EditorGUIUtility.standardVerticalSpacing);
|
|
|
|
|
|
if (data == null)
|
|
{
|
|
using (EcsGUI.SetAlignment(TextAnchor.MiddleCenter))
|
|
{
|
|
GUI.Label(rect, "Select any record");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
using (EcsGUI.CheckChanged())
|
|
{
|
|
rect.height = EditorGUIUtility.singleLineHeight;
|
|
rect = rect.Move(0, EditorGUIUtility.standardVerticalSpacing);
|
|
string ClassName = DrawEditableLine(rect, "Name:", data.OldTypeData.ClassName, data.NewTypeData.ClassName);
|
|
rect = rect.Move(0, EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing);
|
|
string NamespaceName = DrawEditableLine(rect, "Namespace:", data.OldTypeData.NamespaceName, data.NewTypeData.NamespaceName);
|
|
rect = rect.Move(0, EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing);
|
|
string AssemblyName = DrawEditableLine(rect, "Assembly:", data.OldTypeData.AssemblyName, data.NewTypeData.AssemblyName);
|
|
if (EcsGUI.Changed)
|
|
{
|
|
data.NewTypeData = new Internal.TypeData(ClassName, NamespaceName, AssemblyName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
using (EcsGUI.Layout.BeginHorizontal(GUILayout.Height(26f)))
|
|
{
|
|
if (GUILayout.Button("Re-Collect", GUILayout.ExpandHeight(true), GUILayout.ExpandWidth(false)))
|
|
{
|
|
|
|
}
|
|
if (GUILayout.Button("Repaire missing references", GUILayout.ExpandHeight(true)))
|
|
{
|
|
_selectedMissingsResolvingData = null;
|
|
RepaireFileUtility.RepaieAsset(_missingRefContainer);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private bool TryInit()
|
|
{
|
|
var allCurrentDirtyScenes = EditorSceneManager
|
|
.GetSceneManagerSetup()
|
|
.Where(sceneSetup => sceneSetup.isLoaded)
|
|
.Select(sceneSetup => EditorSceneManager.GetSceneByPath(sceneSetup.path))
|
|
.Where(scene => scene.isDirty)
|
|
.ToArray();
|
|
|
|
if (allCurrentDirtyScenes.Length != 0)
|
|
{
|
|
bool result = EditorUtility.DisplayDialog(
|
|
"Current active scene(s) is dirty",
|
|
"Please save all active scenes as they may be overwritten",
|
|
"Save active scene and Continue",
|
|
"Cancel update"
|
|
);
|
|
if (result == false)
|
|
return false;
|
|
|
|
foreach (var dirtyScene in allCurrentDirtyScenes)
|
|
EditorSceneManager.SaveScene(dirtyScene);
|
|
}
|
|
|
|
_missingRefContainer.Collect();
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
#endif |