File size: 5,461 Bytes
18a519f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | 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;
}
}
}
|