XChartsEditor.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using UnityEditor;
  6. using UnityEngine;
  7. using UnityEngine.EventSystems;
  8. using UnityEngine.UI;
  9. using XCharts.Runtime;
  10. using ADB = UnityEditor.AssetDatabase;
  11. namespace XCharts.Editor
  12. {
  13. public partial class XChartsEditor : UnityEditor.Editor
  14. {
  15. private static Transform GetParent()
  16. {
  17. GameObject selectObj = Selection.activeGameObject;
  18. if (selectObj == null)
  19. {
  20. var canvas = GameObject.FindObjectOfType<Canvas>();
  21. if (canvas != null) return canvas.transform;
  22. else
  23. {
  24. var canvasObject = new GameObject();
  25. canvasObject.name = "Canvas";
  26. canvas = canvasObject.AddComponent<Canvas>();
  27. canvas.renderMode = RenderMode.ScreenSpaceCamera;
  28. var mainCamera = GameObject.FindGameObjectWithTag("MainCamera");
  29. canvas.worldCamera = mainCamera == null ? null : mainCamera.GetComponent<Camera>();
  30. canvasObject.AddComponent<CanvasScaler>();
  31. canvasObject.AddComponent<GraphicRaycaster>();
  32. if (GameObject.Find("EventSystem") == null)
  33. {
  34. var eventSystem = new GameObject();
  35. eventSystem.name = "EventSystem";
  36. eventSystem.AddComponent<EventSystem>();
  37. eventSystem.AddComponent<StandaloneInputModule>();
  38. }
  39. return canvas.transform;
  40. }
  41. }
  42. else
  43. {
  44. return selectObj.transform;
  45. }
  46. }
  47. private static string GetName(Transform parent, string name)
  48. {
  49. if (parent.Find(name) == null) return name;
  50. for (int i = 1; i <= 10; i++)
  51. {
  52. var newName = string.Format("{0} ({1})", name, i);
  53. if (parent.Find(newName) == null)
  54. {
  55. return newName;
  56. }
  57. }
  58. return name;
  59. }
  60. public static T AddChart<T>(string chartName, string titleName = null) where T : BaseChart
  61. {
  62. XCThemeMgr.CheckReloadTheme();
  63. var chart = AddGraph<T>(chartName);
  64. if (!string.IsNullOrEmpty(titleName))
  65. {
  66. var title = chart.GetChartComponent<Title>();
  67. title.text = titleName;
  68. }
  69. return chart;
  70. }
  71. public static T AddGraph<T>(string graphName) where T : Graphic
  72. {
  73. var parent = GetParent();
  74. if (parent == null) return null;
  75. XCThemeMgr.CheckReloadTheme();
  76. var obj = new GameObject();
  77. obj.name = GetName(parent, graphName);
  78. obj.layer = LayerMask.NameToLayer("UI");
  79. var t = obj.AddComponent<T>();
  80. obj.transform.SetParent(parent);
  81. obj.transform.localScale = Vector3.one;
  82. obj.transform.localPosition = Vector3.zero;
  83. obj.transform.localRotation = Quaternion.Euler(0, 0, 0);
  84. var rect = obj.GetComponent<RectTransform>();
  85. rect.anchorMin = new Vector2(0.5f, 0.5f);
  86. rect.anchorMax = new Vector2(0.5f, 0.5f);
  87. rect.pivot = new Vector2(0.5f, 0.5f);
  88. Selection.activeGameObject = obj;
  89. EditorUtility.SetDirty(obj);
  90. return t;
  91. }
  92. [MenuItem("XCharts/EmptyChart", priority = 43)]
  93. [MenuItem("GameObject/XCharts/EmptyChart", priority = 43)]
  94. public static void AddBaseChart()
  95. {
  96. AddChart<BaseChart>("EmptyChart");
  97. }
  98. [MenuItem("XCharts/RadarChart/Polygon Radar", priority = 47)]
  99. [MenuItem("GameObject/XCharts/RadarChart/Polygon Radar", priority = 47)]
  100. public static void AddRadarChart()
  101. {
  102. AddChart<RadarChart>("RadarChart");
  103. }
  104. [MenuItem("XCharts/RadarChart/Cirle Radar", priority = 47)]
  105. [MenuItem("GameObject/XCharts/RadarChart/Cirle Radar", priority = 47)]
  106. public static void AddRadarChart_CirleRadar()
  107. {
  108. var chart = AddChart<RadarChart>("RadarChart");
  109. chart.DefaultCircleRadarChart();
  110. }
  111. [MenuItem("XCharts/ScatterChart/Scatter", priority = 48)]
  112. [MenuItem("GameObject/XCharts/ScatterChart/Scatter", priority = 48)]
  113. public static void AddScatterChart()
  114. {
  115. AddChart<ScatterChart>("ScatterChart");
  116. }
  117. [MenuItem("XCharts/ScatterChart/Bubble", priority = 48)]
  118. [MenuItem("GameObject/XCharts/ScatterChart/Bubble", priority = 48)]
  119. public static void AddScatterChart_Bubble()
  120. {
  121. var chart = AddChart<ScatterChart>("ScatterChart");
  122. chart.DefaultBubbleChart();
  123. }
  124. [MenuItem("XCharts/HeatmapChart/Heatmap", priority = 49)]
  125. [MenuItem("GameObject/XCharts/HeatmapChart/Heatmap", priority = 49)]
  126. public static void AddHeatmapChart()
  127. {
  128. AddChart<HeatmapChart>("HeatmapChart");
  129. }
  130. [MenuItem("XCharts/HeatmapChart/Count Heatmap", priority = 49)]
  131. [MenuItem("GameObject/XCharts/HeatmapChart/Count Heatmap", priority = 49)]
  132. public static void AddHeatmapChart_Count()
  133. {
  134. var chart = AddChart<HeatmapChart>("HeatmapChart");
  135. chart.DefaultCountHeatmapChart();
  136. }
  137. [MenuItem("XCharts/RingChart/Ring", priority = 51)]
  138. [MenuItem("GameObject/XCharts/RingChart/Ring", priority = 51)]
  139. public static void AddRingChart()
  140. {
  141. AddChart<RingChart>("RingChart");
  142. }
  143. [MenuItem("XCharts/RingChart/Multiple Ring", priority = 51)]
  144. [MenuItem("GameObject/XCharts/RingChart/Multiple Ring", priority = 51)]
  145. public static void AddRingChart_MultiRing()
  146. {
  147. var chart = AddChart<RingChart>("RingChart");
  148. chart.DefaultMultipleRingChart();
  149. }
  150. [MenuItem("XCharts/CandlestickChart/Candlestick", priority = 54)]
  151. [MenuItem("GameObject/XCharts/CandlestickChart/Candlestick", priority = 54)]
  152. public static void CandlestickChart()
  153. {
  154. AddChart<CandlestickChart>("CandlestickChart");
  155. }
  156. [MenuItem("XCharts/ParallelChart/Parallel", priority = 55)]
  157. [MenuItem("GameObject/XCharts/ParallelChart/Parallel", priority = 55)]
  158. public static void ParallelChart()
  159. {
  160. AddChart<ParallelChart>("ParallelChart");
  161. }
  162. [MenuItem("XCharts/SimplifiedChart/Line", priority = 56)]
  163. [MenuItem("GameObject/XCharts/SimplifiedChart/Line", priority = 56)]
  164. public static void SimplifiedLineChart()
  165. {
  166. AddChart<SimplifiedLineChart>("SimplifiedLineChart");
  167. }
  168. [MenuItem("XCharts/SimplifiedChart/Bar", priority = 57)]
  169. [MenuItem("GameObject/XCharts/SimplifiedChart/Bar", priority = 57)]
  170. public static void SimplifiedBarChart()
  171. {
  172. AddChart<SimplifiedBarChart>("SimplifiedBarChart");
  173. }
  174. [MenuItem("XCharts/SimplifiedChart/Candlestick", priority = 58)]
  175. [MenuItem("GameObject/XCharts/SimplifiedChart/Candlestick", priority = 58)]
  176. public static void SimplifiedCandlestickChart()
  177. {
  178. AddChart<SimplifiedCandlestickChart>("SimplifiedCandlestickChart");
  179. }
  180. [MenuItem("XCharts/Themes Reload")]
  181. public static void ReloadTheme()
  182. {
  183. XCThemeMgr.ReloadThemeList();
  184. }
  185. #region Text mesh pro support
  186. #if UNITY_2017_1_OR_NEWER
  187. const string SYMBOL_TMP = "dUI_TextMeshPro";
  188. const string ASMDEF_TMP = "Unity.TextMeshPro";
  189. #if !dUI_TextMeshPro
  190. [MenuItem("XCharts/TextMeshPro Enable")]
  191. #endif
  192. public static void EnableTextMeshPro()
  193. {
  194. if (!IsSpecifyAssemblyExist(ASMDEF_TMP))
  195. {
  196. Debug.LogError("TextMeshPro is not in the project, please import TextMeshPro package first.");
  197. return;
  198. }
  199. if (EditorUtility.DisplayDialog("TextMeshPro Enable", "TextMeshPro is disabled, do you want to enable it?", "Yes", "Cancel"))
  200. {
  201. DefineSymbolsUtil.AddGlobalDefine(SYMBOL_TMP);
  202. XChartsMgr.RemoveAllChartObject();
  203. CheckAsmdefTmpReference(true);
  204. }
  205. }
  206. #if dUI_TextMeshPro
  207. [MenuItem("XCharts/TextMeshPro Disable")]
  208. #endif
  209. public static void DisableTextMeshPro()
  210. {
  211. if (EditorUtility.DisplayDialog("TextMeshPro Disable", "TextMeshPro is enabled, do you want to disable it?", "Yes", "Cancel"))
  212. {
  213. CheckAsmdefTmpReference(false);
  214. DefineSymbolsUtil.RemoveGlobalDefine(SYMBOL_TMP);
  215. XChartsMgr.RemoveAllChartObject();
  216. }
  217. }
  218. public static void CheckAsmdefTmpReference(bool enable)
  219. {
  220. if (enable)
  221. {
  222. InsertSpecifyReferenceIntoAssembly(Platform.Editor, ASMDEF_TMP);
  223. InsertSpecifyReferenceIntoAssembly(Platform.Runtime, ASMDEF_TMP);
  224. }
  225. else
  226. {
  227. RemoveSpecifyReferenceFromAssembly(Platform.Editor, ASMDEF_TMP);
  228. RemoveSpecifyReferenceFromAssembly(Platform.Runtime, ASMDEF_TMP);
  229. }
  230. }
  231. #endif
  232. #endregion
  233. #region InputSystem Support
  234. #if UNITY_2019_1_OR_NEWER
  235. //As InputSystem is released in 2019.1+ ,when unity version is 2019.1+ , enable InputSystem Support
  236. const string SYMBOL_I_S = "INPUT_SYSTEM_ENABLED";
  237. const string ASMDEF_I_S = "Unity.InputSystem";
  238. #if !INPUT_SYSTEM_ENABLED
  239. [MenuItem("XCharts/InputSystem Enable")]
  240. #endif
  241. public static void EnableInputSystem()
  242. {
  243. if (!IsSpecifyAssemblyExist(ASMDEF_I_S))
  244. {
  245. Debug.LogError("InputSystem is not in the project, please import InputSystem package first.");
  246. return;
  247. }
  248. if (EditorUtility.DisplayDialog("InputSystem Enable", "InputSystem is disabled, do you want to enable it?", "Yes", "Cancel"))
  249. {
  250. CheckAsmdefInputSystemReference(true);
  251. DefineSymbolsUtil.AddGlobalDefine(SYMBOL_I_S);
  252. }
  253. }
  254. #if INPUT_SYSTEM_ENABLED
  255. [MenuItem("XCharts/InputSystem Disable")]
  256. #endif
  257. public static void DisableInputSystem()
  258. {
  259. if (EditorUtility.DisplayDialog("InputSystem Disable", "InputSystem is enabled, do you want to disable it?", "Yes", "Cancel"))
  260. {
  261. CheckAsmdefInputSystemReference(false);
  262. DefineSymbolsUtil.RemoveGlobalDefine(SYMBOL_I_S);
  263. }
  264. }
  265. public static void CheckAsmdefInputSystemReference(bool enable)
  266. {
  267. if(enable)
  268. {
  269. InsertSpecifyReferenceIntoAssembly(Platform.Editor, ASMDEF_I_S);
  270. InsertSpecifyReferenceIntoAssembly(Platform.Runtime, ASMDEF_I_S);
  271. }
  272. else
  273. {
  274. RemoveSpecifyReferenceFromAssembly(Platform.Editor, ASMDEF_I_S);
  275. RemoveSpecifyReferenceFromAssembly(Platform.Runtime, ASMDEF_I_S);
  276. }
  277. }
  278. #endif
  279. #endregion
  280. #region Assistant members
  281. #if UNITY_2017_1_OR_NEWER
  282. // as text mesh pro is released in 2017.1, so we may use these function and types in 2017.1 or later
  283. private static void InsertSpecifyReferenceIntoAssembly(Platform platform, string reference)
  284. {
  285. var file = GetPackageAssemblyDefinitionPath(platform);
  286. var content = File.ReadAllText(file);
  287. var data = new AssemblyDefinitionData();
  288. EditorJsonUtility.FromJsonOverwrite(content, data);
  289. if (!data.references.Contains(reference))
  290. {
  291. data.references.Add(reference);
  292. var json = EditorJsonUtility.ToJson(data, true);
  293. File.WriteAllText(file, json);
  294. AssetDatabase.SaveAssets();
  295. AssetDatabase.Refresh();
  296. }
  297. }
  298. private static void RemoveSpecifyReferenceFromAssembly(Platform platform, string reference)
  299. {
  300. var file = GetPackageAssemblyDefinitionPath(platform);
  301. var content = File.ReadAllText(file);
  302. var data = new AssemblyDefinitionData();
  303. EditorJsonUtility.FromJsonOverwrite(content, data);
  304. if (data.references.Contains(reference))
  305. {
  306. data.references.Remove(reference);
  307. var json = EditorJsonUtility.ToJson(data, true);
  308. File.WriteAllText(file, json);
  309. }
  310. }
  311. public enum Platform { Editor, Runtime }
  312. public static string GetPackageAssemblyDefinitionPath(Platform platform)
  313. {
  314. var p = platform == Platform.Editor ? "Editor" : "Runtime";
  315. var f = "XCharts." + p + ".asmdef";
  316. var sub = Path.Combine(p, f);
  317. string packagePath = Path.GetFullPath("Packages/com.monitor1394.xcharts");
  318. if (!Directory.Exists(packagePath))
  319. {
  320. packagePath = ADB.FindAssets("t:Script")
  321. .Where(v => Path.GetFileNameWithoutExtension(ADB.GUIDToAssetPath(v)) == "XChartsMgr")
  322. .Select(id => ADB.GUIDToAssetPath(id))
  323. .FirstOrDefault();
  324. packagePath = Path.GetDirectoryName(packagePath);
  325. packagePath = packagePath.Substring(0, packagePath.LastIndexOf("Runtime"));
  326. }
  327. return Path.Combine(packagePath, sub);
  328. }
  329. public static bool IsSpecifyAssemblyExist(string name)
  330. {
  331. #if UNITY_2018_1_OR_NEWER
  332. foreach (var assembly in UnityEditor.Compilation.CompilationPipeline.GetAssemblies(UnityEditor.Compilation.AssembliesType.Player))
  333. {
  334. if (assembly.name.Equals(name)) return true;
  335. }
  336. #elif UNITY_2017_3_OR_NEWER
  337. foreach (var assembly in UnityEditor.Compilation.CompilationPipeline.GetAssemblies())
  338. {
  339. if (assembly.name.Equals(name)) return true;
  340. }
  341. #endif
  342. return false;
  343. }
  344. [Serializable]
  345. class AssemblyDefinitionData
  346. {
  347. #pragma warning disable 649
  348. public string name;
  349. public List<string> references;
  350. public List<string> includePlatforms;
  351. public List<string> excludePlatforms;
  352. public bool allowUnsafeCode;
  353. public bool overrideReferences;
  354. public List<string> precompiledReferences;
  355. public bool autoReferenced;
  356. public List<string> defineConstraints;
  357. public List<string> versionDefines;
  358. public bool noEngineReferences;
  359. #pragma warning restore 649
  360. }
  361. #endif
  362. #endregion
  363. }
  364. }