345 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			345 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using UnityEngine;
 | |
| using UnityEngine.Timeline;
 | |
| 
 | |
| namespace UnityEditor.Timeline
 | |
| {
 | |
|     static class EditMode
 | |
|     {
 | |
|         public enum EditType
 | |
|         {
 | |
|             None = -1,
 | |
|             Mix = 0,
 | |
|             Ripple = 1,
 | |
|             Replace = 2
 | |
|         }
 | |
| 
 | |
|         interface ISubEditMode
 | |
|         {
 | |
|             IMoveItemMode moveItemMode { get; }
 | |
|             IMoveItemDrawer moveItemDrawer { get; }
 | |
|             ITrimItemMode trimItemMode { get; }
 | |
|             ITrimItemDrawer trimItemDrawer { get; }
 | |
|             IAddDeleteItemMode addDeleteItemMode { get; }
 | |
| 
 | |
|             Color color { get; }
 | |
|             KeyCode clutchKey { get; }
 | |
| 
 | |
|             void Reset();
 | |
|         }
 | |
| 
 | |
|         class SubEditMode<TMoveMode, TTrimMode, TAddDeleteMode> : ISubEditMode
 | |
|             where TMoveMode : class, IMoveItemMode, IMoveItemDrawer, new()
 | |
|             where TTrimMode : class, ITrimItemMode, ITrimItemDrawer, new()
 | |
|             where TAddDeleteMode : class, IAddDeleteItemMode, new()
 | |
|         {
 | |
|             public SubEditMode(Color guiColor, KeyCode key)
 | |
|             {
 | |
|                 color = guiColor;
 | |
|                 clutchKey = key;
 | |
|                 Reset();
 | |
|             }
 | |
| 
 | |
|             public void Reset()
 | |
|             {
 | |
|                 m_MoveItemMode = new TMoveMode();
 | |
|                 m_TrimItemMode = new TTrimMode();
 | |
|                 m_AddDeleteItemMode = new TAddDeleteMode();
 | |
|             }
 | |
| 
 | |
|             TMoveMode m_MoveItemMode;
 | |
|             TTrimMode m_TrimItemMode;
 | |
|             TAddDeleteMode m_AddDeleteItemMode;
 | |
| 
 | |
|             public IMoveItemMode moveItemMode { get { return m_MoveItemMode; } }
 | |
|             public IMoveItemDrawer moveItemDrawer { get { return m_MoveItemMode; } }
 | |
|             public ITrimItemMode trimItemMode { get { return m_TrimItemMode; } }
 | |
|             public ITrimItemDrawer trimItemDrawer { get { return m_TrimItemMode; } }
 | |
|             public IAddDeleteItemMode addDeleteItemMode { get { return m_AddDeleteItemMode; } }
 | |
|             public Color color { get; }
 | |
|             public KeyCode clutchKey { get; }
 | |
|         }
 | |
| 
 | |
|         static readonly Dictionary<EditType, ISubEditMode> k_EditModes = new Dictionary<EditType, ISubEditMode>
 | |
|         {
 | |
|             { EditType.Mix,     new SubEditMode<MoveItemModeMix, TrimItemModeMix, AddDeleteItemModeMix>(DirectorStyles.kMixToolColor, KeyCode.Alpha1) },
 | |
|             { EditType.Ripple,  new SubEditMode<MoveItemModeRipple, TrimItemModeRipple, AddDeleteItemModeRipple>(DirectorStyles.kRippleToolColor, KeyCode.Alpha2) },
 | |
|             { EditType.Replace, new SubEditMode<MoveItemModeReplace, TrimItemModeReplace, AddDeleteItemModeReplace>(DirectorStyles.kReplaceToolColor, KeyCode.Alpha3) }
 | |
|         };
 | |
| 
 | |
|         static EditType s_CurrentEditType = EditType.Mix;
 | |
|         static EditType s_OverrideEditType = EditType.None;
 | |
| 
 | |
|         static ITrimmable s_CurrentTrimItem;
 | |
|         static TrimEdge s_CurrentTrimDirection;
 | |
|         static MoveItemHandler s_CurrentMoveItemHandler;
 | |
|         static EditModeInputHandler s_InputHandler = new EditModeInputHandler();
 | |
| 
 | |
|         static ITrimItemMode trimMode
 | |
|         {
 | |
|             get { return GetSubEditMode(editType).trimItemMode; }
 | |
|         }
 | |
| 
 | |
|         static ITrimItemDrawer trimDrawer
 | |
|         {
 | |
|             get { return GetSubEditMode(editType).trimItemDrawer; }
 | |
|         }
 | |
| 
 | |
|         static IMoveItemMode moveMode
 | |
|         {
 | |
|             get { return GetSubEditMode(editType).moveItemMode; }
 | |
|         }
 | |
| 
 | |
|         static IMoveItemDrawer moveDrawer
 | |
|         {
 | |
|             get { return GetSubEditMode(editType).moveItemDrawer; }
 | |
|         }
 | |
| 
 | |
|         static IAddDeleteItemMode addDeleteMode
 | |
|         {
 | |
|             get { return GetSubEditMode(editType).addDeleteItemMode; }
 | |
|         }
 | |
| 
 | |
|         public static EditModeInputHandler inputHandler
 | |
|         {
 | |
|             get { return s_InputHandler; }
 | |
|         }
 | |
| 
 | |
|         static Color modeColor
 | |
|         {
 | |
|             get { return GetSubEditMode(editType).color; }
 | |
|         }
 | |
| 
 | |
|         public static EditType editType
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (s_OverrideEditType != EditType.None)
 | |
|                     return s_OverrideEditType;
 | |
| 
 | |
|                 var window = TimelineWindow.instance;
 | |
|                 if (window != null)
 | |
|                     s_CurrentEditType = window.state.editType;
 | |
| 
 | |
|                 return s_CurrentEditType;
 | |
|             }
 | |
|             set
 | |
|             {
 | |
|                 s_CurrentEditType = value;
 | |
| 
 | |
|                 var window = TimelineWindow.instance;
 | |
|                 if (window != null)
 | |
|                     window.state.editType = value;
 | |
| 
 | |
|                 s_OverrideEditType = EditType.None;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         static ISubEditMode GetSubEditMode(EditType type)
 | |
|         {
 | |
|             var subEditMode = k_EditModes[type];
 | |
|             if (subEditMode != null)
 | |
|                 return subEditMode;
 | |
| 
 | |
|             Debug.LogError("Unsupported editmode type");
 | |
|             return null;
 | |
|         }
 | |
| 
 | |
|         static EditType GetSubEditType(KeyCode key)
 | |
|         {
 | |
|             foreach (var subEditMode in k_EditModes)
 | |
|             {
 | |
|                 if (subEditMode.Value.clutchKey == key)
 | |
|                     return subEditMode.Key;
 | |
|             }
 | |
|             return EditType.None;
 | |
|         }
 | |
| 
 | |
|         public static void ClearEditMode()
 | |
|         {
 | |
|             k_EditModes[editType].Reset();
 | |
|         }
 | |
| 
 | |
|         public static void BeginTrim(ITimelineItem item, TrimEdge trimDirection)
 | |
|         {
 | |
|             var itemToTrim = item as ITrimmable;
 | |
|             if (itemToTrim == null) return;
 | |
| 
 | |
|             s_CurrentTrimItem = itemToTrim;
 | |
|             s_CurrentTrimDirection = trimDirection;
 | |
|             trimMode.OnBeforeTrim(itemToTrim, trimDirection);
 | |
|             UndoExtensions.RegisterTrack(itemToTrim.parentTrack, L10n.Tr("Trim Clip"));
 | |
|         }
 | |
| 
 | |
|         public static void TrimStart(ITimelineItem item, double time, bool affectTimeScale)
 | |
|         {
 | |
|             var itemToTrim = item as ITrimmable;
 | |
|             if (itemToTrim == null) return;
 | |
| 
 | |
|             trimMode.TrimStart(itemToTrim, time, affectTimeScale);
 | |
|         }
 | |
| 
 | |
|         public static void TrimEnd(ITimelineItem item, double time, bool affectTimeScale)
 | |
|         {
 | |
|             var itemToTrim = item as ITrimmable;
 | |
|             if (itemToTrim == null) return;
 | |
| 
 | |
|             trimMode.TrimEnd(itemToTrim, time, affectTimeScale);
 | |
|         }
 | |
| 
 | |
|         public static void DrawTrimGUI(WindowState state, TimelineItemGUI item, TrimEdge edge)
 | |
|         {
 | |
|             trimDrawer.DrawGUI(state, item.rect, modeColor, edge);
 | |
|         }
 | |
| 
 | |
|         public static void FinishTrim()
 | |
|         {
 | |
|             s_CurrentTrimItem = null;
 | |
| 
 | |
|             TimelineCursors.ClearCursor();
 | |
|             ClearEditMode();
 | |
| 
 | |
|             TimelineEditor.Refresh(RefreshReason.ContentsModified);
 | |
|         }
 | |
| 
 | |
|         public static void BeginMove(MoveItemHandler moveItemHandler)
 | |
|         {
 | |
|             s_CurrentMoveItemHandler = moveItemHandler;
 | |
|             moveMode.BeginMove(s_CurrentMoveItemHandler.movingItems);
 | |
|         }
 | |
| 
 | |
|         public static void UpdateMove()
 | |
|         {
 | |
|             moveMode.UpdateMove(s_CurrentMoveItemHandler.movingItems);
 | |
|         }
 | |
| 
 | |
|         public static void OnTrackDetach(IEnumerable<ItemsPerTrack> grabbedTrackItems)
 | |
|         {
 | |
|             moveMode.OnTrackDetach(grabbedTrackItems);
 | |
|         }
 | |
| 
 | |
|         public static void HandleTrackSwitch(IEnumerable<ItemsPerTrack> grabbedTrackItems)
 | |
|         {
 | |
|             moveMode.HandleTrackSwitch(grabbedTrackItems);
 | |
|         }
 | |
| 
 | |
|         public static bool AllowTrackSwitch()
 | |
|         {
 | |
|             return moveMode.AllowTrackSwitch();
 | |
|         }
 | |
| 
 | |
|         public static double AdjustStartTime(WindowState state, ItemsPerTrack itemsGroup, double time)
 | |
|         {
 | |
|             return moveMode.AdjustStartTime(state, itemsGroup, time);
 | |
|         }
 | |
| 
 | |
|         public static bool ValidateDrag(ItemsPerTrack itemsGroup)
 | |
|         {
 | |
|             return moveMode.ValidateMove(itemsGroup);
 | |
|         }
 | |
| 
 | |
|         public static void DrawMoveGUI(WindowState state, IEnumerable<MovingItems> movingItems)
 | |
|         {
 | |
|             moveDrawer.DrawGUI(state, movingItems, modeColor);
 | |
|         }
 | |
| 
 | |
|         public static void FinishMove()
 | |
|         {
 | |
|             var manipulatedItemsList = s_CurrentMoveItemHandler.movingItems;
 | |
|             moveMode.FinishMove(manipulatedItemsList);
 | |
| 
 | |
|             foreach (var itemsGroup in manipulatedItemsList)
 | |
|                 foreach (var item in itemsGroup.items)
 | |
|                     item.parentTrack = itemsGroup.targetTrack;
 | |
| 
 | |
|             s_CurrentMoveItemHandler = null;
 | |
| 
 | |
|             TimelineCursors.ClearCursor();
 | |
|             ClearEditMode();
 | |
| 
 | |
|             TimelineEditor.Refresh(RefreshReason.ContentsModified);
 | |
|         }
 | |
| 
 | |
|         public static void FinalizeInsertItemsAtTime(IEnumerable<ItemsPerTrack> newItems, double requestedTime)
 | |
|         {
 | |
|             addDeleteMode.InsertItemsAtTime(newItems, requestedTime);
 | |
|         }
 | |
| 
 | |
|         public static void PrepareItemsDelete(IEnumerable<ItemsPerTrack> newItems)
 | |
|         {
 | |
|             addDeleteMode.RemoveItems(newItems);
 | |
|         }
 | |
| 
 | |
|         public static void HandleModeClutch()
 | |
|         {
 | |
|             if (Event.current.type == EventType.KeyDown && EditorGUI.IsEditingTextField())
 | |
|                 return;
 | |
| 
 | |
|             var prevType = editType;
 | |
| 
 | |
|             if (Event.current.type == EventType.KeyDown)
 | |
|             {
 | |
|                 var clutchEditType = GetSubEditType(Event.current.keyCode);
 | |
|                 if (clutchEditType != EditType.None)
 | |
|                 {
 | |
|                     s_OverrideEditType = clutchEditType;
 | |
|                     Event.current.Use();
 | |
|                 }
 | |
|             }
 | |
|             else if (Event.current.type == EventType.KeyUp)
 | |
|             {
 | |
|                 var clutchEditType = GetSubEditType(Event.current.keyCode);
 | |
|                 if (clutchEditType == s_OverrideEditType)
 | |
|                 {
 | |
|                     s_OverrideEditType = EditType.None;
 | |
|                     Event.current.Use();
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if (prevType != editType)
 | |
|             {
 | |
|                 if (s_CurrentTrimItem != null)
 | |
|                 {
 | |
|                     trimMode.OnBeforeTrim(s_CurrentTrimItem, s_CurrentTrimDirection);
 | |
|                 }
 | |
|                 else if (s_CurrentMoveItemHandler != null)
 | |
|                 {
 | |
|                     if (s_CurrentMoveItemHandler.movingItems == null)
 | |
|                     {
 | |
|                         s_CurrentMoveItemHandler = null;
 | |
|                         return;
 | |
|                     }
 | |
| 
 | |
|                     foreach (var movingItems in s_CurrentMoveItemHandler.movingItems)
 | |
|                     {
 | |
|                         if (movingItems != null && movingItems.HasAnyDetachedParents())
 | |
|                         {
 | |
|                             foreach (var items in movingItems.items)
 | |
|                             {
 | |
|                                 items.parentTrack = movingItems.originalTrack;
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     var movingSelection = s_CurrentMoveItemHandler.movingItems;
 | |
| 
 | |
|                     // Handle clutch key transition if needed
 | |
|                     GetSubEditMode(prevType).moveItemMode.OnModeClutchExit(movingSelection);
 | |
|                     moveMode.OnModeClutchEnter(movingSelection);
 | |
| 
 | |
|                     moveMode.BeginMove(movingSelection);
 | |
|                     moveMode.HandleTrackSwitch(movingSelection);
 | |
| 
 | |
|                     UpdateMove();
 | |
|                     s_CurrentMoveItemHandler.RefreshPreviewItems();
 | |
| 
 | |
|                     TimelineWindow.instance.state.rebuildGraph = true; // TODO Rebuild only if parent changed
 | |
|                 }
 | |
| 
 | |
|                 TimelineWindow.instance.Repaint(); // TODO Refresh the toolbar without doing a full repaint?
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |