EditMode.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.Timeline;
  5. namespace UnityEditor.Timeline
  6. {
  7. static class EditMode
  8. {
  9. public enum EditType
  10. {
  11. None = -1,
  12. Mix = 0,
  13. Ripple = 1,
  14. Replace = 2
  15. }
  16. interface ISubEditMode
  17. {
  18. IMoveItemMode moveItemMode { get; }
  19. IMoveItemDrawer moveItemDrawer { get; }
  20. ITrimItemMode trimItemMode { get; }
  21. ITrimItemDrawer trimItemDrawer { get; }
  22. IAddDeleteItemMode addDeleteItemMode { get; }
  23. Color color { get; }
  24. KeyCode clutchKey { get; }
  25. void Reset();
  26. }
  27. class SubEditMode<TMoveMode, TTrimMode, TAddDeleteMode>: ISubEditMode
  28. where TMoveMode : class, IMoveItemMode, IMoveItemDrawer, new()
  29. where TTrimMode : class, ITrimItemMode, ITrimItemDrawer, new()
  30. where TAddDeleteMode : class, IAddDeleteItemMode, new()
  31. {
  32. public SubEditMode(Color guiColor, KeyCode key)
  33. {
  34. color = guiColor;
  35. clutchKey = key;
  36. Reset();
  37. }
  38. public void Reset()
  39. {
  40. m_MoveItemMode = new TMoveMode();
  41. m_TrimItemMode = new TTrimMode();
  42. m_AddDeleteItemMode = new TAddDeleteMode();
  43. }
  44. TMoveMode m_MoveItemMode;
  45. TTrimMode m_TrimItemMode;
  46. TAddDeleteMode m_AddDeleteItemMode;
  47. public IMoveItemMode moveItemMode { get { return m_MoveItemMode; } }
  48. public IMoveItemDrawer moveItemDrawer { get { return m_MoveItemMode; } }
  49. public ITrimItemMode trimItemMode { get { return m_TrimItemMode; } }
  50. public ITrimItemDrawer trimItemDrawer { get { return m_TrimItemMode; } }
  51. public IAddDeleteItemMode addDeleteItemMode { get { return m_AddDeleteItemMode; } }
  52. public Color color { get; }
  53. public KeyCode clutchKey { get; }
  54. }
  55. static readonly Dictionary<EditType, ISubEditMode> k_EditModes = new Dictionary<EditType, ISubEditMode>
  56. {
  57. { EditType.Mix, new SubEditMode<MoveItemModeMix, TrimItemModeMix, AddDeleteItemModeMix>(DirectorStyles.kMixToolColor, KeyCode.Alpha1) },
  58. { EditType.Ripple, new SubEditMode<MoveItemModeRipple, TrimItemModeRipple, AddDeleteItemModeRipple>(DirectorStyles.kRippleToolColor, KeyCode.Alpha2) },
  59. { EditType.Replace, new SubEditMode<MoveItemModeReplace, TrimItemModeReplace, AddDeleteItemModeReplace>(DirectorStyles.kReplaceToolColor, KeyCode.Alpha3) }
  60. };
  61. static EditType s_CurrentEditType = EditType.Mix;
  62. static EditType s_OverrideEditType = EditType.None;
  63. static ITrimmable s_CurrentTrimItem;
  64. static TrimEdge s_CurrentTrimDirection;
  65. static MoveItemHandler s_CurrentMoveItemHandler;
  66. static EditModeInputHandler s_InputHandler = new EditModeInputHandler();
  67. static ITrimItemMode trimMode
  68. {
  69. get { return GetSubEditMode(editType).trimItemMode; }
  70. }
  71. static ITrimItemDrawer trimDrawer
  72. {
  73. get { return GetSubEditMode(editType).trimItemDrawer; }
  74. }
  75. static IMoveItemMode moveMode
  76. {
  77. get { return GetSubEditMode(editType).moveItemMode; }
  78. }
  79. static IMoveItemDrawer moveDrawer
  80. {
  81. get { return GetSubEditMode(editType).moveItemDrawer; }
  82. }
  83. static IAddDeleteItemMode addDeleteMode
  84. {
  85. get { return GetSubEditMode(editType).addDeleteItemMode; }
  86. }
  87. public static EditModeInputHandler inputHandler
  88. {
  89. get { return s_InputHandler; }
  90. }
  91. static Color modeColor
  92. {
  93. get { return GetSubEditMode(editType).color; }
  94. }
  95. public static EditType editType
  96. {
  97. get
  98. {
  99. if (s_OverrideEditType != EditType.None)
  100. return s_OverrideEditType;
  101. var window = TimelineWindow.instance;
  102. if (window != null)
  103. s_CurrentEditType = window.state.editType;
  104. return s_CurrentEditType;
  105. }
  106. set
  107. {
  108. s_CurrentEditType = value;
  109. var window = TimelineWindow.instance;
  110. if (window != null)
  111. window.state.editType = value;
  112. s_OverrideEditType = EditType.None;
  113. }
  114. }
  115. static ISubEditMode GetSubEditMode(EditType type)
  116. {
  117. var subEditMode = k_EditModes[type];
  118. if (subEditMode != null)
  119. return subEditMode;
  120. Debug.LogError("Unsupported editmode type");
  121. return null;
  122. }
  123. static EditType GetSubEditType(KeyCode key)
  124. {
  125. foreach (var subEditMode in k_EditModes)
  126. {
  127. if (subEditMode.Value.clutchKey == key)
  128. return subEditMode.Key;
  129. }
  130. return EditType.None;
  131. }
  132. public static void ClearEditMode()
  133. {
  134. k_EditModes[editType].Reset();
  135. }
  136. public static void BeginTrim(ITimelineItem item, TrimEdge trimDirection)
  137. {
  138. var itemToTrim = item as ITrimmable;
  139. if (itemToTrim == null) return;
  140. s_CurrentTrimItem = itemToTrim;
  141. s_CurrentTrimDirection = trimDirection;
  142. trimMode.OnBeforeTrim(itemToTrim, trimDirection);
  143. TimelineUndo.PushUndo(itemToTrim.parentTrack, "Trim Clip");
  144. }
  145. public static void TrimStart(ITimelineItem item, double time)
  146. {
  147. var itemToTrim = item as ITrimmable;
  148. if (itemToTrim == null) return;
  149. trimMode.TrimStart(itemToTrim, time);
  150. }
  151. public static void TrimEnd(ITimelineItem item, double time, bool affectTimeScale)
  152. {
  153. var itemToTrim = item as ITrimmable;
  154. if (itemToTrim == null) return;
  155. trimMode.TrimEnd(itemToTrim, time, affectTimeScale);
  156. }
  157. public static void DrawTrimGUI(WindowState state, TimelineItemGUI item, TrimEdge edge)
  158. {
  159. trimDrawer.DrawGUI(state, item.rect, modeColor, edge);
  160. }
  161. public static void FinishTrim()
  162. {
  163. s_CurrentTrimItem = null;
  164. TimelineCursors.ClearCursor();
  165. ClearEditMode();
  166. TimelineEditor.Refresh(RefreshReason.ContentsModified);
  167. }
  168. public static void BeginMove(MoveItemHandler moveItemHandler)
  169. {
  170. s_CurrentMoveItemHandler = moveItemHandler;
  171. moveMode.BeginMove(s_CurrentMoveItemHandler.movingItems);
  172. }
  173. public static void UpdateMove()
  174. {
  175. moveMode.UpdateMove(s_CurrentMoveItemHandler.movingItems);
  176. }
  177. public static void OnTrackDetach(IEnumerable<ItemsPerTrack> grabbedTrackItems)
  178. {
  179. moveMode.OnTrackDetach(grabbedTrackItems);
  180. }
  181. public static void HandleTrackSwitch(IEnumerable<ItemsPerTrack> grabbedTrackItems)
  182. {
  183. moveMode.HandleTrackSwitch(grabbedTrackItems);
  184. }
  185. public static bool AllowTrackSwitch()
  186. {
  187. return moveMode.AllowTrackSwitch();
  188. }
  189. public static double AdjustStartTime(WindowState state, ItemsPerTrack itemsGroup, double time)
  190. {
  191. return moveMode.AdjustStartTime(state, itemsGroup, time);
  192. }
  193. public static bool ValidateDrag(ItemsPerTrack itemsGroup)
  194. {
  195. return moveMode.ValidateMove(itemsGroup);
  196. }
  197. public static void DrawMoveGUI(WindowState state, IEnumerable<MovingItems> movingItems)
  198. {
  199. moveDrawer.DrawGUI(state, movingItems, modeColor);
  200. }
  201. public static void FinishMove()
  202. {
  203. var manipulatedItemsList = s_CurrentMoveItemHandler.movingItems;
  204. moveMode.FinishMove(manipulatedItemsList);
  205. foreach (var itemsGroup in manipulatedItemsList)
  206. foreach (var item in itemsGroup.items)
  207. item.parentTrack = itemsGroup.targetTrack;
  208. s_CurrentMoveItemHandler = null;
  209. TimelineCursors.ClearCursor();
  210. ClearEditMode();
  211. TimelineEditor.Refresh(RefreshReason.ContentsModified);
  212. }
  213. public static void FinalizeInsertItemsAtTime(IEnumerable<ItemsPerTrack> newItems, double requestedTime)
  214. {
  215. addDeleteMode.InsertItemsAtTime(newItems, requestedTime);
  216. }
  217. public static void PrepareItemsDelete(IEnumerable<ItemsPerTrack> newItems)
  218. {
  219. addDeleteMode.RemoveItems(newItems);
  220. }
  221. public static void HandleModeClutch()
  222. {
  223. if (Event.current.type == EventType.KeyDown && EditorGUI.IsEditingTextField())
  224. return;
  225. var prevType = editType;
  226. if (Event.current.type == EventType.KeyDown)
  227. {
  228. var clutchEditType = GetSubEditType(Event.current.keyCode);
  229. if (clutchEditType != EditType.None)
  230. {
  231. s_OverrideEditType = clutchEditType;
  232. Event.current.Use();
  233. }
  234. }
  235. else if (Event.current.type == EventType.KeyUp)
  236. {
  237. var clutchEditType = GetSubEditType(Event.current.keyCode);
  238. if (clutchEditType == s_OverrideEditType)
  239. {
  240. s_OverrideEditType = EditType.None;
  241. Event.current.Use();
  242. }
  243. }
  244. if (prevType != editType)
  245. {
  246. if (s_CurrentTrimItem != null)
  247. {
  248. trimMode.OnBeforeTrim(s_CurrentTrimItem, s_CurrentTrimDirection);
  249. }
  250. else if (s_CurrentMoveItemHandler != null)
  251. {
  252. if (s_CurrentMoveItemHandler.movingItems == null)
  253. {
  254. s_CurrentMoveItemHandler = null;
  255. return;
  256. }
  257. foreach (var movingItems in s_CurrentMoveItemHandler.movingItems)
  258. {
  259. if (movingItems != null && movingItems.HasAnyDetachedParents())
  260. {
  261. foreach (var items in movingItems.items)
  262. {
  263. items.parentTrack = movingItems.originalTrack;
  264. }
  265. }
  266. }
  267. var movingSelection = s_CurrentMoveItemHandler.movingItems;
  268. // Handle clutch key transition if needed
  269. GetSubEditMode(prevType).moveItemMode.OnModeClutchExit(movingSelection);
  270. moveMode.OnModeClutchEnter(movingSelection);
  271. moveMode.BeginMove(movingSelection);
  272. moveMode.HandleTrackSwitch(movingSelection);
  273. UpdateMove();
  274. s_CurrentMoveItemHandler.RefreshPreviewItems();
  275. TimelineWindow.instance.state.rebuildGraph = true; // TODO Rebuild only if parent changed
  276. }
  277. TimelineWindow.instance.Repaint(); // TODO Refresh the toolbar without doing a full repaint?
  278. }
  279. }
  280. }
  281. }