You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
5.3 KiB
156 lines
5.3 KiB
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; |
|
} |
|
} |
|
}
|
|
|