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

WindowController.cs 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using UnityEngine;
  5. using UnityEngine.U2D.Animation;
  6. namespace UnityEditor.U2D.Animation.SpriteLibraryEditor
  7. {
  8. internal enum ActionType
  9. {
  10. SelectCategory, SelectLabels,
  11. RenameCategory, RenameLabel,
  12. CreateCategory, CreateLabel,
  13. DeleteCategories, DeleteLabels,
  14. ReorderCategories, ReorderLabels,
  15. ModifiedCategories, ModifiedLabels,
  16. SetMainLibrary,
  17. SetLabelSprite,
  18. None
  19. }
  20. internal enum ViewType
  21. {
  22. List, Grid
  23. }
  24. internal struct ViewData
  25. {
  26. /// <summary>
  27. /// View type (List / Grid).
  28. /// </summary>
  29. public ViewType viewType;
  30. /// <summary>
  31. /// Relative size for selected View Type in range 0-1.
  32. /// </summary>
  33. public float relativeSize;
  34. /// <summary>
  35. /// Absolute size based on the slider position in range 0-1.
  36. /// </summary>
  37. public float absoluteSize;
  38. }
  39. internal enum SearchType
  40. {
  41. CategoryAndLabel,
  42. Category,
  43. Label
  44. }
  45. internal class WindowController
  46. {
  47. ISpriteLibraryEditorWindow m_Window;
  48. SpriteLibraryEditorModel m_Model;
  49. List<string> selectedCategories => m_Model.GetSelectedCategories();
  50. List<string> selectedLabels => m_Model.GetSelectedLabels();
  51. public SpriteLibraryAsset GetSelectedAsset() => m_Model.selectedAsset;
  52. ControllerEvents m_ControllerEvents;
  53. ViewEvents m_ViewEvents;
  54. bool hasSelectedLibrary => m_Model.selectedAsset != null;
  55. const float k_ViewSizeDivision = 0.1f;
  56. float m_ViewSize;
  57. ViewType m_ViewType = ViewType.List;
  58. string m_FilterString = "";
  59. SearchType m_FilterType = SearchType.CategoryAndLabel;
  60. string m_SelectedAssetPath;
  61. const string k_DefaultLabelName = "New Label";
  62. const string k_DefaultCategoryName = "New Category";
  63. bool m_AutoSave;
  64. bool m_SelectionLocked;
  65. public WindowController(ISpriteLibraryEditorWindow window, SpriteLibraryEditorModel model, ControllerEvents controllerEvents, ViewEvents viewEvents)
  66. {
  67. m_Window = window;
  68. m_ControllerEvents = controllerEvents;
  69. m_ViewEvents = viewEvents;
  70. m_Model = model;
  71. m_SelectedAssetPath = AssetDatabase.GetAssetPath(SpriteLibrarySourceAssetImporter.GetAssetFromSelection());
  72. AddAssetPostprocessorListeners();
  73. AddViewEventListeners();
  74. Selection.selectionChanged += SelectionChanged;
  75. Undo.undoRedoPerformed += PropagateLastAction;
  76. m_AutoSave = SpriteLibraryEditorWindow.Settings.autoSave;
  77. }
  78. public void Destroy()
  79. {
  80. RemoveAssetPostprocessorListeners();
  81. Selection.selectionChanged -= SelectionChanged;
  82. Undo.undoRedoPerformed -= PropagateLastAction;
  83. if (m_Model != null)
  84. m_Model.Destroy();
  85. }
  86. public void SaveChanges()
  87. {
  88. m_Model.SaveLibrary(m_SelectedAssetPath);
  89. m_ControllerEvents.onSelectedLibrary?.Invoke(m_Model.selectedAsset);
  90. }
  91. public void RevertChanges()
  92. {
  93. m_Model.SelectLabels(new List<string>());
  94. m_Model.SelectCategories(new List<string>());
  95. m_Model.SelectAsset(m_Model.selectedAsset);
  96. m_ControllerEvents.onSelectedLibrary?.Invoke(m_Model.selectedAsset);
  97. RefreshView();
  98. RefreshSelection();
  99. }
  100. public void SelectAsset(SpriteLibraryAsset asset, bool modifiedExternally = false)
  101. {
  102. if (!modifiedExternally)
  103. {
  104. if (asset == null || asset == m_Model.selectedAsset)
  105. return;
  106. if (m_Window.hasUnsavedChanges)
  107. m_Window.HandleUnsavedChanges();
  108. }
  109. m_SelectedAssetPath = asset != null ? AssetDatabase.GetAssetPath(asset) : null;
  110. m_Model.SelectAsset(asset);
  111. m_ControllerEvents.onSelectedLibrary?.Invoke(asset);
  112. RefreshView();
  113. RefreshSelection();
  114. }
  115. void AddViewEventListeners()
  116. {
  117. m_ViewEvents.onCreateNewSpriteLibraryAsset.AddListener(CreateNewSpriteLibraryAsset);
  118. m_ViewEvents.onSave.AddListener(OnSave);
  119. m_ViewEvents.onRevert.AddListener(OnRevert);
  120. m_ViewEvents.onToggleAutoSave.AddListener(ToggleAutoSave);
  121. m_ViewEvents.onToggleSelectionLock.AddListener(ToggleSelectionLock);
  122. m_ViewEvents.onViewSizeUpdate.AddListener(ChangeViewSize);
  123. m_ViewEvents.onViewTypeUpdate.AddListener(ChangeViewType);
  124. m_ViewEvents.onSelectedFilter.AddListener(SelectedFilter);
  125. m_ViewEvents.onSelectedFilterType.AddListener(SelectedFilterType);
  126. m_ViewEvents.onSetMainAsset.AddListener(SetMainAsset);
  127. m_ViewEvents.onSelectCategories.AddListener(SelectCategories);
  128. m_ViewEvents.onSelectLabels.AddListener(SelectLabels);
  129. m_ViewEvents.onCreateNewCategory.AddListener(CreateNewCategory);
  130. m_ViewEvents.onRenameCategory.AddListener(RenameSelectedCategory);
  131. m_ViewEvents.onReorderCategories.AddListener(ReorderCategories);
  132. m_ViewEvents.onDeleteCategories.AddListener(DeleteSelectedCategories);
  133. m_ViewEvents.onCreateNewLabel.AddListener(CreateNewLabel);
  134. m_ViewEvents.onRenameLabel.AddListener(RenameSelectedLabel);
  135. m_ViewEvents.onReorderLabels.AddListener(ReorderLabels);
  136. m_ViewEvents.onDeleteLabels.AddListener(DeleteSelectedLabels);
  137. m_ViewEvents.onSetLabelSprite.AddListener(SetLabelSprite);
  138. m_ViewEvents.onAddDataToCategories.AddListener(AddDataToCategories);
  139. m_ViewEvents.onAddDataToLabels.AddListener(AddDataToLabels);
  140. m_ViewEvents.onRevertOverridenLabels.AddListener(RevertOverridenLabels);
  141. }
  142. void AddAssetPostprocessorListeners()
  143. {
  144. SpriteLibraryAssetPostprocessor.OnImported += OnAssetModified;
  145. SpriteLibraryAssetPostprocessor.OnDeleted += OnAssetModified;
  146. SpriteLibraryAssetPostprocessor.OnMovedAssetFromTo += OnAssetMoved;
  147. }
  148. void RemoveAssetPostprocessorListeners()
  149. {
  150. SpriteLibraryAssetPostprocessor.OnImported -= OnAssetModified;
  151. SpriteLibraryAssetPostprocessor.OnDeleted -= OnAssetModified;
  152. SpriteLibraryAssetPostprocessor.OnMovedAssetFromTo -= OnAssetMoved;
  153. }
  154. void CreateNewSpriteLibraryAsset(string newAssetPath)
  155. {
  156. if (string.IsNullOrEmpty(newAssetPath) || !string.Equals(Path.GetExtension(newAssetPath), SpriteLibrarySourceAsset.extension, StringComparison.OrdinalIgnoreCase))
  157. return;
  158. // Make sure that the extension is exactly the same
  159. if (Path.GetExtension(newAssetPath) != SpriteLibrarySourceAsset.extension)
  160. newAssetPath = newAssetPath.Replace(Path.GetExtension(newAssetPath), SpriteLibrarySourceAsset.extension);
  161. var assetToSave = ScriptableObject.CreateInstance<SpriteLibrarySourceAsset>();
  162. SpriteLibrarySourceAssetImporter.SaveSpriteLibrarySourceAsset(assetToSave, newAssetPath);
  163. AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
  164. var newAsset = AssetDatabase.LoadAssetAtPath<SpriteLibraryAsset>(newAssetPath);
  165. Selection.objects = new UnityEngine.Object[] { newAsset };
  166. }
  167. void ChangeViewSize(float newSize)
  168. {
  169. m_ViewSize = newSize;
  170. if (m_ViewSize > k_ViewSizeDivision && m_ViewType == ViewType.List)
  171. m_ViewType = ViewType.Grid;
  172. if (m_ViewSize < k_ViewSizeDivision && m_ViewType == ViewType.Grid)
  173. m_ViewType = ViewType.List;
  174. m_ControllerEvents.onViewChanged?.Invoke(new ViewData { viewType = m_ViewType, relativeSize = GetAdjustedViewSize(m_ViewSize, m_ViewType), absoluteSize = m_ViewSize });
  175. }
  176. void ChangeViewType(ViewType viewType)
  177. {
  178. if (m_ViewType == viewType)
  179. return;
  180. m_ViewType = viewType;
  181. m_ViewSize = m_ViewType == ViewType.List ? 0.0f : k_ViewSizeDivision;
  182. m_ControllerEvents.onViewChanged?.Invoke(new ViewData { viewType = m_ViewType, relativeSize = GetAdjustedViewSize(m_ViewSize, m_ViewType), absoluteSize = m_ViewSize });
  183. }
  184. static float GetAdjustedViewSize(float size, ViewType viewType)
  185. {
  186. if (viewType == ViewType.List)
  187. return size / k_ViewSizeDivision;
  188. return (size - k_ViewSizeDivision) / (1 - k_ViewSizeDivision);
  189. }
  190. void SelectedFilterType(SearchType newFilterType)
  191. {
  192. if (m_FilterType == newFilterType)
  193. return;
  194. m_FilterType = newFilterType;
  195. RefreshView();
  196. }
  197. void SelectedFilter(string newFilterString)
  198. {
  199. if (string.Equals(m_FilterString, newFilterString, StringComparison.OrdinalIgnoreCase))
  200. return;
  201. m_FilterString = newFilterString;
  202. RefreshView();
  203. }
  204. void OnAssetModified(string modifiedAssetPath)
  205. {
  206. var isModifiedExternally = !(m_SelectedAssetPath != modifiedAssetPath || m_Model.isSaving);
  207. if (!isModifiedExternally)
  208. return;
  209. SelectAsset(AssetDatabase.LoadAssetAtPath<SpriteLibraryAsset>(m_SelectedAssetPath), true);
  210. }
  211. void OnAssetMoved(string sourcePath, string destinationPath)
  212. {
  213. if (sourcePath == m_SelectedAssetPath)
  214. {
  215. if (string.IsNullOrEmpty(destinationPath))
  216. {
  217. SelectAsset(null, true);
  218. }
  219. else
  220. {
  221. m_Model.SetAssetPath(destinationPath);
  222. m_SelectedAssetPath = destinationPath;
  223. }
  224. }
  225. }
  226. void SelectionChanged()
  227. {
  228. if (!m_SelectionLocked)
  229. SelectAsset(SpriteLibrarySourceAssetImporter.GetAssetFromSelection());
  230. }
  231. void RefreshView()
  232. {
  233. var areCategoriesFiltered = m_FilterType is SearchType.CategoryAndLabel or SearchType.Category && !string.IsNullOrEmpty(m_FilterString);
  234. var filteredCategories = m_Model.GetFilteredCategories(m_FilterString, m_FilterType);
  235. m_ControllerEvents.onModifiedCategories?.Invoke(filteredCategories, areCategoriesFiltered);
  236. var areLabelsFiltered = m_FilterType is SearchType.CategoryAndLabel or SearchType.Label && !string.IsNullOrEmpty(m_FilterString);
  237. var filteredLabels = m_Model.GetFilteredLabels(m_FilterString, m_FilterType);
  238. m_ControllerEvents.onModifiedLabels?.Invoke(filteredLabels, areLabelsFiltered);
  239. m_ControllerEvents.onLibraryDataChanged?.Invoke(m_Model.isModified);
  240. }
  241. void RefreshSelection()
  242. {
  243. m_ControllerEvents.onSelectedCategories?.Invoke(selectedCategories);
  244. m_ControllerEvents.onSelectedLabels?.Invoke(selectedLabels);
  245. }
  246. void PropagateLastAction()
  247. {
  248. if (SpriteLibraryEditorModel.IsActionModifyingAssets(m_Model.lastActionType))
  249. AutoSave();
  250. if (m_Model.lastActionType == ActionType.SetMainLibrary)
  251. m_ControllerEvents.onMainLibraryChanged?.Invoke(m_Model.GetMainLibrary());
  252. RefreshView();
  253. RefreshSelection();
  254. m_Model.lastActionType = ActionType.None;
  255. }
  256. void SetMainAsset(SpriteLibraryAsset libraryAsset)
  257. {
  258. if (!hasSelectedLibrary)
  259. return;
  260. var validAsset = true;
  261. if (libraryAsset != null)
  262. {
  263. if (libraryAsset == m_Model.selectedAsset || SpriteLibrarySourceAssetImporter.GetAssetParentChain(libraryAsset).Contains(GetSelectedAsset()))
  264. {
  265. Debug.LogWarning(TextContent.spriteLibraryCircularDependency);
  266. validAsset = false;
  267. }
  268. }
  269. if (validAsset)
  270. {
  271. m_Model.BeginUndo(ActionType.SetMainLibrary, TextContent.spriteLibrarySetMainLibrary);
  272. m_Model.SetMainLibrary(libraryAsset);
  273. m_Model.SelectCategories(new List<string>());
  274. m_Model.SelectLabels(new List<string>());
  275. m_Model.EndUndo();
  276. AutoSave();
  277. m_ControllerEvents.onMainLibraryChanged?.Invoke(libraryAsset);
  278. RefreshView();
  279. RefreshSelection();
  280. }
  281. else
  282. {
  283. m_ControllerEvents.onMainLibraryChanged?.Invoke(m_Model.GetMainLibrary());
  284. }
  285. }
  286. void SelectCategories(IList<string> newSelection)
  287. {
  288. if (!hasSelectedLibrary)
  289. return;
  290. newSelection ??= new List<string>();
  291. if (Equals(m_Model.GetSelectedCategories(), newSelection))
  292. return;
  293. m_Model.BeginUndo(ActionType.SelectCategory, TextContent.spriteLibrarySelectCategories);
  294. m_Model.SelectCategories(newSelection);
  295. m_Model.SelectLabels(new List<string>());
  296. m_Model.EndUndo();
  297. RefreshView();
  298. RefreshSelection();
  299. }
  300. void SelectLabels(IList<string> newSelection)
  301. {
  302. newSelection ??= new List<string>();
  303. if (AreSequencesEqual(m_Model.GetSelectedLabels(), newSelection))
  304. return;
  305. m_Model.BeginUndo(ActionType.SelectLabels, TextContent.spriteLibrarySelectLabels);
  306. m_Model.SelectLabels(newSelection);
  307. m_Model.EndUndo();
  308. RefreshSelection();
  309. }
  310. void CreateNewCategory(string categoryName = null, IList<Sprite> sprites = null)
  311. {
  312. if (!hasSelectedLibrary)
  313. return;
  314. if (string.IsNullOrEmpty(categoryName))
  315. categoryName = k_DefaultCategoryName;
  316. m_Model.BeginUndo(ActionType.CreateCategory, TextContent.spriteLibraryCreateCategory);
  317. m_Model.CreateNewCategory(categoryName, sprites);
  318. m_Model.SelectCategories(new List<string> { m_Model.GetAllCategories()[^1].name });
  319. m_Model.SelectLabels(new List<string>());
  320. m_Model.EndUndo();
  321. AutoSave();
  322. RefreshView();
  323. RefreshSelection();
  324. }
  325. void RenameSelectedCategory(string newName)
  326. {
  327. if (!hasSelectedLibrary || !m_Model.hasSelectedCategories)
  328. return;
  329. newName = newName?.Trim();
  330. if (string.IsNullOrEmpty(newName))
  331. return;
  332. var categoryData = GetCategoryData(selectedCategories[0]);
  333. if (categoryData == null || categoryData.fromMain)
  334. return;
  335. m_Model.BeginUndo(ActionType.RenameCategory, TextContent.spriteLibraryRenameCategory);
  336. m_Model.RenameSelectedCategory(newName);
  337. m_Model.EndUndo();
  338. AutoSave();
  339. RefreshView();
  340. RefreshSelection();
  341. }
  342. void ReorderCategories(IList<string> reorderedCategories)
  343. {
  344. if (!hasSelectedLibrary || !m_Model.hasSelectedCategories)
  345. return;
  346. if (m_Model.CompareCategories(reorderedCategories))
  347. return;
  348. var categoriesToReorder = selectedCategories;
  349. m_Model.BeginUndo(ActionType.ReorderCategories, TextContent.spriteLibraryReorderCategories);
  350. m_Model.ReorderCategories(reorderedCategories);
  351. m_Model.SelectCategories(categoriesToReorder);
  352. m_Model.EndUndo();
  353. AutoSave();
  354. RefreshView();
  355. RefreshSelection();
  356. }
  357. void DeleteSelectedCategories()
  358. {
  359. if (!hasSelectedLibrary || !m_Model.hasSelectedCategories)
  360. return;
  361. var validCategories = false;
  362. foreach (var category in selectedCategories)
  363. {
  364. var categoryData = GetCategoryData(category);
  365. if (categoryData != null && !categoryData.fromMain)
  366. {
  367. validCategories = true;
  368. break;
  369. }
  370. }
  371. if (!validCategories)
  372. return;
  373. m_Model.BeginUndo(ActionType.DeleteCategories, TextContent.spriteLibraryDeleteCategories);
  374. m_Model.DeleteSelectedCategories();
  375. m_Model.SelectCategories(new List<string>());
  376. m_Model.SelectLabels(new List<string>());
  377. m_Model.EndUndo();
  378. AutoSave();
  379. RefreshView();
  380. RefreshSelection();
  381. }
  382. void CreateNewLabel(string labelName = null)
  383. {
  384. if (!hasSelectedLibrary || !m_Model.hasSelectedCategories)
  385. return;
  386. if (string.IsNullOrEmpty(labelName))
  387. labelName = k_DefaultLabelName;
  388. m_Model.BeginUndo(ActionType.CreateLabel, TextContent.spriteLibraryCreateLabel);
  389. m_Model.CreateNewLabel(labelName);
  390. m_Model.SelectLabels(new List<string> { m_Model.GetAllLabels()[^1].name });
  391. m_Model.EndUndo();
  392. AutoSave();
  393. RefreshView();
  394. RefreshSelection();
  395. }
  396. void RenameSelectedLabel(string newName)
  397. {
  398. if (!hasSelectedLibrary || !m_Model.hasSelectedCategories || !m_Model.hasSelectedLabels)
  399. return;
  400. var labelData = GetLabelData(selectedLabels[0]);
  401. if (labelData == null || labelData.fromMain)
  402. return;
  403. newName = newName?.Trim();
  404. if (newName == string.Empty)
  405. return;
  406. m_Model.BeginUndo(ActionType.RenameLabel, TextContent.spriteLibraryRenameLabel);
  407. m_Model.RenameSelectedLabel(newName);
  408. m_Model.EndUndo();
  409. AutoSave();
  410. RefreshView();
  411. RefreshSelection();
  412. }
  413. void ReorderLabels(IList<string> reorderedLabels)
  414. {
  415. if (!hasSelectedLibrary || !m_Model.hasSelectedCategories)
  416. return;
  417. if (m_Model.CompareLabels(reorderedLabels))
  418. return;
  419. var labelsToReorder = selectedLabels;
  420. m_Model.BeginUndo(ActionType.ReorderLabels, TextContent.spriteLibraryReorderLabels);
  421. m_Model.ReorderLabels(reorderedLabels);
  422. m_Model.SelectLabels(labelsToReorder);
  423. m_Model.EndUndo();
  424. AutoSave();
  425. RefreshView();
  426. }
  427. void DeleteSelectedLabels()
  428. {
  429. if (!hasSelectedLibrary || !m_Model.hasSelectedCategories || !m_Model.hasSelectedLabels)
  430. return;
  431. var canAnyLabelBeDeleted = false;
  432. foreach (var label in selectedLabels)
  433. {
  434. if (!GetLabelData(label).fromMain)
  435. {
  436. canAnyLabelBeDeleted = true;
  437. break;
  438. }
  439. }
  440. if (!canAnyLabelBeDeleted)
  441. return;
  442. m_Model.BeginUndo(ActionType.DeleteLabels, TextContent.spriteLibraryDeleteLabels);
  443. m_Model.DeleteSelectedLabels();
  444. m_Model.SelectLabels(new List<string>());
  445. m_Model.EndUndo();
  446. AutoSave();
  447. RefreshView();
  448. RefreshSelection();
  449. }
  450. void SetLabelSprite(string labelName, Sprite newSprite)
  451. {
  452. if (!hasSelectedLibrary || !m_Model.hasSelectedCategories)
  453. return;
  454. var labelData = GetLabelData(labelName);
  455. if (labelData == null || labelData.sprite == newSprite)
  456. return;
  457. m_Model.BeginUndo(ActionType.SetLabelSprite, TextContent.spriteLibrarySetLabelSprite);
  458. m_Model.SetLabelSprite(labelName, newSprite);
  459. m_Model.EndUndo();
  460. AutoSave();
  461. RefreshView();
  462. RefreshSelection();
  463. }
  464. void ToggleAutoSave(bool newAutoSaveValue)
  465. {
  466. m_AutoSave = newAutoSaveValue;
  467. if (m_AutoSave)
  468. OnSave();
  469. }
  470. void OnSave()
  471. {
  472. m_Window.SaveChanges();
  473. }
  474. void OnRevert()
  475. {
  476. if (m_Window.hasUnsavedChanges)
  477. m_Window.HandleRevertChanges();
  478. }
  479. void AutoSave()
  480. {
  481. if (m_AutoSave)
  482. m_Window.SaveChanges();
  483. }
  484. void ToggleSelectionLock(bool isSelectionLocked)
  485. {
  486. m_SelectionLocked = isSelectionLocked;
  487. SelectionChanged();
  488. }
  489. void AddDataToCategories(IList<DragAndDropData> spritesData, bool alt, string category)
  490. {
  491. if (!hasSelectedLibrary)
  492. return;
  493. if (spritesData == null || spritesData.Count == 0)
  494. return;
  495. m_Model.BeginUndo(ActionType.ModifiedCategories, TextContent.spriteLibraryAddDataToCategories);
  496. foreach (var data in spritesData)
  497. {
  498. var isDroppedIntoEmptyArea = string.IsNullOrEmpty(category);
  499. if (isDroppedIntoEmptyArea)
  500. {
  501. if (data.spriteSourceType == SpriteSourceType.Psb)
  502. HandlePsdData(data);
  503. else if (data.spriteSourceType == SpriteSourceType.Sprite)
  504. m_Model.CreateNewCategory(data.name, data.sprites);
  505. }
  506. else
  507. m_Model.AddLabelsToCategory(category, data.sprites, true);
  508. }
  509. m_Model.EndUndo();
  510. AutoSave();
  511. RefreshView();
  512. RefreshSelection();
  513. }
  514. void AddDataToLabels(IList<DragAndDropData> spritesData, bool alt, string label)
  515. {
  516. if (!hasSelectedLibrary || !m_Model.hasSelectedCategories)
  517. return;
  518. var sprites = new List<Sprite>();
  519. foreach (var data in spritesData)
  520. sprites.AddRange(data.sprites);
  521. if (sprites.Count == 0)
  522. return;
  523. m_Model.BeginUndo(ActionType.ModifiedLabels, TextContent.spriteLibraryAddDataToLabels);
  524. if (!string.IsNullOrEmpty(label))
  525. m_Model.SetLabelSprite(label, sprites[0]);
  526. else // empty area
  527. m_Model.AddLabelsToCategory(selectedCategories[0], sprites, false);
  528. m_Model.EndUndo();
  529. AutoSave();
  530. RefreshView();
  531. RefreshSelection();
  532. }
  533. void HandlePsdData(DragAndDropData data)
  534. {
  535. var psdFilePath = AssetDatabase.GetAssetPath(data.sprites[0]);
  536. var characterObj = AssetDatabase.LoadAssetAtPath<GameObject>(psdFilePath);
  537. var categoryDictionary = new Dictionary<string, List<Sprite>>();
  538. var objectList = new Queue<Transform>();
  539. objectList.Enqueue(characterObj.transform);
  540. while (objectList.Count > 0)
  541. {
  542. var goTransform = objectList.Dequeue();
  543. var spriteList = new List<Sprite>();
  544. for (var i = 0; i < goTransform.childCount; i++)
  545. {
  546. var childTransform = goTransform.GetChild(i);
  547. var spriteRenderer = childTransform.GetComponent<SpriteRenderer>();
  548. if (spriteRenderer != null)
  549. spriteList.Add(spriteRenderer.sprite);
  550. else
  551. objectList.Enqueue(childTransform);
  552. }
  553. if (spriteList.Count > 0)
  554. {
  555. if (goTransform == characterObj.transform)
  556. {
  557. foreach (var sprite in spriteList)
  558. categoryDictionary[sprite.name] = new List<Sprite> { sprite };
  559. }
  560. else
  561. {
  562. categoryDictionary[goTransform.name] = spriteList;
  563. }
  564. }
  565. }
  566. foreach (var (categoryName, sprites) in categoryDictionary)
  567. {
  568. var addedToCategory = false;
  569. foreach (var cat in m_Model.GetAllCategories())
  570. {
  571. if (cat.name == categoryName)
  572. {
  573. m_Model.AddLabelsToCategory(categoryName, sprites, true);
  574. addedToCategory = true;
  575. break;
  576. }
  577. }
  578. if (!addedToCategory)
  579. m_Model.CreateNewCategory(categoryName, sprites);
  580. }
  581. }
  582. void RevertOverridenLabels(IList<string> labels)
  583. {
  584. if (!hasSelectedLibrary || !m_Model.hasSelectedCategories)
  585. return;
  586. var canRevertChanges = false;
  587. foreach (var label in labels)
  588. {
  589. if (string.IsNullOrEmpty(label))
  590. continue;
  591. var data = GetLabelData(label);
  592. if (data != null && (data.spriteOverride || data.categoryFromMain && !data.fromMain))
  593. {
  594. canRevertChanges = true;
  595. break;
  596. }
  597. }
  598. if (!canRevertChanges)
  599. return;
  600. m_Model.BeginUndo(ActionType.SetLabelSprite, TextContent.spriteLibrarySetLabelSprite);
  601. m_Model.RevertLabels(labels);
  602. m_Model.SelectLabels(new List<string>());
  603. m_Model.EndUndo();
  604. AutoSave();
  605. RefreshView();
  606. RefreshSelection();
  607. }
  608. CategoryData GetCategoryData(string categoryName)
  609. {
  610. if (string.IsNullOrEmpty(categoryName))
  611. return null;
  612. foreach (var category in m_Model.GetAllCategories())
  613. {
  614. if (category.name == categoryName)
  615. return category;
  616. }
  617. return null;
  618. }
  619. LabelData GetLabelData(string labelName)
  620. {
  621. if (string.IsNullOrEmpty(labelName))
  622. return null;
  623. foreach (var label in m_Model.GetAllLabels())
  624. {
  625. if (label.name == labelName)
  626. return label;
  627. }
  628. return null;
  629. }
  630. static bool AreSequencesEqual(IList<string> first, IList<string> second)
  631. {
  632. if (first == null || second == null || first.Count != second.Count)
  633. return false;
  634. for (var i = 0; i < first.Count; i++)
  635. {
  636. if (first[i] != second[i])
  637. return false;
  638. }
  639. return true;
  640. }
  641. }
  642. }