TrimItemModeRipple.cs 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using System;
  2. using System.Linq;
  3. using UnityEngine;
  4. using UnityEngine.Timeline;
  5. namespace UnityEditor.Timeline
  6. {
  7. class TrimItemModeRipple : ITrimItemMode, ITrimItemDrawer
  8. {
  9. double m_OriginalClipStart;
  10. double m_OriginalClipEnd;
  11. ITrimmable[] m_NextItems;
  12. double m_BlendDuration;
  13. double m_TrimStartShift;
  14. public void OnBeforeTrim(ITrimmable item, TrimEdge trimDirection)
  15. {
  16. m_OriginalClipStart = item.start;
  17. m_OriginalClipEnd = item.end;
  18. m_TrimStartShift = 0.0;
  19. var sortedClips = ItemsUtils.GetItemsExcept(item.parentTrack, new[] { item })
  20. .OfType<ITrimmable>()
  21. .OrderBy(c => c.start);
  22. var clipStart = (DiscreteTime)item.start;
  23. var clipEnd = (DiscreteTime)item.end;
  24. m_NextItems = sortedClips.Where(c => (DiscreteTime)c.start >= clipStart && (DiscreteTime)c.end >= clipEnd).ToArray();
  25. var overlapped = sortedClips.LastOrDefault(c => (DiscreteTime)c.start == clipStart && (DiscreteTime)c.end == clipEnd);
  26. if (overlapped != null)
  27. {
  28. m_BlendDuration = overlapped.end - overlapped.start;
  29. }
  30. else
  31. {
  32. m_BlendDuration = 0.0;
  33. var prevClip = sortedClips.LastOrDefault(c => (DiscreteTime)c.start <= clipStart && (DiscreteTime)c.end <= clipEnd);
  34. if (prevClip != null)
  35. m_BlendDuration += Math.Max(prevClip.end - item.start, 0.0);
  36. var nextClip = sortedClips.FirstOrDefault(c => (DiscreteTime)c.start >= clipStart && (DiscreteTime)c.end >= clipEnd);
  37. if (nextClip != null)
  38. m_BlendDuration += Math.Max(item.end - nextClip.start, 0.0);
  39. }
  40. }
  41. public void TrimStart(ITrimmable item, double time)
  42. {
  43. var prevEnd = item.end;
  44. // HACK If time is negative, make sure we shift the SetStart operation to a positive space.
  45. if (time < 0.0)
  46. m_TrimStartShift = Math.Max(-time, m_TrimStartShift);
  47. item.start = m_OriginalClipEnd - item.duration + m_TrimStartShift;
  48. time += m_TrimStartShift;
  49. if (m_BlendDuration > 0.0)
  50. time = Math.Min(time, item.end - m_BlendDuration);
  51. item.SetStart(time);
  52. item.start = m_OriginalClipStart;
  53. var offset = item.end - prevEnd;
  54. foreach (var timelineClip in m_NextItems)
  55. timelineClip.start += offset;
  56. }
  57. public void TrimEnd(ITrimmable item, double time, bool affectTimeScale)
  58. {
  59. var prevEnd = item.end;
  60. if (m_BlendDuration > 0.0)
  61. time = Math.Max(time, item.start + m_BlendDuration);
  62. item.SetEnd(time, affectTimeScale);
  63. var offset = item.end - prevEnd;
  64. foreach (var timelineClip in m_NextItems)
  65. timelineClip.start += offset;
  66. }
  67. public void DrawGUI(WindowState state, Rect bounds, Color color, TrimEdge edge)
  68. {
  69. EditModeGUIUtils.DrawBoundsEdge(bounds, color, edge);
  70. TimelineCursors.SetCursor(TimelineCursors.CursorType.Ripple);
  71. }
  72. }
  73. }