SignalReceiverItem.cs 6.8 KB

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