// Reparents a list of tracks to a new parent // the new parent cannot be null (has to be track asset or sequence) // the insertAfter can be null (will not reorder) internal static bool ReparentTracks(List <TrackAsset> tracksToMove, PlayableAsset targetParent, TrackAsset insertMarker = null, bool insertBefore = false) { var targetParentTrack = targetParent as TrackAsset; var targetSequenceTrack = targetParent as TimelineAsset; if (tracksToMove == null || tracksToMove.Count == 0 || (targetParentTrack == null && targetSequenceTrack == null)) { return(false); } // invalid parent type on a track if (targetParentTrack != null && tracksToMove.Any(x => !TimelineCreateUtilities.ValidateParentTrack(targetParentTrack, x.GetType()))) { return(false); } // no valid tracks means this is simply a rearrangement var validTracks = tracksToMove.Where(x => x.parent != targetParent).ToList(); if (insertMarker == null && !validTracks.Any()) { return(false); } var parents = validTracks.Select(x => x.parent).Where(x => x != null).Distinct().ToList(); // push the current state of the tracks that will change foreach (var p in parents) { TimelineUndo.PushUndo(p, "Reparent"); } foreach (var t in validTracks) { TimelineUndo.PushUndo(t, "Reparent"); } TimelineUndo.PushUndo(targetParent, "Reparent"); // need to reparent tracks first, before moving them. foreach (var t in validTracks) { if (t.parent != targetParent) { TrackAsset toMoveParent = t.parent as TrackAsset; TimelineAsset toMoveTimeline = t.parent as TimelineAsset; if (toMoveTimeline != null) { toMoveTimeline.RemoveTrack(t); } else if (toMoveParent != null) { toMoveParent.RemoveSubTrack(t); } if (targetParentTrack != null) { targetParentTrack.AddChild(t); targetParentTrack.SetCollapsed(false); } else { targetSequenceTrack.AddTrackInternal(t); } } } if (insertMarker != null) { // re-ordering track. This is using internal APIs, so invalidation of the tracks must be done manually to avoid // cache mismatches var children = targetParentTrack != null ? targetParentTrack.subTracksObjects : targetSequenceTrack.trackObjects; TimelineUtility.ReorderTracks(children, tracksToMove, insertMarker, insertBefore); if (targetParentTrack != null) { targetParentTrack.Invalidate(); } if (insertMarker.timelineAsset != null) { insertMarker.timelineAsset.Invalidate(); } } return(true); }
internal static bool ReparentTracks(List <TrackAsset> tracksToMove, PlayableAsset targetParent, TrackAsset insertMarker, bool insertBefore) { TrackAsset trackAsset = targetParent as TrackAsset; TimelineAsset timelineAsset = targetParent as TimelineAsset; bool result; if (tracksToMove == null || tracksToMove.Count == 0 || (trackAsset == null && timelineAsset == null)) { result = false; } else { List <TrackAsset> list = (from x in tracksToMove where x.parent != targetParent select x).ToList <TrackAsset>(); if (insertMarker == null && !list.Any <TrackAsset>()) { result = false; } else { List <PlayableAsset> list2 = (from x in list select x.parent into x where x != null select x).Distinct <PlayableAsset>().ToList <PlayableAsset>(); TimelineUndo.PushUndo(targetParent, "Reparent"); foreach (PlayableAsset current in list2) { TimelineUndo.PushUndo(current, "Reparent"); } foreach (TrackAsset current2 in list) { TimelineUndo.PushUndo(current2, "Reparent"); } foreach (TrackAsset current3 in list) { if (current3.parent != targetParent) { TrackAsset trackAsset2 = current3.parent as TrackAsset; TimelineAsset timelineAsset2 = current3.parent as TimelineAsset; if (timelineAsset2 != null) { timelineAsset2.RemoveTrack(current3); } else if (trackAsset2 != null) { trackAsset2.RemoveSubTrack(current3); } if (trackAsset != null) { trackAsset.AddChild(current3); trackAsset.SetCollapsed(false); } else { timelineAsset.AddTrackInternal(current3); } } } if (insertMarker != null) { List <TrackAsset> allTracks = (!(trackAsset != null)) ? timelineAsset.tracks : trackAsset.subTracks; TimelineUtility.ReorderTracks(allTracks, tracksToMove, insertMarker, insertBefore); if (insertMarker.timelineAsset != null) { insertMarker.timelineAsset.Invalidate(); } } result = true; } } return(result); }