using System;
namespace UnityEngine.Timeline
{
///
/// Extension methods for TimelineClip
///
public static class TimelineClipExtensions
{
static readonly string k_UndoSetParentTrackText = "Move Clip";
///
/// Tries to move a TimelineClip to a different track. Validates that the destination track can accept the clip before performing the move.
/// Fails if the clip's PlayableAsset is null, the current and destination tracks are the same or the destination track cannot accept the clip.
///
/// Clip that is being moved
/// Desired destination track
/// Thrown if or are null
/// Thrown if the PlayableAsset in the TimelineClip is null
/// Thrown if the current parent track and destination track are the same
/// Thrown if the destination track cannot hold tracks of the given type
public static void MoveToTrack(this TimelineClip clip, TrackAsset destinationTrack)
{
if (clip == null)
{
throw new ArgumentNullException($"'this' argument for {nameof(MoveToTrack)} cannot be null.");
}
if (destinationTrack == null)
{
throw new ArgumentNullException("Cannot move TimelineClip to a null track.");
}
TrackAsset parentTrack = clip.GetParentTrack();
Object asset = clip.asset;
// If the asset is null we cannot validate its type against the destination track
if (asset == null)
{
throw new InvalidOperationException("Cannot move a TimelineClip to a different track if the TimelineClip's PlayableAsset is null.");
}
if (parentTrack == destinationTrack)
{
throw new InvalidOperationException($"TimelineClip is already on {destinationTrack.name}.");
}
if (!destinationTrack.ValidateClipType(asset.GetType()))
{
throw new InvalidOperationException($"Track {destinationTrack.name} cannot contain clips of type {clip.GetType().Name}.");
}
MoveToTrack_Impl(clip, destinationTrack, asset, parentTrack);
}
///
/// Tries to move a TimelineClip to a different track. Validates that the destination track can accept the clip before performing the move.
/// Fails if the clip's PlayableAsset is null, the current and destination tracks are the same or the destination track cannot accept the clip.
///
/// Clip that is being moved
/// Desired destination track
/// Returns true if the clip was successfully moved to the destination track, false otherwise. Also returns false if either argument is null
/// Thrown if or are null
public static bool TryMoveToTrack(this TimelineClip clip, TrackAsset destinationTrack)
{
if (clip == null)
{
throw new ArgumentNullException($"'this' argument for {nameof(TryMoveToTrack)} cannot be null.");
}
if (destinationTrack == null)
{
throw new ArgumentNullException("Cannot move TimelineClip to a null parent.");
}
TrackAsset parentTrack = clip.GetParentTrack();
Object asset = clip.asset;
// If the asset is null we cannot validate its type against the destination track
if (asset == null)
{
return false;
}
if (parentTrack != destinationTrack)
{
if (!destinationTrack.ValidateClipType(asset.GetType()))
{
return false;
}
MoveToTrack_Impl(clip, destinationTrack, asset, parentTrack);
return true;
}
return false;
}
static void MoveToTrack_Impl(TimelineClip clip, TrackAsset destinationTrack, Object asset, TrackAsset parentTrack)
{
TimelineUndo.PushUndo(asset, k_UndoSetParentTrackText);
if (parentTrack != null)
{
TimelineUndo.PushUndo(parentTrack, k_UndoSetParentTrackText);
}
TimelineUndo.PushUndo(destinationTrack, k_UndoSetParentTrackText);
clip.SetParentTrack_Internal(destinationTrack);
if (parentTrack == null)
{
TimelineCreateUtilities.SaveAssetIntoObject(asset, destinationTrack);
}
else if (parentTrack.timelineAsset != destinationTrack.timelineAsset)
{
TimelineCreateUtilities.RemoveAssetFromObject(asset, parentTrack);
TimelineCreateUtilities.SaveAssetIntoObject(asset, destinationTrack);
}
}
}
}