SignalReceiverItem.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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.RegisterCompleteObjectUndo(m_CurrentReceiver, Styles.UndoCreateSignalAsset);
  39. m_CurrentReceiver.ChangeSignalAtIndex(m_CurrentRowIdx, value);
  40. }
  41. }
  42. public float GetHeight()
  43. {
  44. return k_EvtDrawer.GetPropertyHeight(m_Evt, GUIContent.none);
  45. }
  46. public void Draw(Rect rect, int colIdx, int rowIdx, float padding, SignalReceiver target)
  47. {
  48. switch (colIdx)
  49. {
  50. case 0:
  51. DrawSignalNameColumn(rect, padding, target, rowIdx);
  52. break;
  53. case 1:
  54. DrawReactionColumn(rect, rowIdx);
  55. break;
  56. default:
  57. throw new ArgumentOutOfRangeException();
  58. }
  59. }
  60. void DrawSignalNameColumn(Rect rect, float padding, SignalReceiver target, int rowIdx)
  61. {
  62. using (new EditorGUI.DisabledScope(!enabled))
  63. {
  64. if (!readonlySignal)
  65. {
  66. m_CurrentRowIdx = rowIdx;
  67. m_CurrentReceiver = target;
  68. rect.x += padding;
  69. rect.width -= padding;
  70. rect.height = EditorGUIUtility.singleLineHeight;
  71. GUI.SetNextControlName(SignalName);
  72. SignalUtility.DrawSignalNames(this, rect, GUIContent.none, false);
  73. }
  74. else
  75. {
  76. GUI.SetNextControlName(SignalNameReadOnly);
  77. var signalAsset = m_Asset.objectReferenceValue;
  78. GUI.Label(rect,
  79. signalAsset != null
  80. ? EditorGUIUtility.TempContent(signalAsset.name)
  81. : Styles.EmptySignalList);
  82. }
  83. }
  84. }
  85. void DrawReactionColumn(Rect rect, int rowIdx)
  86. {
  87. if (!readonlySignal)
  88. {
  89. var optionButtonSize = GetOptionButtonSize();
  90. rect.width -= optionButtonSize.x;
  91. var optionButtonRect = new Rect
  92. {
  93. x = rect.xMax,
  94. y = rect.y,
  95. width = optionButtonSize.x,
  96. height = optionButtonSize.y
  97. };
  98. DrawOptionsButton(optionButtonRect, rowIdx, m_CurrentReceiver);
  99. }
  100. using (new EditorGUI.DisabledScope(!enabled))
  101. {
  102. var nameAsString = m_Asset.objectReferenceValue == null ? "Null" : m_Asset.objectReferenceValue.name;
  103. using (var change = new EditorGUI.ChangeCheckScope())
  104. {
  105. EditorGUI.PropertyField(rect, m_Evt, EditorGUIUtility.TempContent(nameAsString));
  106. if (change.changed)
  107. m_TreeView.dirty = true;
  108. }
  109. }
  110. }
  111. static Vector2 GetOptionButtonSize()
  112. {
  113. EditorGUIUtility.SetIconSize(Vector2.zero);
  114. return EditorStyles.iconButton.CalcSize(EditorGUI.GUIContents.titleSettingsIcon);
  115. }
  116. void DrawOptionsButton(Rect rect, int rowIdx, SignalReceiver target)
  117. {
  118. GUI.SetNextControlName(SignalOptions);
  119. if (EditorGUI.DropdownButton(rect, EditorGUI.GUIContents.titleSettingsIcon, FocusType.Passive, EditorStyles.iconButton))
  120. {
  121. var menu = new GenericMenu();
  122. menu.AddItem(new GUIContent(Styles.SignalListDuplicateOption), false, () =>
  123. {
  124. Undo.RegisterCompleteObjectUndo(target, "Duplicate Row");
  125. var evtCloner = ScriptableObject.CreateInstance<UnityEventCloner>();
  126. evtCloner.evt = target.GetReactionAtIndex(rowIdx);
  127. var clone = Object.Instantiate(evtCloner);
  128. target.AddEmptyReaction(clone.evt);
  129. m_TreeView.dirty = true;
  130. });
  131. menu.AddItem(new GUIContent(Styles.SignalListDeleteOption), false, () =>
  132. {
  133. Undo.RegisterCompleteObjectUndo(target, "Delete Row");
  134. target.RemoveAtIndex(rowIdx);
  135. m_TreeView.dirty = true;
  136. });
  137. menu.ShowAsContext();
  138. }
  139. }
  140. IEnumerable<SignalAsset> ISignalAssetProvider.AvailableSignalAssets()
  141. {
  142. var ret = SignalManager.assets.Except(m_CurrentReceiver.GetRegisteredSignals());
  143. return signalAsset == null ? ret : ret.Union(new List<SignalAsset> {signalAsset}).ToList();
  144. }
  145. void ISignalAssetProvider.CreateNewSignalAsset(string path)
  146. {
  147. var newSignalAsset = SignalManager.CreateSignalAssetInstance(path);
  148. m_CurrentReceiver.ChangeSignalAtIndex(m_CurrentRowIdx, newSignalAsset);
  149. }
  150. class UnityEventCloner : ScriptableObject
  151. {
  152. public UnityEvent evt;
  153. }
  154. }
  155. }