TrimItemModeReplace.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. using System;
  2. using System.Linq;
  3. using UnityEngine;
  4. using UnityEngine.Timeline;
  5. namespace UnityEditor.Timeline
  6. {
  7. class TrimItemModeReplace : ITrimItemMode, ITrimItemDrawer
  8. {
  9. ITrimmable m_Item;
  10. ITrimmable m_ItemToBeReplaced;
  11. double m_ClipOriginalEdgeValue;
  12. bool m_TrimReplace;
  13. double m_Min;
  14. double m_Max;
  15. public void OnBeforeTrim(ITrimmable item, TrimEdge trimDirection)
  16. {
  17. m_Item = item;
  18. var sortedClips = ItemsUtils.GetItemsExcept(item.parentTrack, new[] { item })
  19. .OfType<ITrimmable>()
  20. .OrderBy(c => c.start);
  21. var clipStart = (DiscreteTime)item.start;
  22. var clipEnd = (DiscreteTime)item.end;
  23. var overlapped = sortedClips.LastOrDefault(c => (DiscreteTime)c.start == clipStart && (DiscreteTime)c.end == clipEnd);
  24. ITrimmable nextItem;
  25. ITrimmable prevItem;
  26. m_Min = 0.0;
  27. m_Max = double.PositiveInfinity;
  28. if (trimDirection == TrimEdge.Start)
  29. {
  30. nextItem = sortedClips.FirstOrDefault(c => (DiscreteTime)c.start >= clipStart && (DiscreteTime)c.end > clipEnd);
  31. prevItem = sortedClips.LastOrDefault(c => (DiscreteTime)c.start <= clipStart && (DiscreteTime)c.end < clipEnd);
  32. if (prevItem != null)
  33. m_Min = prevItem.start + EditModeUtils.BlendDuration(prevItem, TrimEdge.Start) + TimelineClip.kMinDuration;
  34. if (nextItem != null)
  35. m_Max = nextItem.start;
  36. m_ItemToBeReplaced = prevItem;
  37. if (m_ItemToBeReplaced != null)
  38. m_ClipOriginalEdgeValue = m_ItemToBeReplaced.end;
  39. }
  40. else
  41. {
  42. nextItem = sortedClips.FirstOrDefault(c => c != overlapped && (DiscreteTime)c.start >= clipStart && (DiscreteTime)c.end >= clipEnd);
  43. prevItem = sortedClips.LastOrDefault(c => c != overlapped && (DiscreteTime)c.start <= clipStart && (DiscreteTime)c.end <= clipEnd);
  44. if (prevItem != null)
  45. m_Min = prevItem.end;
  46. if (nextItem != null)
  47. m_Max = nextItem.end - EditModeUtils.BlendDuration(nextItem, TrimEdge.End) - TimelineClip.kMinDuration;
  48. m_ItemToBeReplaced = nextItem;
  49. if (m_ItemToBeReplaced != null)
  50. m_ClipOriginalEdgeValue = m_ItemToBeReplaced.start;
  51. }
  52. m_TrimReplace = false;
  53. }
  54. public void TrimStart(ITrimmable item, double time)
  55. {
  56. time = Math.Min(Math.Max(time, m_Min), m_Max);
  57. if (m_ItemToBeReplaced != null)
  58. {
  59. if (!m_TrimReplace)
  60. m_TrimReplace = item.start >= m_ItemToBeReplaced.end;
  61. }
  62. time = Math.Max(time, 0.0);
  63. item.SetStart(time);
  64. if (m_ItemToBeReplaced != null && m_TrimReplace)
  65. {
  66. var prevEnd = Math.Min(item.start, m_ClipOriginalEdgeValue);
  67. m_ItemToBeReplaced.SetEnd(prevEnd, false);
  68. }
  69. }
  70. public void TrimEnd(ITrimmable item, double time, bool affectTimeScale)
  71. {
  72. time = Math.Min(Math.Max(time, m_Min), m_Max);
  73. if (m_ItemToBeReplaced != null)
  74. {
  75. if (!m_TrimReplace)
  76. m_TrimReplace = item.end <= m_ItemToBeReplaced.start;
  77. }
  78. item.SetEnd(time, affectTimeScale);
  79. if (m_ItemToBeReplaced != null && m_TrimReplace)
  80. {
  81. var nextStart = Math.Max(item.end, m_ClipOriginalEdgeValue);
  82. m_ItemToBeReplaced.SetStart(nextStart);
  83. }
  84. }
  85. public void DrawGUI(WindowState state, Rect bounds, Color color, TrimEdge edge)
  86. {
  87. bool shouldDraw = m_ItemToBeReplaced != null && (edge == TrimEdge.End && m_Item.end > m_ClipOriginalEdgeValue) ||
  88. (edge == TrimEdge.Start && m_Item.start < m_ClipOriginalEdgeValue);
  89. if (shouldDraw)
  90. {
  91. var cursorType = TimelineCursors.CursorType.Replace;
  92. if (EditModeUtils.HasBlends(m_Item, edge))
  93. {
  94. color = DirectorStyles.kMixToolColor;
  95. cursorType = (edge == TrimEdge.End)
  96. ? TimelineCursors.CursorType.MixRight
  97. : TimelineCursors.CursorType.MixLeft;
  98. }
  99. EditModeGUIUtils.DrawBoundsEdge(bounds, color, edge);
  100. TimelineCursors.SetCursor(cursorType);
  101. }
  102. else
  103. {
  104. TimelineCursors.ClearCursor();
  105. }
  106. }
  107. }
  108. }