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