157 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			157 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using System.Collections.Generic; | ||
|  | using System.Linq; | ||
|  | using UnityEngine; | ||
|  | using UnityEngine.Timeline; | ||
|  | 
 | ||
|  | namespace UnityEditor.Timeline | ||
|  | { | ||
|  |     class Clipboard | ||
|  |     { | ||
|  |         class ExposedReferenceTable : IExposedPropertyTable | ||
|  |         { | ||
|  |             Dictionary<PropertyName, Object> m_ReferenceTable = new Dictionary<PropertyName, Object>(); | ||
|  |             public void SetReferenceValue(PropertyName id, Object value) | ||
|  |             { | ||
|  |                 m_ReferenceTable[id] = value; | ||
|  |             } | ||
|  | 
 | ||
|  |             public Object GetReferenceValue(PropertyName id, out bool idValid) | ||
|  |             { | ||
|  |                 Object reference; | ||
|  |                 idValid = m_ReferenceTable.TryGetValue(id, out reference); | ||
|  |                 return reference; | ||
|  |             } | ||
|  | 
 | ||
|  |             public void ClearReferenceValue(PropertyName id) | ||
|  |             { | ||
|  |                 m_ReferenceTable.Remove(id); | ||
|  |             } | ||
|  | 
 | ||
|  |             public void Clear() | ||
|  |             { | ||
|  |                 m_ReferenceTable.Clear(); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         public struct ClipboardTrackEntry | ||
|  |         { | ||
|  |             public TrackAsset item; | ||
|  |             public TrackAsset parent; | ||
|  |             public List<Object> bindings; | ||
|  |         } | ||
|  | 
 | ||
|  |         static readonly int kListInitialSize = 10; | ||
|  | 
 | ||
|  |         readonly List<ItemsPerTrack> m_ItemsData = new List<ItemsPerTrack>(kListInitialSize); | ||
|  |         readonly List<ClipboardTrackEntry> m_trackData = new List<ClipboardTrackEntry>(kListInitialSize); | ||
|  |         TimelineAsset rootTimeline; | ||
|  | 
 | ||
|  |         public readonly IExposedPropertyTable exposedPropertyTable = new ExposedReferenceTable(); | ||
|  | 
 | ||
|  |         public Clipboard() | ||
|  |         { | ||
|  |             rootTimeline = CreateTimeline(); | ||
|  | 
 | ||
|  |             EditorApplication.playModeStateChanged += OnPlayModeChanged; | ||
|  |         } | ||
|  | 
 | ||
|  |         public void CopyItems(IEnumerable<ITimelineItem> items) | ||
|  |         { | ||
|  |             using (new TimelineUndo.DisableUndoGuard(true)) | ||
|  |             { | ||
|  |                 var itemsByParent = items.ToLookup(i => i.parentTrack); | ||
|  |                 foreach (var itemsGroup in itemsByParent) | ||
|  |                 { | ||
|  |                     var parent = itemsGroup.Key; | ||
|  |                     var itemsList = new List<ITimelineItem>(); | ||
|  |                     foreach (var item in itemsGroup) | ||
|  |                     { | ||
|  |                         if (item is ClipItem) | ||
|  |                             itemsList.Add(CopyItem((ClipItem)item)); | ||
|  |                         else if (item is MarkerItem) | ||
|  |                             itemsList.Add(CopyItem((MarkerItem)item)); | ||
|  |                     } | ||
|  |                     m_ItemsData.Add(new ItemsPerTrack(parent, itemsList)); | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         ClipItem CopyItem(ClipItem clipItem) | ||
|  |         { | ||
|  |             var newClip = TimelineHelpers.Clone(clipItem.clip, TimelineWindow.instance.state.editSequence.director, exposedPropertyTable, rootTimeline); | ||
|  |             return new ClipItem(newClip); | ||
|  |         } | ||
|  | 
 | ||
|  |         static MarkerItem CopyItem(MarkerItem markerItem) | ||
|  |         { | ||
|  |             var markerObject = markerItem.marker as Object; | ||
|  |             if (markerObject != null) | ||
|  |             { | ||
|  |                 var newMarker = Object.Instantiate(markerObject); | ||
|  |                 newMarker.name = markerObject.name; | ||
|  |                 return new MarkerItem((IMarker)newMarker); | ||
|  |             } | ||
|  | 
 | ||
|  |             return null; | ||
|  |         } | ||
|  | 
 | ||
|  |         public void CopyTracks(IEnumerable<TrackAsset> tracks) | ||
|  |         { | ||
|  |             using (new TimelineUndo.DisableUndoGuard(true)) | ||
|  |             { | ||
|  |                 foreach (var track in TrackExtensions.FilterTracks(tracks)) | ||
|  |                 { | ||
|  |                     var newTrack = track.Duplicate(TimelineEditor.inspectedDirector, TimelineEditor.clipboard.exposedPropertyTable, rootTimeline); | ||
|  | 
 | ||
|  |                     var originalTracks = track.GetFlattenedChildTracks().Append(track); | ||
|  |                     var newTracks = newTrack.GetFlattenedChildTracks().Append(newTrack); | ||
|  | 
 | ||
|  |                     var toBind = new List<Object>(); | ||
|  | 
 | ||
|  |                     // Collect all track bindings to duplicate | ||
|  |                     var originalIt = originalTracks.GetEnumerator(); | ||
|  |                     var newIt = newTracks.GetEnumerator(); | ||
|  |                     while (originalIt.MoveNext() && newIt.MoveNext()) | ||
|  |                     { | ||
|  |                         toBind.Add(TimelineEditor.inspectedDirector != null ? TimelineEditor.inspectedDirector.GetGenericBinding(originalIt.Current) : null); | ||
|  |                     } | ||
|  |                     m_trackData.Add(new ClipboardTrackEntry { item = newTrack, parent = track.parent as TrackAsset, bindings = toBind }); | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         public IEnumerable<ClipboardTrackEntry> GetTracks() | ||
|  |         { | ||
|  |             return m_trackData; | ||
|  |         } | ||
|  | 
 | ||
|  |         public IEnumerable<ItemsPerTrack> GetCopiedItems() | ||
|  |         { | ||
|  |             return m_ItemsData; | ||
|  |         } | ||
|  | 
 | ||
|  |         public void Clear() | ||
|  |         { | ||
|  |             m_ItemsData.Clear(); | ||
|  |             m_trackData.Clear(); | ||
|  |             rootTimeline = CreateTimeline(); | ||
|  |             ((ExposedReferenceTable)exposedPropertyTable).Clear(); | ||
|  |         } | ||
|  | 
 | ||
|  |         private void OnPlayModeChanged(PlayModeStateChange state) | ||
|  |         { | ||
|  |             if (state == PlayModeStateChange.EnteredEditMode || state == PlayModeStateChange.EnteredPlayMode) | ||
|  |                 Clear(); | ||
|  |         } | ||
|  | 
 | ||
|  |         static TimelineAsset CreateTimeline() | ||
|  |         { | ||
|  |             var timeline = ScriptableObject.CreateInstance<TimelineAsset>(); | ||
|  |             timeline.hideFlags |= HideFlags.DontSave; | ||
|  |             timeline.name = "Clipboard"; | ||
|  | 
 | ||
|  |             return timeline; | ||
|  |         } | ||
|  |     } | ||
|  | } |