BoneVisibilityTool.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. using UnityEditor.IMGUI.Controls;
  4. using System;
  5. using System.Linq;
  6. using UnityEngine.UIElements;
  7. namespace UnityEditor.U2D.Animation
  8. {
  9. internal class BoneVisibilityTool : BoneTreeWidgetModel, IVisibilityTool
  10. {
  11. private BoneTreeWidgetController m_Controller;
  12. VisualElement IVisibilityTool.view { get { return (VisualElement)m_View; } }
  13. public string name { get { return "Bone"; } }
  14. public bool isAvailable
  15. {
  16. get { return true; }
  17. }
  18. public BoneVisibilityTool(SkinningCache s)
  19. {
  20. m_SkinningCache = s;
  21. }
  22. public void Setup()
  23. {
  24. m_Data = skinningCache.CreateCache<BoneVisibilityToolData>();
  25. m_Controller = new BoneReparentToolController(this, skinningCache.events);//new BoneTreeWidgetController(this, skinningCache.events);
  26. m_View = new BoneReparentToolView()
  27. {
  28. GetModel = () => this,
  29. GetController = () => m_Controller
  30. };
  31. }
  32. public void Dispose()
  33. {}
  34. public void Activate()
  35. {
  36. m_Controller.Activate();
  37. if (m_Data.previousVisiblity != m_Data.allVisibility)
  38. {
  39. m_Data.previousVisiblity = m_Data.allVisibility;
  40. }
  41. }
  42. public void Deactivate()
  43. {
  44. m_Controller.Deactivate();
  45. }
  46. public void SetAvailabilityChangeCallback(Action callback)
  47. {}
  48. }
  49. internal class BoneVisibilityToolView : VisibilityToolViewBase, IBoneVisibilityToolView
  50. {
  51. public Func<BoneTreeWidgetController> GetController = () => null;
  52. public Func<IBoneTreeViewModel> GetModel = () => null;
  53. public BoneVisibilityToolView()
  54. {
  55. m_TreeView = new BoneTreeView(m_TreeViewState, SetupToolColumnHeader())
  56. {
  57. GetController = InternalGetController
  58. };
  59. SetupSearchField();
  60. }
  61. protected virtual VisibilityToolColumnHeader SetupToolColumnHeader()
  62. {
  63. var columns = new MultiColumnHeaderState.Column[2];
  64. columns[0] = new MultiColumnHeaderState.Column
  65. {
  66. headerContent = VisibilityTreeViewBase.VisibilityIconStyle.visibilityOnIcon,
  67. headerTextAlignment = TextAlignment.Center,
  68. width = 32,
  69. minWidth = 32,
  70. maxWidth = 32,
  71. autoResize = false,
  72. allowToggleVisibility = true
  73. };
  74. columns[1] = new MultiColumnHeaderState.Column
  75. {
  76. headerContent = EditorGUIUtility.TrTextContent(TextContent.bone),
  77. headerTextAlignment = TextAlignment.Center,
  78. width = 200,
  79. minWidth = 130,
  80. autoResize = true,
  81. allowToggleVisibility = false
  82. };
  83. var multiColumnHeaderState = new MultiColumnHeaderState(columns);
  84. return new VisibilityToolColumnHeader(multiColumnHeaderState)
  85. {
  86. GetAllVisibility = GetAllVisibility,
  87. SetAllVisibility = SetAllVisibility,
  88. canSort = false,
  89. height = 20,
  90. visibilityColumn = 0
  91. };
  92. }
  93. BoneTreeWidgetController InternalGetController()
  94. {
  95. return GetController();
  96. }
  97. protected void SetAllVisibility(bool visibility)
  98. {
  99. GetController().SetAllVisibility(visibility);
  100. }
  101. protected bool GetAllVisibility()
  102. {
  103. return GetModel().GetAllVisibility();
  104. }
  105. public void OnSelectionChange(SkeletonCache skeleton)
  106. {
  107. ((BoneTreeView)m_TreeView).SetupHierarchy();
  108. }
  109. public void OnBoneSelectionChange(SkeletonSelection bones)
  110. {
  111. ((BoneTreeView)m_TreeView).OnBoneSelectionChanged(bones);
  112. }
  113. public void OnBoneExpandedChange(BoneCache[] bones)
  114. {
  115. ((BoneTreeView)m_TreeView).OnBoneExpandedChanged(bones);
  116. }
  117. public void OnBoneNameChanged(BoneCache bone)
  118. {
  119. ((BoneTreeView)m_TreeView).OnBoneNameChanged(bone);
  120. }
  121. public void Deactivate()
  122. {
  123. if (m_TreeView.HasSelection())
  124. m_TreeView.EndRename();
  125. }
  126. }
  127. class BoneTreeView : VisibilityTreeViewBase
  128. {
  129. public Func<BoneTreeWidgetController> GetController = () => null;
  130. public BoneTreeView(TreeViewState treeViewState, MultiColumnHeader columnHeader)
  131. : base(treeViewState, columnHeader)
  132. {
  133. columnIndexForTreeFoldouts = 1;
  134. ReloadView();
  135. }
  136. public void SetupHierarchy()
  137. {
  138. ReloadView();
  139. }
  140. private void ReloadView()
  141. {
  142. Reload();
  143. }
  144. public void OnBoneSelectionChanged(SkeletonSelection boneSelection)
  145. {
  146. var bones = boneSelection.elements.ToSpriteSheetIfNeeded();
  147. var ids = GetController().GetIDsToSelect(bones);
  148. var result = GetController().GetIDsToExpand(bones);
  149. var expandIds = GetExpanded().ToList();
  150. if (result.Count > 0)
  151. expandIds = expandIds.Union(result).ToList();
  152. SetExpanded(expandIds);
  153. SetSelection(ids);
  154. }
  155. public void OnBoneExpandedChanged(BoneCache[] bones)
  156. {
  157. var expandIds = GetController().GetIDsToSelect(bones);
  158. if (expandIds.Length == 0)
  159. return;
  160. SetExpanded(expandIds.Union(GetExpanded()).ToList());
  161. }
  162. public void OnBoneNameChanged(BoneCache bone)
  163. {
  164. GetController().SetTreeViewBoneName(GetRows(), bone);
  165. }
  166. protected override void SelectionChanged(IList<int> selectedIds)
  167. {
  168. GetController().SelectBones(selectedIds, GetRows());
  169. }
  170. protected override void ExpandedStateChanged()
  171. {
  172. GetController().ExpandBones(GetExpanded(), GetRows());
  173. }
  174. protected override float GetCustomRowHeight(int row, TreeViewItem item)
  175. {
  176. return EditorGUIUtility.singleLineHeight * 1.1f;
  177. }
  178. void CellGUI(Rect cellRect, TreeViewItem item, int column, ref RowGUIArgs args)
  179. {
  180. CenterRectUsingSingleLineHeight(ref cellRect);
  181. switch (column)
  182. {
  183. case 0:
  184. DrawVisibilityCell(cellRect, item);
  185. break;
  186. case 1:
  187. DrawNameCell(cellRect, item, ref args);
  188. break;
  189. case 2:
  190. DrawDepthCell(cellRect, item);
  191. break;
  192. }
  193. }
  194. void DrawDepthCell(Rect cellRect, TreeViewItem item)
  195. {
  196. var boneItemView = item as TreeViewItemBase<BoneCache>;
  197. int depth = GetController().GetTreeItemDepthValue(boneItemView);
  198. const int width = 30;
  199. cellRect.height = EditorGUIUtility.singleLineHeight;
  200. cellRect.x += (cellRect.width - width) * 0.5f;
  201. cellRect.width = width;
  202. EditorGUI.BeginChangeCheck();
  203. depth = EditorGUI.IntField(cellRect, depth);
  204. if (EditorGUI.EndChangeCheck())
  205. GetController().SetTreeItemDepthValue(boneItemView, depth);
  206. }
  207. void DrawVisibilityCell(Rect cellRect, TreeViewItem item)
  208. {
  209. GUIStyle style = MultiColumnHeader.DefaultStyles.columnHeaderCenterAligned;
  210. EditorGUI.BeginChangeCheck();
  211. var boneItemView = item as TreeViewItemBase<BoneCache>;
  212. bool visible = GetController().GetTreeItemVisibility(boneItemView);
  213. visible = GUI.Toggle(cellRect, visible, visible ? VisibilityIconStyle.visibilityOnIcon : VisibilityIconStyle.visibilityOffIcon, style);
  214. if (EditorGUI.EndChangeCheck())
  215. {
  216. GetController().SetTreeItemVisibility(boneItemView, visible, Event.current.alt);
  217. }
  218. }
  219. void DrawNameCell(Rect cellRect, TreeViewItem item, ref RowGUIArgs args)
  220. {
  221. args.rowRect = cellRect;
  222. base.RowGUI(args);
  223. }
  224. protected override Rect GetRenameRect(Rect rowRect, int row, TreeViewItem item)
  225. {
  226. Rect cellRect = GetCellRectForTreeFoldouts(rowRect);
  227. CenterRectUsingSingleLineHeight(ref cellRect);
  228. return base.GetRenameRect(cellRect, row, item);
  229. }
  230. protected override void RowGUI(RowGUIArgs args)
  231. {
  232. var item = args.item;
  233. for (int i = 0; i < args.GetNumVisibleColumns(); ++i)
  234. {
  235. CellGUI(args.GetCellRect(i), item, args.GetColumn(i), ref args);
  236. }
  237. }
  238. protected override TreeViewItem BuildRoot()
  239. {
  240. var root = new TreeViewItem {id = 0, depth = -1, displayName = "Root"};
  241. List<TreeViewItem> rows = GetController() != null ? GetController().BuildTreeView() : new List<TreeViewItem>();
  242. SetupParentsAndChildrenFromDepths(root, rows);
  243. return root;
  244. }
  245. protected override bool CanRename(TreeViewItem item)
  246. {
  247. return GetController().CanRename();
  248. }
  249. protected override void RenameEnded(RenameEndedArgs args)
  250. {
  251. var rows = GetRows();
  252. GetController().TreeViewItemRename(rows, args.itemID, args.newName);
  253. base.RenameEnded(args);
  254. }
  255. // dragging
  256. const string k_GenericDragID = "GenericDragColumnDragging";
  257. protected override bool CanStartDrag(CanStartDragArgs args)
  258. {
  259. return true;
  260. }
  261. protected override void SetupDragAndDrop(SetupDragAndDropArgs args)
  262. {
  263. if (GetController().CanDrag() && !hasSearch)
  264. {
  265. DragAndDrop.PrepareStartDrag();
  266. var draggedRows = GetRows().Where(item => args.draggedItemIDs.Contains(item.id)).ToList();
  267. DragAndDrop.SetGenericData(k_GenericDragID, draggedRows);
  268. DragAndDrop.objectReferences = new UnityEngine.Object[] {}; // this IS required for dragging to work
  269. string title = draggedRows.Count == 1 ? draggedRows[0].displayName : "< Multiple >";
  270. DragAndDrop.StartDrag(title);
  271. }
  272. }
  273. protected override DragAndDropVisualMode HandleDragAndDrop(DragAndDropArgs args)
  274. {
  275. // Check if we can handle the current drag data (could be dragged in from other areas/windows in the editor)
  276. var draggedRows = DragAndDrop.GetGenericData(k_GenericDragID) as List<TreeViewItem>;
  277. if (draggedRows == null)
  278. return DragAndDropVisualMode.None;
  279. // Parent item is null when dragging outside any tree view items.
  280. switch (args.dragAndDropPosition)
  281. {
  282. case DragAndDropPosition.UponItem:
  283. case DragAndDropPosition.OutsideItems:
  284. case DragAndDropPosition.BetweenItems:
  285. {
  286. var newParent = args.parentItem as TreeViewItemBase<BoneCache>;
  287. bool validDrag = false;
  288. validDrag = GetController().CanReparent(newParent, draggedRows);
  289. if (args.performDrop && validDrag)
  290. {
  291. GetController().ReparentItems(newParent, draggedRows, args.insertAtIndex);
  292. Reload();
  293. var selectedIDs = draggedRows.ConvertAll(b => b.id);
  294. SetSelection(selectedIDs, TreeViewSelectionOptions.RevealAndFrame);
  295. SelectionChanged(selectedIDs);
  296. }
  297. return validDrag ? DragAndDropVisualMode.Move : DragAndDropVisualMode.None;
  298. }
  299. }
  300. return DragAndDropVisualMode.None;
  301. }
  302. }
  303. }