static void Insert(TrackAsset track, IEnumerable <ITimelineItem> items) { if (track == null) { return; } var orderedItems = ItemsUtils.GetItemsExcept(track, items) .OfType <ITrimmable>() .OrderBy(i => i.start).ToArray(); foreach (var item in items.OfType <ITrimmable>()) { var from = item.start; var to = item.end; var overlappedItems = orderedItems.Where(i => EditModeUtils.Overlaps(i, from, to)); foreach (var overlappedItem in overlappedItems) { if (EditModeUtils.IsItemWithinRange(overlappedItem, from, to)) { overlappedItem.Delete(); } else { if (overlappedItem.start >= from) { overlappedItem.TrimStart(to); } else { overlappedItem.TrimEnd(from); } } } var includingItems = orderedItems.Where(c => c.start <from && c.end> to); foreach (var includingItem in includingItems) { var newItem = includingItem.CloneTo(track, includingItem.start) as ITrimmable; includingItem.TrimStart(to); if (newItem != null) { newItem.SetEnd(from, false); } } } }
public static PlacementValidity GetPlacementValidity(ITimelineItem item, IEnumerable <ITimelineItem> otherItems) { if (item.duration <= 0.0) { return(PlacementValidity.Valid); //items without any duration can always be placed } var sortedItems = otherItems.Where(i => i.duration > 0.0).OrderBy(c => c.start); var candidates = new List <ITimelineItem>(); foreach (var sortedItem in sortedItems) { if ((DiscreteTime)sortedItem.start >= (DiscreteTime)item.end) { // No need to process further break; } if ((DiscreteTime)sortedItem.end <= (DiscreteTime)item.start) { // Skip continue; } candidates.Add(sortedItem); } var discreteStart = (DiscreteTime)item.start; var discreteEnd = (DiscreteTime)item.end; // Note: Order of tests matters for (int i = 0, n = candidates.Count; i < n; i++) { var candidate = candidates[i]; var blendItem = item as IBlendable; if (blendItem != null && blendItem.supportsBlending) { if (EditModeUtils.Contains(candidate.start, candidate.end, item)) { return(PlacementValidity.InvalidIsWithin); } if (i < n - 1) { var nextCandidate = candidates[i + 1]; var discreteNextCandidateStart = (DiscreteTime)nextCandidate.start; var discreteCandidateEnd = (DiscreteTime)candidate.end; if (discreteCandidateEnd > discreteNextCandidateStart) { if (discreteStart >= discreteNextCandidateStart) { // Note: In case the placement is fully within a blend, // InvalidStartsInBlend MUST have priority return(PlacementValidity.InvalidStartsInBlend); } if (discreteEnd > discreteNextCandidateStart && discreteEnd <= discreteCandidateEnd) { return(PlacementValidity.InvalidEndsInBlend); } if (discreteStart < discreteNextCandidateStart && discreteEnd > discreteCandidateEnd) { return(PlacementValidity.InvalidContainsBlend); } } } if (EditModeUtils.Contains(item.start, item.end, candidate)) { return(PlacementValidity.InvalidContains); } } else { if (EditModeUtils.Overlaps(item, candidate.start, candidate.end) || EditModeUtils.Overlaps(candidate, item.start, item.end)) { return(PlacementValidity.InvalidOverlapWithNonBlendableClip); } } } return(PlacementValidity.Valid); }