FileReorderableList.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using UnityEngine;
  5. using UnityEditor;
  6. using UnityEditorInternal;
  7. namespace Pack
  8. {
  9. public class FileReorderableList
  10. {
  11. private ReorderableList m_ReorderableList;
  12. private string m_Title;
  13. private List<string> m_Files;
  14. private List<string> m_SrcFiles;
  15. private List<string> m_NeedFulFiles;
  16. private string m_RootPath;
  17. private string m_SearchPattern;
  18. public FileReorderableList(string title, List<string> files, List<string> srcFiles, List<string> needfulFiles, string rootPath, string searchPattern)
  19. {
  20. if (string.IsNullOrEmpty(title))
  21. m_Title = "从上到下依次覆盖";
  22. else
  23. m_Title = title;
  24. SetParams(files, srcFiles, needfulFiles, rootPath, searchPattern);
  25. }
  26. public void SetParams(List<string> files, List<string> srcFiles, List<string> needfulFiles, string rootPath, string searchPattern)
  27. {
  28. m_Files = files;
  29. m_SrcFiles = srcFiles;
  30. m_NeedFulFiles = needfulFiles;
  31. m_RootPath = rootPath;
  32. m_SearchPattern = searchPattern;
  33. if (m_ReorderableList == null)
  34. {
  35. m_ReorderableList = new ReorderableList(m_Files, typeof(string), true, true, true, true);
  36. m_ReorderableList.drawHeaderCallback = OnDrawHeaderCallback;
  37. m_ReorderableList.drawElementCallback = OnDrawElementCallback;
  38. m_ReorderableList.drawNoneElementCallback = OnDrawNoneElementCallback;
  39. m_ReorderableList.onCanAddCallback = OnCanAddCallback;
  40. m_ReorderableList.onAddDropdownCallback = OnAddDropdownCallback;
  41. m_ReorderableList.onCanRemoveCallback = OnCanRemoveCallback;
  42. m_ReorderableList.onRemoveCallback = OnRemoveCallback;
  43. m_ReorderableList.onChangedCallback = OnChangedCallback;
  44. m_ReorderableList.headerHeight = PackGUI.styles.reorderableListHeadBg.fixedHeight;
  45. m_ReorderableList.elementHeight = 24;
  46. }
  47. else
  48. {
  49. m_ReorderableList.list = files;
  50. }
  51. }
  52. public float GetHeight()
  53. {
  54. return m_ReorderableList.GetHeight();
  55. }
  56. public void DoList(Rect rect)
  57. {
  58. m_ReorderableList.DoList(rect);
  59. }
  60. private void OnDrawHeaderCallback(Rect rect)
  61. {
  62. if (Event.current.type == EventType.Repaint)
  63. {
  64. Rect headerRect = rect;
  65. headerRect.y -= 1;
  66. headerRect.height += 2;
  67. headerRect.xMax += 6;
  68. headerRect.xMin -= 6;
  69. PackGUI.styles.reorderableListHeadBg.Draw(headerRect, false, false, false, false);
  70. }
  71. Rect labelRect = rect;
  72. labelRect.y += (labelRect.height - PackGUI.styles.label.fixedHeight) * 0.5f;
  73. EditorGUI.LabelField(labelRect, EditorGUIUtility.TrTempContent(m_Title), PackGUI.styles.label);
  74. Vector2 size = PackGUI.styles.miniButton.CalcSize(EditorGUIUtility.TrTempContent("打开文件夹"));
  75. Rect btnRect = rect;
  76. btnRect.x += btnRect.width - size.x;
  77. btnRect.width = size.x;
  78. btnRect.y += (btnRect.height - size.y) * 0.5f;
  79. PackGUI.BeginChangeEnabled(true);
  80. if (GUI.Button(btnRect, "打开文件夹", PackGUI.styles.miniButton))
  81. {
  82. EditorUtility.OpenWithDefaultApp(Path.GetFullPath(m_RootPath));
  83. }
  84. PackGUI.EndChangeEnabled();
  85. }
  86. private void OnDrawNoneElementCallback(Rect rect)
  87. {
  88. EditorGUI.LabelField(rect, "列表是空的", PackGUI.styles.label);
  89. }
  90. private void OnDrawElementCallback(Rect rect, int index, bool isActive, bool isFocused)
  91. {
  92. Vector2 size = PackGUI.styles.miniButton.CalcSize(EditorGUIUtility.TrTempContent("打开文件夹"));
  93. Rect labelRect = rect;
  94. labelRect.width = labelRect.width - size.x;
  95. bool changed = true;
  96. if (m_SrcFiles != null)
  97. {
  98. if (index < m_SrcFiles.Count)
  99. {
  100. changed = (m_SrcFiles[index] != m_Files[index]);
  101. }
  102. }
  103. if (changed) PackGUI.BeginChangeGUIColor(Color.red);
  104. EditorGUI.LabelField(labelRect, m_Files[index], PackGUI.styles.label);
  105. if (changed) PackGUI.EndChangeGUIColor();
  106. Rect btnRect = rect;
  107. btnRect.x += btnRect.width - size.x;
  108. btnRect.width = size.x;
  109. PackGUI.BeginChangeEnabled(true);
  110. if (GUI.Button(btnRect, "打开文件夹", PackGUI.styles.miniButton))
  111. {
  112. EditorUtility.OpenWithDefaultApp(Path.GetFullPath(m_RootPath + m_Files[index]));
  113. }
  114. PackGUI.EndChangeEnabled();
  115. }
  116. private bool OnCanAddCallback(ReorderableList list)
  117. {
  118. List<string> lhs = GetRelativePath(m_RootPath);
  119. return !ArrayUtility.ArrayEquals(lhs.ToArray(), m_Files.ToArray());
  120. }
  121. private bool OnCanRemoveCallback(ReorderableList list)
  122. {
  123. return m_NeedFulFiles == null || !m_NeedFulFiles.Contains(m_Files[list.index]);
  124. }
  125. private void OnRemoveCallback(ReorderableList list)
  126. {
  127. m_Files.RemoveAt(list.index);
  128. }
  129. private void OnAddDropdownCallback(Rect buttonRect, ReorderableList list)
  130. {
  131. List<string> ls = GetRelativePath(m_RootPath);
  132. GenericMenu menu = new GenericMenu();
  133. for (int i = 0, iMax = ls.Count; i < iMax; i++)
  134. {
  135. if (m_Files.Contains(ls[i]))
  136. {
  137. menu.AddDisabledItem(EditorGUIUtility.TrTextContent(ls[i]), true);
  138. }
  139. else
  140. {
  141. menu.AddItem(EditorGUIUtility.TrTextContent(ls[i]), false, AddPluginsAndroid, ls[i]);
  142. }
  143. }
  144. menu.DropDown(buttonRect);
  145. }
  146. private void AddPluginsAndroid(object value)
  147. {
  148. m_Files.Add((string)value);
  149. }
  150. private void OnChangedCallback(ReorderableList list)
  151. {
  152. if (m_NeedFulFiles == null) return;
  153. for (int i = m_NeedFulFiles.Count - 1; i >= 0; i--)
  154. {
  155. m_Files.Remove(m_NeedFulFiles[i]);
  156. m_Files.Insert(0, m_NeedFulFiles[i]);
  157. }
  158. }
  159. private List<string> GetRelativePath(string rootPath)
  160. {
  161. rootPath = Path.GetFullPath(rootPath);
  162. List<string> ls = new List<string>();
  163. foreach (var item in Directory.GetFiles(rootPath, m_SearchPattern, SearchOption.AllDirectories))
  164. {
  165. string path = Path.GetFullPath(item);
  166. path = path.Substring(rootPath.Length, path.Length - rootPath.Length);
  167. path = path.Replace('\\', '/');
  168. ls.Add(path);
  169. }
  170. return ls;
  171. }
  172. }
  173. }