BoneTreeViewController.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEditor.IMGUI.Controls;
  5. namespace UnityEditor.U2D.Animation
  6. {
  7. internal class BoneTreeWidgetController
  8. {
  9. protected IBoneTreeViewModel m_Model;
  10. protected SkinningEvents m_SkinningEvents;
  11. public BoneTreeWidgetController(IBoneTreeViewModel model, SkinningEvents eventSystem)
  12. {
  13. m_Model = model;
  14. m_SkinningEvents = eventSystem;
  15. }
  16. public void Activate()
  17. {
  18. SetupSkeleton();
  19. m_SkinningEvents.selectedSpriteChanged.AddListener(OnSelectionChange);
  20. m_SkinningEvents.skinningModeChanged.AddListener(OnSkinningModuleModeChanged);
  21. m_SkinningEvents.boneSelectionChanged.AddListener(OnBoneSelectionChanged);
  22. m_SkinningEvents.boneNameChanged.AddListener(OnBoneNameChanged);
  23. m_SkinningEvents.skeletonTopologyChanged.AddListener(SkeletonTopologyChanged);
  24. }
  25. public void Deactivate()
  26. {
  27. m_SkinningEvents.selectedSpriteChanged.RemoveListener(OnSelectionChange);
  28. m_SkinningEvents.skinningModeChanged.RemoveListener(OnSkinningModuleModeChanged);
  29. m_SkinningEvents.boneSelectionChanged.RemoveListener(OnBoneSelectionChanged);
  30. m_SkinningEvents.boneNameChanged.RemoveListener(OnBoneNameChanged);
  31. m_SkinningEvents.skeletonTopologyChanged.RemoveListener(SkeletonTopologyChanged);
  32. if (m_Model.view != null)
  33. m_Model.view.Deactivate();
  34. }
  35. private void OnSelectionChange(SpriteCache sprite)
  36. {
  37. SetupSkeleton();
  38. m_Model.SetAllVisibility(null, true);
  39. }
  40. private void OnBoneSelectionChanged()
  41. {
  42. m_Model.view.OnBoneSelectionChange(m_Model.GetBoneSelection());
  43. }
  44. private void OnBoneNameChanged(BoneCache bone)
  45. {
  46. m_Model.view.OnBoneNameChanged(bone);
  47. }
  48. private void OnSkinningModuleModeChanged(SkinningMode mode)
  49. {
  50. SetupSkeleton();
  51. m_Model.SetAllVisibility(null, true);
  52. }
  53. private void SetupSkeleton()
  54. {
  55. m_Model.view.OnSelectionChange(m_Model.GetSelectedSkeleton());
  56. m_Model.view.OnBoneExpandedChange(m_Model.GetExpandedBones());
  57. m_Model.view.OnBoneSelectionChange(m_Model.GetBoneSelection());
  58. }
  59. public void SetAllVisibility(bool visibility)
  60. {
  61. var skeleton = m_Model.GetSelectedSkeleton();
  62. if (skeleton != null)
  63. {
  64. using (m_Model.UndoScope(TextContent.boneVisibility))
  65. {
  66. m_Model.SetAllVisibility(skeleton, visibility);
  67. }
  68. }
  69. }
  70. private void SkeletonTopologyChanged(SkeletonCache skeleton)
  71. {
  72. m_Model.view.OnSelectionChange(skeleton);
  73. }
  74. public List<TreeViewItem> BuildTreeView()
  75. {
  76. var rows = new List<TreeViewItem>();
  77. var skeleton = m_Model.GetSelectedSkeleton();
  78. if (skeleton != null)
  79. {
  80. var bones = skeleton.bones;
  81. var children = bones.Where(x => x.parentBone == null).ToArray();
  82. Array.Sort(children, (a, b) => a.siblingIndex.CompareTo(b.siblingIndex));
  83. foreach (var bone in children)
  84. AddTreeViewItem(rows, bone, bones, 0);
  85. }
  86. return rows;
  87. }
  88. private static void AddTreeViewItem(IList<TreeViewItem> rows, BoneCache bone, BoneCache[] bones, int depth)
  89. {
  90. var item = new TreeViewItemBase<BoneCache>(bone.GetInstanceID(), depth, bone.name, bone);
  91. rows.Add(item);
  92. var children = bones.Where(x => x.parentBone == bone).ToArray();
  93. Array.Sort(children, (a, b) => a.siblingIndex.CompareTo(b.siblingIndex));
  94. foreach (var childBone in children)
  95. AddTreeViewItem(rows, childBone, bones, depth + 1);
  96. }
  97. public List<int> GetIDsToExpand(BoneCache[] bones)
  98. {
  99. var result = new List<int>();
  100. if (bones != null)
  101. {
  102. foreach (var bone in bones)
  103. {
  104. if (bone != null)
  105. {
  106. var parent = bone.parentBone;
  107. while (parent != null)
  108. {
  109. int parentId = parent.GetInstanceID();
  110. result.Add(parentId);
  111. parent = parent.parentBone;
  112. }
  113. }
  114. }
  115. }
  116. return result;
  117. }
  118. public int[] GetIDsToSelect(BoneCache[] bones)
  119. {
  120. return bones == null ? new int[0] : Array.ConvertAll(bones, x => x != null ? x.GetInstanceID() : 0);
  121. }
  122. public void SelectBones(IList<int> selectedIds, IList<TreeViewItem> items)
  123. {
  124. var selectedBones = items.Where(x => selectedIds.Contains(x.id)).Select(y => ((TreeViewItemBase<BoneCache>)y).customData).ToArray();
  125. using (m_Model.UndoScope(TextContent.boneSelection))
  126. {
  127. m_Model.SelectBones(selectedBones);
  128. m_SkinningEvents.boneSelectionChanged.Invoke();
  129. }
  130. }
  131. public void ExpandBones(IList<int> expandedIds, IList<TreeViewItem> items)
  132. {
  133. var expandedBones = items.Where(x => expandedIds.Contains(x.id)).Select(y => ((TreeViewItemBase<BoneCache>)y).customData).ToArray();
  134. using (m_Model.UndoScope(TextContent.expandBones))
  135. {
  136. m_Model.SetExpandedBones(expandedBones);
  137. }
  138. }
  139. public bool GetTreeItemVisibility(TreeViewItemBase<BoneCache> item)
  140. {
  141. return m_Model.GetVisibility(item.customData);
  142. }
  143. public void SetTreeItemVisibility(TreeViewItemBase<BoneCache> item, bool visible, bool includeChildren)
  144. {
  145. var bone = item.customData;
  146. if (bone != null && bone.isVisible != visible)
  147. {
  148. using (m_Model.UndoScope(TextContent.visibilityChange))
  149. {
  150. m_Model.SetVisibility(item.customData, visible);
  151. if (includeChildren)
  152. {
  153. // toggle all children as well
  154. SetChildrenVisibility(item, visible);
  155. }
  156. }
  157. }
  158. }
  159. void SetChildrenVisibility(TreeViewItemBase<BoneCache> bone, bool visible)
  160. {
  161. if (bone.children == null)
  162. return;
  163. foreach (var childBone in bone.children)
  164. {
  165. var cb = childBone as TreeViewItemBase<BoneCache>;
  166. SetChildrenVisibility(cb, visible);
  167. m_Model.SetVisibility(cb.customData, visible);
  168. }
  169. }
  170. public int GetTreeItemDepthValue(TreeViewItemBase<BoneCache> bone)
  171. {
  172. return m_Model.GetDepth(bone.customData);
  173. }
  174. public void SetTreeItemDepthValue(TreeViewItemBase<BoneCache> bone, int value)
  175. {
  176. if (bone != null && bone.customData != null)
  177. {
  178. using (m_Model.UndoScope(TextContent.boneDepth))
  179. {
  180. m_Model.SetDepth(bone.customData, value);
  181. m_SkinningEvents.boneNameChanged.Invoke(bone.customData);
  182. }
  183. }
  184. }
  185. public void SetTreeViewBoneName(IList<TreeViewItem> items, BoneCache bone)
  186. {
  187. var treeBone = items.FirstOrDefault(x => ((TreeViewItemBase<BoneCache>)x).customData == bone);
  188. if (treeBone != null)
  189. treeBone.displayName = bone.name;
  190. }
  191. public void TreeViewItemRename(IList<TreeViewItem> rows, int itemID, string newName)
  192. {
  193. var item = rows.FirstOrDefault(x => x.id == itemID) as TreeViewItemBase<BoneCache>;
  194. if (item == null)
  195. return;
  196. if (item.customData != null && item.customData.name != newName && !string.IsNullOrEmpty(newName)
  197. && !string.IsNullOrWhiteSpace(newName))
  198. {
  199. item.displayName = newName;
  200. using (m_Model.UndoScope(TextContent.boneName))
  201. {
  202. m_Model.SetName(item.customData, newName);
  203. m_SkinningEvents.boneNameChanged.Invoke(item.customData);
  204. }
  205. }
  206. }
  207. public bool CanReparent(TreeViewItemBase<BoneCache> parent, List<TreeViewItem> draggedItems)
  208. {
  209. TreeViewItemBase<BoneCache> currentParent = parent;
  210. while (currentParent != null)
  211. {
  212. if (draggedItems.Contains(currentParent))
  213. return false;
  214. currentParent = currentParent.parent as TreeViewItemBase<BoneCache>;
  215. }
  216. return true;
  217. }
  218. public void ReparentItems(TreeViewItemBase<BoneCache> newParent, List<TreeViewItem> draggedItems, int insertAtIndex)
  219. {
  220. if ((m_Model.hasCharacter && m_Model.mode != SkinningMode.Character) ||
  221. (!m_Model.hasCharacter && m_Model.mode == SkinningMode.Character))
  222. return;
  223. var parent = newParent != null ? newParent.customData : null;
  224. using (m_Model.UndoScope(TextContent.setParentBone))
  225. {
  226. for (var i = draggedItems.Count - 1; i >= 0; --i)
  227. {
  228. var bone = ((TreeViewItemBase<BoneCache>)draggedItems[i]).customData;
  229. m_Model.SetBoneParent(parent, bone, insertAtIndex);
  230. m_SkinningEvents.skeletonTopologyChanged.Invoke(bone.skeleton);
  231. }
  232. }
  233. }
  234. public virtual bool CanDrag()
  235. {
  236. m_SkinningEvents.boneVisibility.Invoke("drag");
  237. return false;
  238. }
  239. public virtual bool CanRename()
  240. {
  241. m_SkinningEvents.boneVisibility.Invoke("rename");
  242. return false;
  243. }
  244. }
  245. }