| using System; |
| using System.Collections.Generic; |
| using System.Linq; |
| using UnityEngine; |
| using UnityEngine.Timeline; |
|
|
| namespace UnityEditor.Timeline |
| { |
| partial class TimelineWindow |
| { |
| |
| |
| |
| public override TimelineNavigator navigator => new TimelineNavigator(this); |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| internal class TimelineNavigatorImpl |
| { |
| |
| |
| |
| |
| public TimelineNavigatorImpl(IWindowStateProvider window) |
| { |
| if (window == null) |
| throw new ArgumentNullException(nameof(window), |
| "TimelineNavigator cannot be used with a null window"); |
| m_Window = window; |
| } |
|
|
| |
| |
| |
| |
| public SequenceContext GetCurrentContext() |
| { |
| return GetBreadcrumbs().LastOrDefault(); |
| } |
|
|
| |
| |
| |
| |
| public SequenceContext GetParentContext() |
| { |
| |
| if (windowState.editSequence == windowState.masterSequence) |
| return SequenceContext.Invalid; |
| var contexts = GetBreadcrumbs(); |
| var length = contexts.Count(); |
| return contexts.ElementAtOrDefault(length - 2); |
| } |
|
|
| |
| |
| |
| |
| public SequenceContext GetRootContext() |
| { |
| return GetBreadcrumbs().FirstOrDefault(); |
| } |
|
|
| |
| |
| |
| |
| public IEnumerable<SequenceContext> GetChildContexts() |
| { |
| return windowState.GetSubSequences(); |
| } |
|
|
| |
| |
| |
| |
| public IEnumerable<SequenceContext> GetBreadcrumbs() |
| { |
| return CollectBreadcrumbContexts(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public void NavigateTo(SequenceContext context) |
| { |
| if (!context.IsValid()) |
| throw new ArgumentException( |
| $"Argument {nameof(context)} is not valid. Check validity with SequenceContext.IsValid."); |
|
|
| |
| if (windowState.editSequence.hostClip == context.clip && |
| windowState.editSequence.director == context.director && |
| windowState.editSequence.asset == context.director.playableAsset) |
| { |
| return; |
| } |
|
|
| if (context.clip == null) |
| { |
| if (context.director != windowState.masterSequence.director) |
| throw new InvalidOperationException($"{nameof(context)} is not a valid destination in this context. " + |
| $"To change the root context, use TimelineEditorWindow.SetTimeline instead."); |
| } |
|
|
| var children = GetChildContexts().ToArray(); |
| var breadcrumbs = CollectBreadcrumbContexts().ToArray(); |
|
|
| if (!children.Contains(context) && !breadcrumbs.Contains(context)) |
| { |
| throw new InvalidOperationException( |
| "The provided SequenceContext is not a valid destination. " + |
| "Use GetChildContexts or GetBreadcrumbs to acquire valid destination contexts."); |
| } |
|
|
| if (children.Contains(context)) |
| { |
| windowState.SetCurrentSequence(context.director.playableAsset as TimelineAsset, context.director, context.clip); |
| return; |
| } |
|
|
| var idx = Array.IndexOf(breadcrumbs, context); |
| if (idx != -1) |
| { |
| windowState.PopSequencesUntilCount(idx + 1); |
| } |
| } |
|
|
| private IWindowState windowState |
| { |
| get |
| { |
| if (m_Window == null || m_Window.windowState == null) |
| throw new InvalidOperationException("The Window associated to this instance has been destroyed"); |
| return m_Window.windowState; |
| } |
| } |
|
|
| private IEnumerable<SequenceContext> CollectBreadcrumbContexts() |
| { |
| return windowState.allSequences?.Select(s => new SequenceContext(s.director, s.hostClip)); |
| } |
|
|
| private readonly IWindowStateProvider m_Window; |
| } |
| } |
| } |
|
|