ReadmeEditor.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEditor;
  5. using System;
  6. using System.IO;
  7. using System.Reflection;
  8. [CustomEditor(typeof(Readme))]
  9. [InitializeOnLoad]
  10. public class ReadmeEditor : Editor
  11. {
  12. static string s_ShowedReadmeSessionStateName = "ReadmeEditor.showedReadme";
  13. static string s_ReadmeSourceDirectory = "Assets/TutorialInfo";
  14. const float k_Space = 16f;
  15. static ReadmeEditor()
  16. {
  17. EditorApplication.delayCall += SelectReadmeAutomatically;
  18. }
  19. static void RemoveTutorial()
  20. {
  21. if (EditorUtility.DisplayDialog("Remove Readme Assets",
  22. $"All contents under {s_ReadmeSourceDirectory} will be removed, are you sure you want to proceed?",
  23. "Proceed",
  24. "Cancel"))
  25. {
  26. if (Directory.Exists(s_ReadmeSourceDirectory))
  27. {
  28. FileUtil.DeleteFileOrDirectory(s_ReadmeSourceDirectory);
  29. FileUtil.DeleteFileOrDirectory(s_ReadmeSourceDirectory + ".meta");
  30. }
  31. else
  32. {
  33. Debug.Log($"Could not find the Readme folder at {s_ReadmeSourceDirectory}");
  34. }
  35. var readmeAsset = SelectReadme();
  36. if (readmeAsset != null)
  37. {
  38. var path = AssetDatabase.GetAssetPath(readmeAsset);
  39. FileUtil.DeleteFileOrDirectory(path + ".meta");
  40. FileUtil.DeleteFileOrDirectory(path);
  41. }
  42. AssetDatabase.Refresh();
  43. }
  44. }
  45. static void SelectReadmeAutomatically()
  46. {
  47. if (!SessionState.GetBool(s_ShowedReadmeSessionStateName, false))
  48. {
  49. var readme = SelectReadme();
  50. SessionState.SetBool(s_ShowedReadmeSessionStateName, true);
  51. if (readme && !readme.loadedLayout)
  52. {
  53. LoadLayout();
  54. readme.loadedLayout = true;
  55. }
  56. }
  57. }
  58. static void LoadLayout()
  59. {
  60. var assembly = typeof(EditorApplication).Assembly;
  61. var windowLayoutType = assembly.GetType("UnityEditor.WindowLayout", true);
  62. var method = windowLayoutType.GetMethod("LoadWindowLayout", BindingFlags.Public | BindingFlags.Static);
  63. method.Invoke(null, new object[] { Path.Combine(Application.dataPath, "TutorialInfo/Layout.wlt"), false });
  64. }
  65. static Readme SelectReadme()
  66. {
  67. var ids = AssetDatabase.FindAssets("Readme t:Readme");
  68. if (ids.Length == 1)
  69. {
  70. var readmeObject = AssetDatabase.LoadMainAssetAtPath(AssetDatabase.GUIDToAssetPath(ids[0]));
  71. Selection.objects = new UnityEngine.Object[] { readmeObject };
  72. return (Readme)readmeObject;
  73. }
  74. else
  75. {
  76. Debug.Log("Couldn't find a readme");
  77. return null;
  78. }
  79. }
  80. protected override void OnHeaderGUI()
  81. {
  82. var readme = (Readme)target;
  83. Init();
  84. var iconWidth = Mathf.Min(EditorGUIUtility.currentViewWidth / 3f - 20f, 128f);
  85. GUILayout.BeginHorizontal("In BigTitle");
  86. {
  87. if (readme.icon != null)
  88. {
  89. GUILayout.Space(k_Space);
  90. GUILayout.Label(readme.icon, GUILayout.Width(iconWidth), GUILayout.Height(iconWidth));
  91. }
  92. GUILayout.Space(k_Space);
  93. GUILayout.BeginVertical();
  94. {
  95. GUILayout.FlexibleSpace();
  96. GUILayout.Label(readme.title, TitleStyle);
  97. GUILayout.FlexibleSpace();
  98. }
  99. GUILayout.EndVertical();
  100. GUILayout.FlexibleSpace();
  101. }
  102. GUILayout.EndHorizontal();
  103. }
  104. public override void OnInspectorGUI()
  105. {
  106. var readme = (Readme)target;
  107. Init();
  108. foreach (var section in readme.sections)
  109. {
  110. if (!string.IsNullOrEmpty(section.heading))
  111. {
  112. GUILayout.Label(section.heading, HeadingStyle);
  113. }
  114. if (!string.IsNullOrEmpty(section.text))
  115. {
  116. GUILayout.Label(section.text, BodyStyle);
  117. }
  118. if (!string.IsNullOrEmpty(section.linkText))
  119. {
  120. if (LinkLabel(new GUIContent(section.linkText)))
  121. {
  122. Application.OpenURL(section.url);
  123. }
  124. }
  125. GUILayout.Space(k_Space);
  126. }
  127. if (GUILayout.Button("Remove Readme Assets", ButtonStyle))
  128. {
  129. RemoveTutorial();
  130. }
  131. }
  132. bool m_Initialized;
  133. GUIStyle LinkStyle
  134. {
  135. get { return m_LinkStyle; }
  136. }
  137. [SerializeField]
  138. GUIStyle m_LinkStyle;
  139. GUIStyle TitleStyle
  140. {
  141. get { return m_TitleStyle; }
  142. }
  143. [SerializeField]
  144. GUIStyle m_TitleStyle;
  145. GUIStyle HeadingStyle
  146. {
  147. get { return m_HeadingStyle; }
  148. }
  149. [SerializeField]
  150. GUIStyle m_HeadingStyle;
  151. GUIStyle BodyStyle
  152. {
  153. get { return m_BodyStyle; }
  154. }
  155. [SerializeField]
  156. GUIStyle m_BodyStyle;
  157. GUIStyle ButtonStyle
  158. {
  159. get { return m_ButtonStyle; }
  160. }
  161. [SerializeField]
  162. GUIStyle m_ButtonStyle;
  163. void Init()
  164. {
  165. if (m_Initialized)
  166. return;
  167. m_BodyStyle = new GUIStyle(EditorStyles.label);
  168. m_BodyStyle.wordWrap = true;
  169. m_BodyStyle.fontSize = 14;
  170. m_BodyStyle.richText = true;
  171. m_TitleStyle = new GUIStyle(m_BodyStyle);
  172. m_TitleStyle.fontSize = 26;
  173. m_HeadingStyle = new GUIStyle(m_BodyStyle);
  174. m_HeadingStyle.fontStyle = FontStyle.Bold;
  175. m_HeadingStyle.fontSize = 18;
  176. m_LinkStyle = new GUIStyle(m_BodyStyle);
  177. m_LinkStyle.wordWrap = false;
  178. // Match selection color which works nicely for both light and dark skins
  179. m_LinkStyle.normal.textColor = new Color(0x00 / 255f, 0x78 / 255f, 0xDA / 255f, 1f);
  180. m_LinkStyle.stretchWidth = false;
  181. m_ButtonStyle = new GUIStyle(EditorStyles.miniButton);
  182. m_ButtonStyle.fontStyle = FontStyle.Bold;
  183. m_Initialized = true;
  184. }
  185. bool LinkLabel(GUIContent label, params GUILayoutOption[] options)
  186. {
  187. var position = GUILayoutUtility.GetRect(label, LinkStyle, options);
  188. Handles.BeginGUI();
  189. Handles.color = LinkStyle.normal.textColor;
  190. Handles.DrawLine(new Vector3(position.xMin, position.yMax), new Vector3(position.xMax, position.yMax));
  191. Handles.color = Color.white;
  192. Handles.EndGUI();
  193. EditorGUIUtility.AddCursorRect(position, MouseCursor.Link);
  194. return GUI.Button(position, label, LinkStyle);
  195. }
  196. }