290 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			290 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using System.Linq; | ||
|  | using UnityEngine; | ||
|  | using UnityEngine.Timeline; | ||
|  | 
 | ||
|  | namespace UnityEditor.Timeline | ||
|  | { | ||
|  |     partial class TimelineWindow | ||
|  |     { | ||
|  |         static readonly GUIContent[] k_TimeReferenceGUIContents = | ||
|  |         { | ||
|  |             L10n.TextContent("Local", "Display time based on the current timeline."), | ||
|  |             L10n.TextContent("Global", "Display time based on the master timeline.") | ||
|  |         }; | ||
|  | 
 | ||
|  |         TimelineMarkerHeaderGUI m_MarkerHeaderGUI; | ||
|  | 
 | ||
|  |         void MarkerHeaderGUI() | ||
|  |         { | ||
|  |             var timelineAsset = state.editSequence.asset; | ||
|  |             if (timelineAsset == null) | ||
|  |                 return; | ||
|  | 
 | ||
|  |             if (m_MarkerHeaderGUI == null) | ||
|  |                 m_MarkerHeaderGUI = new TimelineMarkerHeaderGUI(timelineAsset, state); | ||
|  |             m_MarkerHeaderGUI.Draw(markerHeaderRect, markerContentRect, state); | ||
|  |         } | ||
|  | 
 | ||
|  |         void DrawTransportToolbar() | ||
|  |         { | ||
|  |             using (new EditorGUI.DisabledScope(currentMode.PreviewState(state) == TimelineModeGUIState.Disabled)) | ||
|  |             { | ||
|  |                 PreviewModeButtonGUI(); | ||
|  |             } | ||
|  | 
 | ||
|  |             using (new EditorGUI.DisabledScope(currentMode.ToolbarState(state) == TimelineModeGUIState.Disabled)) | ||
|  |             { | ||
|  |                 GotoBeginingSequenceGUI(); | ||
|  |                 PreviousEventButtonGUI(); | ||
|  |                 PlayButtonGUI(); | ||
|  |                 NextEventButtonGUI(); | ||
|  |                 GotoEndSequenceGUI(); | ||
|  |                 PlayRangeButtonGUI(); | ||
|  |                 TimeCodeGUI(); | ||
|  |                 ReferenceTimeGUI(); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         void PreviewModeButtonGUI() | ||
|  |         { | ||
|  |             if (state.ignorePreview && !Application.isPlaying) | ||
|  |             { | ||
|  |                 GUILayout.Label(DirectorStyles.previewDisabledContent, DirectorStyles.Instance.previewButtonDisabled); | ||
|  |                 return; | ||
|  |             } | ||
|  | 
 | ||
|  |             EditorGUI.BeginChangeCheck(); | ||
|  |             var enabled = state.previewMode; | ||
|  |             enabled = GUILayout.Toggle(enabled, DirectorStyles.previewContent, EditorStyles.toolbarButton); | ||
|  |             if (EditorGUI.EndChangeCheck()) | ||
|  |             { | ||
|  |                 // turn off auto play as well, so it doesn't auto reenable | ||
|  |                 if (!enabled) | ||
|  |                 { | ||
|  |                     state.SetPlaying(false); | ||
|  |                     state.recording = false; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 state.previewMode = enabled; | ||
|  | 
 | ||
|  |                 // if we are successfully enabled, rebuild the graph so initial states work correctly | ||
|  |                 // Note: testing both values because previewMode setter can "fail" | ||
|  |                 if (enabled && state.previewMode) | ||
|  |                     state.rebuildGraph = true; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         void GotoBeginingSequenceGUI() | ||
|  |         { | ||
|  |             if (GUILayout.Button(DirectorStyles.gotoBeginingContent, EditorStyles.toolbarButton)) | ||
|  |             { | ||
|  |                 state.editSequence.time = 0; | ||
|  |                 state.EnsurePlayHeadIsVisible(); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // in the editor the play button starts/stops simulation | ||
|  |         void PlayButtonGUIEditor() | ||
|  |         { | ||
|  |             EditorGUI.BeginChangeCheck(); | ||
|  |             var isPlaying = GUILayout.Toggle(state.playing, DirectorStyles.playContent, EditorStyles.toolbarButton); | ||
|  |             if (EditorGUI.EndChangeCheck()) | ||
|  |             { | ||
|  |                 state.SetPlaying(isPlaying); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // in playmode the button reflects the playing state. | ||
|  |         //  needs to disabled if playing is not possible | ||
|  |         void PlayButtonGUIPlayMode() | ||
|  |         { | ||
|  |             bool buttonEnabled = state.masterSequence.director != null && | ||
|  |                 state.masterSequence.director.isActiveAndEnabled; | ||
|  |             using (new EditorGUI.DisabledScope(!buttonEnabled)) | ||
|  |             { | ||
|  |                 PlayButtonGUIEditor(); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         void PlayButtonGUI() | ||
|  |         { | ||
|  |             if (!Application.isPlaying) | ||
|  |                 PlayButtonGUIEditor(); | ||
|  |             else | ||
|  |                 PlayButtonGUIPlayMode(); | ||
|  |         } | ||
|  | 
 | ||
|  |         void NextEventButtonGUI() | ||
|  |         { | ||
|  |             if (GUILayout.Button(DirectorStyles.nextFrameContent, EditorStyles.toolbarButton)) | ||
|  |             { | ||
|  |                 state.referenceSequence.frame += 1; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         void PreviousEventButtonGUI() | ||
|  |         { | ||
|  |             if (GUILayout.Button(DirectorStyles.previousFrameContent, EditorStyles.toolbarButton)) | ||
|  |             { | ||
|  |                 state.referenceSequence.frame -= 1; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         void GotoEndSequenceGUI() | ||
|  |         { | ||
|  |             if (GUILayout.Button(DirectorStyles.gotoEndContent, EditorStyles.toolbarButton)) | ||
|  |             { | ||
|  |                 state.editSequence.time = state.editSequence.asset.duration; | ||
|  |                 state.EnsurePlayHeadIsVisible(); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         void PlayRangeButtonGUI() | ||
|  |         { | ||
|  |             using (new EditorGUI.DisabledScope(state.ignorePreview || state.IsEditingASubTimeline())) | ||
|  |             { | ||
|  |                 state.playRangeEnabled = GUILayout.Toggle(state.playRangeEnabled, DirectorStyles.Instance.playrangeContent, EditorStyles.toolbarButton); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         void AddButtonGUI() | ||
|  |         { | ||
|  |             if (currentMode.trackOptionsState.newButton == TimelineModeGUIState.Hidden) | ||
|  |                 return; | ||
|  | 
 | ||
|  |             using (new EditorGUI.DisabledScope(currentMode.trackOptionsState.newButton == TimelineModeGUIState.Disabled)) | ||
|  |             { | ||
|  |                 if (EditorGUILayout.DropdownButton(DirectorStyles.newContent, FocusType.Passive, EditorStyles.toolbarPopup)) | ||
|  |                 { | ||
|  |                     // if there is 1 and only 1 track selected, AND it's a group, add to that group | ||
|  |                     var groupTracks = SelectionManager.SelectedTracks().ToList(); | ||
|  |                     if (groupTracks.Any(x => x.GetType() != typeof(GroupTrack) || x.lockedInHierarchy)) | ||
|  |                         groupTracks = null; | ||
|  | 
 | ||
|  |                     SequencerContextMenu.ShowNewTracksContextMenu(groupTracks, state, EditorGUILayout.s_LastRect); | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         void ShowMarkersButton() | ||
|  |         { | ||
|  |             var asset = state.editSequence.asset; | ||
|  |             if (asset == null) | ||
|  |                 return; | ||
|  | 
 | ||
|  |             var content = state.showMarkerHeader ? DirectorStyles.showMarkersOn : DirectorStyles.showMarkersOff; | ||
|  |             SetShowMarkerHeader(GUILayout.Toggle(state.showMarkerHeader, content, DirectorStyles.Instance.showMarkersBtn)); | ||
|  |         } | ||
|  | 
 | ||
|  |         internal void SetShowMarkerHeader(bool newValue) | ||
|  |         { | ||
|  |             TimelineAsset asset = state.editSequence.asset; | ||
|  |             if (state.showMarkerHeader == newValue || asset == null) | ||
|  |                 return; | ||
|  | 
 | ||
|  |             string undoOperation = L10n.Tr("Toggle Show Markers"); | ||
|  |             if (newValue) | ||
|  |             { | ||
|  |                 //Create the marker track if it does not exist | ||
|  |                 TimelineUndo.PushUndo(asset, undoOperation); | ||
|  |                 asset.CreateMarkerTrack(); | ||
|  |             } | ||
|  |             else | ||
|  |             { | ||
|  |                 SelectionManager.Remove(asset.markerTrack); | ||
|  | 
 | ||
|  |                 if (asset.markerTrack != null && asset.markerTrack.isEmpty) | ||
|  |                 { | ||
|  |                     TimelineUndo.PushUndo(asset, undoOperation); | ||
|  |                     asset.RemoveMarkerTrack(); | ||
|  |                 } | ||
|  |             } | ||
|  | 
 | ||
|  |             if (asset.markerTrack != null) | ||
|  |             { | ||
|  |                 asset.markerTrack.SetShowTrackMarkers(newValue); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         static void EditModeToolbarGUI(TimelineMode mode) | ||
|  |         { | ||
|  |             using (new EditorGUI.DisabledScope(mode.EditModeButtonsState(instance.state) == TimelineModeGUIState.Disabled)) | ||
|  |             { | ||
|  |                 var editType = EditMode.editType; | ||
|  | 
 | ||
|  |                 EditorGUI.BeginChangeCheck(); | ||
|  |                 var mixIcon = editType == EditMode.EditType.Mix ? DirectorStyles.mixOn : DirectorStyles.mixOff; | ||
|  |                 GUILayout.Toggle(editType == EditMode.EditType.Mix, mixIcon, DirectorStyles.Instance.editModeBtn); | ||
|  |                 if (EditorGUI.EndChangeCheck()) | ||
|  |                     EditMode.editType = EditMode.EditType.Mix; | ||
|  | 
 | ||
|  |                 EditorGUI.BeginChangeCheck(); | ||
|  |                 var rippleIcon = editType == EditMode.EditType.Ripple ? DirectorStyles.rippleOn : DirectorStyles.rippleOff; | ||
|  |                 GUILayout.Toggle(editType == EditMode.EditType.Ripple, rippleIcon, DirectorStyles.Instance.editModeBtn); | ||
|  |                 if (EditorGUI.EndChangeCheck()) | ||
|  |                     EditMode.editType = EditMode.EditType.Ripple; | ||
|  | 
 | ||
|  |                 EditorGUI.BeginChangeCheck(); | ||
|  |                 var replaceIcon = editType == EditMode.EditType.Replace ? DirectorStyles.replaceOn : DirectorStyles.replaceOff; | ||
|  |                 GUILayout.Toggle(editType == EditMode.EditType.Replace, replaceIcon, DirectorStyles.Instance.editModeBtn); | ||
|  |                 if (EditorGUI.EndChangeCheck()) | ||
|  |                     EditMode.editType = EditMode.EditType.Replace; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // Draws the box to enter the time field | ||
|  |         void TimeCodeGUI() | ||
|  |         { | ||
|  |             const string timeFieldHint = "TimelineWindow-TimeCodeGUI"; | ||
|  | 
 | ||
|  |             EditorGUI.BeginChangeCheck(); | ||
|  |             var currentTime = state.editSequence.asset != null ? TimeReferenceUtility.ToTimeString(state.editSequence.time, "0.####") : "0"; | ||
|  |             var r = EditorGUILayout.GetControlRect(false, EditorGUI.kSingleLineHeight, EditorStyles.toolbarTextField, GUILayout.Width(WindowConstants.timeCodeWidth)); | ||
|  |             var id = GUIUtility.GetControlID(timeFieldHint.GetHashCode(), FocusType.Keyboard, r); | ||
|  |             var newCurrentTime = EditorGUI.DelayedTextFieldInternal(r, id, GUIContent.none, currentTime, null, EditorStyles.toolbarTextField); | ||
|  | 
 | ||
|  |             if (EditorGUI.EndChangeCheck()) | ||
|  |                 state.editSequence.time = TimeReferenceUtility.FromTimeString(newCurrentTime); | ||
|  |         } | ||
|  | 
 | ||
|  |         void ReferenceTimeGUI() | ||
|  |         { | ||
|  |             if (!state.IsEditingASubTimeline()) | ||
|  |                 return; | ||
|  | 
 | ||
|  |             EditorGUI.BeginChangeCheck(); | ||
|  |             state.timeReferenceMode = (TimeReferenceMode)EditorGUILayout.CycleButton((int)state.timeReferenceMode, k_TimeReferenceGUIContents, DirectorStyles.Instance.timeReferenceButton); | ||
|  |             if (EditorGUI.EndChangeCheck()) | ||
|  |                 OnTimeReferenceModeChanged(); | ||
|  |         } | ||
|  | 
 | ||
|  |         void OnTimeReferenceModeChanged() | ||
|  |         { | ||
|  |             m_TimeAreaDirty = true; | ||
|  |             InitTimeAreaFrameRate(); | ||
|  |             SyncTimeAreaShownRange(); | ||
|  | 
 | ||
|  |             foreach (var inspector in InspectorWindow.GetAllInspectorWindows()) | ||
|  |             { | ||
|  |                 inspector.Repaint(); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         void DrawHeaderEditButtons() | ||
|  |         { | ||
|  |             if (state.editSequence.asset == null) | ||
|  |                 return; | ||
|  | 
 | ||
|  |             using (new GUILayout.HorizontalScope(EditorStyles.toolbar, GUILayout.Width(sequenceHeaderRect.width))) | ||
|  |             { | ||
|  |                 GUILayout.Space(DirectorStyles.kBaseIndent); | ||
|  |                 AddButtonGUI(); | ||
|  |                 GUILayout.FlexibleSpace(); | ||
|  |                 EditModeToolbarGUI(currentMode); | ||
|  |                 ShowMarkersButton(); | ||
|  |                 EditorGUILayout.Space(); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | } |