MeshVisibilityTool.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  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 MeshVisibilityTool : IVisibilityTool
  10. {
  11. private MeshVisibilityToolView m_View;
  12. private MeshVisibilityToolModel m_Model;
  13. private SkinningCache m_SkinningCache;
  14. public SkinningCache skinningCache { get { return m_SkinningCache; } }
  15. public MeshVisibilityTool(SkinningCache s)
  16. {
  17. m_SkinningCache = s;
  18. }
  19. public void Setup()
  20. {
  21. m_Model = skinningCache.CreateCache<MeshVisibilityToolModel>();
  22. m_View = new MeshVisibilityToolView(skinningCache)
  23. {
  24. GetModel = () => m_Model,
  25. SetAllVisibility = SetAllVisibility,
  26. GetAllVisibility = GetAllVisibility
  27. };
  28. }
  29. public void Dispose()
  30. {
  31. }
  32. public VisualElement view { get { return m_View; } }
  33. public string name { get { return "Mesh"; } }
  34. public void Activate()
  35. {
  36. skinningCache.events.selectedSpriteChanged.AddListener(OnSelectionChange);
  37. skinningCache.events.skinningModeChanged.AddListener(OnViewModeChanged);
  38. OnViewModeChanged(skinningCache.mode);
  39. if (m_Model.previousVisiblity != m_Model.allVisibility)
  40. {
  41. SetAllMeshVisibility();
  42. m_Model.previousVisiblity = m_Model.allVisibility;
  43. }
  44. }
  45. public void Deactivate()
  46. {
  47. skinningCache.events.selectedSpriteChanged.RemoveListener(OnSelectionChange);
  48. skinningCache.events.skinningModeChanged.RemoveListener(OnViewModeChanged);
  49. }
  50. public bool isAvailable
  51. {
  52. get { return false; }
  53. }
  54. public void SetAvailabilityChangeCallback(Action callback)
  55. {}
  56. private void OnViewModeChanged(SkinningMode characterMode)
  57. {
  58. if (characterMode == SkinningMode.Character)
  59. {
  60. m_View.Setup(skinningCache.GetSprites());
  61. }
  62. else
  63. {
  64. m_View.Setup(new[] { skinningCache.selectedSprite });
  65. }
  66. }
  67. private void OnSelectionChange(SpriteCache sprite)
  68. {
  69. OnViewModeChanged(skinningCache.mode);
  70. SetAllMeshVisibility();
  71. }
  72. void SetAllVisibility(bool visibility)
  73. {
  74. using (skinningCache.UndoScope(TextContent.meshVisibility))
  75. {
  76. m_Model.allVisibility = visibility;
  77. SetAllMeshVisibility();
  78. }
  79. }
  80. void SetAllMeshVisibility()
  81. {
  82. SpriteCache[] sprites;
  83. if (skinningCache.mode == SkinningMode.Character)
  84. sprites = skinningCache.GetSprites();
  85. else
  86. sprites = new[] { skinningCache.selectedSprite };
  87. foreach (var spr in sprites)
  88. {
  89. if (spr != null)
  90. m_Model.SetMeshVisibility(spr, m_Model.allVisibility);
  91. }
  92. }
  93. bool GetAllVisibility()
  94. {
  95. return m_Model.allVisibility;
  96. }
  97. }
  98. internal class MeshVisibilityToolModel : SkinningObject
  99. {
  100. [SerializeField]
  101. bool m_AllVisibility = true;
  102. bool m_PreviousVisibility = true;
  103. public bool allVisibility
  104. {
  105. get {return m_AllVisibility; }
  106. set { m_AllVisibility = value; }
  107. }
  108. public void SetMeshVisibility(SpriteCache sprite, bool visibility)
  109. {
  110. }
  111. public bool GetMeshVisibility(SpriteCache sprite)
  112. {
  113. return false;
  114. }
  115. public bool ShouldDisable(SpriteCache sprite)
  116. {
  117. var mesh = sprite.GetMesh();
  118. return mesh == null || mesh.vertices.Count == 0;
  119. }
  120. public bool previousVisiblity
  121. {
  122. get { return m_PreviousVisibility; }
  123. set { m_PreviousVisibility = value; }
  124. }
  125. }
  126. internal class MeshVisibilityToolView : VisibilityToolViewBase
  127. {
  128. public Func<MeshVisibilityToolModel> GetModel = () => null;
  129. public Action<bool> SetAllVisibility = (b) => {};
  130. public Func<bool> GetAllVisibility = () => true;
  131. public SkinningCache skinningCache { get; set; }
  132. public MeshVisibilityToolView(SkinningCache s)
  133. {
  134. skinningCache = s;
  135. var columns = new MultiColumnHeaderState.Column[2];
  136. columns[0] = new MultiColumnHeaderState.Column
  137. {
  138. headerContent = EditorGUIUtility.TrTextContent(TextContent.name),
  139. headerTextAlignment = TextAlignment.Center,
  140. width = 200,
  141. minWidth = 130,
  142. autoResize = true,
  143. allowToggleVisibility = false
  144. };
  145. columns[1] = new MultiColumnHeaderState.Column
  146. {
  147. headerContent = new GUIContent(EditorGUIUtility.FindTexture("visibilityOn")),
  148. headerTextAlignment = TextAlignment.Center,
  149. width = 32,
  150. minWidth = 32,
  151. maxWidth = 32,
  152. autoResize = false,
  153. allowToggleVisibility = true
  154. };
  155. var multiColumnHeaderState = new MultiColumnHeaderState(columns);
  156. var multiColumnHeader = new VisibilityToolColumnHeader(multiColumnHeaderState)
  157. {
  158. GetAllVisibility = InternalGetAllVisibility,
  159. SetAllVisibility = InternalSetAllVisibility,
  160. canSort = false,
  161. height = 20,
  162. visibilityColumn = 1
  163. };
  164. m_TreeView = new MeshTreeView(m_TreeViewState, multiColumnHeader)
  165. {
  166. GetModel = InternalGetModel
  167. };
  168. SetupSearchField();
  169. }
  170. MeshVisibilityToolModel InternalGetModel()
  171. {
  172. return GetModel();
  173. }
  174. public void Setup(SpriteCache[] sprites)
  175. {
  176. ((MeshTreeView)m_TreeView).Setup(sprites);
  177. ((MeshTreeView)m_TreeView).SetSelection(skinningCache.selectedSprite);
  178. }
  179. bool InternalGetAllVisibility()
  180. {
  181. return GetAllVisibility();
  182. }
  183. void InternalSetAllVisibility(bool visibility)
  184. {
  185. SetAllVisibility(visibility);
  186. }
  187. }
  188. class MeshTreeView : VisibilityTreeViewBase
  189. {
  190. private List<SpriteCache> m_Sprites = new List<SpriteCache>();
  191. public MeshTreeView(TreeViewState treeViewState, MultiColumnHeader header)
  192. : base(treeViewState, header)
  193. {
  194. this.showAlternatingRowBackgrounds = true;
  195. this.useScrollView = true;
  196. Reload();
  197. }
  198. public Func<MeshVisibilityToolModel> GetModel = () => null;
  199. public void Setup(SpriteCache[] sprites)
  200. {
  201. m_Sprites.Clear();
  202. m_Sprites.AddRange(sprites);
  203. Reload();
  204. }
  205. private static TreeViewItem CreateTreeViewItem(SpriteCache part)
  206. {
  207. return new TreeViewItemBase<SpriteCache>(part.GetInstanceID(), -1, part.name, part);
  208. }
  209. private void AddTreeViewItem(IList<TreeViewItem> rows, SpriteCache part)
  210. {
  211. if (string.IsNullOrEmpty(searchString) || part.name.IndexOf(searchString, StringComparison.OrdinalIgnoreCase) >= 0)
  212. {
  213. var item = CreateTreeViewItem(part);
  214. rows.Add(item);
  215. rootItem.AddChild(item);
  216. }
  217. }
  218. private void CellGUI(Rect cellRect, TreeViewItem item, int column, ref RowGUIArgs args)
  219. {
  220. CenterRectUsingSingleLineHeight(ref cellRect);
  221. switch (column)
  222. {
  223. case 0:
  224. DrawNameCell(cellRect, item, ref args);
  225. break;
  226. case 1:
  227. DrawVisibilityCell(cellRect, item);
  228. break;
  229. }
  230. }
  231. private void DrawVisibilityCell(Rect cellRect, TreeViewItem item)
  232. {
  233. GUIStyle style = MultiColumnHeader.DefaultStyles.columnHeaderCenterAligned;
  234. var itemView = item as TreeViewItemBase<SpriteCache>;
  235. var shouldDisable = GetModel().ShouldDisable(itemView.customData);
  236. using (new EditorGUI.DisabledScope(shouldDisable))
  237. {
  238. EditorGUI.BeginChangeCheck();
  239. bool visible = GetModel().GetMeshVisibility(itemView.customData);
  240. visible = GUI.Toggle(cellRect, visible, visible ? VisibilityIconStyle.visibilityOnIcon : VisibilityIconStyle.visibilityOffIcon, style);
  241. if (EditorGUI.EndChangeCheck())
  242. GetModel().SetMeshVisibility(itemView.customData, visible);
  243. }
  244. }
  245. private void DrawNameCell(Rect cellRect, TreeViewItem item, ref RowGUIArgs args)
  246. {
  247. args.rowRect = cellRect;
  248. base.RowGUI(args);
  249. }
  250. protected override void RowGUI(RowGUIArgs args)
  251. {
  252. var item = args.item;
  253. for (int i = 0; i < args.GetNumVisibleColumns(); ++i)
  254. {
  255. CellGUI(args.GetCellRect(i), item, args.GetColumn(i), ref args);
  256. }
  257. }
  258. protected override void SelectionChanged(IList<int> selectedIds)
  259. {
  260. SpriteCache newSelected = null;
  261. if (selectedIds.Count > 0)
  262. {
  263. var selected = GetRows().FirstOrDefault(x => ((TreeViewItemBase<SpriteCache>)x).customData.GetInstanceID() == selectedIds[0]) as TreeViewItemBase<SpriteCache>;
  264. if (selected != null)
  265. newSelected = selected.customData;
  266. }
  267. var skinningCache = newSelected.skinningCache;
  268. using (skinningCache.UndoScope(TextContent.selectionChange))
  269. {
  270. skinningCache.events.selectedSpriteChanged.Invoke(newSelected);
  271. }
  272. }
  273. public void SetSelection(SpriteCache sprite)
  274. {
  275. var rows = GetRows();
  276. for (int i = 0; rows != null && i < rows.Count; ++i)
  277. {
  278. var r = (TreeViewItemBase<SpriteCache>)rows[i];
  279. if (r.customData == sprite)
  280. {
  281. SetSelection(new[] { r.customData.GetInstanceID() }, TreeViewSelectionOptions.RevealAndFrame);
  282. break;
  283. }
  284. }
  285. }
  286. protected override IList<TreeViewItem> BuildRows(TreeViewItem root)
  287. {
  288. var rows = GetRows() ?? new List<TreeViewItem>(200);
  289. rows.Clear();
  290. m_Sprites.RemoveAll(s => s == null);
  291. foreach (var sprite in m_Sprites)
  292. AddTreeViewItem(rows, sprite);
  293. SetupDepthsFromParentsAndChildren(root);
  294. return rows;
  295. }
  296. }
  297. }