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;
 | |
|         }
 | |
|     }
 | |
| }
 |