summaryrefslogtreecommitdiff
path: root/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Window/TimelineWindow.cs
diff options
context:
space:
mode:
authorAndrew Lee <alee14498@protonmail.com>2020-04-19 17:19:32 -0400
committerAndrew Lee <alee14498@protonmail.com>2020-04-19 17:19:32 -0400
commitc55fba8ab2a1c9d3df65eda4a5a1e957f4aa1f78 (patch)
treeee4d51c7c1d633e11f46453ef1edd3c77c4ef9f7 /Library/PackageCache/com.unity.timeline@1.2.13/Editor/Window/TimelineWindow.cs
downloadProject-Sandbox-c55fba8ab2a1c9d3df65eda4a5a1e957f4aa1f78.tar.gz
Project-Sandbox-c55fba8ab2a1c9d3df65eda4a5a1e957f4aa1f78.tar.bz2
Project-Sandbox-c55fba8ab2a1c9d3df65eda4a5a1e957f4aa1f78.zip
Inital commit
Diffstat (limited to 'Library/PackageCache/com.unity.timeline@1.2.13/Editor/Window/TimelineWindow.cs')
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Window/TimelineWindow.cs541
1 files changed, 541 insertions, 0 deletions
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Window/TimelineWindow.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Window/TimelineWindow.cs
new file mode 100644
index 0000000..e3e21bc
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Window/TimelineWindow.cs
@@ -0,0 +1,541 @@
+using System;
+using System.Collections.Generic;
+using UnityEditor.Callbacks;
+using UnityEngine;
+using UnityEngine.Events;
+using UnityEngine.Playables;
+using UnityEngine.SceneManagement;
+using UnityEngine.Timeline;
+
+namespace UnityEditor.Timeline
+{
+ [EditorWindowTitle(title = "Timeline", useTypeNameAsIconName = true)]
+ partial class TimelineWindow : EditorWindow, IHasCustomMenu
+ {
+ [Serializable]
+ public class TimelineWindowPreferences
+ {
+ public bool frameSnap = true;
+ public bool edgeSnaps = true;
+ public bool muteAudioScrub = true;
+ public bool playRangeLoopMode = true;
+ public PlaybackScrollMode autoScrollMode;
+ public EditMode.EditType editType = EditMode.EditType.Mix;
+ public TimeReferenceMode timeReferenceMode = TimeReferenceMode.Local;
+ }
+
+ [SerializeField] TimelineWindowPreferences m_Preferences = new TimelineWindowPreferences();
+ public TimelineWindowPreferences preferences { get { return m_Preferences; } }
+
+ [SerializeField]
+ EditorGUIUtility.EditorLockTracker m_LockTracker = new EditorGUIUtility.EditorLockTracker();
+
+ readonly PreviewResizer m_PreviewResizer = new PreviewResizer();
+ bool m_LastFrameHadSequence;
+ bool m_ForceRefreshLastSelection;
+ int m_CurrentSceneHashCode = -1;
+
+ [NonSerialized]
+ bool m_HasBeenInitialized;
+
+ [SerializeField]
+ SequenceHierarchy m_SequenceHierarchy;
+ static SequenceHierarchy s_LastHierarchy;
+
+ public static TimelineWindow instance { get; private set; }
+ public Rect clientArea { get; set; }
+ public bool isDragging { get; set; }
+ public static DirectorStyles styles { get { return DirectorStyles.Instance; } }
+ public List<TimelineTrackBaseGUI> allTracks
+ {
+ get
+ {
+ return treeView != null ? treeView.allTrackGuis : new List<TimelineTrackBaseGUI>();
+ }
+ }
+
+ public WindowState state { get; private set; }
+
+ public bool locked
+ {
+ get
+ {
+ // we can never be in a locked state if there is no timeline asset
+ if (state.editSequence.asset == null)
+ return false;
+
+ return m_LockTracker.isLocked;
+ }
+ set { m_LockTracker.isLocked = value; }
+ }
+
+ public bool hierarchyChangedThisFrame { get; private set; }
+
+ public TimelineWindow()
+ {
+ InitializeManipulators();
+ m_LockTracker.lockStateChanged.AddPersistentListener(OnLockStateChanged, UnityEventCallState.EditorAndRuntime);
+ }
+
+ void OnLockStateChanged(bool locked)
+ {
+ // Make sure that upon unlocking, any selection change is updated
+ // Case 1123119 -- only force rebuild if not recording
+ if (!locked)
+ RefreshSelection(state != null && !state.recording);
+ }
+
+ void OnEnable()
+ {
+ if (m_SequencePath == null)
+ m_SequencePath = new SequencePath();
+
+ if (m_SequenceHierarchy == null)
+ {
+ // The sequence hierarchy will become null if maximize on play is used for in/out of playmode
+ // a static var will hang on to the reference
+ if (s_LastHierarchy != null)
+ m_SequenceHierarchy = s_LastHierarchy;
+ else
+ m_SequenceHierarchy = SequenceHierarchy.CreateInstance();
+
+ state = null;
+ }
+ s_LastHierarchy = m_SequenceHierarchy;
+
+ titleContent = GetLocalizedTitleContent();
+
+ m_PreviewResizer.Init("TimelineWindow");
+
+ // Unmaximize fix : when unmaximizing, a new window is enabled and disabled. Prevent it from overriding the instance pointer.
+ if (instance == null)
+ instance = this;
+
+ AnimationClipCurveCache.Instance.OnEnable();
+ TrackAsset.OnClipPlayableCreate += m_PlayableLookup.UpdatePlayableLookup;
+ TrackAsset.OnTrackAnimationPlayableCreate += m_PlayableLookup.UpdatePlayableLookup;
+
+ if (state == null)
+ {
+ state = new WindowState(this, s_LastHierarchy);
+ Initialize();
+ RefreshSelection(true);
+ m_ForceRefreshLastSelection = true;
+ }
+ }
+
+ void OnDisable()
+ {
+ if (instance == this)
+ instance = null;
+
+ if (state != null)
+ state.Reset();
+
+ if (instance == null)
+ SelectionManager.RemoveTimelineSelection();
+
+ AnimationClipCurveCache.Instance.OnDisable();
+ TrackAsset.OnClipPlayableCreate -= m_PlayableLookup.UpdatePlayableLookup;
+ TrackAsset.OnTrackAnimationPlayableCreate -= m_PlayableLookup.UpdatePlayableLookup;
+ TimelineWindowViewPrefs.SaveAll();
+ TimelineWindowViewPrefs.UnloadAllViewModels();
+ }
+
+ void OnDestroy()
+ {
+ if (state != null)
+ {
+ state.OnDestroy();
+ }
+ m_HasBeenInitialized = false;
+ RemoveEditorCallbacks();
+ AnimationClipCurveCache.Instance.Clear();
+ TimelineAnimationUtilities.UnlinkAnimationWindow();
+ }
+
+ void OnLostFocus()
+ {
+ isDragging = false;
+
+ if (state != null)
+ state.captured.Clear();
+
+ Repaint();
+ }
+
+ void OnFocus()
+ {
+ if (state == null) return;
+
+ if (lastSelectedGO != Selection.activeObject)
+ {
+ // selection may have changed while Timeline Editor was looking away
+ RefreshSelection(false);
+
+ // Inline curves may have become out of sync
+ RefreshInlineCurves();
+ }
+ }
+
+ void OnHierarchyChange()
+ {
+ hierarchyChangedThisFrame = true;
+ Repaint();
+ }
+
+ void OnStateChange()
+ {
+ state.UpdateRecordingState();
+ if (treeView != null && state.editSequence.asset != null)
+ treeView.Reload();
+ if (m_MarkerHeaderGUI != null)
+ m_MarkerHeaderGUI.Rebuild();
+ }
+
+ void OnGUI()
+ {
+ InitializeGUIIfRequired();
+ UpdateGUIConstants();
+ UpdateViewStateHash();
+
+ EditMode.HandleModeClutch(); // TODO We Want that here?
+
+ DetectStylesChange();
+ DetectActiveSceneChanges();
+ DetectStateChanges();
+
+ state.ProcessStartFramePendingUpdates();
+
+ var clipRect = new Rect(0.0f, 0.0f, position.width, position.height);
+ clipRect.xMin += state.sequencerHeaderWidth;
+
+ using (new GUIViewportScope(clipRect))
+ state.InvokeWindowOnGuiStarted(Event.current);
+
+ if (Event.current.type == EventType.MouseDrag && state != null && state.mouseDragLag > 0.0f)
+ {
+ state.mouseDragLag -= Time.deltaTime;
+ return;
+ }
+
+ if (PerformUndo())
+ return;
+
+ if (EditorApplication.isPlaying)
+ {
+ if (state != null)
+ {
+ if (state.recording)
+ state.recording = false;
+ }
+ Repaint();
+ }
+
+ clientArea = position;
+
+ PlaybackScroller.AutoScroll(state);
+ DoLayout();
+
+ // overlays
+ if (state.captured.Count > 0)
+ {
+ using (new GUIViewportScope(clipRect))
+ {
+ foreach (var o in state.captured)
+ {
+ o.Overlay(Event.current, state);
+ }
+ Repaint();
+ }
+ }
+
+ if (state.showQuadTree)
+ state.spacePartitioner.DebugDraw();
+
+ // attempt another rebuild -- this will avoid 1 frame flashes
+ if (Event.current.type == EventType.Repaint)
+ {
+ RebuildGraphIfNecessary();
+ state.ProcessEndFramePendingUpdates();
+ }
+
+ using (new GUIViewportScope(clipRect))
+ {
+ if (Event.current.type == EventType.Repaint)
+ EditMode.inputHandler.OnGUI(state, Event.current);
+ }
+
+ if (Event.current.type == EventType.Repaint)
+ hierarchyChangedThisFrame = false;
+ }
+
+ static void DetectStylesChange()
+ {
+ DirectorStyles.ReloadStylesIfNeeded();
+ }
+
+ void DetectActiveSceneChanges()
+ {
+ if (m_CurrentSceneHashCode == -1)
+ {
+ m_CurrentSceneHashCode = SceneManager.GetActiveScene().GetHashCode();
+ }
+
+ if (m_CurrentSceneHashCode != SceneManager.GetActiveScene().GetHashCode())
+ {
+ bool isSceneStillLoaded = false;
+ for (int a = 0; a < SceneManager.sceneCount; a++)
+ {
+ var scene = SceneManager.GetSceneAt(a);
+ if (scene.GetHashCode() == m_CurrentSceneHashCode && scene.isLoaded)
+ {
+ isSceneStillLoaded = true;
+ break;
+ }
+ }
+
+ if (!isSceneStillLoaded)
+ {
+ if (!locked)
+ ClearCurrentTimeline();
+ m_CurrentSceneHashCode = SceneManager.GetActiveScene().GetHashCode();
+ }
+ }
+ }
+
+ void DetectStateChanges()
+ {
+ if (state != null)
+ {
+ state.editSequence.ResetIsReadOnly(); //Force reset readonly for asset flag for each frame.
+ // detect if the sequence was removed under our feet
+ if (m_LastFrameHadSequence && state.editSequence.asset == null)
+ {
+ ClearCurrentTimeline();
+ }
+ m_LastFrameHadSequence = state.editSequence.asset != null;
+
+ // the currentDirector can get set to null by a deletion or scene unloading so polling is required
+ if (state.editSequence.director == null)
+ {
+ state.recording = false;
+ state.previewMode = false;
+
+ //Case 1201405 : Check if the lock state is valid with the lock tracker state
+ if (locked != m_LockTracker.isLocked)
+ m_LockTracker.isLocked = locked;
+
+ if (!locked && m_LastFrameHadSequence)
+ {
+ // the user may be adding a new PlayableDirector to a selected GameObject, make sure the timeline editor is shows the proper director if none is already showing
+ var selectedGameObject = Selection.activeObject != null ? Selection.activeObject as GameObject : null;
+ var selectedDirector = selectedGameObject != null ? selectedGameObject.GetComponent<PlayableDirector>() : null;
+ if (selectedDirector != null)
+ {
+ SetCurrentTimeline(selectedDirector);
+ }
+ }
+ }
+ else
+ {
+ // the user may have changed the timeline associated with the current director
+ if (state.editSequence.asset != state.editSequence.director.playableAsset)
+ {
+ if (!locked)
+ {
+ SetCurrentTimeline(state.editSequence.director);
+ }
+ else
+ {
+ // Keep locked on the current timeline but set the current director to null since it's not the timeline owner anymore
+ SetCurrentTimeline(state.editSequence.asset);
+ }
+ }
+ }
+ }
+ }
+
+ void Initialize()
+ {
+ if (!m_HasBeenInitialized)
+ {
+ InitializeStateChange();
+ InitializeEditorCallbacks();
+ m_HasBeenInitialized = true;
+ }
+ }
+
+ void RefreshLastSelectionIfRequired()
+ {
+ // case 1088918 - workaround for the instanceID to object cache being update during Awake.
+ // This corrects any playableDirector ptrs with the correct cached version
+ // This can happen when going from edit to playmode
+ if (m_ForceRefreshLastSelection)
+ {
+ m_ForceRefreshLastSelection = false;
+ RestoreLastSelection(true);
+ }
+ }
+
+ void InitializeGUIIfRequired()
+ {
+ RefreshLastSelectionIfRequired();
+ InitializeTimeArea();
+ if (treeView == null && state.editSequence.asset != null)
+ {
+ treeView = new TimelineTreeViewGUI(this, state.editSequence.asset, position);
+ }
+ }
+
+ void UpdateGUIConstants()
+ {
+ m_HorizontalScrollBarSize =
+ GUI.skin.horizontalScrollbar.fixedHeight + GUI.skin.horizontalScrollbar.margin.top;
+ m_VerticalScrollBarSize = (treeView != null && treeView.showingVerticalScrollBar)
+ ? GUI.skin.verticalScrollbar.fixedWidth + GUI.skin.verticalScrollbar.margin.left
+ : 0;
+ }
+
+ void UpdateViewStateHash()
+ {
+ if (Event.current.type == EventType.Layout)
+ state.UpdateViewStateHash();
+ }
+
+ static bool PerformUndo()
+ {
+ if (!Event.current.isKey)
+ return false;
+
+ if (Event.current.keyCode != KeyCode.Z)
+ return false;
+
+ if (!EditorGUI.actionKey)
+ return false;
+
+ return true;
+ }
+
+ public void RebuildGraphIfNecessary(bool evaluate = true)
+ {
+ if (state == null || state.editSequence.director == null || state.editSequence.asset == null)
+ return;
+
+ if (state.rebuildGraph)
+ {
+ // rebuilding the graph resets the time
+ double time = state.editSequence.time;
+
+ var wasPlaying = false;
+
+ // disable preview mode,
+ if (!EditorApplication.isPlaying)
+ {
+ wasPlaying = state.playing;
+
+ state.previewMode = false;
+ state.GatherProperties(state.masterSequence.director);
+ }
+ state.RebuildPlayableGraph();
+ state.editSequence.time = time;
+
+ if (wasPlaying)
+ state.Play();
+
+ if (evaluate)
+ {
+ // put the scene back in the correct state
+ state.EvaluateImmediate();
+
+ // this is necessary to see accurate results when inspector refreshes
+ // case 1154802 - this will property re-force time on the director, so
+ // the play head won't snap back to the timeline duration on rebuilds
+ if (!state.playing)
+ state.Evaluate();
+ }
+ Repaint();
+ }
+
+ state.rebuildGraph = false;
+ }
+
+ // for tests
+ public new void RepaintImmediately()
+ {
+ base.RepaintImmediately();
+ }
+
+ internal static bool IsEditingTimelineAsset(TimelineAsset timelineAsset)
+ {
+ return instance != null && instance.state != null && instance.state.editSequence.asset == timelineAsset;
+ }
+
+ internal static void RepaintIfEditingTimelineAsset(TimelineAsset timelineAsset)
+ {
+ if (IsEditingTimelineAsset(timelineAsset))
+ instance.Repaint();
+ }
+
+ internal class DoCreateTimeline : ProjectWindowCallback.EndNameEditAction
+ {
+ public override void Action(int instanceId, string pathName, string resourceFile)
+ {
+ var timeline = ScriptableObject.CreateInstance<TimelineAsset>();
+ AssetDatabase.CreateAsset(timeline, pathName);
+ ProjectWindowUtil.ShowCreatedAsset(timeline);
+ }
+ }
+
+ [MenuItem("Assets/Create/Timeline", false, 450)]
+ public static void CreateNewTimeline()
+ {
+ var icon = EditorGUIUtility.IconContent("TimelineAsset Icon").image as Texture2D;
+ ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, ScriptableObject.CreateInstance<DoCreateTimeline>(), "New Timeline.playable", icon, null);
+ }
+
+ [MenuItem("Window/Sequencing/Timeline", false, 1)]
+ public static void ShowWindow()
+ {
+ GetWindow<TimelineWindow>(typeof(SceneView));
+ instance.Focus();
+ }
+
+ [OnOpenAsset(1)]
+ public static bool OnDoubleClick(int instanceID, int line)
+ {
+ var assetDoubleClicked = EditorUtility.InstanceIDToObject(instanceID) as TimelineAsset;
+ if (assetDoubleClicked == null)
+ return false;
+
+ ShowWindow();
+ instance.SetCurrentTimeline(assetDoubleClicked);
+
+ return true;
+ }
+
+ public virtual void AddItemsToMenu(GenericMenu menu)
+ {
+ bool disabled = state == null || state.editSequence.asset == null;
+
+ m_LockTracker.AddItemsToMenu(menu, disabled);
+ }
+
+ protected virtual void ShowButton(Rect r)
+ {
+ bool disabled = state == null || state.editSequence.asset == null;
+
+ m_LockTracker.ShowButton(r, DirectorStyles.Instance.lockButton, disabled);
+ }
+
+ internal void TreeViewKeyboardCallback()
+ {
+ if (Event.current.type != EventType.KeyDown)
+ return;
+ if (TimelineAction.HandleShortcut(state, Event.current))
+ {
+ Event.current.Use();
+ }
+ }
+ }
+}