No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

WindowController.cs 26KB

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