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