EditModeRippleUtils.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine.Timeline;
  5. namespace UnityEditor.Timeline
  6. {
  7. static class EditModeRippleUtils
  8. {
  9. public static void Insert(IEnumerable<ItemsPerTrack> itemsGroups)
  10. {
  11. var start = double.MaxValue;
  12. var end = double.MinValue;
  13. foreach (var itemsGroup in itemsGroups)
  14. {
  15. start = Math.Min(start, itemsGroup.items.Min(c => c.start));
  16. end = Math.Max(end, itemsGroup.items.Max(c => c.end));
  17. }
  18. var offset = 0.0;
  19. var discreteStart = (DiscreteTime)start;
  20. var discreteEnd = (DiscreteTime)end;
  21. var itemTypes = ItemsUtils.GetItemTypes(itemsGroups);
  22. var siblingsToRipple = new List<ITimelineItem>();
  23. foreach (var itemsGroup in itemsGroups)
  24. {
  25. //can only ripple items of the same type as those selected
  26. siblingsToRipple.AddRange(ItemsUtils.GetItemsExcept(itemsGroup.targetTrack, itemsGroup.items).Where(i => itemTypes.Contains(i.GetType())));
  27. foreach (var item in siblingsToRipple)
  28. {
  29. var discreteItemStart = (DiscreteTime)item.start;
  30. var discreteItemEnd = (DiscreteTime)item.end;
  31. if ((discreteItemStart < discreteStart && discreteItemEnd > discreteStart) || (discreteItemStart >= discreteStart && discreteItemStart < discreteEnd))
  32. offset = Math.Max(offset, end - item.start);
  33. }
  34. }
  35. if (offset > 0.0)
  36. {
  37. foreach (var sibling in siblingsToRipple)
  38. {
  39. if ((DiscreteTime)sibling.end > (DiscreteTime)start)
  40. sibling.start += offset;
  41. }
  42. }
  43. }
  44. public static void Remove(IEnumerable<ItemsPerTrack> itemsGroups)
  45. {
  46. foreach (var itemsGroup in itemsGroups)
  47. Remove(itemsGroup.targetTrack, itemsGroup.items);
  48. }
  49. static void Remove(TrackAsset track, IEnumerable<ITimelineItem> items)
  50. {
  51. if (track == null) return;
  52. //can only ripple items of the same type as those selected
  53. var itemTypes = ItemsUtils.GetItemTypes(items);
  54. var siblingsToRipple = ItemsUtils.GetItemsExcept(track, items)
  55. .Where(i => itemTypes.Contains(i.GetType()))
  56. .OrderBy(c => c.start)
  57. .ToArray();
  58. var orderedItems = items
  59. .OrderBy(c => c.start)
  60. .ToArray();
  61. var cumulativeOffset = 0.0;
  62. foreach (var item in orderedItems)
  63. {
  64. var offset = item.end - item.start;
  65. var start = item.start - cumulativeOffset;
  66. var end = item.end - cumulativeOffset;
  67. var nextItem = siblingsToRipple.FirstOrDefault(c => (DiscreteTime)c.start > (DiscreteTime)start && (DiscreteTime)c.start < (DiscreteTime)end);
  68. if (nextItem != null)
  69. {
  70. offset -= end - nextItem.start;
  71. }
  72. var prevItem = siblingsToRipple.FirstOrDefault(c => (DiscreteTime)c.end > (DiscreteTime)start && (DiscreteTime)c.end < (DiscreteTime)end);
  73. if (prevItem != null)
  74. {
  75. offset -= prevItem.end - start;
  76. }
  77. if (offset <= 0.0)
  78. continue;
  79. cumulativeOffset += offset;
  80. for (int i = siblingsToRipple.Length - 1; i >= 0; --i)
  81. {
  82. var c = siblingsToRipple[i];
  83. if ((DiscreteTime)c.start < (DiscreteTime)start)
  84. break;
  85. c.start = c.start - offset;
  86. }
  87. }
  88. }
  89. }
  90. }