Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / ui / editorTools / EditorToolsPanel.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Text.RegularExpressions;
  5. using Godot;
  6.  
  7. #if TOOLS
  8. using Generator;
  9. #endif
  10.  
  11. namespace UI.EditorTools;
  12.  
  13. /// <summary>
  14. /// Godot编辑器扩展工具
  15. /// </summary>
  16. [Tool]
  17. public partial class EditorToolsPanel : EditorTools
  18. {
  19. #if TOOLS
  20. //Tips 关闭回调
  21. private Action _onTipsClose;
  22.  
  23. //询问窗口关闭
  24. private Action<bool> _onConfirmClose;
  25.  
  26. //存放创建房间中选择组的下拉框数据
  27. private Dictionary<int, string> _createRoomGroupValueMap;
  28. //存放创建房间中选择类型的下拉框数据
  29. private Dictionary<int, string> _createRoomTypeValueMap;
  30.  
  31. public override void OnShowUi()
  32. {
  33. //tips
  34. _onTipsClose = null;
  35. L_Tips.Instance.OkButtonText = "确定";
  36. L_Tips.Instance.CloseRequested += OnTipsClose;
  37. L_Tips.Instance.Confirmed += OnTipsClose;
  38. L_Tips.Instance.Canceled += OnTipsClose;
  39.  
  40. //confirm
  41. _onConfirmClose = null;
  42. L_Confirm.Instance.OkButtonText = "确定";
  43. L_Confirm.Instance.CancelButtonText = "取消";
  44. L_Confirm.Instance.Canceled += OnCanceled;
  45. L_Confirm.Instance.CloseRequested += OnCanceled;
  46. L_Confirm.Instance.Confirmed += OnConfirm;
  47. InitSelectOptions();
  48.  
  49. var container = L_ScrollContainer.L_MarginContainer.L_VBoxContainer;
  50. //重新生成 ResourcePath
  51. container.L_HBoxContainer.L_Button.Instance.Pressed += GenerateResourcePath;
  52. //重新打包房间配置
  53. container.L_HBoxContainer2.L_Button.Instance.Pressed += GenerateRoomConfig;
  54. //重新生成ui代码
  55. container.L_HBoxContainer4.L_Button.Instance.Pressed += OnGenerateCurrentUiCode;
  56. //创建ui
  57. container.L_HBoxContainer3.L_Button.Instance.Pressed += OnCreateUI;
  58. //重新生成UiManagerMethods.cs代码
  59. container.L_HBoxContainer5.L_Button.Instance.Pressed += GenerateUiManagerMethods;
  60. //创建地牢房间
  61. container.L_HBoxContainer6.L_Button.Instance.Pressed += GenerateDungeonRoom;
  62. //导出excel表
  63. container.L_HBoxContainer7.L_Button.Instance.Pressed += ExportExcel;
  64. }
  65.  
  66. public override void OnHideUi()
  67. {
  68. L_Tips.Instance.CloseRequested -= OnTipsClose;
  69. L_Tips.Instance.Confirmed -= OnTipsClose;
  70. L_Tips.Instance.Canceled -= OnTipsClose;
  71. L_Confirm.Instance.Canceled -= OnCanceled;
  72. L_Confirm.Instance.CloseRequested -= OnCanceled;
  73. L_Confirm.Instance.Confirmed -= OnConfirm;
  74. var container = L_ScrollContainer.L_MarginContainer.L_VBoxContainer;
  75. container.L_HBoxContainer.L_Button.Instance.Pressed -= GenerateResourcePath;
  76. container.L_HBoxContainer2.L_Button.Instance.Pressed -= GenerateRoomConfig;
  77. container.L_HBoxContainer4.L_Button.Instance.Pressed -= OnGenerateCurrentUiCode;
  78. container.L_HBoxContainer3.L_Button.Instance.Pressed -= OnCreateUI;
  79. container.L_HBoxContainer5.L_Button.Instance.Pressed -= GenerateUiManagerMethods;
  80. container.L_HBoxContainer6.L_Button.Instance.Pressed -= GenerateDungeonRoom;
  81. container.L_HBoxContainer7.L_Button.Instance.Pressed -= ExportExcel;
  82. }
  83.  
  84. public override void Process(float delta)
  85. {
  86. if (_createRoomGroupValueMap == null || _createRoomTypeValueMap == null)
  87. {
  88. InitSelectOptions();
  89. }
  90. }
  91.  
  92. //创建ui的下拉框数据
  93. private void InitSelectOptions()
  94. {
  95. _createRoomGroupValueMap = new Dictionary<int, string>();
  96. _createRoomTypeValueMap = new Dictionary<int, string>();
  97. var container = L_ScrollContainer.L_MarginContainer.L_VBoxContainer;
  98. var select1 = container.L_HBoxContainer6.L_RoomGroupSelect.Instance;
  99. select1.Clear();
  100. var directoryInfo = new DirectoryInfo(GameConfig.RoomTileDir);
  101. var directoryInfoArray = directoryInfo.GetDirectories();
  102. for (var i = 0; i < directoryInfoArray.Length; i++)
  103. {
  104. var text = directoryInfoArray[i].Name;
  105. select1.AddItem(text, i);
  106. _createRoomGroupValueMap.Add(i, text);
  107. }
  108.  
  109. var select2 = container.L_HBoxContainer6.L_RoomTypeSelect.Instance;
  110. select2.Clear();
  111. var dungeonRoomTypes = Enum.GetValues<DungeonRoomType>();
  112. for (var i = 0; i < dungeonRoomTypes.Length; i++)
  113. {
  114. var typeName = DungeonManager.DungeonRoomTypeToString(dungeonRoomTypes[i]);
  115. var text = typeName + " (" +
  116. DungeonManager.DungeonRoomTypeToDescribeString(dungeonRoomTypes[i]) + ")";
  117. select2.AddItem(text, i);
  118. _createRoomTypeValueMap.Add(i, typeName);
  119. }
  120. }
  121.  
  122. /// <summary>
  123. /// Tips 关闭信号回调
  124. /// </summary>
  125. private void OnTipsClose()
  126. {
  127. if (_onTipsClose != null)
  128. {
  129. _onTipsClose();
  130. _onTipsClose = null;
  131. }
  132. }
  133.  
  134. /// <summary>
  135. /// Confirm 确认信号回调
  136. /// </summary>
  137. private void OnConfirm()
  138. {
  139. if (_onConfirmClose != null)
  140. {
  141. _onConfirmClose(true);
  142. _onConfirmClose = null;
  143. }
  144. }
  145.  
  146. /// <summary>
  147. /// Confirm 取消信号回调
  148. /// </summary>
  149. private void OnCanceled()
  150. {
  151. if (_onConfirmClose != null)
  152. {
  153. _onConfirmClose(false);
  154. _onConfirmClose = null;
  155. }
  156. }
  157. /// <summary>
  158. /// 打开提示窗口, 并设置宽高
  159. /// </summary>
  160. /// <param name="title">窗口标题</param>
  161. /// <param name="message">显示内容</param>
  162. /// <param name="width">窗口宽度</param>
  163. /// <param name="height">窗口高度</param>
  164. /// <param name="onClose">当窗口关闭时的回调</param>
  165. public void ShowTips(string title, string message, int width, int height, Action onClose = null)
  166. {
  167. var tips = L_Tips.Instance;
  168. tips.Size = new Vector2I(width, height);
  169. tips.Title = title;
  170. tips.DialogText = message;
  171. _onTipsClose = onClose;
  172. tips.Show();
  173. }
  174. /// <summary>
  175. /// 打开提示窗口
  176. /// </summary>
  177. /// <param name="title">窗口标题</param>
  178. /// <param name="message">显示内容</param>
  179. /// <param name="onClose">当窗口关闭时的回调</param>
  180. public void ShowTips(string title, string message, Action onClose = null)
  181. {
  182. ShowTips(title, message, 350, 200, onClose);
  183. }
  184.  
  185. /// <summary>
  186. /// 关闭提示窗口
  187. /// </summary>
  188. public void CloseTips()
  189. {
  190. L_Tips.Instance.Hide();
  191. _onTipsClose = null;
  192. }
  193.  
  194. /// <summary>
  195. /// 打开询问窗口, 并设置宽高
  196. /// </summary>
  197. /// <param name="title">窗口标题</param>
  198. /// <param name="message">显示内容</param>
  199. /// <param name="width">窗口宽度</param>
  200. /// <param name="height">窗口高度</param>
  201. /// <param name="onClose">当窗口关闭时的回调, 参数如果为 true 表示点击了确定按钮</param>
  202. public void ShowConfirm(string title, string message, int width, int height, Action<bool> onClose = null)
  203. {
  204. var confirm = L_Confirm.Instance;
  205. confirm.Size = new Vector2I(width, height);
  206. confirm.Title = title;
  207. confirm.DialogText = message;
  208. _onConfirmClose = onClose;
  209. confirm.Show();
  210. }
  211. /// <summary>
  212. /// 打开询问窗口
  213. /// </summary>
  214. /// <param name="title">窗口标题</param>
  215. /// <param name="message">显示内容</param>
  216. /// <param name="onClose">当窗口关闭时的回调, 参数如果为 true 表示点击了确定按钮</param>
  217. public void ShowConfirm(string title, string message, Action<bool> onClose = null)
  218. {
  219. ShowConfirm(title, message, 350, 200, onClose);
  220. }
  221.  
  222. /// <summary>
  223. /// 关闭询问窗口
  224. /// </summary>
  225. public void CloseConfirm()
  226. {
  227. L_Confirm.Instance.Hide();
  228. _onConfirmClose = null;
  229. }
  230.  
  231. /// <summary>
  232. /// 重新生成当前ui的代码
  233. /// </summary>
  234. private void OnGenerateCurrentUiCode()
  235. {
  236. if (Plugin.Plugin.Instance != null)
  237. {
  238. var root = Plugin.Plugin.Instance.GetEditorInterface().GetEditedSceneRoot();
  239. if (root != null && Plugin.Plugin.Instance.CheckIsUi(root))
  240. {
  241. if (UiGenerator.GenerateUiCodeFromEditor(root))
  242. {
  243. ShowTips("提示", "生成UI代码执行成功!");
  244. }
  245. else
  246. {
  247. ShowTips("错误", "生成UI代码执行失败! 前往控制台查看错误日志!");
  248. }
  249. }
  250. else
  251. {
  252. ShowTips("错误", "当前的场景不是受管束的UI场景!");
  253. }
  254. }
  255. }
  256. /// <summary>
  257. /// 创建Ui
  258. /// </summary>
  259. private void OnCreateUI()
  260. {
  261. var uiName = L_ScrollContainer.L_MarginContainer.L_VBoxContainer.L_HBoxContainer3.L_LineEdit.Instance.Text;
  262. ShowConfirm("提示", "是否创建UI:" + uiName, (result) =>
  263. {
  264. if (result)
  265. {
  266. //检查名称是否合规
  267. if (!Regex.IsMatch(uiName, "^[A-Z][a-zA-Z0-9]*$"))
  268. {
  269. ShowTips("错误", "UI名称'" + uiName + "'不符合名称约束, UI名称只允许大写字母开头, 且名称中只允许出现大小字母和数字!");
  270. return;
  271. }
  272.  
  273. //检查是否有同名的Ui
  274. var path = GameConfig.UiPrefabDir + uiName + ".tscn";
  275. if (File.Exists(path))
  276. {
  277. ShowTips("错误", "已经存在相同名称'" + uiName + "'的UI了, 不能重复创建!");
  278. return;
  279. }
  280. //执行创建操作
  281. if (UiGenerator.CreateUi(uiName, true))
  282. {
  283. ShowTips("提示", "创建UI成功!");
  284. }
  285. else
  286. {
  287. ShowTips("错误", "创建UI失败! 前往控制台查看错误日志!");
  288. }
  289. }
  290. });
  291. }
  292.  
  293. /// <summary>
  294. /// 更新 ResourcePath
  295. /// </summary>
  296. private void GenerateResourcePath()
  297. {
  298. if (ResourcePathGenerator.Generate())
  299. {
  300. ShowTips("提示", "ResourcePath.cs生成完成!");
  301. }
  302. else
  303. {
  304. ShowTips("错误", "ResourcePath.cs生成失败! 前往控制台查看错误日志!");
  305. }
  306. }
  307.  
  308. /// <summary>
  309. /// 重新打包房间配置
  310. /// </summary>
  311. private void GenerateRoomConfig()
  312. {
  313. if (DungeonRoomGenerator.GenerateRoomConfig())
  314. {
  315. ShowTips("提示", "打包地牢房间配置执行完成!");
  316. }
  317. else
  318. {
  319. ShowTips("错误", "打包地牢房间配置执行失败! 前往控制台查看错误日志!");
  320. }
  321. }
  322.  
  323. /// <summary>
  324. /// 重新生成UiManagerMethods.cs代码
  325. /// </summary>
  326. private void GenerateUiManagerMethods()
  327. {
  328. if (UiManagerMethodsGenerator.Generate())
  329. {
  330. ShowTips("提示", "生成UiManagerMethods.cs代码执行完成!");
  331. }
  332. else
  333. {
  334. ShowTips("错误", "生成UiManagerMethods.cs代码执行失败! 前往控制台查看错误日志!");
  335. }
  336. }
  337.  
  338. /// <summary>
  339. /// 创建地牢房间
  340. /// </summary>
  341. private void GenerateDungeonRoom()
  342. {
  343. var node = L_ScrollContainer.L_MarginContainer.L_VBoxContainer.L_HBoxContainer6;
  344. var group = _createRoomGroupValueMap[node.L_RoomGroupSelect.Instance.Selected];
  345. var type = _createRoomTypeValueMap[node.L_RoomTypeSelect.Instance.Selected];
  346. var roomName = node.L_RoomNameInput.Instance.Text;
  347.  
  348. var pathName = group + "/" + type + "/" + roomName;
  349. ShowConfirm("提示", "是否创建房间:" + pathName, (result) =>
  350. {
  351. if (result)
  352. {
  353. //检查名称是否合规
  354. if (!Regex.IsMatch(roomName, "^\\w+$"))
  355. {
  356. ShowTips("错误", "房间名称'" + roomName + "'不符合名称约束, 房间名称只允许包含大写字母和数字!");
  357. return;
  358. }
  359.  
  360. //检查是否有同名的Ui
  361. var path = GameConfig.RoomTileDir + pathName + ".tscn";
  362. if (File.Exists(path))
  363. {
  364. ShowTips("错误", "已经存在相同名称'" + pathName + "'的房间了, 不能重复创建!");
  365. return;
  366. }
  367. //执行创建操作
  368. if (DungeonRoomGenerator.CreateDungeonRoom(group, type, roomName, true))
  369. {
  370. ShowTips("提示", "创建房间成功!");
  371. }
  372. else
  373. {
  374. ShowTips("错误", "创建房间失败! 前往控制台查看错误日志!");
  375. }
  376. }
  377. });
  378. }
  379.  
  380. /// <summary>
  381. /// 导出excel表
  382. /// </summary>
  383. private void ExportExcel()
  384. {
  385. ExcelGenerator.ExportExcel();
  386. ShowTips("提示", "已启动导表程序, 注意查看控制台信息!");
  387. }
  388. /// <summary>
  389. /// 在编辑器中打开一个提示窗口
  390. /// </summary>
  391. public static void ShowTipsInEditor(string title, string message, Action onClose)
  392. {
  393. var editorToolsInstance = UiManager.Get_EditorTools_Instance();
  394. if (editorToolsInstance.Length > 0)
  395. {
  396. editorToolsInstance[0].ShowTips(title, message, onClose);
  397. }
  398. }
  399. /// <summary>
  400. /// 在编辑器中打开一个询问窗口
  401. /// </summary>
  402. public static void ShowConfirmInEditor(string title, string message, Action<bool> onClose = null)
  403. {
  404. var editorToolsInstance = UiManager.Get_EditorTools_Instance();
  405. if (editorToolsInstance.Length > 0)
  406. {
  407. editorToolsInstance[0].ShowConfirm(title, message, onClose);
  408. }
  409. }
  410. #else
  411. public override void OnShowUi()
  412. {
  413. }
  414. public override void OnHideUi()
  415. {
  416. }
  417. #endif
  418. }