暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

PSDImporterEditorLayerTreeView.cs 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. using System.Collections.Generic;
  2. using System.IO;
  3. using System.Linq;
  4. using UnityEditor.Experimental;
  5. using UnityEditor.IMGUI.Controls;
  6. using UnityEngine;
  7. namespace UnityEditor.U2D.PSD
  8. {
  9. internal class PSDLayerImportSettingSerializedPropertyWrapper : IPSDLayerMappingStrategyComparable
  10. {
  11. PSDLayerData m_Layer;
  12. SerializedProperty m_Array;
  13. SerializedProperty m_Element;
  14. SerializedProperty m_NameProperty;
  15. SerializedProperty m_LayerIdProperty;
  16. SerializedProperty m_FlattenProperty;
  17. SerializedProperty m_IsGroup;
  18. public string name
  19. {
  20. get => m_NameProperty.stringValue;
  21. set
  22. {
  23. CheckAndAddElement();
  24. m_NameProperty.stringValue = value;
  25. }
  26. }
  27. public bool isGroup
  28. {
  29. get => m_IsGroup.boolValue;
  30. set
  31. {
  32. CheckAndAddElement();
  33. m_IsGroup.boolValue = value;
  34. }
  35. }
  36. public int layerID
  37. {
  38. get => m_LayerIdProperty.intValue;
  39. set
  40. {
  41. CheckAndAddElement();
  42. m_LayerIdProperty.intValue = value;
  43. }
  44. }
  45. public bool flatten
  46. {
  47. get => m_FlattenProperty == null ? false : m_FlattenProperty.boolValue;
  48. set
  49. {
  50. CheckAndAddElement();
  51. m_FlattenProperty.boolValue = value;
  52. }
  53. }
  54. void CheckAndAddElement()
  55. {
  56. if (m_Element == null)
  57. {
  58. var arraySize = m_Array.arraySize;
  59. m_Array.arraySize = arraySize + 1;
  60. m_Element = m_Array.GetArrayElementAtIndex(arraySize);
  61. CacheProperty(m_Element);
  62. flatten = false;
  63. name = m_Layer.name;
  64. layerID = m_Layer.layerID;
  65. isGroup = m_Layer.isGroup;
  66. }
  67. }
  68. void CacheProperty(SerializedProperty property)
  69. {
  70. m_NameProperty = property.FindPropertyRelative("name");
  71. m_LayerIdProperty = property.FindPropertyRelative("layerId");
  72. m_FlattenProperty = property.FindPropertyRelative("flatten");
  73. m_IsGroup = property.FindPropertyRelative("isGroup");
  74. }
  75. public PSDLayerImportSettingSerializedPropertyWrapper(SerializedProperty sp, SerializedProperty array, PSDLayerData layer)
  76. {
  77. if (sp != null)
  78. {
  79. m_Element = sp;
  80. CacheProperty(sp);
  81. }
  82. m_Array = array;
  83. m_Layer = layer;
  84. }
  85. }
  86. class PSDNode : TreeViewItem
  87. {
  88. PSDLayerData m_Layer;
  89. bool m_Disable = false;
  90. PSDLayerImportSettingSerializedPropertyWrapper m_Property;
  91. public bool disable
  92. {
  93. get => m_Disable;
  94. set => m_Disable = value;
  95. }
  96. public PSDNode()
  97. {
  98. id = 1;
  99. displayName = "";
  100. }
  101. public PSDNode(PSDLayerData layer, int id, PSDLayerImportSettingSerializedPropertyWrapper importSetting)
  102. {
  103. m_Layer = layer;
  104. displayName = layer.name;
  105. this.id = id;
  106. m_Property = importSetting;
  107. }
  108. public virtual void ChildGroupFlatten(bool flatten) { }
  109. public virtual void FlattenStateChange() { }
  110. public virtual void NotifyParentOnFlattenChange() { }
  111. public PSDLayerData layer => m_Layer;
  112. public bool flatten
  113. {
  114. get => m_Property.flatten;
  115. set => m_Property.flatten = value;
  116. }
  117. }
  118. class PSDLayerNode : PSDNode
  119. {
  120. public PSDLayerNode(PSDLayerData layer, int id, PSDLayerImportSettingSerializedPropertyWrapper property):base(layer, id, property)
  121. { }
  122. }
  123. class PSDLayerGroupNode : PSDNode
  124. {
  125. int m_ChildFlattenCount;
  126. public PSDLayerGroupNode(PSDLayerData layer, int id, PSDLayerImportSettingSerializedPropertyWrapper property)
  127. : base(layer, id, property)
  128. {
  129. this.icon = EditorGUIUtility.FindTexture(EditorResources.folderIconName);
  130. m_ChildFlattenCount = 0;
  131. }
  132. public int childFlattenCount => m_ChildFlattenCount;
  133. public override void NotifyParentOnFlattenChange()
  134. {
  135. var pp = parent as PSDNode;
  136. if(pp != null)
  137. pp.ChildGroupFlatten(flatten);
  138. }
  139. public override void ChildGroupFlatten(bool flatten)
  140. {
  141. m_ChildFlattenCount += flatten ? 1 : -1;
  142. var pp = parent as PSDNode;
  143. if(pp != null)
  144. pp.ChildGroupFlatten(flatten);
  145. }
  146. public override void FlattenStateChange()
  147. {
  148. if (children != null)
  149. {
  150. foreach (var child in children)
  151. {
  152. var p = ((PSDNode)child);
  153. if (p != null)
  154. {
  155. //p.disable = flatten || this.disable;
  156. p.FlattenStateChange();
  157. }
  158. }
  159. }
  160. }
  161. }
  162. static class Style
  163. {
  164. static public GUIStyle hoverLine = "TV Selection";
  165. static public GUIStyle flattenToggleStyle = "MultiColumnHeaderCenter";
  166. static public readonly string k_LightIconResourcePath = "Icons/Light";
  167. static public readonly string k_DarkIconResourcePath = "Icons/Dark";
  168. static public readonly string k_SelectedIconResourcePath = "Icons/Selected";
  169. public static readonly GUIContent layerHiddenToolTip = EditorGUIUtility.TrTextContent("", "The layer is hidden in the source file.");
  170. public static readonly GUIContent[] mergedIcon =
  171. {
  172. new GUIContent(LoadIconResource("Layers Separated", k_LightIconResourcePath, k_DarkIconResourcePath), L10n.Tr("Layers Separated. Click to merge them.")),
  173. new GUIContent(LoadIconResource("Layers Separated", k_SelectedIconResourcePath, k_SelectedIconResourcePath), L10n.Tr("Layers Separated. Click to merge them."))
  174. };
  175. public static readonly GUIContent[] separateIcon =
  176. {
  177. new GUIContent(LoadIconResource("Layers Collapsed", k_LightIconResourcePath, k_DarkIconResourcePath), L10n.Tr("Layers merged. Click to separate them.")),
  178. new GUIContent(LoadIconResource("Layers Collapsed", k_SelectedIconResourcePath, k_SelectedIconResourcePath), L10n.Tr("Layers merged. Click to separate them."))
  179. };
  180. public static readonly GUIContent[] mergedMix =
  181. {
  182. new GUIContent(LoadIconResource("Layers Mixed", k_LightIconResourcePath, k_DarkIconResourcePath), L10n.Tr("Group contains child groups that are merged.")),
  183. new GUIContent(LoadIconResource("Layers Mixed", k_SelectedIconResourcePath, k_SelectedIconResourcePath), L10n.Tr("Group contains child groups that are merged."))
  184. };
  185. const string k_ResourcePath = "Packages/com.unity.2d.psdimporter/Editor/Assets";
  186. public static int iconSize = 16;
  187. public static int iconPadding = 6;
  188. public static Texture2D LoadIconResource(string name, string personalPath, string proPath)
  189. {
  190. string iconPath = "";
  191. if (EditorGUIUtility.isProSkin && !string.IsNullOrEmpty(proPath))
  192. iconPath = Path.Combine(proPath, name);
  193. else
  194. iconPath = Path.Combine(personalPath, name);
  195. if (EditorGUIUtility.pixelsPerPoint > 1.0f)
  196. {
  197. var icon2x = Load<Texture2D>(iconPath + "@4x.png");
  198. if (icon2x != null)
  199. return icon2x;
  200. }
  201. return Load<Texture2D>(iconPath+"@2x.png");
  202. }
  203. internal static T Load<T>(string path) where T : Object
  204. {
  205. var assetPath = Path.Combine(k_ResourcePath, path);
  206. var asset = AssetDatabase.LoadAssetAtPath<T>(assetPath);
  207. return asset;
  208. }
  209. static Style()
  210. {
  211. flattenToggleStyle.border = new RectOffset();
  212. flattenToggleStyle.margin = new RectOffset();
  213. flattenToggleStyle.padding = new RectOffset();
  214. }
  215. }
  216. internal class PSDImporterEditorLayerTreeView : IMGUI.Controls.TreeView
  217. {
  218. PSDLayerData[] m_Layers;
  219. bool m_ShowHidden;
  220. bool m_HasChanged;
  221. string m_RootName;
  222. SerializedProperty m_PSDLayerImportSetting;
  223. IPSDLayerMappingStrategy m_MappingStrategy;
  224. int m_LastArraySize;
  225. public PSDImporterEditorLayerTreeView(string rootName, TreeViewState treeViewState, PSDLayerData[] layers, bool showHidden, SerializedProperty psdLayerImportSetting, IPSDLayerMappingStrategy mappingStrategy)
  226. : base(treeViewState)
  227. {
  228. m_Layers = layers;
  229. showAlternatingRowBackgrounds = true;
  230. showBorder = true;
  231. m_ShowHidden = showHidden;
  232. m_HasChanged = false;
  233. baseIndent = 16;
  234. useScrollView = true;
  235. m_RootName = rootName;
  236. m_PSDLayerImportSetting = psdLayerImportSetting;
  237. m_MappingStrategy = mappingStrategy;
  238. Reload();
  239. }
  240. public bool showHidden
  241. {
  242. get => m_ShowHidden;
  243. set => m_ShowHidden = value;
  244. }
  245. public override void OnGUI(Rect rect)
  246. {
  247. if(m_PSDLayerImportSetting.arraySize != m_LastArraySize)
  248. Reload();
  249. base.OnGUI(rect);
  250. m_LastArraySize = m_PSDLayerImportSetting.arraySize;
  251. }
  252. protected override TreeViewItem BuildRoot()
  253. {
  254. m_PSDLayerImportSetting.serializedObject.Update();
  255. m_LastArraySize = m_PSDLayerImportSetting.arraySize;
  256. var root = new TreeViewItem { id = -1, depth = -1, displayName = "Root" };
  257. var fileRoot = new PSDNode(){id = -2};
  258. fileRoot.displayName = m_RootName;
  259. //fileRoot.icon = EditorGUIUtility.IconContent("Texture Icon").image as Texture2D;
  260. root.AddChild(fileRoot);
  261. var spWrapper = new List<PSDLayerImportSettingSerializedPropertyWrapper>();
  262. if (m_PSDLayerImportSetting.arraySize > 0)
  263. {
  264. var firstElement = m_PSDLayerImportSetting.GetArrayElementAtIndex(0);
  265. for (int i = 0; i < m_PSDLayerImportSetting.arraySize; ++i)
  266. {
  267. spWrapper.Add(new PSDLayerImportSettingSerializedPropertyWrapper(firstElement, m_PSDLayerImportSetting, null));
  268. firstElement.Next(false);
  269. }
  270. }
  271. if (m_Layers != null)
  272. {
  273. PSDNode[] nodes = new PSDNode[m_Layers.Length];
  274. for(int i = 0; i < m_Layers.Length; ++i)
  275. {
  276. var l = m_Layers[i];
  277. var importSettingIndex = spWrapper.FindIndex(x => m_MappingStrategy.Compare(x, l));
  278. PSDLayerImportSettingSerializedPropertyWrapper importSetting = null;
  279. if (importSettingIndex < 0)
  280. {
  281. importSetting = new PSDLayerImportSettingSerializedPropertyWrapper(null, m_PSDLayerImportSetting, l);
  282. }
  283. else
  284. {
  285. importSetting = spWrapper[importSettingIndex];
  286. spWrapper.RemoveAt(importSettingIndex);
  287. }
  288. if (l!= null && l.isGroup)
  289. nodes[i] = new PSDLayerGroupNode(l, i, importSetting);
  290. else
  291. nodes[i] = new PSDLayerNode(l, i, importSetting);
  292. var node = nodes[i];
  293. node.disable = !node.layer.isVisible;
  294. while (node.layer.parentIndex != -1 && nodes[i].disable == false)
  295. {
  296. if (!node.layer.isVisible || !nodes[node.layer.parentIndex].layer.isVisible)
  297. {
  298. nodes[i].disable = true;
  299. }
  300. node = nodes[node.layer.parentIndex];
  301. }
  302. }
  303. foreach (var node in nodes)
  304. {
  305. //if (showHidden || node.layer.isVisible)
  306. {
  307. if (node.layer.parentIndex == -1)
  308. {
  309. fileRoot.AddChild(node);
  310. }
  311. else
  312. {
  313. nodes[node.layer.parentIndex].AddChild(node);
  314. if(node.flatten)
  315. nodes[node.layer.parentIndex].ChildGroupFlatten(node.flatten);
  316. }
  317. }
  318. }
  319. }
  320. SetupDepthsFromParentsAndChildren(root);
  321. SetExpanded(fileRoot.id, true);
  322. return root;
  323. }
  324. protected override void RowGUI(RowGUIArgs args)
  325. {
  326. var node = (PSDNode)args.item;
  327. var rowRect = args.rowRect;
  328. var hover = rowRect.Contains(Event.current.mousePosition);
  329. var a1 = args.focused;
  330. var a2 = args.selected;
  331. if (hover && Event.current.type == EventType.Repaint)
  332. {
  333. args.selected = args.focused = true;
  334. Style.hoverLine.Draw(rowRect, false, false, a2, true);
  335. }
  336. using (new EditorGUI.DisabledScope(node.disable))
  337. {
  338. if (node.disable)
  339. {
  340. var r = new Rect(rowRect.x + args.item.depth * this.depthIndentWidth + this.foldoutWidth + 32, rowRect.y, rowRect.width, rowRect.height);
  341. GUI.Label(r, Style.layerHiddenToolTip);
  342. }
  343. base.RowGUI(args);
  344. }
  345. args.focused = a1;
  346. args.selected = a2;
  347. // if (node.layer != null && !node.layer.isVisible)
  348. // {
  349. // //GUI.Box(new Rect(rowRect.x, rowRect.y, Style.iconSize, Style.iconSize), Style.visibilityIcon, Style.flattenToggleStyle);
  350. // }
  351. if (args.item is PSDLayerGroupNode)
  352. {
  353. var group = (PSDLayerGroupNode)args.item;
  354. Rect toggleRect = new Rect(rowRect.x + args.item.depth * this.depthIndentWidth, rowRect.y, Style.iconSize, Style.iconSize);
  355. GUIContent[] icon = null;
  356. if (group.childFlattenCount != 0)
  357. icon = Style.mergedMix;
  358. if (hover)
  359. {
  360. if(group.flatten)
  361. icon = Style.separateIcon;
  362. else
  363. icon = Style.mergedIcon;
  364. }
  365. else if(group.flatten)
  366. icon = Style.mergedIcon;
  367. if (icon != null)
  368. {
  369. hover = toggleRect.Contains(Event.current.mousePosition);
  370. var iconIndex = args.selected | hover ? 1 : 0;
  371. EditorGUI.BeginChangeCheck();
  372. var flatten = GUI.Toggle(toggleRect, group.flatten, icon[iconIndex], Style.flattenToggleStyle);
  373. if (EditorGUI.EndChangeCheck())
  374. {
  375. group.flatten = flatten;
  376. group.FlattenStateChange();
  377. group.NotifyParentOnFlattenChange();
  378. m_HasChanged = true;
  379. }
  380. }
  381. }
  382. }
  383. public bool GetHasChangeAndClear()
  384. {
  385. var v = m_HasChanged;
  386. m_HasChanged = false;
  387. return v;
  388. }
  389. }
  390. }