A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3using UnityEditor.IMGUI.Controls;
4using UnityEngine;
5using UnityEngine.Timeline;
6
7namespace UnityEditor.Timeline.Signals
8{
9 class SignalReceiverTreeView : TreeView
10 {
11 public bool dirty { private get; set; }
12
13 SerializedProperty signals { get; set; }
14 SerializedProperty events { get; set; }
15
16 readonly SignalReceiver m_Target;
17
18 const float k_VerticalPadding = 5;
19 const float k_HorizontalPadding = 5;
20
21 public SignalReceiverTreeView(TreeViewState state, MultiColumnHeader multiColumnHeader, SignalReceiver receiver, SerializedObject serializedObject)
22 : base(state, multiColumnHeader)
23 {
24 m_Target = receiver;
25 useScrollView = true;
26 SetSerializedProperties(serializedObject);
27 getNewSelectionOverride = (item, selection, shift) => new List<int>(); // Disable Selection
28 }
29
30 SignalAsset signalAssetContext { get; set; }
31 public bool readonlySignals { get; set; }
32
33 public void SetSignalContext(SignalAsset assetContext = null)
34 {
35 signalAssetContext = assetContext;
36 dirty = true;
37 }
38
39 void SetSerializedProperties(SerializedObject serializedObject)
40 {
41 signals = SignalReceiverUtility.FindSignalsProperty(serializedObject);
42 events = SignalReceiverUtility.FindEventsProperty(serializedObject);
43 Reload();
44 }
45
46 public void Draw()
47 {
48 var rect = EditorGUILayout.GetControlRect(true, GetTotalHeight());
49 OnGUI(rect);
50 }
51
52 public void RefreshIfDirty()
53 {
54 var signalsListSizeHasChanged = signals.arraySize != GetRows().Count;
55 if (dirty || signalsListSizeHasChanged)
56 Reload();
57 dirty = false;
58 }
59
60 public static MultiColumnHeaderState.Column[] GetColumns()
61 {
62 return new[]
63 {
64 new MultiColumnHeaderState.Column
65 {
66 headerContent = L10n.TextContent("Signal"),
67 contextMenuText = "",
68 headerTextAlignment = TextAlignment.Center,
69 width = 50, minWidth = 50,
70 autoResize = true,
71 allowToggleVisibility = false,
72 canSort = false
73 },
74 new MultiColumnHeaderState.Column
75 {
76 headerContent = L10n.TextContent("Reaction"),
77 contextMenuText = "",
78 headerTextAlignment = TextAlignment.Center,
79 width = 120, minWidth = 120,
80 autoResize = true,
81 allowToggleVisibility = false,
82 canSort = false
83 }
84 };
85 }
86
87 protected override TreeViewItem BuildRoot()
88 {
89 var root = new TreeViewItem(-1, -1) { children = new List<TreeViewItem>() };
90
91 var matchingId = signalAssetContext != null && readonlySignals ? FindIdForSignal(signals, signalAssetContext) : -1;
92 if (matchingId >= 0)
93 AddItem(root, matchingId);
94
95 for (var i = 0; i < signals.arraySize; ++i)
96 {
97 if (i == matchingId) continue;
98 AddItem(root, i, !readonlySignals);
99 }
100
101 return root;
102 }
103
104 protected override void RowGUI(RowGUIArgs args)
105 {
106 var item = (SignalReceiverItem)args.item;
107 for (var i = 0; i < args.GetNumVisibleColumns(); ++i)
108 {
109 var rect = args.GetCellRect(i);
110 rect.y += k_VerticalPadding;
111 item.Draw(rect, args.GetColumn(i), args.row, k_HorizontalPadding, m_Target);
112 }
113 }
114
115 protected override float GetCustomRowHeight(int row, TreeViewItem treeItem)
116 {
117 var item = treeItem as SignalReceiverItem;
118 return item.GetHeight() + k_VerticalPadding;
119 }
120
121 void AddItem(TreeViewItem root, int id, bool enabled = true)
122 {
123 var signal = signals.GetArrayElementAtIndex(id);
124 var evt = events.GetArrayElementAtIndex(id);
125 root.children.Add(new SignalReceiverItem(signal, evt, id, readonlySignals, enabled, this));
126 }
127
128 float GetTotalHeight()
129 {
130 var height = 0.0f;
131 foreach (var item in GetRows())
132 {
133 var signalListItem = item as SignalReceiverItem;
134 height += signalListItem.GetHeight() + k_VerticalPadding;
135 }
136
137 var scrollbarPadding = showingHorizontalScrollBar ? GUI.skin.horizontalScrollbar.fixedHeight : k_VerticalPadding;
138 return height + multiColumnHeader.height + scrollbarPadding;
139 }
140
141 static int FindIdForSignal(SerializedProperty signals, SignalAsset signalToFind)
142 {
143 for (var i = 0; i < signals.arraySize; ++i)
144 {
145 //signal in the receiver that matches the current signal asset will be displayed first
146 var serializedProperty = signals.GetArrayElementAtIndex(i);
147 var signalReferenceValue = serializedProperty.objectReferenceValue;
148 var signalToFindRefValue = signalToFind;
149 if (signalReferenceValue != null && signalReferenceValue == signalToFindRefValue)
150 return i;
151 }
152 return -1;
153 }
154 }
155}