TimelineWindow_HeaderGui.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. using System.Linq;
  2. using UnityEngine;
  3. using UnityEngine.Timeline;
  4. namespace UnityEditor.Timeline
  5. {
  6. partial class TimelineWindow
  7. {
  8. static readonly GUIContent[] k_TimeReferenceGUIContents =
  9. {
  10. EditorGUIUtility.TrTextContent("Local", "Display time based on the current timeline."),
  11. EditorGUIUtility.TrTextContent("Global", "Display time based on the master timeline.")
  12. };
  13. TimelineMarkerHeaderGUI m_MarkerHeaderGUI;
  14. void SequencerHeaderGUI()
  15. {
  16. using (new EditorGUI.DisabledScope(state.editSequence.asset == null))
  17. {
  18. GUILayout.BeginVertical();
  19. {
  20. TransportToolbarGUI();
  21. GUILayout.BeginHorizontal(GUILayout.Width(sequenceHeaderRect.width));
  22. {
  23. if (state.editSequence.asset != null)
  24. {
  25. GUILayout.Space(DirectorStyles.kBaseIndent);
  26. AddButtonGUI();
  27. GUILayout.FlexibleSpace();
  28. EditModeToolbarGUI(currentMode);
  29. ShowMarkersButton();
  30. EditorGUILayout.Space();
  31. }
  32. }
  33. GUILayout.EndHorizontal();
  34. }
  35. GUILayout.EndVertical();
  36. }
  37. }
  38. void MarkerHeaderGUI()
  39. {
  40. var timelineAsset = state.editSequence.asset;
  41. if (timelineAsset == null)
  42. return;
  43. if (m_MarkerHeaderGUI == null)
  44. m_MarkerHeaderGUI = new TimelineMarkerHeaderGUI(timelineAsset, state);
  45. m_MarkerHeaderGUI.Draw(markerHeaderRect, markerContentRect, state);
  46. }
  47. void TransportToolbarGUI()
  48. {
  49. GUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.Width(sequenceHeaderRect.width));
  50. {
  51. using (new EditorGUI.DisabledScope(currentMode.PreviewState(state) == TimelineModeGUIState.Disabled))
  52. {
  53. PreviewModeButtonGUI();
  54. }
  55. using (new EditorGUI.DisabledScope(currentMode.ToolbarState(state) == TimelineModeGUIState.Disabled))
  56. {
  57. GotoBeginingSequenceGUI();
  58. PreviousEventButtonGUI();
  59. PlayButtonGUI();
  60. NextEventButtonGUI();
  61. GotoEndSequenceGUI();
  62. GUILayout.Space(10.0f);
  63. PlayRangeButtonGUI();
  64. GUILayout.FlexibleSpace();
  65. TimeCodeGUI();
  66. ReferenceTimeGUI();
  67. }
  68. }
  69. GUILayout.EndHorizontal();
  70. }
  71. void PreviewModeButtonGUI()
  72. {
  73. EditorGUI.BeginChangeCheck();
  74. var enabled = state.previewMode;
  75. enabled = GUILayout.Toggle(enabled, DirectorStyles.previewContent, EditorStyles.toolbarButton);
  76. if (EditorGUI.EndChangeCheck())
  77. {
  78. // turn off auto play as well, so it doesn't auto reenable
  79. if (!enabled)
  80. {
  81. state.SetPlaying(false);
  82. state.recording = false;
  83. }
  84. state.previewMode = enabled;
  85. // if we are successfully enabled, rebuild the graph so initial states work correctly
  86. // Note: testing both values because previewMode setter can "fail"
  87. if (enabled && state.previewMode)
  88. state.rebuildGraph = true;
  89. }
  90. }
  91. void GotoBeginingSequenceGUI()
  92. {
  93. if (GUILayout.Button(DirectorStyles.gotoBeginingContent, EditorStyles.toolbarButton))
  94. {
  95. state.editSequence.time = 0;
  96. state.EnsurePlayHeadIsVisible();
  97. }
  98. }
  99. // in the editor the play button starts/stops simulation
  100. void PlayButtonGUIEditor()
  101. {
  102. EditorGUI.BeginChangeCheck();
  103. var isPlaying = GUILayout.Toggle(state.playing, DirectorStyles.playContent, EditorStyles.toolbarButton);
  104. if (EditorGUI.EndChangeCheck())
  105. {
  106. state.SetPlaying(isPlaying);
  107. }
  108. }
  109. // in playmode the button reflects the playing state.
  110. // needs to disabled if playing is not possible
  111. void PlayButtonGUIPlayMode()
  112. {
  113. bool buttonEnabled = state.masterSequence.director != null &&
  114. state.masterSequence.director.isActiveAndEnabled;
  115. using (new EditorGUI.DisabledScope(!buttonEnabled))
  116. {
  117. PlayButtonGUIEditor();
  118. }
  119. }
  120. void PlayButtonGUI()
  121. {
  122. if (!Application.isPlaying)
  123. PlayButtonGUIEditor();
  124. else
  125. PlayButtonGUIPlayMode();
  126. }
  127. void NextEventButtonGUI()
  128. {
  129. if (GUILayout.Button(DirectorStyles.nextFrameContent, EditorStyles.toolbarButton))
  130. {
  131. state.referenceSequence.frame += 1;
  132. }
  133. }
  134. void PreviousEventButtonGUI()
  135. {
  136. if (GUILayout.Button(DirectorStyles.previousFrameContent, EditorStyles.toolbarButton))
  137. {
  138. state.referenceSequence.frame -= 1;
  139. }
  140. }
  141. void GotoEndSequenceGUI()
  142. {
  143. if (GUILayout.Button(DirectorStyles.gotoEndContent, EditorStyles.toolbarButton))
  144. {
  145. state.editSequence.time = state.editSequence.asset.duration;
  146. state.EnsurePlayHeadIsVisible();
  147. }
  148. }
  149. void PlayRangeButtonGUI()
  150. {
  151. using (new EditorGUI.DisabledScope(EditorApplication.isPlaying || state.IsEditingASubTimeline()))
  152. {
  153. state.playRangeEnabled = GUILayout.Toggle(state.playRangeEnabled, DirectorStyles.Instance.playrangeContent, EditorStyles.toolbarButton);
  154. }
  155. }
  156. void AddButtonGUI()
  157. {
  158. if (currentMode.trackOptionsState.newButton == TimelineModeGUIState.Hidden)
  159. return;
  160. using (new EditorGUI.DisabledScope(currentMode.trackOptionsState.newButton == TimelineModeGUIState.Disabled))
  161. {
  162. if (EditorGUILayout.DropdownButton(DirectorStyles.newContent, FocusType.Passive, EditorStyles.toolbarPopup))
  163. {
  164. // if there is 1 and only 1 track selected, AND it's a group, add to that group
  165. var groupTracks = SelectionManager.SelectedTracks().ToList();
  166. if (groupTracks.Any(x => x.GetType() != typeof(GroupTrack) || x.lockedInHierarchy))
  167. groupTracks = null;
  168. SequencerContextMenu.ShowNewTracksContextMenu(groupTracks, state, EditorGUILayout.s_LastRect);
  169. }
  170. }
  171. }
  172. void ShowMarkersButton()
  173. {
  174. var asset = state.editSequence.asset;
  175. if (asset == null)
  176. return;
  177. var content = state.showMarkerHeader ? DirectorStyles.showMarkersOn : DirectorStyles.showMarkersOff;
  178. SetShowMarkerHeader(GUILayout.Toggle(state.showMarkerHeader, content, DirectorStyles.Instance.showMarkersBtn));
  179. }
  180. internal void SetShowMarkerHeader(bool newValue)
  181. {
  182. if (state.showMarkerHeader == newValue)
  183. return;
  184. TimelineUndo.PushUndo(state.editSequence.viewModel, "Toggle Show Markers");
  185. state.showMarkerHeader = newValue;
  186. if (!newValue)
  187. {
  188. var asset = state.editSequence.asset;
  189. if (asset != null && asset.markerTrack != null)
  190. {
  191. SelectionManager.Remove(asset.markerTrack);
  192. foreach (var marker in asset.markerTrack.GetMarkers())
  193. {
  194. SelectionManager.Remove(marker);
  195. }
  196. }
  197. }
  198. }
  199. internal void SetShowTrackMarkers(TrackAsset track, bool showMarkerHeader)
  200. {
  201. var currentValue = track.GetShowMarkers();
  202. if (currentValue != showMarkerHeader)
  203. {
  204. TimelineUndo.PushUndo(state.editSequence.viewModel, "Toggle Show Markers");
  205. track.SetShowMarkers(showMarkerHeader);
  206. if (!showMarkerHeader)
  207. {
  208. foreach (var marker in track.GetMarkers())
  209. {
  210. SelectionManager.Remove(marker);
  211. }
  212. }
  213. }
  214. }
  215. static void EditModeToolbarGUI(TimelineMode mode)
  216. {
  217. using (new EditorGUI.DisabledScope(mode.EditModeButtonsState(instance.state) == TimelineModeGUIState.Disabled))
  218. {
  219. var editType = EditMode.editType;
  220. using (var checkScope = new EditorGUI.ChangeCheckScope())
  221. {
  222. var icon = editType == EditMode.EditType.Mix ? DirectorStyles.mixOn : DirectorStyles.mixOff;
  223. GUILayout.Toggle(editType == EditMode.EditType.Mix, icon, DirectorStyles.Instance.editModeBtn);
  224. if (checkScope.changed)
  225. EditMode.editType = EditMode.EditType.Mix;
  226. }
  227. using (var checkScope = new EditorGUI.ChangeCheckScope())
  228. {
  229. var icon = editType == EditMode.EditType.Ripple ? DirectorStyles.rippleOn : DirectorStyles.rippleOff;
  230. GUILayout.Toggle(editType == EditMode.EditType.Ripple, icon, DirectorStyles.Instance.editModeBtn);
  231. if (checkScope.changed)
  232. EditMode.editType = EditMode.EditType.Ripple;
  233. }
  234. using (var checkScope = new EditorGUI.ChangeCheckScope())
  235. {
  236. var icon = editType == EditMode.EditType.Replace ? DirectorStyles.replaceOn : DirectorStyles.replaceOff;
  237. GUILayout.Toggle(editType == EditMode.EditType.Replace, icon, DirectorStyles.Instance.editModeBtn);
  238. if (checkScope.changed)
  239. EditMode.editType = EditMode.EditType.Replace;
  240. }
  241. }
  242. }
  243. // Draws the box to enter the time field
  244. void TimeCodeGUI()
  245. {
  246. EditorGUI.BeginChangeCheck();
  247. var currentTime = state.editSequence.asset != null ? TimeReferenceUtility.ToTimeString(state.editSequence.time, "F1") : "0";
  248. var r = EditorGUILayout.GetControlRect(false, EditorGUI.kSingleLineHeight, EditorStyles.toolbarTextField, GUILayout.MinWidth(WindowConstants.minTimeCodeWidth));
  249. var id = GUIUtility.GetControlID("RenameFieldTextField".GetHashCode(), FocusType.Passive, r);
  250. var newCurrentTime = EditorGUI.DelayedTextFieldInternal(r, id, GUIContent.none, currentTime, null, EditorStyles.toolbarTextField);
  251. if (EditorGUI.EndChangeCheck())
  252. state.editSequence.time = TimeReferenceUtility.FromTimeString(newCurrentTime);
  253. }
  254. void ReferenceTimeGUI()
  255. {
  256. if (!state.IsEditingASubTimeline())
  257. return;
  258. EditorGUI.BeginChangeCheck();
  259. var rect = EditorGUILayout.GetControlRect(false, EditorGUI.kSingleLineHeight, EditorStyles.toolbarButton, GUILayout.Width(WindowConstants.refTimeWidth));
  260. state.timeReferenceMode = (TimeReferenceMode)EditorGUI.CycleButton(rect, (int)state.timeReferenceMode, k_TimeReferenceGUIContents, EditorStyles.toolbarButtonRight);
  261. if (EditorGUI.EndChangeCheck())
  262. OnTimeReferenceModeChanged();
  263. }
  264. void OnTimeReferenceModeChanged()
  265. {
  266. m_TimeAreaDirty = true;
  267. InitTimeAreaFrameRate();
  268. SyncTimeAreaShownRange();
  269. foreach (var inspector in InspectorWindow.GetAllInspectorWindows())
  270. {
  271. inspector.Repaint();
  272. }
  273. }
  274. }
  275. }