A game about forced loneliness, made by TACStudios
at master 185 lines 7.3 kB view raw
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using UnityEditor.IMGUI.Controls; 5using UnityEngine; 6using UnityEngine.Events; 7using UnityEngine.Timeline; 8using Object = UnityEngine.Object; 9 10namespace UnityEditor.Timeline.Signals 11{ 12 class SignalReceiverItem : TreeViewItem, ISignalAssetProvider 13 { 14 static readonly SignalEventDrawer k_EvtDrawer = new SignalEventDrawer(); 15 16 readonly SerializedProperty m_Asset; 17 readonly SerializedProperty m_Evt; 18 readonly SignalReceiverTreeView m_TreeView; 19 20 int m_CurrentRowIdx; 21 SignalReceiver m_CurrentReceiver; 22 23 internal readonly bool enabled; 24 internal readonly bool readonlySignal; 25 26 internal const string SignalName = "SignalName"; 27 internal const string SignalNameReadOnly = "SignalNameReadOnly"; 28 internal const string SignalOptions = "SignalOptions"; 29 30 public SignalReceiverItem(SerializedProperty signalAsset, SerializedProperty eventListEntry, int id, bool readonlySignal, bool enabled, SignalReceiverTreeView treeView) 31 : base(id, 0) 32 { 33 m_Asset = signalAsset; 34 m_Evt = eventListEntry; 35 this.enabled = enabled; 36 this.readonlySignal = readonlySignal; 37 m_TreeView = treeView; 38 } 39 40 public SignalAsset signalAsset 41 { 42 get { return m_CurrentReceiver.GetSignalAssetAtIndex(m_CurrentRowIdx); } 43 set 44 { 45 Undo.RecordObject(m_CurrentReceiver, Styles.UndoCreateSignalAsset); 46 m_CurrentReceiver.ChangeSignalAtIndex(m_CurrentRowIdx, value); 47 PrefabUtility.RecordPrefabInstancePropertyModifications(m_CurrentReceiver); 48 } 49 } 50 51 public float GetHeight() 52 { 53 return k_EvtDrawer.GetPropertyHeight(m_Evt, GUIContent.none); 54 } 55 56 public void Draw(Rect rect, int colIdx, int rowIdx, float padding, SignalReceiver target) 57 { 58 switch (colIdx) 59 { 60 case 0: 61 DrawSignalNameColumn(rect, padding, target, rowIdx); 62 break; 63 case 1: 64 DrawReactionColumn(rect, rowIdx); 65 break; 66 default: 67 throw new ArgumentOutOfRangeException(); 68 } 69 } 70 71 void DrawSignalNameColumn(Rect rect, float padding, SignalReceiver target, int rowIdx) 72 { 73 using (new EditorGUI.DisabledScope(!enabled)) 74 { 75 if (!readonlySignal) 76 { 77 m_CurrentRowIdx = rowIdx; 78 m_CurrentReceiver = target; 79 80 rect.x += padding; 81 rect.width -= padding; 82 rect.height = EditorGUIUtility.singleLineHeight; 83 GUI.SetNextControlName(SignalName); 84 SignalUtility.DrawSignalNames(this, rect, GUIContent.none, false); 85 } 86 else 87 { 88 GUI.SetNextControlName(SignalNameReadOnly); 89 var signalAsset = m_Asset.objectReferenceValue; 90 GUI.Label(rect, 91 signalAsset != null 92 ? EditorGUIUtility.TempContent(signalAsset.name) 93 : Styles.EmptySignalList); 94 } 95 } 96 } 97 98 void DrawReactionColumn(Rect rect, int rowIdx) 99 { 100 if (!readonlySignal) 101 { 102 var optionButtonSize = GetOptionButtonSize(); 103 rect.width -= optionButtonSize.x; 104 105 var optionButtonRect = new Rect 106 { 107 x = rect.xMax, 108 y = rect.y, 109 width = optionButtonSize.x, 110 height = optionButtonSize.y 111 }; 112 DrawOptionsButton(optionButtonRect, rowIdx, m_CurrentReceiver); 113 } 114 115 using (new EditorGUI.DisabledScope(!enabled)) 116 { 117 var nameAsString = m_Asset.objectReferenceValue == null ? "Null" : m_Asset.objectReferenceValue.name; 118 using (var change = new EditorGUI.ChangeCheckScope()) 119 { 120 EditorGUI.PropertyField(rect, m_Evt, EditorGUIUtility.TempContent(nameAsString)); 121 if (change.changed) 122 m_TreeView.dirty = true; 123 } 124 } 125 } 126 127 static Vector2 GetOptionButtonSize() 128 { 129 EditorGUIUtility.SetIconSize(Vector2.zero); 130 return EditorStyles.iconButton.CalcSize(EditorGUI.GUIContents.titleSettingsIcon); 131 } 132 133 void DrawOptionsButton(Rect rect, int rowIdx, SignalReceiver target) 134 { 135 GUI.SetNextControlName(SignalOptions); 136 if (EditorGUI.DropdownButton(rect, EditorGUI.GUIContents.titleSettingsIcon, FocusType.Passive, EditorStyles.iconButton)) 137 { 138 var menu = new GenericMenu(); 139 menu.AddItem(new GUIContent(Styles.SignalListDuplicateOption), false, () => 140 { 141 Undo.RecordObject(target, Styles.UndoDuplicateRow); 142 var evtCloner = ScriptableObject.CreateInstance<UnityEventCloner>(); 143 evtCloner.evt = target.GetReactionAtIndex(rowIdx); 144 var clone = Object.Instantiate(evtCloner); 145 target.AddEmptyReaction(clone.evt); 146 m_TreeView.dirty = true; 147 PrefabUtility.RecordPrefabInstancePropertyModifications(target); 148 }); 149 menu.AddItem(new GUIContent(Styles.SignalListDeleteOption), false, () => 150 { 151 Undo.RecordObject(target, Styles.UndoDeleteRow); 152 target.RemoveAtIndex(rowIdx); 153 m_TreeView.dirty = true; 154 PrefabUtility.RecordPrefabInstancePropertyModifications(target); 155 }); 156 menu.ShowAsContext(); 157 } 158 } 159 160 IEnumerable<SignalAsset> ISignalAssetProvider.AvailableSignalAssets() 161 { 162 var ret = SignalManager.assets.Except(m_CurrentReceiver.GetRegisteredSignals()); 163 return signalAsset == null ? ret : ret.Union(new List<SignalAsset> { signalAsset }).ToList(); 164 } 165 166 void ISignalAssetProvider.CreateNewSignalAsset(string path) 167 { 168 var newSignalAsset = SignalManager.CreateSignalAssetInstance(path); 169 Undo.RecordObject(m_CurrentReceiver, Styles.UndoCreateSignalAsset); 170 171 // case 1241170 - overwriting an existing signal with throw an exception. Instead, clear the old key 172 int index = m_CurrentReceiver.GetRegisteredSignals().ToList().IndexOf(newSignalAsset); 173 if (index != -1) 174 m_CurrentReceiver.ChangeSignalAtIndex(index, null); 175 176 m_CurrentReceiver.ChangeSignalAtIndex(m_CurrentRowIdx, newSignalAsset); 177 PrefabUtility.RecordPrefabInstancePropertyModifications(m_CurrentReceiver); 178 } 179 180 class UnityEventCloner : ScriptableObject 181 { 182 public UnityEvent evt; 183 } 184 } 185}