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