public static void BindWithEditorValidation(PlayableDirector director, TrackAsset bindTo, Object objectToBind)
        {
            TrackEditor trackEditor     = CustomTimelineEditorCache.GetTrackEditor(bindTo);
            Object      validatedObject = trackEditor.GetBindingFrom_Safe(objectToBind, bindTo);

            Bind(director, bindTo, validatedObject);
        }
Esempio n. 2
0
        public static IMarker CreateMarkerOnTrack(Type markerType, Object assignableObject, TrackAsset parentTrack, double candidateTime)
        {
            WindowState state = null;

            if (TimelineWindow.instance != null)
            {
                state = TimelineWindow.instance.state;
            }

            var newMarker = parentTrack.CreateMarker(markerType, candidateTime); //Throws if marker is not an object

            if (assignableObject != null)
            {
                var director = state != null ? state.editSequence.director : null;
                foreach (var field in ObjectReferenceField.FindObjectReferences(markerType))
                {
                    if (field.IsAssignable(assignableObject))
                    {
                        field.Assign(newMarker as ScriptableObject, assignableObject, director);
                        break;
                    }
                }
            }

            try
            {
                CustomTimelineEditorCache.GetMarkerEditor(newMarker).OnCreate(newMarker, null);
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }

            return(newMarker);
        }
Esempio n. 3
0
        internal static void RecursiveSubtrackClone(TrackAsset source, TrackAsset duplicate, PlayableDirector director, PlayableAsset assetOwner)
        {
            var subtracks = source.GetChildTracks();

            foreach (var sub in subtracks)
            {
                var newSub = TimelineHelpers.Clone(duplicate, sub, director, assetOwner);
                duplicate.AddChild(newSub);
                RecursiveSubtrackClone(sub, newSub, director, assetOwner);

                // Call the custom editor on Create
                var customEditor = CustomTimelineEditorCache.GetTrackEditor(newSub);
                try
                {
                    customEditor.OnCreate(newSub, sub);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                }

                // registration has to happen AFTER recursion
                TimelineUndo.RegisterCreatedObjectUndo(newSub, "Duplicate");
                TimelineCreateUtilities.SaveAssetIntoObject(newSub, assetOwner);
            }
        }
Esempio n. 4
0
        public static IMarker CloneMarkerToParent(IMarker marker, TrackAsset parent)
        {
            var markerObject = marker as ScriptableObject;

            if (markerObject == null)
            {
                return(null);
            }

            var newMarkerObject = Object.Instantiate(markerObject);

            AddMarkerToParent(newMarkerObject, parent);

            newMarkerObject.name = markerObject.name;
            try
            {
                CustomTimelineEditorCache.GetMarkerEditor((IMarker)newMarkerObject).OnCreate((IMarker)newMarkerObject, marker);
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }


            return((IMarker)newMarkerObject);
        }
Esempio n. 5
0
        public static TrackAsset CreateTrack(TimelineAsset asset, Type type, TrackAsset parent = null, string name = null)
        {
            if (asset == null)
            {
                return(null);
            }

            var track = asset.CreateTrack(type, parent, name);

            if (track != null)
            {
                if (parent != null)
                {
                    parent.SetCollapsed(false);
                }

                var editor = CustomTimelineEditorCache.GetTrackEditor(track);
                try
                {
                    editor.OnCreate(track, null);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                }
                TimelineEditor.Refresh(RefreshReason.ContentsAddedOrRemoved);
            }

            return(track);
        }
        void DrawSimpleClip(Rect targetRect, ClipBorder border, Color overlay)
        {
            var drawOptions = UpdateClipDrawOptions(CustomTimelineEditorCache.GetClipEditor(clip), clip);
            var blends      = GetClipBlends();

            ClipDrawer.DrawSimpleClip(clip, targetRect, border, overlay, drawOptions, blends);
        }
Esempio n. 7
0
        static TimelineClip DuplicateClip(TimelineClip clip, IExposedPropertyTable sourceTable, IExposedPropertyTable destTable, PlayableAsset newOwner)
        {
            var newClip = Clone(clip, sourceTable, destTable, newOwner);

            var track = clip.parentTrack;

            if (track != null)
            {
                newClip.parentTrack = track;
                track.AddClip(newClip);
            }

            var editor = CustomTimelineEditorCache.GetClipEditor(clip);

            try
            {
                editor.OnCreate(newClip, track, clip);
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }

            return(newClip);
        }
Esempio n. 8
0
        public virtual void OnEnable()
        {
            m_IsBuiltInType      = target != null && target.GetType().Assembly == typeof(TrackAsset).Assembly;
            m_Name               = serializedObject.FindProperty("m_Name");
            m_TrackCurvesWrapper = new TrackCurvesWrapper(target as TrackAsset);
            m_HeaderIcon         = TrackResourceCache.s_DefaultIcon.image;

            // only worry about the first track. if types are different, a different inspector is used.
            var track = target as TrackAsset;

            if (track != null)
            {
                var drawer = CustomTimelineEditorCache.GetTrackEditor(track);
                UnityEngine.Object binding = null;
                var director = m_Context as PlayableDirector;
                if (director != null)
                {
                    binding = director.GetGenericBinding(track);
                }

                var options = drawer.GetTrackOptions(track, binding);
                if (options.icon != null)
                {
                    m_HeaderIcon = options.icon;
                }
                else
                {
                    m_HeaderIcon = TrackResourceCache.GetTrackIcon(track).image;
                }
            }
        }
Esempio n. 9
0
        static TimelineClip DuplicateClip(TimelineClip clip, PlayableDirector director, PlayableAsset newOwner)
        {
            var newClip = Clone(clip, director, newOwner);

            var track = clip.parentTrack;

            if (track != null)
            {
                newClip.parentTrack = track;
                track.AddClip(newClip);
            }

            var editor = CustomTimelineEditorCache.GetClipEditor(clip);

            try
            {
                editor.OnCreate(newClip, track, clip);
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }

            return(newClip);
        }
Esempio n. 10
0
        /// <summary>
        /// Shared code for adding a clip to a track
        /// </summary>
        static void AddClipOnTrack(TimelineClip newClip, TrackAsset parentTrack, double candidateTime, Object assignableObject, WindowState state)
        {
            var playableAsset = newClip.asset as IPlayableAsset;

            newClip.parentTrack = null;
            newClip.timeScale   = 1.0;
            newClip.mixInCurve  = AnimationCurve.EaseInOut(0, 0, 1, 1);
            newClip.mixOutCurve = AnimationCurve.EaseInOut(0, 1, 1, 0);

            var playableDirector = state != null ? state.editSequence.director : null;

            if (assignableObject != null)
            {
                foreach (var field in ObjectReferenceField.FindObjectReferences(playableAsset.GetType()))
                {
                    if (field.IsAssignable(assignableObject))
                    {
                        newClip.displayName = assignableObject.name;
                        field.Assign(newClip.asset as PlayableAsset, assignableObject, playableDirector);
                        break;
                    }
                }
            }

            // get the clip editor
            try
            {
                CustomTimelineEditorCache.GetClipEditor(newClip).OnCreate(newClip, parentTrack, null);
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }


            // reset the duration as the newly assigned values may have changed the default
            if (playableAsset != null)
            {
                var candidateDuration = playableAsset.duration;

                if (!double.IsInfinity(candidateDuration) && candidateDuration > 0)
                {
                    newClip.duration = Math.Min(Math.Max(candidateDuration, TimelineClip.kMinDuration), TimelineClip.kMaxTimeValue);
                }
            }

            var newClipsByTracks = new[] { new ItemsPerTrack(parentTrack, new[] { newClip.ToItem() }) };

            FinalizeInsertItemsUsingCurrentEditMode(state, newClipsByTracks, candidateTime);

            if (state != null)
            {
                state.Refresh();
            }
        }
Esempio n. 11
0
 public static TrackDrawOptions GetTrackOptions_Safe(this TrackEditor editor, TrackAsset track, UnityEngine.Object binding)
 {
     try
     {
         return(editor.GetTrackOptions(track, binding));
     }
     catch (Exception e)
     {
         Debug.LogException(e);
         return(CustomTimelineEditorCache.GetDefaultTrackEditor().GetTrackOptions(track, binding));
     }
 }
Esempio n. 12
0
        static ClipDrawOptions UpdateClipDrawOptions(ClipEditor clipEditor, TimelineClip clip)
        {
            try
            {
                return(clipEditor.GetClipOptions(clip));
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }

            return(CustomTimelineEditorCache.GetDefaultClipEditor().GetClipOptions(clip));
        }
Esempio n. 13
0
        public TimelineClipGUI(TimelineClip clip, IRowGUI parent, IZOrderProvider provider) : base(parent)
        {
            zOrderProvider = provider;
            zOrder         = provider.Next();

            m_EditorItem = EditorClipFactory.GetEditorClip(clip);
            m_ClipEditor = CustomTimelineEditorCache.GetClipEditor(clip);

            supportResize = true;

            leftHandle  = new TimelineClipHandle(this, TrimEdge.Start);
            rightHandle = new TimelineClipHandle(this, TrimEdge.End);

            ItemToItemGui.Add(clip, this);
        }
        public static IList<PlayableDirector> GetSubTimelines(TimelineClip clip, IExposedPropertyTable director)
        {
            var editor = CustomTimelineEditorCache.GetClipEditor(clip);
            List<PlayableDirector> directors = new List<PlayableDirector>();
            try
            {
                editor.GetSubTimelines(clip, director as PlayableDirector, directors);
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }

            return directors;
        }
Esempio n. 15
0
 void UpdateDrawData()
 {
     if (Event.current.type == EventType.Layout)
     {
         try
         {
             m_MarkerDrawOptions = m_Editor.GetMarkerOptions(marker);
         }
         catch (Exception e)
         {
             Debug.LogException(e);
             m_MarkerDrawOptions = CustomTimelineEditorCache.GetDefaultMarkerEditor().GetMarkerOptions(marker);
         }
     }
 }
        void OnBeforeSequenceChange()
        {
            treeView          = null;
            m_MarkerHeaderGUI = null;
            m_TimeAreaDirty   = true;

            state.Reset();
            m_PlayableLookup.ClearPlayableLookup();

            // clear old editors to caches, like audio previews, get flushed
            CustomTimelineEditorCache.ClearCache <ClipEditor>();
            CustomTimelineEditorCache.ClearCache <MarkerEditor>();
            CustomTimelineEditorCache.ClearCache <TrackEditor>();

            m_PreviousMasterSequence = state.masterSequence.asset;
        }
Esempio n. 17
0
        void UpdateDrawData(WindowState state)
        {
            if (Event.current.type == EventType.Layout)
            {
                m_TrackDrawData.m_ShowTrackBindings = false;
                m_TrackDrawData.m_TrackBinding      = null;


                if (state.editSequence.director != null && showSceneReference)
                {
                    m_TrackDrawData.m_ShowTrackBindings = state.GetWindow().currentMode.ShouldShowTrackBindings(state);
                    m_TrackDrawData.m_TrackBinding      = state.editSequence.director.GetGenericBinding(track);
                }

                var lastError  = m_TrackDrawOptions.errorText;
                var lastHeight = m_TrackDrawOptions.minimumHeight;
                try
                {
                    m_TrackDrawOptions = m_TrackEditor.GetTrackOptions(track, m_TrackDrawData.m_TrackBinding);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                    m_TrackDrawOptions = CustomTimelineEditorCache.GetDefaultTrackEditor().GetTrackOptions(track, m_TrackDrawData.m_TrackBinding);
                }

                m_TrackDrawData.m_AllowsRecording = DoesTrackAllowsRecording(track);
                m_TrackDrawData.m_TrackIcon       = m_TrackDrawOptions.icon;
                if (m_TrackDrawData.m_TrackIcon == null)
                {
                    m_TrackDrawData.m_TrackIcon = m_DefaultTrackIcon.image;
                }
                // if the problem state has changed, it may be due to external bindings
                // in that case, we need to tell the graph to rebuild.
                // there is no notification from the engine for some markers that invalidate the graph (addcomponent)
                if (m_TrackDrawData.m_ShowTrackBindings && lastError != null && !lastError.Equals(m_TrackDrawOptions.errorText) && !state.playing)
                {
                    state.rebuildGraph = true;
                }

                // track height has changed. need to update gui
                if (!Mathf.Approximately(lastHeight, m_TrackDrawOptions.minimumHeight))
                {
                    state.Refresh();
                }
            }
        }
Esempio n. 18
0
        public TimelineMarkerGUI(IMarker theMarker, IRowGUI parent, IZOrderProvider provider) : base(parent)
        {
            marker       = theMarker;
            m_Selectable = marker.GetType().IsSubclassOf(typeof(UnityObject));

            m_MarkerHash = 0;
            var o = marker as object;

            if (!o.Equals(null))
            {
                m_MarkerHash = o.GetHashCode();
            }

            zOrderProvider = provider;
            zOrder         = zOrderProvider.Next();
            ItemToItemGui.Add(marker, this);
            m_Editor = CustomTimelineEditorCache.GetMarkerEditor(theMarker);
        }
Esempio n. 19
0
        public TimelineTrackGUI(TreeViewController tv, TimelineTreeViewGUI w, int id, int depth, TreeViewItem parent, string displayName, TrackAsset sequenceActor)
            : base(tv, w, id, depth, parent, displayName, sequenceActor, false)
        {
            AnimationTrack animationTrack = sequenceActor as AnimationTrack;

            if (animationTrack != null)
            {
                m_InfiniteTrackDrawer = new InfiniteTrackDrawer(new AnimationTrackKeyDataSource(animationTrack));
            }
            else if (sequenceActor.HasAnyAnimatableParameters() && !sequenceActor.clips.Any())
            {
                m_InfiniteTrackDrawer = new InfiniteTrackDrawer(new TrackPropertyCurvesDataSource(sequenceActor));
            }

            UpdateInfiniteClipEditor(w.TimelineWindow);

            var bindings = track.outputs.ToArray();

            m_TrackDrawData.m_HasBinding = bindings.Length > 0;
            if (m_TrackDrawData.m_HasBinding)
            {
                m_TrackDrawData.m_Binding = bindings[0];
            }
            m_TrackDrawData.m_IsSubTrack      = IsSubTrack();
            m_TrackDrawData.m_AllowsRecording = DoesTrackAllowsRecording(sequenceActor);
            m_DefaultTrackIcon = TrackResourceCache.GetTrackIcon(track);


            m_TrackEditor = CustomTimelineEditorCache.GetTrackEditor(sequenceActor);

            try
            {
                m_TrackDrawOptions = m_TrackEditor.GetTrackOptions(track, null);
            }
            catch (Exception e)
            {
                Debug.LogException(e);
                m_TrackDrawOptions = CustomTimelineEditorCache.GetDefaultTrackEditor().GetTrackOptions(track, null);
            }

            m_TrackDrawOptions.errorText = null; // explicitly setting to null for an uninitialized state

            RebuildGUICacheIfNecessary();
        }
        static void RecursiveSubtrackClone(TrackAsset source, TrackAsset duplicate, IExposedPropertyTable sourceTable, IExposedPropertyTable destTable, PlayableAsset assetOwner)
        {
            var subtracks = source.GetChildTracks();

            foreach (var sub in subtracks)
            {
                var newSub = TimelineHelpers.Clone(duplicate, sub, sourceTable, destTable, assetOwner);
                duplicate.AddChild(newSub);
                RecursiveSubtrackClone(sub, newSub, sourceTable, destTable, assetOwner);

                // Call the custom editor on Create
                var customEditor = CustomTimelineEditorCache.GetTrackEditor(newSub);
                customEditor.OnCreate_Safe(newSub, sub);

                // registration has to happen AFTER recursion
                TimelineCreateUtilities.SaveAssetIntoObject(newSub, assetOwner);
                TimelineUndo.RegisterCreatedObjectUndo(newSub, L10n.Tr("Duplicate"));
            }
        }
Esempio n. 21
0
        void UpdateDrawData(WindowState state)
        {
            if (Event.current.type == EventType.Layout)
            {
                m_TrackDrawData.m_ShowTrackBindings = false;
                m_TrackDrawData.m_TrackBinding      = null;


                if (state.editSequence.director != null && showSceneReference)
                {
                    m_TrackDrawData.m_ShowTrackBindings = state.GetWindow().currentMode.ShouldShowTrackBindings(state);
                    m_TrackDrawData.m_TrackBinding      = state.editSequence.director.GetGenericBinding(track);
                }

                var lastError  = m_TrackDrawOptions.errorText;
                var lastHeight = m_TrackDrawOptions.minimumHeight;
                try
                {
                    m_TrackDrawOptions = m_TrackEditor.GetTrackOptions(track, m_TrackDrawData.m_TrackBinding);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                    m_TrackDrawOptions = CustomTimelineEditorCache.GetDefaultTrackEditor().GetTrackOptions(track, m_TrackDrawData.m_TrackBinding);
                }

                m_TrackDrawData.m_AllowsRecording = DoesTrackAllowsRecording(track);
                m_TrackDrawData.m_TrackIcon       = m_TrackDrawOptions.icon;
                if (m_TrackDrawData.m_TrackIcon == null)
                {
                    m_TrackDrawData.m_TrackIcon = m_DefaultTrackIcon.image;
                }

                // track height has changed. need to update gui
                if (!Mathf.Approximately(lastHeight, m_TrackDrawOptions.minimumHeight))
                {
                    state.Refresh();
                }
            }
        }
        public static void BindWithInteractiveEditorValidation(PlayableDirector director, TrackAsset bindTo, Object objectToBind)
        {
            TrackEditor trackEditor = CustomTimelineEditorCache.GetTrackEditor(bindTo);

            if (trackEditor.SupportsBindingAssign())
            {
                BindWithEditorValidation(director, bindTo, objectToBind);
            }
            else
            {
                Type          bindingType = TypeUtility.GetTrackBindingAttribute(bindTo.GetType())?.type;
                BindingAction action      = GetBindingAction(bindingType, objectToBind);
                if (action == BindingAction.BindToMissingComponent)
                {
                    InteractiveBindToMissingComponent(director, bindTo, objectToBind, bindingType);
                }
                else
                {
                    var validatedObject = GetBinding(action, objectToBind, bindingType);
                    Bind(director, bindTo, validatedObject);
                }
            }
        }
        public static IMarker CreateMarkerAtTime(TrackAsset parent, Type markerType, double time)
        {
            var marker = parent.CreateMarker(markerType, time);

            var obj = marker as ScriptableObject;

            if (obj != null)
            {
                obj.name = TypeUtility.GetDisplayName(markerType);
            }

            SelectionManager.Add(marker);

            try
            {
                CustomTimelineEditorCache.GetMarkerEditor(marker).OnCreate(marker, null);
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }

            return(marker);
        }
Esempio n. 24
0
        public static bool HasCustomEditor(TimelineClip clip)
        {
            var editor = CustomTimelineEditorCache.GetClipEditor(clip);

            return(editor != CustomTimelineEditorCache.GetDefaultClipEditor());
        }
Esempio n. 25
0
        internal static TrackAsset Duplicate(this TrackAsset track, PlayableDirector director,
                                             TimelineAsset destinationTimeline = null)
        {
            if (track == null)
            {
                return(null);
            }

            // if the destination is us, clear to avoid bad parenting (case 919421)
            if (destinationTimeline == track.timelineAsset)
            {
                destinationTimeline = null;
            }

            var timelineParent = track.parent as TimelineAsset;
            var trackParent    = track.parent as TrackAsset;

            if (timelineParent == null && trackParent == null)
            {
                Debug.LogWarning("Cannot duplicate track because it is not parented to known type");
                return(null);
            }

            // Determine who the final parent is. If we are pasting into another track, it's always the timeline.
            //  Otherwise it's the original parent
            PlayableAsset finalParent = destinationTimeline != null ? destinationTimeline : track.parent;

            // grab the list of tracks to generate a name from (923360) to get the list of names
            // no need to do this part recursively
            var finalTrackParent   = finalParent as TrackAsset;
            var finalTimelineAsset = finalParent as TimelineAsset;
            var otherTracks        = (finalTimelineAsset != null) ? finalTimelineAsset.trackObjects : finalTrackParent.subTracksObjects;

            // Important to create the new objects before pushing the original undo, or redo breaks the
            //  sequence
            var newTrack = TimelineHelpers.Clone(finalParent, track, director, finalParent);

            newTrack.name = TimelineCreateUtilities.GenerateUniqueActorName(otherTracks, newTrack.name);

            RecursiveSubtrackClone(track, newTrack, director, finalParent);
            TimelineUndo.RegisterCreatedObjectUndo(newTrack, "Duplicate");
            TimelineCreateUtilities.SaveAssetIntoObject(newTrack, finalParent);
            TimelineUndo.PushUndo(finalParent, "Duplicate");

            if (destinationTimeline != null) // other timeline
            {
                destinationTimeline.AddTrackInternal(newTrack);
            }
            else if (timelineParent != null) // this timeline, no parent
            {
                ReparentTracks(new List <TrackAsset> {
                    newTrack
                }, timelineParent, timelineParent.GetRootTracks().Last(), false);
            }
            else // this timeline, with parent
            {
                trackParent.AddChild(newTrack);
            }

            // Call the custom editor. this check prevents the call when copying to the clipboard
            if (destinationTimeline == null || destinationTimeline == TimelineEditor.inspectedAsset)
            {
                var customEditor = CustomTimelineEditorCache.GetTrackEditor(newTrack);
                try
                {
                    customEditor.OnCreate(newTrack, track);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                }
            }

            return(newTrack);
        }