mirror of
https://github.com/DCFApixels/DragonECS-Unity.git
synced 2025-09-17 17:34:34 +08:00
502 lines
19 KiB
C#
502 lines
19 KiB
C#
#if UNITY_EDITOR
|
||
using DCFApixels.DragonECS.Unity.Editors;
|
||
using DCFApixels.DragonECS.Unity.Internal;
|
||
using System;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
|
||
namespace DCFApixels.DragonECS.Unity.Docs.Editors
|
||
{
|
||
internal class DragonDocsWindow : EditorWindow
|
||
{
|
||
public const string TITLE = "Documentation";
|
||
[MenuItem("Tools/" + EcsConsts.FRAMEWORK_NAME + "/" + TITLE)]
|
||
static void Open()
|
||
{
|
||
var wnd = GetWindow<DragonDocsWindow>();
|
||
wnd.titleContent = new GUIContent(TITLE);
|
||
wnd.minSize = new Vector2(100f, 120f);
|
||
wnd.Show();
|
||
}
|
||
|
||
private int _selectedIndex = 0;
|
||
|
||
private Vector2 ButtonsScrolPosition;
|
||
private Vector2 DataScrolPosition;
|
||
|
||
private Vector2 _buttonsWidthDragStartPos = Vector2.zero;
|
||
private float _buttonsWidthDragStartValue = 200f;
|
||
private float _buttonsWidth = 200f;
|
||
private DragState _dragState;
|
||
private enum DragState
|
||
{
|
||
None,
|
||
Init,
|
||
Update,
|
||
}
|
||
|
||
private DragonDocsPrefs Prefs { get { return DragonDocsPrefs.instance; } }
|
||
private static bool IsShowHidden
|
||
{
|
||
get { return UserSettingsPrefs.instance.IsShowHidden; }
|
||
set { UserSettingsPrefs.instance.IsShowHidden = value; }
|
||
}
|
||
private static bool IsUseCustomNames
|
||
{
|
||
get { return UserSettingsPrefs.instance.IsUseCustomNames; }
|
||
set { UserSettingsPrefs.instance.IsUseCustomNames = value; }
|
||
}
|
||
|
||
|
||
private bool _searchingSampleChanged = false;
|
||
private string _searchingSampleEnter = string.Empty;
|
||
private string _searchingSample = string.Empty;
|
||
private bool[] _searchingHideMetaMap = System.Array.Empty<bool>();
|
||
private bool[] _searchingHideGroupMap = System.Array.Empty<bool>();
|
||
|
||
private void OnGUI()
|
||
{
|
||
Event current = Event.current;
|
||
DragonDocs docs = DragonDocsPrefs.instance.Docs;
|
||
if (docs == null || docs.Metas.IsEmpty)
|
||
{
|
||
docs = DragonDocs.Generate();
|
||
DragonDocsPrefs.instance.Save(docs);
|
||
}
|
||
var metas = docs.Metas;
|
||
var infos = DragonDocsPrefs.instance.Infos;
|
||
if (_searchingHideMetaMap.Length < metas.Length)
|
||
{
|
||
System.Array.Resize(ref _searchingHideMetaMap, metas.Length);
|
||
}
|
||
if (_searchingHideGroupMap.Length < infos.Length)
|
||
{
|
||
System.Array.Resize(ref _searchingHideGroupMap, DragonDocsPrefs.instance.Infos.Length);
|
||
}
|
||
|
||
if (_selectedIndex < 0 || _selectedIndex >= infos.Length)
|
||
{
|
||
_selectedIndex = 0;
|
||
}
|
||
|
||
|
||
DrawToolbar();
|
||
|
||
GUILayout.BeginHorizontal(GUILayout.ExpandHeight(true));
|
||
|
||
MetaGroupInfo selectedGroupInfo;
|
||
using (EcsGUI.Layout.BeginScrollView(ref ButtonsScrolPosition, UnityEditorUtility.GetClearBackgrounStyle(), GUILayout.Width(_buttonsWidth)))
|
||
{
|
||
selectedGroupInfo = DrawGroups();
|
||
}
|
||
|
||
DrawDragger();
|
||
|
||
GUILayout.Space(EditorGUIUtility.standardVerticalSpacing * -2f);
|
||
|
||
using (EcsGUI.Layout.BeginScrollView(ref DataScrolPosition, UnityEditorUtility.GetTransperentBlackBackgrounStyle(), GUILayout.ExpandWidth(true)))
|
||
{
|
||
DrawSelectedGroupMeta(selectedGroupInfo);
|
||
}
|
||
|
||
//GUILayout.Space(EditorGUIUtility.standardVerticalSpacing * -2f);
|
||
GUILayout.EndHorizontal();
|
||
|
||
Rect r = GUILayoutUtility.GetLastRect();
|
||
float h = r.height;
|
||
r.height = EditorGUIUtility.standardVerticalSpacing;
|
||
//EditorGUI.DrawRect(r, new Color(0, 0, 0, 0.3f));
|
||
r.y += h;
|
||
EditorGUI.DrawRect(r, new Color(0, 0, 0, 0.3f));
|
||
|
||
GUI.enabled = true;
|
||
|
||
if (_selectedIndex >= 0 && _selectedIndex < infos.Length)
|
||
{
|
||
GUILayout.Label(infos[_selectedIndex].Path);
|
||
}
|
||
}
|
||
|
||
private void DrawToolbar()
|
||
{
|
||
using (EcsGUI.SetColor(GUI.color * 0.8f))
|
||
GUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||
GUILayout.Space(EditorGUIUtility.standardVerticalSpacing * 2f);
|
||
|
||
if (GUILayout.Button("Update", EditorStyles.toolbarButton, GUILayout.Width(80f)))
|
||
{
|
||
DragonDocs docs = DragonDocs.Generate();
|
||
DragonDocsPrefs.instance.Save(docs);
|
||
}
|
||
|
||
if (EcsGUI.Layout.IconButton(IsShowHidden ? Icons.Instance.VisibilityIconOn : Icons.Instance.VisibilityIconOff, 0f, IsShowHidden ? "Show Hidden" : "Don't Show Hidden", EditorStyles.toolbarButton, GUILayout.Width(EditorGUIUtility.singleLineHeight * 1.6f)))
|
||
{
|
||
IsShowHidden = !IsShowHidden;
|
||
}
|
||
|
||
if (EcsGUI.Layout.IconButton(IsUseCustomNames ? Icons.Instance.LabelIconMeta : Icons.Instance.LabelIconType, 1f, IsUseCustomNames ? "Use Meta Name" : "Use Type Name", EditorStyles.toolbarButton, GUILayout.Width(EditorGUIUtility.singleLineHeight * 1.6f)))
|
||
{
|
||
IsUseCustomNames = !IsUseCustomNames;
|
||
}
|
||
|
||
GUILayout.Label("");
|
||
EditorGUI.BeginChangeCheck();
|
||
_searchingSampleEnter = EditorGUILayout.TextField(_searchingSampleEnter, EditorStyles.toolbarSearchField, GUILayout.ExpandHeight(true), GUILayout.MaxWidth(200f));
|
||
if (EditorGUI.EndChangeCheck())
|
||
{
|
||
_searchingSampleChanged = true;
|
||
}
|
||
if ((_searchingSampleChanged && Event.current.keyCode == KeyCode.Return) ||
|
||
EcsGUI.Layout.IconButton(Icons.Instance.SearchIcon, 1f, null, EditorStyles.toolbarButton, GUILayout.ExpandHeight(true), GUILayout.Width(EditorGUIUtility.singleLineHeight * 1.6f)))
|
||
{
|
||
Searh();
|
||
}
|
||
GUILayout.Space(EditorGUIUtility.standardVerticalSpacing * 2f);
|
||
GUILayout.EndHorizontal();
|
||
|
||
GUILayout.Space(EditorGUIUtility.standardVerticalSpacing * -2f);
|
||
}
|
||
|
||
private void Searh()
|
||
{
|
||
_searchingSample = _searchingSampleEnter;
|
||
_searchingSampleChanged = false;
|
||
DragonDocs docs = DragonDocsPrefs.instance.Docs;
|
||
var metas = docs.Metas;
|
||
if (_searchingSample.Length <= 0)
|
||
{
|
||
var infos = DragonDocsPrefs.instance.Infos;
|
||
var isExpands = DragonDocsPrefs.instance.IsExpands;
|
||
|
||
for (int i = 0; i < _searchingHideMetaMap.Length; i++)
|
||
{
|
||
_searchingHideMetaMap[i] = false;
|
||
}
|
||
for (int i = 0; i < _searchingHideGroupMap.Length; i++)
|
||
{
|
||
_searchingHideGroupMap[i] = false;
|
||
}
|
||
|
||
{
|
||
int i = _selectedIndex;
|
||
var info = infos[i];
|
||
int depth = info.Depth;
|
||
while (depth > 0)
|
||
{
|
||
i--;
|
||
info = infos[i];
|
||
|
||
if (info.Depth >= depth)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
depth = info.Depth;
|
||
isExpands[i] = true;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var infos = DragonDocsPrefs.instance.Infos;
|
||
|
||
for (int i = 0; i < infos.Length; i++)
|
||
{
|
||
var info = infos[i];
|
||
int visibleCount = 0;
|
||
bool isUseCustomNames = IsUseCustomNames;
|
||
for (int j = info.StartIndex, jMax = j + info.Length; j < jMax; j++)
|
||
{
|
||
var b = (isUseCustomNames ? metas[j].Name : metas[j].TypeName).Contains(_searchingSample, System.StringComparison.InvariantCultureIgnoreCase);
|
||
_searchingHideMetaMap[j] = !b;
|
||
|
||
if (b)
|
||
{
|
||
visibleCount++;
|
||
}
|
||
}
|
||
|
||
_searchingHideGroupMap[i] = visibleCount == 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
private void DrawSelectedGroupMeta(MetaGroupInfo info)
|
||
{
|
||
bool hide = IsShowHidden == false;
|
||
var metas = Prefs.Docs.Metas;
|
||
int iMax = info.Length;
|
||
for (int i = 0, j = info.StartIndex; i < iMax; j++)
|
||
{
|
||
if (_searchingHideMetaMap[j] || (metas[j]._isHidden && hide))
|
||
{
|
||
iMax--;
|
||
}
|
||
else
|
||
{
|
||
DrawMeta(metas[j], i, 12);
|
||
i++;
|
||
}
|
||
}
|
||
if (iMax <= 0)
|
||
{
|
||
GUILayout.Label(info.Length <= 0 ? "empty group" : "there are hidden items", EditorStyles.centeredGreyMiniLabel, GUILayout.ExpandHeight(true), GUILayout.ExpandWidth(true));
|
||
}
|
||
}
|
||
|
||
private void DrawMeta(DragonDocsMeta meta, int index, int total)
|
||
{
|
||
using (EcsGUI.SetIndentLevel(0))
|
||
{
|
||
Color panelColor = EcsGUI.SelectPanelColor(meta.Color.ToMetaColor(), meta.IsCustomColor, index, total).Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE);
|
||
Color alphaPanelColor = panelColor;
|
||
alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA;
|
||
|
||
using (EcsGUI.Layout.BeginVertical(alphaPanelColor))
|
||
{
|
||
GUILayout.Space(1f);
|
||
|
||
//draw title block
|
||
using (EcsGUI.Layout.BeginHorizontal())
|
||
{
|
||
GUILayout.TextArea(IsUseCustomNames ? meta.Name : meta.TypeName, EditorStyles.boldLabel, GUILayout.ExpandWidth(false));
|
||
|
||
if (meta.TryGetSourceType(out System.Type targetType) && ScriptsCache.TryGetScriptAsset(targetType.ToMeta(), out MonoScript script))
|
||
{
|
||
EcsGUI.Layout.ScriptAssetButton(script, GUILayout.Width(18f));
|
||
}
|
||
|
||
if (meta.IsCustomName)
|
||
{
|
||
using (EcsGUI.SetAlpha(0.64f)) using (EcsGUI.SetAlignment(GUI.skin.label, TextAnchor.MiddleRight))
|
||
{
|
||
GUILayout.TextArea(IsUseCustomNames ? meta.TypeName : meta.Name, GUI.skin.label);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
GUILayout.Label("");
|
||
}
|
||
|
||
|
||
if (string.IsNullOrEmpty(meta.MetaID) == false)
|
||
{
|
||
GUILayout.Space(-EditorGUIUtility.standardVerticalSpacing);
|
||
EcsGUI.Layout.CopyMetaIDButton(meta.MetaID, GUILayout.Width(18f));
|
||
}
|
||
}
|
||
|
||
void DrawLine()
|
||
{
|
||
Rect lineRect = GUILayoutUtility.GetLastRect(); ;
|
||
lineRect.yMin = lineRect.yMax;
|
||
lineRect.yMax += 1f;
|
||
lineRect.y += 5f;
|
||
EditorGUI.DrawRect(lineRect, new Color(1, 1, 1, 0.12f));
|
||
}
|
||
|
||
bool isWithMetaID = string.IsNullOrEmpty(meta.MetaID) == false;
|
||
|
||
//draw description block
|
||
if (string.IsNullOrEmpty(meta.Description) == false)
|
||
{
|
||
DrawLine();
|
||
|
||
GUILayout.Space(7f);
|
||
|
||
GUILayout.TextArea(meta.Description, EditorStyles.wordWrappedLabel);
|
||
}
|
||
|
||
//draw tags block
|
||
if (meta._tags.Length > 0)
|
||
{
|
||
DrawLine();
|
||
|
||
GUILayout.Space(3f);
|
||
|
||
var tagsstring = string.Join(',', meta._tags);
|
||
using (EcsGUI.SetAlpha(0.5f))
|
||
{
|
||
GUILayout.TextArea(tagsstring, EditorStyles.wordWrappedMiniLabel);
|
||
}
|
||
}
|
||
|
||
GUILayout.Space(1f);
|
||
}
|
||
}
|
||
}
|
||
|
||
private MetaGroupInfo DrawGroups()
|
||
{
|
||
Event current = Event.current;
|
||
MetaGroupInfo result = new MetaGroupInfo("NO_NAME", "NO_NAME", 0, 0, 0);
|
||
var infos = Prefs.Infos;
|
||
var isExpands = Prefs.IsExpands;
|
||
|
||
using (EcsGUI.SetIndentLevel(0))
|
||
{
|
||
int clippingDepth = int.MaxValue;
|
||
|
||
for (int i = 0; i < infos.Length; i++)
|
||
{
|
||
if (infos.Length > _searchingHideGroupMap.Length)
|
||
{
|
||
Array.Resize(ref _searchingHideGroupMap, infos.Length);
|
||
}
|
||
if (_searchingHideGroupMap[i]) { continue; }
|
||
|
||
var groupInfo = infos[i];
|
||
|
||
if (i == _selectedIndex)
|
||
{
|
||
result = groupInfo;
|
||
}
|
||
|
||
if (_searchingSample.Length == 0 && groupInfo.Depth > clippingDepth)
|
||
{
|
||
continue;
|
||
}
|
||
else
|
||
{
|
||
clippingDepth = int.MaxValue;
|
||
}
|
||
|
||
if (_searchingSample.Length == 0)
|
||
{
|
||
EcsGUI.IndentLevel = groupInfo.Depth;
|
||
}
|
||
|
||
GUIContent label = UnityEditorUtility.GetLabel(_searchingSample.Length == 0 ? groupInfo.Name : groupInfo.Path);
|
||
Rect r = GUILayoutUtility.GetRect(label, EditorStyles.foldout);
|
||
|
||
if (i == _selectedIndex)
|
||
{
|
||
EditorGUI.DrawRect(r, new Color(0.12f, 0.5f, 1f, 0.40f));
|
||
}
|
||
|
||
using (EcsGUI.SetColor(0, 0, 0, 0)) using (EcsGUI.Disable) { GUI.Button(r, ""); }
|
||
|
||
bool isClick = false;
|
||
if (EcsGUI.HitTest(r))
|
||
{
|
||
EditorGUI.DrawRect(r, new Color(1f, 1f, 1f, 0.12f));
|
||
if (current.type == EventType.MouseUp)
|
||
{
|
||
isClick = true;
|
||
|
||
//_selectedIndex = i;
|
||
//current.Use();
|
||
}
|
||
}
|
||
|
||
if (_searchingSample.Length != 0 || (i + 1 == infos.Length || infos[i + 1].Depth <= groupInfo.Depth))
|
||
{
|
||
using (EcsGUI.SetBackgroundColor(0, 0, 0, 0))
|
||
{
|
||
EditorGUI.Foldout(r, false, label, EditorStyles.foldout);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
EditorGUI.BeginChangeCheck();
|
||
isExpands[i] = EditorGUI.Foldout(r, isExpands[i], label, EditorStyles.foldout);
|
||
if (EditorGUI.EndChangeCheck())
|
||
{
|
||
isClick = false;
|
||
}
|
||
}
|
||
|
||
if (isClick)
|
||
{
|
||
_selectedIndex = i;
|
||
current.Use();
|
||
}
|
||
|
||
if (isExpands[i] == false)
|
||
{
|
||
clippingDepth = groupInfo.Depth;
|
||
}
|
||
|
||
if (groupInfo.Length > 0)
|
||
{
|
||
r.xMax = r.xMin;
|
||
r.xMin -= 2f;
|
||
|
||
r.yMin += 1;
|
||
r.yMax -= 1;
|
||
EditorGUI.DrawRect(r, new Color(0.2f, 0.6f, 1f));
|
||
}
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
private void DrawDragger()
|
||
{
|
||
const float DRAG_RESIZE_WIDTH = 4f;
|
||
|
||
Rect rect = GUILayoutUtility.GetLastRect();
|
||
float m = DRAG_RESIZE_WIDTH;
|
||
if (_dragState != DragState.None)
|
||
{
|
||
m *= 2f;
|
||
}
|
||
rect.xMin = rect.xMax;
|
||
rect.x -= m / 2f;
|
||
rect.width = m;
|
||
|
||
EditorGUI.DrawRect(rect.AddPadding(1f, 0), new Color(0, 0, 0, 0.3f));
|
||
|
||
Event current = Event.current;
|
||
switch (current.type)
|
||
{
|
||
case EventType.MouseDown:
|
||
if (EcsGUI.HitTest(rect))
|
||
{
|
||
_buttonsWidthDragStartPos = current.mousePosition;
|
||
_buttonsWidthDragStartValue = _buttonsWidth;
|
||
_dragState = DragState.Init;
|
||
current.Use();
|
||
}
|
||
break;
|
||
case EventType.MouseUp:
|
||
if (_dragState != DragState.None)
|
||
{
|
||
_dragState = DragState.None;
|
||
current.Use();
|
||
}
|
||
break;
|
||
case EventType.MouseDrag:
|
||
{
|
||
switch (_dragState)
|
||
{
|
||
case DragState.Init:
|
||
{
|
||
if ((Event.current.mousePosition - _buttonsWidthDragStartPos).sqrMagnitude > 16f)
|
||
{
|
||
_dragState = DragState.Update;
|
||
}
|
||
}
|
||
break;
|
||
case DragState.Update:
|
||
{
|
||
_buttonsWidth = _buttonsWidthDragStartValue + (Event.current.mousePosition.x - _buttonsWidthDragStartPos.x);
|
||
_buttonsWidth = Mathf.Max(6f, _buttonsWidth);
|
||
current.Use();//TODO кажется это можно использовать вместо лайфахака с кнопкой для моментальной реакции пир наведении курсора для кнопок с иконками
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
case EventType.Repaint:
|
||
{
|
||
|
||
|
||
EditorGUIUtility.AddCursorRect(rect, MouseCursor.SlideArrow);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif |