summaryrefslogtreecommitdiff
path: root/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions
diff options
context:
space:
mode:
authorAndrew Lee <alee14498@protonmail.com>2020-04-19 17:19:32 -0400
committerAndrew Lee <alee14498@protonmail.com>2020-04-19 17:19:32 -0400
commitc55fba8ab2a1c9d3df65eda4a5a1e957f4aa1f78 (patch)
treeee4d51c7c1d633e11f46453ef1edd3c77c4ef9f7 /Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions
downloadProject-Sandbox-c55fba8ab2a1c9d3df65eda4a5a1e957f4aa1f78.tar.gz
Project-Sandbox-c55fba8ab2a1c9d3df65eda4a5a1e957f4aa1f78.tar.bz2
Project-Sandbox-c55fba8ab2a1c9d3df65eda4a5a1e957f4aa1f78.zip
Inital commit
Diffstat (limited to 'Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions')
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/ClipsActions.cs376
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/ClipsActions.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/ItemAction.cs124
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/ItemAction.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/MarkerActions.cs17
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/MarkerActions.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus.meta8
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus/MenuItemActionBase.cs177
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus/MenuItemActionBase.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus/TimelineContextMenu.cs448
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus/TimelineContextMenu.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/TimelineActions.cs946
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/TimelineActions.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/TrackActions.cs521
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/TrackActions.cs.meta11
15 files changed, 2694 insertions, 0 deletions
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/ClipsActions.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/ClipsActions.cs
new file mode 100644
index 0000000..e12af71
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/ClipsActions.cs
@@ -0,0 +1,376 @@
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using JetBrains.Annotations;
+using UnityEngine;
+using UnityEngine.Timeline;
+using UnityEngine.Playables;
+using ClipAction = UnityEditor.Timeline.ItemAction<UnityEngine.Timeline.TimelineClip>;
+
+namespace UnityEditor.Timeline
+{
+ [MenuEntry("Edit in Animation Window", MenuOrder.ClipEditAction.EditInAnimationWindow), UsedImplicitly]
+ class EditClipInAnimationWindow : ClipAction
+ {
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TimelineClip[] clips)
+ {
+ if (clips.Length == 1 && clips[0].animationClip != null)
+ return MenuActionDisplayState.Visible;
+ return MenuActionDisplayState.Hidden;
+ }
+
+ public override bool Execute(WindowState state, TimelineClip[] clips)
+ {
+ var clip = clips[0];
+
+ if (clip.curves != null || clip.animationClip != null)
+ {
+ var clipToEdit = clip.animationClip != null ? clip.animationClip : clip.curves;
+ if (clipToEdit == null)
+ return false;
+
+ var gameObject = state.GetSceneReference(clip.parentTrack);
+ var timeController = TimelineAnimationUtilities.CreateTimeController(state, clip);
+ TimelineAnimationUtilities.EditAnimationClipWithTimeController(
+ clipToEdit, timeController, clip.animationClip != null ? gameObject : null);
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ [MenuEntry("Edit Sub-Timeline", MenuOrder.ClipEditAction.EditSubTimeline), UsedImplicitly]
+ class EditSubTimeline : ClipAction
+ {
+ private static readonly string MultiItemPrefix = "Edit Sub-Timelines/";
+ private static readonly string SingleItemPrefix = "Edit ";
+
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TimelineClip[] clips)
+ {
+ return IsValid(state, clips) ? MenuActionDisplayState.Visible : MenuActionDisplayState.Hidden;
+ }
+
+ bool IsValid(WindowState state, TimelineClip[] clips)
+ {
+ if (clips.Length != 1 || state == null || state.editSequence.director == null) return false;
+ var clip = clips[0];
+
+ var directors = TimelineUtility.GetSubTimelines(clip, state.editSequence.director);
+ return directors.Any(x => x != null);
+ }
+
+ public override bool Execute(WindowState state, TimelineClip[] clips)
+ {
+ if (!IsValid(state, clips)) return false;
+
+ var clip = clips[0];
+
+ var directors = TimelineUtility.GetSubTimelines(clip, state.editSequence.director);
+ ExecuteInternal(state, directors, 0, clip);
+
+ return true;
+ }
+
+ static void ExecuteInternal(WindowState state, IList<PlayableDirector> directors, int directorIndex, TimelineClip clip)
+ {
+ SelectionManager.Clear();
+ state.GetWindow().SetCurrentTimeline(directors[directorIndex], clip);
+ }
+
+ protected override void AddMenuItem(WindowState state, TimelineClip[] items, List<MenuActionItem> menuItems)
+ {
+ if (items == null || items.Length != 1)
+ return;
+
+ var mode = TimelineWindow.instance.currentMode.mode;
+ var menuItem = new MenuActionItem()
+ {
+ category = category,
+ entryName = GetDisplayName(items),
+ shortCut = string.Empty,
+ isChecked = false,
+ isActiveInMode = IsActionActiveInMode(this, mode),
+ priority = priority,
+ state = GetDisplayState(state, items),
+ callback = null
+ };
+
+ var subDirectors = TimelineUtility.GetSubTimelines(items[0], state.editSequence.director);
+ if (subDirectors.Count == 1)
+ {
+ menuItem.entryName = SingleItemPrefix + DisplayNameHelper.GetDisplayName(subDirectors[0]);
+ menuItem.callback = () => Execute(state, items);
+ menuItems.Add(menuItem);
+ }
+ else
+ {
+ for (int i = 0; i < subDirectors.Count; i++)
+ {
+ var index = i;
+ menuItem.category = MultiItemPrefix;
+ menuItem.entryName = DisplayNameHelper.GetDisplayName(subDirectors[i]);
+ menuItem.callback = () => ExecuteInternal(state, subDirectors, index, items[0]);
+ menuItems.Add(menuItem);
+ }
+ }
+ }
+ }
+
+ [MenuEntry("Editing/Trim Start", MenuOrder.ClipAction.TrimStart)]
+ [Shortcut(Shortcuts.Clip.trimStart), UsedImplicitly]
+ class TrimStart : ItemAction<TimelineClip>
+ {
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TimelineClip[] clips)
+ {
+ return clips.All(x => state.editSequence.time <= x.start || state.editSequence.time >= x.start + x.duration) ?
+ MenuActionDisplayState.Disabled : MenuActionDisplayState.Visible;
+ }
+
+ public override bool Execute(WindowState state, TimelineClip[] clips)
+ {
+ return ClipModifier.TrimStart(clips, state.editSequence.time);
+ }
+ }
+
+ [MenuEntry("Editing/Trim End", MenuOrder.ClipAction.TrimEnd), UsedImplicitly]
+ [Shortcut(Shortcuts.Clip.trimEnd)]
+ class TrimEnd : ItemAction<TimelineClip>
+ {
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TimelineClip[] clips)
+ {
+ return clips.All(x => state.editSequence.time <= x.start || state.editSequence.time >= x.start + x.duration) ?
+ MenuActionDisplayState.Disabled : MenuActionDisplayState.Visible;
+ }
+
+ public override bool Execute(WindowState state, TimelineClip[] clips)
+ {
+ return ClipModifier.TrimEnd(clips, state.editSequence.time);
+ }
+ }
+
+ [Shortcut(Shortcuts.Clip.split), MenuEntry("Editing/Split", MenuOrder.ClipAction.Split), UsedImplicitly]
+ class Split : ClipAction
+ {
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TimelineClip[] clips)
+ {
+ return clips.All(x => state.editSequence.time <= x.start || state.editSequence.time >= x.start + x.duration) ?
+ MenuActionDisplayState.Disabled : MenuActionDisplayState.Visible;
+ }
+
+ public override bool Execute(WindowState state, TimelineClip[] clips)
+ {
+ bool success = ClipModifier.Split(clips, state.editSequence.time, state.editSequence.director);
+ if (success)
+ state.Refresh();
+ return success;
+ }
+ }
+
+ [MenuEntry("Editing/Complete Last Loop", MenuOrder.ClipAction.CompleteLastLoop), UsedImplicitly]
+ class CompleteLastLoop : ClipAction
+ {
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TimelineClip[] clips)
+ {
+ bool canDisplay = clips.Any(TimelineHelpers.HasUsableAssetDuration);
+ return canDisplay ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled;
+ }
+
+ public override bool Execute(WindowState state, TimelineClip[] clips)
+ {
+ return ClipModifier.CompleteLastLoop(clips);
+ }
+ }
+
+ [MenuEntry("Editing/Trim Last Loop", MenuOrder.ClipAction.TrimLastLoop), UsedImplicitly]
+ class TrimLastLoop : ClipAction
+ {
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TimelineClip[] clips)
+ {
+ bool canDisplay = clips.Any(TimelineHelpers.HasUsableAssetDuration);
+ return canDisplay ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled;
+ }
+
+ public override bool Execute(WindowState state, TimelineClip[] clips)
+ {
+ return ClipModifier.TrimLastLoop(clips);
+ }
+ }
+
+ [MenuEntry("Editing/Match Duration", MenuOrder.ClipAction.MatchDuration), UsedImplicitly]
+ class MatchDuration : ClipAction
+ {
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TimelineClip[] clips)
+ {
+ return clips.Length > 1 ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled;
+ }
+
+ public override bool Execute(WindowState state, TimelineClip[] clips)
+ {
+ return ClipModifier.MatchDuration(clips);
+ }
+ }
+
+ [MenuEntry("Editing/Double Speed", MenuOrder.ClipAction.DoubleSpeed), UsedImplicitly]
+ class DoubleSpeed : ClipAction
+ {
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TimelineClip[] clips)
+ {
+ bool canDisplay = clips.All(x => x.SupportsSpeedMultiplier());
+
+ return canDisplay ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled;
+ }
+
+ public override bool Execute(WindowState state, TimelineClip[] clips)
+ {
+ return ClipModifier.DoubleSpeed(clips);
+ }
+ }
+
+ [MenuEntry("Editing/Half Speed", MenuOrder.ClipAction.HalfSpeed), UsedImplicitly]
+ class HalfSpeed : ClipAction
+ {
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TimelineClip[] clips)
+ {
+ bool canDisplay = clips.All(x => x.SupportsSpeedMultiplier());
+
+ return canDisplay ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled;
+ }
+
+ public override bool Execute(WindowState state, TimelineClip[] clips)
+ {
+ return ClipModifier.HalfSpeed(clips);
+ }
+ }
+
+ [MenuEntry("Editing/Reset Duration", MenuOrder.ClipAction.ResetDuration), UsedImplicitly]
+ class ResetDuration : ClipAction
+ {
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TimelineClip[] clips)
+ {
+ bool canDisplay = clips.Any(TimelineHelpers.HasUsableAssetDuration);
+ return canDisplay ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled;
+ }
+
+ public override bool Execute(WindowState state, TimelineClip[] clips)
+ {
+ return ClipModifier.ResetEditing(clips);
+ }
+ }
+
+ [MenuEntry("Editing/Reset Speed", MenuOrder.ClipAction.ResetSpeed), UsedImplicitly]
+ class ResetSpeed : ClipAction
+ {
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TimelineClip[] clips)
+ {
+ bool canDisplay = clips.All(x => x.SupportsSpeedMultiplier());
+
+ return canDisplay ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled;
+ }
+
+ public override bool Execute(WindowState state, TimelineClip[] clips)
+ {
+ return ClipModifier.ResetSpeed(clips);
+ }
+ }
+
+ [MenuEntry("Editing/Reset All", MenuOrder.ClipAction.ResetAll), UsedImplicitly]
+ class ResetAll : ClipAction
+ {
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TimelineClip[] clips)
+ {
+ bool canDisplay = clips.Any(TimelineHelpers.HasUsableAssetDuration) ||
+ clips.All(x => x.SupportsSpeedMultiplier());
+
+ return canDisplay ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled;
+ }
+
+ public override bool Execute(WindowState state, TimelineClip[] clips)
+ {
+ var speedResult = ClipModifier.ResetSpeed(clips);
+ var editResult = ClipModifier.ResetEditing(clips);
+ return speedResult || editResult;
+ }
+ }
+
+ [MenuEntry("Tile", MenuOrder.ClipAction.Tile), UsedImplicitly]
+ class Tile : ClipAction
+ {
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TimelineClip[] clips)
+ {
+ return clips.Length > 1 ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled;
+ }
+
+ public override bool Execute(WindowState state, TimelineClip[] clips)
+ {
+ return ClipModifier.Tile(clips);
+ }
+ }
+
+ [MenuEntry("Find Source Asset", MenuOrder.ClipAction.FindSourceAsset), UsedImplicitly]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class FindSourceAsset : ClipAction
+ {
+ protected override MenuActionDisplayState GetDisplayState(WindowState state,
+ TimelineClip[] clips)
+ {
+ if (clips.Length > 1)
+ return MenuActionDisplayState.Disabled;
+
+ if (GetUnderlyingAsset(state, clips[0]) == null)
+ return MenuActionDisplayState.Disabled;
+
+ return MenuActionDisplayState.Visible;
+ }
+
+ public override bool Execute(WindowState state, TimelineClip[] clips)
+ {
+ EditorGUIUtility.PingObject(GetUnderlyingAsset(state, clips[0]));
+ return true;
+ }
+
+ private static UnityEngine.Object GetExternalPlayableAsset(TimelineClip clip)
+ {
+ if (clip.asset == null)
+ return null;
+
+ if ((clip.asset.hideFlags & HideFlags.HideInHierarchy) != 0)
+ return null;
+
+ return clip.asset;
+ }
+
+ private static UnityEngine.Object GetUnderlyingAsset(WindowState state, TimelineClip clip)
+ {
+ var asset = clip.asset as ScriptableObject;
+ if (asset == null)
+ return null;
+
+ var fields = ObjectReferenceField.FindObjectReferences(asset.GetType());
+ if (fields.Length == 0)
+ return GetExternalPlayableAsset(clip);
+
+ // Find the first non-null field
+ foreach (var field in fields)
+ {
+ // skip scene refs in asset mode
+ if (state.editSequence.director == null && field.isSceneReference)
+ continue;
+ var obj = field.Find(asset, state.editSequence.director);
+ if (obj != null)
+ return obj;
+ }
+
+ return GetExternalPlayableAsset(clip);
+ }
+ }
+
+ class CopyClipsToClipboard : ClipAction
+ {
+ public override bool Execute(WindowState state, TimelineClip[] clips)
+ {
+ TimelineEditor.clipboard.CopyItems(clips.ToItems());
+ return true;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/ClipsActions.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/ClipsActions.cs.meta
new file mode 100644
index 0000000..666f56e
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/ClipsActions.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4b721099b5d509d4093e516f59ad9ad6
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/ItemAction.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/ItemAction.cs
new file mode 100644
index 0000000..cd4c3a4
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/ItemAction.cs
@@ -0,0 +1,124 @@
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using UnityEngine.Timeline;
+
+namespace UnityEditor.Timeline
+{
+ [ActiveInMode(TimelineModes.Default)]
+ abstract class ItemAction<T> : MenuItemActionBase where T : class
+ {
+ public abstract bool Execute(WindowState state, T[] items);
+
+ protected virtual MenuActionDisplayState GetDisplayState(WindowState state, T[] items)
+ {
+ return items.Length > 0 ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled;
+ }
+
+ protected virtual string GetDisplayName(T[] items)
+ {
+ return menuName;
+ }
+
+ public bool CanExecute(WindowState state, T[] items)
+ {
+ return GetDisplayState(state, items) == MenuActionDisplayState.Visible;
+ }
+
+ protected virtual void AddMenuItem(WindowState state, T[] items, List<MenuActionItem> menuItem)
+ {
+ var mode = TimelineWindow.instance.currentMode.mode;
+ menuItem.Add(
+ new MenuActionItem()
+ {
+ category = category,
+ entryName = GetDisplayName(items),
+ shortCut = this.shortCut,
+ isChecked = false,
+ isActiveInMode = IsActionActiveInMode(this, mode),
+ priority = priority,
+ state = GetDisplayState(state, items),
+ callback = () => Execute(state, items)
+ }
+ );
+ }
+
+ public static bool HandleShortcut(WindowState state, Event evt, T item)
+ {
+ T[] items = { item };
+
+ foreach (ItemAction<T> action in actions)
+ {
+ var attr = action.GetType().GetCustomAttributes(typeof(ShortcutAttribute), true);
+
+ foreach (ShortcutAttribute shortcut in attr)
+ {
+ if (shortcut.MatchesEvent(evt))
+ {
+ if (s_ShowActionTriggeredByShortcut)
+ Debug.Log(action.GetType().Name);
+
+ if (!IsActionActiveInMode(action, TimelineWindow.instance.currentMode.mode))
+ return false;
+
+ var result = action.Execute(state, items);
+ state.Refresh();
+ state.Evaluate();
+ return result;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ static List<ItemAction<T>> s_ActionClasses;
+
+ static List<ItemAction<T>> actions
+ {
+ get
+ {
+ if (s_ActionClasses == null)
+ {
+ s_ActionClasses = GetActionsOfType(typeof(ItemAction<T>)).Select(x => (ItemAction<T>)x.GetConstructors()[0].Invoke(null)).ToList();
+ }
+
+ return s_ActionClasses;
+ }
+ }
+
+ public static void GetMenuEntries(T[] items, List<MenuActionItem> menuItems)
+ {
+ if (items == null || items.Length == 0)
+ return;
+
+ foreach (var action in actions)
+ {
+ if (action.showInMenu)
+ action.AddMenuItem(TimelineWindow.instance.state, items, menuItems);
+ }
+ }
+
+ public static bool Invoke<TAction>(WindowState state, T[] items)
+ where TAction : ItemAction<T>
+ {
+ var itemsDerived = items.ToArray();
+
+ if (!itemsDerived.Any())
+ return false;
+
+ var action = actions.FirstOrDefault(x => x.GetType() == typeof(TAction));
+
+ if (action != null)
+ return action.Execute(state, itemsDerived);
+
+ return false;
+ }
+
+ public static bool Invoke<TAction>(WindowState state, T item)
+ where TAction : ItemAction<T>
+ {
+ return Invoke<TAction>(state, new[] {item});
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/ItemAction.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/ItemAction.cs.meta
new file mode 100644
index 0000000..fef443a
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/ItemAction.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 84b5362754a9d934ba259398b757d0be
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/MarkerActions.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/MarkerActions.cs
new file mode 100644
index 0000000..410b5c3
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/MarkerActions.cs
@@ -0,0 +1,17 @@
+using JetBrains.Annotations;
+using UnityEngine;
+using UnityEngine.Timeline;
+using MarkerAction = UnityEditor.Timeline.ItemAction<UnityEngine.Timeline.IMarker>;
+
+namespace UnityEditor.Timeline
+{
+ [UsedImplicitly]
+ class CopyMarkersToClipboard : MarkerAction
+ {
+ public override bool Execute(WindowState state, IMarker[] markers)
+ {
+ TimelineEditor.clipboard.CopyItems(markers.ToItems());
+ return true;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/MarkerActions.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/MarkerActions.cs.meta
new file mode 100644
index 0000000..2733046
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/MarkerActions.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5da77d4d078922b4c8466e9e35fb3f5e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus.meta
new file mode 100644
index 0000000..45d9fa7
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 985eed4bc2fbee941b761b8816d9055d
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus/MenuItemActionBase.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus/MenuItemActionBase.cs
new file mode 100644
index 0000000..241650f
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus/MenuItemActionBase.cs
@@ -0,0 +1,177 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using UnityEngine;
+
+namespace UnityEditor.Timeline
+{
+ enum MenuActionDisplayState
+ {
+ Visible,
+ Disabled,
+ Hidden
+ }
+
+ struct MenuActionItem
+ {
+ public string category;
+ public string entryName;
+ public string shortCut;
+ public int priority;
+ public bool isChecked;
+ public bool isActiveInMode;
+ public MenuActionDisplayState state;
+ public GenericMenu.MenuFunction callback;
+ }
+
+ class MenuItemActionBase
+ {
+ public Vector2? mousePosition { get; set; }
+
+ protected static bool s_ShowActionTriggeredByShortcut = false;
+
+ private static MenuEntryAttribute NoMenu = new MenuEntryAttribute(null, MenuOrder.DefaultPriority);
+ private MenuEntryAttribute m_MenuInfo;
+ private string m_ShortCut = null;
+
+
+ public static IEnumerable<Type> GetActionsOfType(Type actionType)
+ {
+ var query = TypeCache.GetTypesDerivedFrom(actionType).Where(type => !type.IsGenericType && !type.IsNested && !type.IsAbstract);
+ return query;
+ }
+
+ public static ShortcutAttribute GetShortcutAttributeForAction(MenuItemActionBase action)
+ {
+ var shortcutAttributes = action.GetType()
+ .GetCustomAttributes(typeof(ShortcutAttribute), true)
+ .Cast<ShortcutAttribute>();
+
+ foreach (var shortcutAttribute in shortcutAttributes)
+ {
+ var shortcutOverride = shortcutAttribute as ShortcutPlatformOverrideAttribute;
+ if (shortcutOverride != null)
+ {
+ if (shortcutOverride.MatchesCurrentPlatform())
+ return shortcutOverride;
+ }
+ else
+ {
+ return shortcutAttribute;
+ }
+ }
+
+ return null;
+ }
+
+ public static void BuildMenu(GenericMenu menu, List<MenuActionItem> items)
+ {
+ // sorted the outer menu by priority, then sort the innermenu by priority
+ var sortedItems =
+ items.GroupBy(x => string.IsNullOrEmpty(x.category) ? x.entryName : x.category).
+ OrderBy(x => x.Min(y => y.priority)).
+ SelectMany(x => x.OrderBy(z => z.priority));
+
+ int lastPriority = Int32.MinValue;
+ string lastCategory = string.Empty;
+
+ foreach (var s in sortedItems)
+ {
+ if (s.state == MenuActionDisplayState.Hidden)
+ continue;
+
+ var priority = s.priority;
+ if (lastPriority == Int32.MinValue)
+ {
+ lastPriority = priority;
+ }
+ else if ((priority / MenuOrder.SeparatorAt) > (lastPriority / MenuOrder.SeparatorAt))
+ {
+ string path = String.Empty;
+ if (lastCategory == s.category)
+ path = s.category;
+ menu.AddSeparator(path);
+ }
+
+ lastPriority = priority;
+ lastCategory = s.category;
+
+ string entry = s.category + s.entryName;
+ if (!string.IsNullOrEmpty(s.shortCut))
+ entry += " " + s.shortCut;
+
+ if (s.state == MenuActionDisplayState.Visible && s.isActiveInMode)
+ menu.AddItem(new GUIContent(entry), s.isChecked, s.callback);
+ else
+ menu.AddDisabledItem(new GUIContent(entry));
+ }
+ }
+
+ public static ActiveInModeAttribute GetActiveInModeAttribute(MenuItemActionBase action)
+ {
+ var attr = action.GetType().GetCustomAttributes(typeof(ActiveInModeAttribute), true);
+
+ if (attr.Length > 0)
+ return (attr[0] as ActiveInModeAttribute);
+
+ return null;
+ }
+
+ public static bool IsActionActiveInMode(MenuItemActionBase action, TimelineModes mode)
+ {
+ ActiveInModeAttribute attr = GetActiveInModeAttribute(action);
+ return attr != null && (attr.modes & mode) != 0;
+ }
+
+ public int priority
+ {
+ get { return menuInfo.priority; }
+ }
+
+ public string category
+ {
+ get { return menuInfo.subMenuPath; }
+ }
+
+ public string menuName
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(menuInfo.name))
+ return L10n.Tr(GetType().Name);
+ return menuInfo.name;
+ }
+ }
+
+ // shortcut used by the menu
+ public string shortCut
+ {
+ get
+ {
+ if (m_ShortCut == null)
+ {
+ var shortcutAttribute = GetShortcutAttributeForAction(this);
+ m_ShortCut = shortcutAttribute == null ? string.Empty : shortcutAttribute.GetMenuShortcut();
+ }
+ return m_ShortCut;
+ }
+ }
+
+ public bool showInMenu
+ {
+ get { return menuInfo != NoMenu; }
+ }
+
+ private MenuEntryAttribute menuInfo
+ {
+ get
+ {
+ if (m_MenuInfo == null)
+ m_MenuInfo = GetType().GetCustomAttributes(typeof(MenuEntryAttribute), false).OfType<MenuEntryAttribute>().DefaultIfEmpty(NoMenu).First();
+ return m_MenuInfo;
+ }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus/MenuItemActionBase.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus/MenuItemActionBase.cs.meta
new file mode 100644
index 0000000..045ed68
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus/MenuItemActionBase.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5882d0e4313310143acb11d1a66c597f
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus/TimelineContextMenu.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus/TimelineContextMenu.cs
new file mode 100644
index 0000000..495a9c3
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus/TimelineContextMenu.cs
@@ -0,0 +1,448 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using UnityEngine.Playables;
+using UnityEngine.Timeline;
+using Object = UnityEngine.Object;
+
+namespace UnityEditor.Timeline
+{
+ static class SequencerContextMenu
+ {
+ static readonly TimelineAction[] MarkerHeaderCommonOperations =
+ {
+ new PasteAction()
+ };
+
+ public static readonly TimelineAction[] MarkerHeaderMenuItems =
+ TimelineAction.AllActions.OfType<MarkerHeaderAction>().
+ Where(a => a.showInMenu).
+ Union(MarkerHeaderCommonOperations).
+ ToArray();
+
+
+ static class Styles
+ {
+ public static readonly string addItemFromAssetTemplate = L10n.Tr("Add {0} From {1}");
+ public static readonly string addSingleItemFromAssetTemplate = L10n.Tr("Add From {1}");
+ public static readonly string addItemTemplate = L10n.Tr("Add {0}");
+ public static readonly string typeSelectorTemplate = L10n.Tr("Select {0}");
+ public static readonly string trackGroup = L10n.Tr("Track Group");
+ public static readonly string trackSubGroup = L10n.Tr("Track Sub-Group");
+ public static readonly string addTrackLayer = L10n.Tr("Add Layer");
+ public static readonly string layerName = L10n.Tr("Layer {0}");
+ }
+
+ public static void ShowMarkerHeaderContextMenu(Vector2? mousePosition, WindowState state)
+ {
+ var menu = new GenericMenu();
+ List<MenuActionItem> items = new List<MenuActionItem>(100);
+ BuildMarkerHeaderContextMenu(items, mousePosition, state);
+ MenuItemActionBase.BuildMenu(menu, items);
+ menu.ShowAsContext();
+ }
+
+ public static void ShowNewTracksContextMenu(ICollection<TrackAsset> tracks, WindowState state)
+ {
+ var menu = new GenericMenu();
+ List<MenuActionItem> items = new List<MenuActionItem>(100);
+ BuildNewTracksContextMenu(items, tracks, state);
+ MenuItemActionBase.BuildMenu(menu, items);
+ menu.ShowAsContext();
+ }
+
+ public static void ShowNewTracksContextMenu(ICollection<TrackAsset> tracks, WindowState state, Rect rect)
+ {
+ var menu = new GenericMenu();
+ List<MenuActionItem> items = new List<MenuActionItem>(100);
+ BuildNewTracksContextMenu(items, tracks, state);
+ MenuItemActionBase.BuildMenu(menu, items);
+ menu.DropDown(rect);
+ }
+
+ public static void ShowTrackContextMenu(TrackAsset[] tracks, Vector2? mousePosition)
+ {
+ if (tracks == null || tracks.Length == 0)
+ return;
+
+ var items = new List<MenuActionItem>();
+ var menu = new GenericMenu();
+ BuildTrackContextMenu(items, tracks, mousePosition);
+ MenuItemActionBase.BuildMenu(menu, items);
+ menu.ShowAsContext();
+ }
+
+ public static void ShowItemContextMenu(Vector2 mousePosition, TimelineClip[] clips, IMarker[] markers)
+ {
+ var menu = new GenericMenu();
+ var items = new List<MenuActionItem>();
+ BuildItemContextMenu(items, mousePosition, clips, markers);
+ MenuItemActionBase.BuildMenu(menu, items);
+ menu.ShowAsContext();
+ }
+
+ internal static void BuildItemContextMenu(List<MenuActionItem> items, Vector2 mousePosition, TimelineClip[] clips, IMarker[] markers)
+ {
+ var state = TimelineWindow.instance.state;
+
+ TimelineAction.GetMenuEntries(TimelineAction.MenuActions, mousePosition, items);
+ ItemAction<TimelineClip>.GetMenuEntries(clips, items);
+ ItemAction<IMarker>.GetMenuEntries(markers, items);
+
+ if (clips.Length > 0)
+ AddMarkerMenuCommands(items, clips.Select(c => c.parentTrack).Distinct().ToList(), TimelineHelpers.GetCandidateTime(state, mousePosition));
+ }
+
+ internal static void BuildNewTracksContextMenu(List<MenuActionItem> menuItems, ICollection<TrackAsset> parentTracks, WindowState state, string format = null)
+ {
+ if (parentTracks == null)
+ parentTracks = new TrackAsset[0];
+
+ if (string.IsNullOrEmpty(format))
+ format = "{0}";
+
+ // Add Group or SubGroup
+ var title = string.Format(format, parentTracks.Any(t => t != null) ? Styles.trackSubGroup : Styles.trackGroup);
+ var menuState = MenuActionDisplayState.Visible;
+ if (state.editSequence.isReadOnly)
+ menuState = MenuActionDisplayState.Disabled;
+ if (parentTracks.Any() && parentTracks.Any(t => t != null && t.lockedInHierarchy))
+ menuState = MenuActionDisplayState.Disabled;
+
+ GenericMenu.MenuFunction command = () =>
+ {
+ SelectionManager.Clear();
+ if (parentTracks.Count == 0)
+ Selection.Add(TimelineHelpers.CreateTrack<GroupTrack>(null, title));
+
+ foreach (var parentTrack in parentTracks)
+ Selection.Add(TimelineHelpers.CreateTrack<GroupTrack>(parentTrack, title));
+
+ TimelineEditor.Refresh(RefreshReason.ContentsAddedOrRemoved);
+ };
+
+ menuItems.Add(
+ new MenuActionItem()
+ {
+ category = string.Empty,
+ entryName = title,
+ shortCut = string.Empty,
+ isActiveInMode = true,
+ isChecked = false,
+ priority = MenuOrder.AddGroupItemStart,
+ state = menuState,
+ callback = command
+ }
+ );
+
+
+ var allTypes = TypeUtility.AllTrackTypes().Where(x => x != typeof(GroupTrack) && !TypeUtility.IsHiddenInMenu(x)).ToList();
+
+ int builtInPriority = MenuOrder.AddTrackItemStart;
+ int customPriority = MenuOrder.AddCustomTrackItemStart;
+ foreach (var trackType in allTypes)
+ {
+ var trackItemType = trackType;
+
+ command = () =>
+ {
+ SelectionManager.Clear();
+
+ if (parentTracks.Count == 0)
+ SelectionManager.Add(TimelineHelpers.CreateTrack((Type)trackItemType, null));
+
+ foreach (var parentTrack in parentTracks)
+ SelectionManager.Add(TimelineHelpers.CreateTrack((Type)trackItemType, parentTrack));
+ };
+
+ menuItems.Add(
+ new MenuActionItem()
+ {
+ category = TimelineHelpers.GetTrackCategoryName(trackType),
+ entryName = string.Format(format, TimelineHelpers.GetTrackMenuName(trackItemType)),
+ shortCut = string.Empty,
+ isActiveInMode = true,
+ isChecked = false,
+ priority = TypeUtility.IsBuiltIn(trackType) ? builtInPriority++ : customPriority++,
+ state = menuState,
+ callback = command
+ }
+ );
+ }
+ }
+
+ internal static void BuildMarkerHeaderContextMenu(List<MenuActionItem> menu, Vector2? mousePosition, WindowState state)
+ {
+ TimelineAction.GetMenuEntries(MarkerHeaderMenuItems, null, menu);
+
+ var timeline = state.editSequence.asset;
+ var time = TimelineHelpers.GetCandidateTime(state, mousePosition);
+ var enabled = timeline.markerTrack == null || !timeline.markerTrack.lockedInHierarchy;
+
+ var addMarkerCommand = new Action<Type, Object>
+ (
+ (type, obj) => AddSingleMarkerCallback(type, time, timeline, state.editSequence.director, obj)
+ );
+
+ AddMarkerMenuCommands(menu, new TrackAsset[] {timeline.markerTrack}, addMarkerCommand, enabled);
+ }
+
+ internal static void BuildTrackContextMenu(List<MenuActionItem> items, TrackAsset[] tracks, Vector2? mousePosition)
+ {
+ if (tracks == null || tracks.Length == 0)
+ return;
+
+ TimelineAction.GetMenuEntries(TimelineAction.MenuActions, mousePosition, items);
+ TrackAction.GetMenuEntries(TimelineWindow.instance.state, mousePosition, tracks, items);
+ AddLayeredTrackCommands(items, tracks);
+
+ var first = tracks.First().GetType();
+ var allTheSame = tracks.All(t => t.GetType() == first);
+ if (allTheSame)
+ {
+ if (first != typeof(GroupTrack))
+ {
+ var candidateTime = TimelineHelpers.GetCandidateTime(TimelineWindow.instance.state, mousePosition, tracks);
+ AddClipMenuCommands(items, tracks, candidateTime);
+ AddMarkerMenuCommands(items, tracks, candidateTime);
+ }
+ else
+ {
+ BuildNewTracksContextMenu(items, tracks, TimelineWindow.instance.state, Styles.addItemTemplate);
+ }
+ }
+ }
+
+ static void AddLayeredTrackCommands(List<MenuActionItem> menuItems, ICollection<TrackAsset> tracks)
+ {
+ if (tracks.Count == 0)
+ return;
+
+ var layeredType = tracks.First().GetType();
+ // animation tracks have a special menu.
+ if (layeredType == typeof(AnimationTrack))
+ return;
+
+ // must implement ILayerable
+ if (!typeof(UnityEngine.Timeline.ILayerable).IsAssignableFrom(layeredType))
+ return;
+
+ if (tracks.Any(t => t.GetType() != layeredType))
+ return;
+
+ // only supported on the master track no nesting.
+ if (tracks.Any(t => t.isSubTrack))
+ return;
+
+ var enabled = tracks.All(t => t != null && !t.lockedInHierarchy) && !TimelineWindow.instance.state.editSequence.isReadOnly;
+ int priority = MenuOrder.TrackAddMenu.AddLayerTrack;
+ GenericMenu.MenuFunction menuCallback = () =>
+ {
+ foreach (var track in tracks)
+ TimelineHelpers.CreateTrack(layeredType, track, string.Format(Styles.layerName, track.GetChildTracks().Count() + 1));
+ };
+
+ var entryName = Styles.addTrackLayer;
+ menuItems.Add(
+ new MenuActionItem()
+ {
+ category = string.Empty,
+ entryName = entryName,
+ shortCut = string.Empty,
+ isActiveInMode = true,
+ isChecked = false,
+ priority = priority++,
+ state = enabled ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled,
+ callback = menuCallback
+ }
+ );
+ }
+
+ static void AddClipMenuCommands(List<MenuActionItem> menuItems, ICollection<TrackAsset> tracks, double candidateTime)
+ {
+ if (!tracks.Any())
+ return;
+
+ var trackAsset = tracks.First();
+ var trackType = trackAsset.GetType();
+ if (tracks.Any(t => t.GetType() != trackType))
+ return;
+
+ var enabled = tracks.All(t => t != null && !t.lockedInHierarchy) && !TimelineWindow.instance.state.editSequence.isReadOnly;
+ var assetTypes = TypeUtility.GetPlayableAssetsHandledByTrack(trackType);
+ var visibleAssetTypes = TypeUtility.GetVisiblePlayableAssetsHandledByTrack(trackType);
+
+ // skips the name if there is only a single type
+ var commandNameTemplate = assetTypes.Count() == 1 ? Styles.addSingleItemFromAssetTemplate : Styles.addItemFromAssetTemplate;
+ int builtInPriority = MenuOrder.AddClipItemStart;
+ int customPriority = MenuOrder.AddCustomClipItemStart;
+ foreach (var assetType in assetTypes)
+ {
+ var assetItemType = assetType;
+ var category = TimelineHelpers.GetItemCategoryName(assetType);
+ Action<Object> onObjectChanged = obj =>
+ {
+ if (obj != null)
+ {
+ foreach (var t in tracks)
+ {
+ TimelineHelpers.CreateClipOnTrack(assetItemType, obj, t, candidateTime);
+ }
+ }
+ };
+
+ foreach (var objectReference in TypeUtility.ObjectReferencesForType(assetType))
+ {
+ var isSceneReference = objectReference.isSceneReference;
+ var dataType = objectReference.type;
+ GenericMenu.MenuFunction menuCallback = () =>
+ {
+ ObjectSelector.get.Show(null, dataType, null, isSceneReference, null, (obj) => onObjectChanged(obj), null);
+ ObjectSelector.get.titleContent = EditorGUIUtility.TrTextContent(string.Format(Styles.typeSelectorTemplate, TypeUtility.GetDisplayName(dataType)));
+ };
+
+ menuItems.Add(
+ new MenuActionItem()
+ {
+ category = category,
+ entryName = string.Format(commandNameTemplate, TypeUtility.GetDisplayName(assetType), TypeUtility.GetDisplayName(objectReference.type)),
+ shortCut = string.Empty,
+ isActiveInMode = true,
+ isChecked = false,
+ priority = TypeUtility.IsBuiltIn(assetType) ? builtInPriority++ : customPriority++,
+ state = enabled ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled,
+ callback = menuCallback
+ }
+ );
+ }
+ }
+
+ foreach (var assetType in visibleAssetTypes)
+ {
+ var assetItemType = assetType;
+ var category = TimelineHelpers.GetItemCategoryName(assetType);
+ var commandName = string.Format(Styles.addItemTemplate, TypeUtility.GetDisplayName(assetType));
+ GenericMenu.MenuFunction command = () =>
+ {
+ foreach (var t in tracks)
+ {
+ TimelineHelpers.CreateClipOnTrack(assetItemType, t, candidateTime);
+ }
+ };
+
+ menuItems.Add(
+ new MenuActionItem()
+ {
+ category = category,
+ entryName = commandName,
+ shortCut = string.Empty,
+ isActiveInMode = true,
+ isChecked = false,
+ priority = TypeUtility.IsBuiltIn(assetItemType) ? builtInPriority++ : customPriority++,
+ state = enabled ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled,
+ callback = command
+ }
+ );
+ }
+ }
+
+ static void AddMarkerMenuCommands(List<MenuActionItem> menu, IEnumerable<Type> markerTypes, Action<Type, Object> addMarkerCommand, bool enabled)
+ {
+ int builtInPriority = MenuOrder.AddMarkerItemStart;
+ int customPriority = MenuOrder.AddCustomMarkerItemStart;
+ foreach (var markerType in markerTypes)
+ {
+ var markerItemType = markerType;
+ string category = TimelineHelpers.GetItemCategoryName(markerItemType);
+ menu.Add(
+ new MenuActionItem()
+ {
+ category = category,
+ entryName = string.Format(Styles.addItemTemplate, TypeUtility.GetDisplayName(markerType)),
+ shortCut = string.Empty,
+ isActiveInMode = true,
+ isChecked = false,
+ priority = TypeUtility.IsBuiltIn(markerType) ? builtInPriority++ : customPriority++,
+ state = enabled ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled,
+ callback = () => addMarkerCommand(markerItemType, null)
+ }
+ );
+
+ foreach (var objectReference in TypeUtility.ObjectReferencesForType(markerType))
+ {
+ var isSceneReference = objectReference.isSceneReference;
+ GenericMenu.MenuFunction menuCallback = () =>
+ {
+ var dataType = markerItemType;
+ ObjectSelector.get.Show(null, dataType, null, isSceneReference, null, (obj) => addMarkerCommand(markerItemType, obj), null);
+ ObjectSelector.get.titleContent = EditorGUIUtility.TrTextContent(string.Format(Styles.typeSelectorTemplate, TypeUtility.GetDisplayName(dataType)));
+ };
+
+ menu.Add(
+ new MenuActionItem()
+ {
+ category = TimelineHelpers.GetItemCategoryName(markerItemType),
+ entryName = string.Format(Styles.addItemFromAssetTemplate, TypeUtility.GetDisplayName(markerType), TypeUtility.GetDisplayName(objectReference.type)),
+ shortCut = string.Empty,
+ isActiveInMode = true,
+ isChecked = false,
+ priority = TypeUtility.IsBuiltIn(markerType) ? builtInPriority++ : customPriority++,
+ state = enabled ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled,
+ callback = menuCallback
+ }
+ );
+ }
+ }
+ }
+
+ static void AddMarkerMenuCommands(List<MenuActionItem> menuItems, ICollection<TrackAsset> tracks, double candidateTime)
+ {
+ if (tracks.Count == 0)
+ return;
+
+ var enabled = tracks.All(t => !t.lockedInHierarchy) && !TimelineWindow.instance.state.editSequence.isReadOnly;
+ var addMarkerCommand = new Action<Type, Object>((type, obj) => AddMarkersCallback(tracks, type, candidateTime, obj));
+
+ AddMarkerMenuCommands(menuItems, tracks, addMarkerCommand, enabled);
+ }
+
+ static void AddMarkerMenuCommands(List<MenuActionItem> menuItems, ICollection<TrackAsset> tracks, Action<Type, Object> command, bool enabled)
+ {
+ var markerTypes = TypeUtility.GetBuiltInMarkerTypes().Union(TypeUtility.GetUserMarkerTypes());
+ if (tracks != null)
+ markerTypes = markerTypes.Where(x => tracks.All(track => (track == null) || TypeUtility.DoesTrackSupportMarkerType(track, x))); // null track indicates marker track to be created
+
+ AddMarkerMenuCommands(menuItems, markerTypes, command, enabled);
+ }
+
+ static void AddMarkersCallback(ICollection<TrackAsset> targets, Type markerType, double time, Object obj)
+ {
+ SelectionManager.Clear();
+ foreach (var target in targets)
+ {
+ var marker = TimelineHelpers.CreateMarkerOnTrack(markerType, obj, target, time);
+ SelectionManager.Add(marker);
+ }
+ TimelineEditor.Refresh(RefreshReason.ContentsAddedOrRemoved);
+ }
+
+ static void AddSingleMarkerCallback(Type markerType, double time, TimelineAsset timeline, PlayableDirector director, Object assignableObject)
+ {
+ timeline.CreateMarkerTrack();
+ var markerTrack = timeline.markerTrack;
+
+ SelectionManager.Clear();
+ var marker = TimelineHelpers.CreateMarkerOnTrack(markerType, assignableObject, markerTrack, time);
+ SelectionManager.Add(marker);
+
+ if (typeof(INotification).IsAssignableFrom(markerType) && director != null)
+ {
+ if (director != null && director.GetGenericBinding(markerTrack) == null)
+ director.SetGenericBinding(markerTrack, director.gameObject);
+ }
+
+ TimelineEditor.Refresh(RefreshReason.ContentsAddedOrRemoved);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus/TimelineContextMenu.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus/TimelineContextMenu.cs.meta
new file mode 100644
index 0000000..adfa86d
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/Menus/TimelineContextMenu.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: de86b4ed8106fd84a8bc2f5d69798d53
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/TimelineActions.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/TimelineActions.cs
new file mode 100644
index 0000000..25e72e8
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/TimelineActions.cs
@@ -0,0 +1,946 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using UnityEditor.ShortcutManagement;
+using UnityEngine;
+using UnityEngine.Timeline;
+using MenuEntryPair = System.Collections.Generic.KeyValuePair<UnityEngine.GUIContent, UnityEditor.Timeline.TimelineAction>;
+
+namespace UnityEditor.Timeline
+{
+ [ActiveInMode(TimelineModes.Default)]
+ abstract class TimelineAction : MenuItemActionBase
+ {
+ public abstract bool Execute(WindowState state);
+
+ public virtual MenuActionDisplayState GetDisplayState(WindowState state)
+ {
+ return MenuActionDisplayState.Visible;
+ }
+
+ public virtual bool IsChecked(WindowState state)
+ {
+ return false;
+ }
+
+ protected string GetDisplayName(WindowState state)
+ {
+ return menuName;
+ }
+
+ bool CanExecute(WindowState state)
+ {
+ return GetDisplayState(state) == MenuActionDisplayState.Visible;
+ }
+
+ public static void Invoke<T>(WindowState state) where T : TimelineAction
+ {
+ var action = AllActions.FirstOrDefault(x => x.GetType() == typeof(T));
+ if (action != null && action.CanExecute(state))
+ action.Execute(state);
+ }
+
+ // an instance of all TimelineActions
+ public static readonly TimelineAction[] AllActions = GetActionsOfType(typeof(TimelineAction)).Select(x => (TimelineAction)x.GetConstructors()[0].Invoke(null)).ToArray();
+
+ // an instance of all TimelineActions that should appear in a regular contextMenu
+ public static readonly TimelineAction[] MenuActions = AllActions.Where(a => a.showInMenu && !(a is MarkerHeaderAction)).ToArray();
+
+ public static void GetMenuEntries(IEnumerable<TimelineAction> actions, Vector2? mousePos, List<MenuActionItem> items)
+ {
+ var state = TimelineWindow.instance.state;
+ var mode = TimelineWindow.instance.currentMode.mode;
+
+ foreach (var action in actions)
+ {
+ var actionItem = action;
+ action.mousePosition = mousePos;
+ items.Add(
+ new MenuActionItem()
+ {
+ category = action.category,
+ entryName = action.GetDisplayName(state),
+ shortCut = action.shortCut,
+ isChecked = action.IsChecked(state),
+ isActiveInMode = IsActionActiveInMode(action, mode),
+ priority = action.priority,
+ state = action.GetDisplayState(state),
+ callback = () =>
+ {
+ actionItem.mousePosition = mousePos;
+ actionItem.Execute(state);
+ actionItem.mousePosition = null;
+ }
+ }
+ );
+ action.mousePosition = null;
+ }
+ }
+
+ public static bool HandleShortcut(WindowState state, Event evt)
+ {
+ if (EditorGUI.IsEditingTextField())
+ return false;
+
+ foreach (var action in AllActions)
+ {
+ var attr = action.GetType().GetCustomAttributes(typeof(ShortcutAttribute), true);
+
+ foreach (ShortcutAttribute shortcut in attr)
+ {
+ if (shortcut.MatchesEvent(evt))
+ {
+ if (s_ShowActionTriggeredByShortcut)
+ Debug.Log(action.GetType().Name);
+
+ if (!IsActionActiveInMode(action, TimelineWindow.instance.currentMode.mode))
+ return false;
+
+ var handled = action.Execute(state);
+ if (handled)
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ protected static bool DoInternal(Type t, WindowState state)
+ {
+ var action = (TimelineAction)t.GetConstructors()[0].Invoke(null);
+
+ if (action.CanExecute(state))
+ return action.Execute(state);
+
+ return false;
+ }
+ }
+
+ // indicates the action only applies to the marker header menu
+ abstract class MarkerHeaderAction : TimelineAction
+ {
+ }
+
+
+ [MenuEntry("Copy", MenuOrder.TimelineAction.Copy)]
+ [Shortcut("Main Menu/Edit/Copy", EventCommandNames.Copy)]
+ class CopyAction : TimelineAction
+ {
+ public static bool Do(WindowState state)
+ {
+ return DoInternal(typeof(CopyAction), state);
+ }
+
+ public override MenuActionDisplayState GetDisplayState(WindowState state)
+ {
+ return SelectionManager.Count() > 0 ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled;
+ }
+
+ public override bool Execute(WindowState state)
+ {
+ TimelineEditor.clipboard.Clear();
+
+ var clips = SelectionManager.SelectedClips().ToArray();
+ if (clips.Length > 0)
+ {
+ ItemAction<TimelineClip>.Invoke<CopyClipsToClipboard>(state, clips);
+ }
+ var markers = SelectionManager.SelectedMarkers().ToArray();
+ if (markers.Length > 0)
+ {
+ ItemAction<IMarker>.Invoke<CopyMarkersToClipboard>(state, markers);
+ }
+ var tracks = SelectionManager.SelectedTracks().ToArray();
+ if (tracks.Length > 0)
+ {
+ CopyTracksToClipboard.Do(state, tracks);
+ }
+
+ return true;
+ }
+ }
+
+ [MenuEntry("Paste", MenuOrder.TimelineAction.Paste)]
+ [Shortcut("Main Menu/Edit/Paste", EventCommandNames.Paste)]
+ class PasteAction : TimelineAction
+ {
+ public static bool Do(WindowState state)
+ {
+ return DoInternal(typeof(PasteAction), state);
+ }
+
+ public override MenuActionDisplayState GetDisplayState(WindowState state)
+ {
+ return CanPaste(state) ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled;
+ }
+
+ public override bool Execute(WindowState state)
+ {
+ if (!CanPaste(state))
+ return false;
+
+ PasteItems(state, mousePosition);
+ PasteTracks(state);
+
+ state.Refresh();
+
+ mousePosition = null;
+ return true;
+ }
+
+ bool CanPaste(WindowState state)
+ {
+ var copiedItems = TimelineEditor.clipboard.GetCopiedItems().ToList();
+
+ if (!copiedItems.Any())
+ return TimelineEditor.clipboard.GetTracks().Any();
+
+ return CanPasteItems(copiedItems, state, mousePosition);
+ }
+
+ static bool CanPasteItems(ICollection<ItemsPerTrack> itemsGroups, WindowState state, Vector2? mousePosition)
+ {
+ var hasItemsCopiedFromMultipleTracks = itemsGroups.Count > 1;
+ var allItemsCopiedFromCurrentAsset = itemsGroups.All(x => x.targetTrack.timelineAsset == state.editSequence.asset);
+ var hasUsedShortcut = mousePosition == null;
+ var anySourceLocked = itemsGroups.Any(x => x.targetTrack != null && x.targetTrack.lockedInHierarchy);
+
+ var targetTrack = GetPickedTrack();
+ if (targetTrack == null)
+ targetTrack = SelectionManager.SelectedTracks().FirstOrDefault();
+
+ //do not paste if the user copied items from another timeline
+ //if the copied items comes from > 1 track (since we do not know where to paste the copied items)
+ //or if a keyboard shortcut was used (since the user will not see the paste result)
+ if (!allItemsCopiedFromCurrentAsset)
+ {
+ var isSelectedTrackInCurrentAsset = targetTrack != null && targetTrack.timelineAsset == state.editSequence.asset;
+ if (hasItemsCopiedFromMultipleTracks || (hasUsedShortcut && !isSelectedTrackInCurrentAsset))
+ return false;
+ }
+
+ if (hasUsedShortcut)
+ return !anySourceLocked; // copy/paste to same track
+
+ if (hasItemsCopiedFromMultipleTracks)
+ {
+ //do not paste if the track which received the paste action does not contain a copied clip
+ return !anySourceLocked && itemsGroups.Select(x => x.targetTrack).Contains(targetTrack);
+ }
+
+ var copiedItems = itemsGroups.SelectMany(i => i.items);
+ return IsTrackValidForItems(targetTrack, copiedItems);
+ }
+
+ static void PasteItems(WindowState state, Vector2? mousePosition)
+ {
+ var copiedItems = TimelineEditor.clipboard.GetCopiedItems().ToList();
+ var numberOfUniqueParentsInClipboard = copiedItems.Count();
+
+ if (numberOfUniqueParentsInClipboard == 0) return;
+ List<ITimelineItem> newItems;
+
+ //if the copied items were on a single parent, then use the mouse position to get the parent OR the original parent
+ if (numberOfUniqueParentsInClipboard == 1)
+ {
+ var itemsGroup = copiedItems.First();
+ TrackAsset target = null;
+ if (mousePosition.HasValue)
+ target = GetPickedTrack();
+ if (target == null)
+ target = FindSuitableParentForSingleTrackPasteWithoutMouse(itemsGroup);
+
+ var candidateTime = TimelineHelpers.GetCandidateTime(state, mousePosition, target);
+ newItems = TimelineHelpers.DuplicateItemsUsingCurrentEditMode(state, TimelineEditor.clipboard.exposedPropertyTable, TimelineEditor.inspectedDirector, itemsGroup, target, candidateTime, "Paste Items").ToList();
+ }
+ //if copied items were on multiple parents, then the destination parents are the same as the original parents
+ else
+ {
+ var time = TimelineHelpers.GetCandidateTime(state, mousePosition, copiedItems.Select(c => c.targetTrack).ToArray());
+ newItems = TimelineHelpers.DuplicateItemsUsingCurrentEditMode(state, TimelineEditor.clipboard.exposedPropertyTable, TimelineEditor.inspectedDirector, copiedItems, time, "Paste Items").ToList();
+ }
+
+ TimelineHelpers.FrameItems(state, newItems);
+ SelectionManager.RemoveTimelineSelection();
+ foreach (var item in newItems)
+ {
+ SelectionManager.Add(item);
+ }
+ }
+
+ static TrackAsset FindSuitableParentForSingleTrackPasteWithoutMouse(ItemsPerTrack itemsGroup)
+ {
+ var groupParent = itemsGroup.targetTrack; //set a main parent in the clipboard
+ var selectedTracks = SelectionManager.SelectedTracks();
+
+ if (selectedTracks.Contains(groupParent))
+ {
+ return groupParent;
+ }
+
+ //find a selected track suitable for all items
+ var itemsToPaste = itemsGroup.items;
+ var compatibleTrack = selectedTracks.FirstOrDefault(t => IsTrackValidForItems(t, itemsToPaste));
+ return compatibleTrack != null ? compatibleTrack : groupParent;
+ }
+
+ static bool IsTrackValidForItems(TrackAsset track, IEnumerable<ITimelineItem> items)
+ {
+ if (track == null || track.lockedInHierarchy) return false;
+ return items.All(i => i.IsCompatibleWithTrack(track));
+ }
+
+ static TrackAsset GetPickedTrack()
+ {
+ var rowGUI = PickerUtils.pickedElements.OfType<IRowGUI>().FirstOrDefault();
+ if (rowGUI != null)
+ return rowGUI.asset;
+
+ return null;
+ }
+
+ static void PasteTracks(WindowState state)
+ {
+ var trackData = TimelineEditor.clipboard.GetTracks().ToList();
+ if (trackData.Any())
+ {
+ SelectionManager.RemoveTimelineSelection();
+ }
+
+ foreach (var track in trackData)
+ {
+ var newTrack = track.item.Duplicate(TimelineEditor.clipboard.exposedPropertyTable, TimelineEditor.inspectedDirector, TimelineEditor.inspectedAsset);
+ SelectionManager.Add(newTrack);
+ foreach (var childTrack in newTrack.GetFlattenedChildTracks())
+ {
+ SelectionManager.Add(childTrack);
+ }
+
+ if (track.parent != null && track.parent.timelineAsset == state.editSequence.asset)
+ {
+ TrackExtensions.ReparentTracks(new List<TrackAsset> { newTrack }, track.parent, track.item);
+ }
+ }
+ }
+ }
+
+ [MenuEntry("Duplicate", MenuOrder.TimelineAction.Duplicate)]
+ [Shortcut("Main Menu/Edit/Duplicate", EventCommandNames.Duplicate)]
+ class DuplicateAction : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ return Execute(state, (item1, item2) => ItemsUtils.TimeGapBetweenItems(item1, item2, state));
+ }
+
+ internal bool Execute(WindowState state, Func<ITimelineItem, ITimelineItem, double> gapBetweenItems)
+ {
+ var selectedItems = SelectionManager.SelectedItems().ToItemsPerTrack().ToList();
+ if (selectedItems.Any())
+ {
+ var requestedTime = CalculateDuplicateTime(selectedItems, gapBetweenItems);
+ var duplicatedItems = TimelineHelpers.DuplicateItemsUsingCurrentEditMode(state, TimelineEditor.inspectedDirector, TimelineEditor.inspectedDirector, selectedItems, requestedTime, "Duplicate Items");
+
+ TimelineHelpers.FrameItems(state, duplicatedItems);
+ SelectionManager.RemoveTimelineSelection();
+ foreach (var item in duplicatedItems)
+ SelectionManager.Add(item);
+ }
+
+ var tracks = SelectionManager.SelectedTracks().ToArray();
+ if (tracks.Length > 0)
+ TrackAction.Invoke<DuplicateTracks>(state, tracks);
+
+ state.Refresh();
+ return true;
+ }
+
+ static double CalculateDuplicateTime(IEnumerable<ItemsPerTrack> duplicatedItems, Func<ITimelineItem, ITimelineItem, double> gapBetweenItems)
+ {
+ //Find the end time of the rightmost item
+ var itemsOnTracks = duplicatedItems.SelectMany(i => i.targetTrack.GetItems()).ToList();
+ var time = itemsOnTracks.Max(i => i.end);
+
+ //From all the duplicated items, select the leftmost items
+ var firstDuplicatedItems = duplicatedItems.Select(i => i.leftMostItem);
+ var leftMostDuplicatedItems = firstDuplicatedItems.OrderBy(i => i.start).GroupBy(i => i.start).FirstOrDefault();
+ if (leftMostDuplicatedItems == null) return 0.0;
+
+ foreach (var leftMostItem in leftMostDuplicatedItems)
+ {
+ var siblings = leftMostItem.parentTrack.GetItems();
+ var rightMostSiblings = siblings.OrderByDescending(i => i.end).GroupBy(i => i.end).FirstOrDefault();
+ if (rightMostSiblings == null) continue;
+
+ foreach (var sibling in rightMostSiblings)
+ time = Math.Max(time, sibling.end + gapBetweenItems(leftMostItem, sibling));
+ }
+
+ return time;
+ }
+ }
+
+ [MenuEntry("Delete", MenuOrder.TimelineAction.Delete)]
+ [Shortcut("Main Menu/Edit/Delete", EventCommandNames.Delete)]
+ [ShortcutPlatformOverride(RuntimePlatform.OSXEditor, KeyCode.Backspace, ShortcutModifiers.Action)]
+ [ActiveInMode(TimelineModes.Default)]
+ class DeleteAction : TimelineAction
+ {
+ public override MenuActionDisplayState GetDisplayState(WindowState state)
+ {
+ return CanDelete(state) ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled;
+ }
+
+ static bool CanDelete(WindowState state)
+ {
+ if (state.editSequence.isReadOnly)
+ return false;
+ // All() returns true when empty
+ return SelectionManager.SelectedTracks().All(x => !x.lockedInHierarchy) &&
+ SelectionManager.SelectedItems().All(x => x.parentTrack == null || !x.parentTrack.lockedInHierarchy);
+ }
+
+ public override bool Execute(WindowState state)
+ {
+ if (SelectionManager.GetCurrentInlineEditorCurve() != null)
+ return false;
+
+ if (!CanDelete(state))
+ return false;
+
+ var selectedItems = SelectionManager.SelectedItems();
+ DeleteItems(selectedItems);
+
+ var tracks = SelectionManager.SelectedTracks().ToArray();
+ if (tracks.Any())
+ TrackAction.Invoke<DeleteTracks>(state, tracks);
+
+ state.Refresh();
+ return selectedItems.Any() || tracks.Length > 0;
+ }
+
+ internal static void DeleteItems(IEnumerable<ITimelineItem> items)
+ {
+ var tracks = items.GroupBy(c => c.parentTrack);
+
+ foreach (var track in tracks)
+ TimelineUndo.PushUndo(track.Key, "Delete Items");
+
+ TimelineAnimationUtilities.UnlinkAnimationWindowFromClips(items.OfType<ClipItem>().Select(i => i.clip));
+
+ EditMode.PrepareItemsDelete(ItemsUtils.ToItemsPerTrack(items));
+ EditModeUtils.Delete(items);
+
+ SelectionManager.RemoveAllClips();
+ }
+ }
+
+ [MenuEntry("Match Content", MenuOrder.TimelineAction.MatchContent)]
+ [Shortcut(Shortcuts.Timeline.matchContent)]
+ class MatchContent : TimelineAction
+ {
+ public override MenuActionDisplayState GetDisplayState(WindowState state)
+ {
+ var clips = SelectionManager.SelectedClips().ToArray();
+
+ if (!clips.Any() || SelectionManager.GetCurrentInlineEditorCurve() != null)
+ return MenuActionDisplayState.Hidden;
+
+ return clips.Any(TimelineHelpers.HasUsableAssetDuration)
+ ? MenuActionDisplayState.Visible
+ : MenuActionDisplayState.Disabled;
+ }
+
+ public override bool Execute(WindowState state)
+ {
+ if (SelectionManager.GetCurrentInlineEditorCurve() != null)
+ return false;
+
+ var clips = SelectionManager.SelectedClips().ToArray();
+ return clips.Length > 0 && ClipModifier.MatchContent(clips);
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.play)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class PlayTimelineAction : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ var currentState = state.playing;
+ state.SetPlaying(!currentState);
+ return true;
+ }
+ }
+
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class SelectAllAction : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ // otherwise select all tracks.
+ SelectionManager.Clear();
+ state.GetWindow().allTracks.ForEach(x => SelectionManager.Add(x.track));
+
+ return true;
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.previousFrame)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class PreviousFrameAction : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ state.editSequence.frame--;
+ return true;
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.nextFrame)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class NextFrameAction : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ state.editSequence.frame++;
+ return true;
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.frameAll)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class FrameAllAction : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ var inlineCurveEditor = SelectionManager.GetCurrentInlineEditorCurve();
+ if (inlineCurveEditor != null && inlineCurveEditor.inlineCurvesSelected)
+ {
+ FrameSelectedAction.FrameInlineCurves(inlineCurveEditor, state, false);
+ return true;
+ }
+
+ if (state.IsEditingASubItem())
+ return false;
+
+ var w = state.GetWindow();
+ if (w == null || w.treeView == null)
+ return false;
+
+ var visibleTracks = w.treeView.visibleTracks.ToList();
+ if (state.editSequence.asset != null && state.editSequence.asset.markerTrack != null)
+ visibleTracks.Add(state.editSequence.asset.markerTrack);
+
+ if (visibleTracks.Count == 0)
+ return false;
+
+ var startTime = float.MaxValue;
+ var endTime = float.MinValue;
+
+ foreach (var t in visibleTracks)
+ {
+ if (t == null)
+ continue;
+
+ double trackStart, trackEnd;
+ t.GetItemRange(out trackStart, out trackEnd);
+ startTime = Mathf.Min(startTime, (float)trackStart);
+ endTime = Mathf.Max(endTime, (float)(trackEnd));
+ }
+
+ if (startTime != float.MinValue)
+ {
+ FrameSelectedAction.FrameRange(startTime, endTime, state);
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class FrameSelectedAction : TimelineAction
+ {
+ public static void FrameRange(float startTime, float endTime, WindowState state)
+ {
+ if (startTime > endTime)
+ {
+ return;
+ }
+
+ var halfDuration = endTime - Math.Max(0.0f, startTime);
+
+ if (halfDuration > 0.0f)
+ {
+ state.SetTimeAreaShownRange(Mathf.Max(-10.0f, startTime - (halfDuration * 0.1f)),
+ endTime + (halfDuration * 0.1f));
+ }
+ else
+ {
+ // start == end
+ // keep the zoom level constant, only pan the time area to center the item
+ var currentRange = state.timeAreaShownRange.y - state.timeAreaShownRange.x;
+ state.SetTimeAreaShownRange(startTime - currentRange / 2, startTime + currentRange / 2);
+ }
+
+ TimelineZoomManipulator.InvalidateWheelZoom();
+ state.Evaluate();
+ }
+
+ public override bool Execute(WindowState state)
+ {
+ var inlineCurveEditor = SelectionManager.GetCurrentInlineEditorCurve();
+ if (inlineCurveEditor != null && inlineCurveEditor.inlineCurvesSelected)
+ {
+ FrameInlineCurves(inlineCurveEditor, state, true);
+ return true;
+ }
+
+ if (state.IsEditingASubItem())
+ return false;
+
+ if (SelectionManager.Count() == 0)
+ return false;
+
+ var startTime = float.MaxValue;
+ var endTime = float.MinValue;
+
+ var clips = SelectionManager.SelectedClipGUI();
+ var markers = SelectionManager.SelectedMarkers();
+ if (!clips.Any() && !markers.Any())
+ return false;
+
+ foreach (var c in clips)
+ {
+ startTime = Mathf.Min(startTime, (float)c.clip.start);
+ endTime = Mathf.Max(endTime, (float)c.clip.end);
+ if (c.clipCurveEditor != null)
+ {
+ c.clipCurveEditor.FrameClip();
+ }
+ }
+
+ foreach (var marker in markers)
+ {
+ startTime = Mathf.Min(startTime, (float)marker.time);
+ endTime = Mathf.Max(endTime, (float)marker.time);
+ }
+
+ FrameRange(startTime, endTime, state);
+
+ return true;
+ }
+
+ public static void FrameInlineCurves(IClipCurveEditorOwner curveEditorOwner, WindowState state, bool selectionOnly)
+ {
+ var curveEditor = curveEditorOwner.clipCurveEditor.curveEditor;
+ var frameBounds = selectionOnly ? curveEditor.GetSelectionBounds() : curveEditor.GetClipBounds();
+
+ var clipGUI = curveEditorOwner as TimelineClipGUI;
+ var areaOffset = 0.0f;
+
+ if (clipGUI != null)
+ {
+ areaOffset = (float)Math.Max(0.0, clipGUI.clip.FromLocalTimeUnbound(0.0));
+
+ var timeScale = (float)clipGUI.clip.timeScale; // Note: The getter for clip.timeScale is guaranteed to never be zero.
+
+ // Apply scaling
+ var newMin = frameBounds.min.x / timeScale;
+ var newMax = (frameBounds.max.x - frameBounds.min.x) / timeScale + newMin;
+
+ frameBounds.SetMinMax(
+ new Vector3(newMin, frameBounds.min.y, frameBounds.min.z),
+ new Vector3(newMax, frameBounds.max.y, frameBounds.max.z));
+ }
+
+ curveEditor.Frame(frameBounds, true, true);
+
+ var area = curveEditor.shownAreaInsideMargins;
+ area.x += areaOffset;
+
+ var curveStart = curveEditorOwner.clipCurveEditor.dataSource.start;
+ FrameRange(curveStart + frameBounds.min.x, curveStart + frameBounds.max.x, state);
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.previousKey)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class PrevKeyAction : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ var keyTraverser = new Utilities.KeyTraverser(state.editSequence.asset, 0.01f / state.referenceSequence.frameRate);
+ var time = keyTraverser.GetPrevKey((float)state.editSequence.time, state.dirtyStamp);
+ if (time != state.editSequence.time)
+ {
+ state.editSequence.time = time;
+ }
+
+ return true;
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.nextKey)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class NextKeyAction : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ var keyTraverser = new Utilities.KeyTraverser(state.editSequence.asset, 0.01f / state.referenceSequence.frameRate);
+ var time = keyTraverser.GetNextKey((float)state.editSequence.time, state.dirtyStamp);
+ if (time != state.editSequence.time)
+ {
+ state.editSequence.time = time;
+ }
+
+ return true;
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.goToStart)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class GotoStartAction : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ state.editSequence.time = 0.0f;
+ state.EnsurePlayHeadIsVisible();
+
+ return true;
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.goToEnd)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class GotoEndAction : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ state.editSequence.time = state.editSequence.duration;
+ state.EnsurePlayHeadIsVisible();
+
+ return true;
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.zoomIn)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class ZoomIn : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ TimelineZoomManipulator.Instance.DoZoom(1.15f, state);
+ return true;
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.zoomOut)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class ZoomOut : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ TimelineZoomManipulator.Instance.DoZoom(0.85f, state);
+ return true;
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.collapseGroup)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class CollapseGroup : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ return KeyboardNavigation.CollapseGroup(state);
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.unCollapseGroup)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class UnCollapseGroup : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ return KeyboardNavigation.UnCollapseGroup(state);
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.selectLeftItem)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class SelectLeftClip : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ // Switches to track header if no left track exists
+ return KeyboardNavigation.SelectLeftItem(state);
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.selectRightItem)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class SelectRightClip : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ return KeyboardNavigation.SelectRightItem(state);
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.selectUpItem)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class SelectUpClip : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ return KeyboardNavigation.SelectUpItem(state);
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.selectUpTrack)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class SelectUpTrack : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ return KeyboardNavigation.SelectUpTrack();
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.selectDownItem)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class SelectDownClip : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ return KeyboardNavigation.SelectDownItem(state);
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.selectDownTrack)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class SelectDownTrack : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ if (!KeyboardNavigation.ClipAreaActive() && !KeyboardNavigation.TrackHeadActive())
+ return KeyboardNavigation.FocusFirstVisibleItem(state);
+ else
+ return KeyboardNavigation.SelectDownTrack();
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.multiSelectLeft)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class MultiselectLeftClip : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ return KeyboardNavigation.SelectLeftItem(state, true);
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.multiSelectRight)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class MultiselectRightClip : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ return KeyboardNavigation.SelectRightItem(state, true);
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.multiSelectUp)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class MultiselectUpTrack : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ return KeyboardNavigation.SelectUpTrack(true);
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.multiSelectDown)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class MultiselectDownTrack : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ return KeyboardNavigation.SelectDownTrack(true);
+ }
+ }
+
+ [Shortcut(Shortcuts.Timeline.toggleClipTrackArea)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class ToggleClipTrackArea : TimelineAction
+ {
+ public override bool Execute(WindowState state)
+ {
+ if (KeyboardNavigation.TrackHeadActive())
+ return KeyboardNavigation.FocusFirstVisibleItem(state, SelectionManager.SelectedTracks());
+
+ if (!KeyboardNavigation.ClipAreaActive())
+ return KeyboardNavigation.FocusFirstVisibleItem(state);
+
+ var item = KeyboardNavigation.GetVisibleSelectedItems().LastOrDefault();
+ if (item != null)
+ SelectionManager.SelectOnly(item.parentTrack);
+ return true;
+ }
+ }
+
+ [MenuEntry("Mute", MenuOrder.TrackAction.MuteTrack)]
+ class ToggleMuteMarkersOnTimeline : MarkerHeaderAction
+ {
+ public override bool IsChecked(WindowState state)
+ {
+ return IsMarkerTrackValid(state) && state.editSequence.asset.markerTrack.muted;
+ }
+
+ public override bool Execute(WindowState state)
+ {
+ if (state.showMarkerHeader)
+ ToggleMute(state);
+ return true;
+ }
+
+ static void ToggleMute(WindowState state)
+ {
+ var timeline = state.editSequence.asset;
+ timeline.CreateMarkerTrack();
+
+ TimelineUndo.PushUndo(timeline.markerTrack, "Toggle Mute");
+ timeline.markerTrack.muted = !timeline.markerTrack.muted;
+ }
+
+ static bool IsMarkerTrackValid(WindowState state)
+ {
+ var timeline = state.editSequence.asset;
+ return timeline != null && timeline.markerTrack != null;
+ }
+ }
+
+ [MenuEntry("Show Markers", MenuOrder.TrackAction.ShowHideMarkers)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class ToggleShowMarkersOnTimeline : MarkerHeaderAction
+ {
+ public override bool IsChecked(WindowState state)
+ {
+ return state.showMarkerHeader;
+ }
+
+ public override bool Execute(WindowState state)
+ {
+ ToggleShow(state);
+ return true;
+ }
+
+ static void ToggleShow(WindowState state)
+ {
+ state.GetWindow().SetShowMarkerHeader(!state.showMarkerHeader);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/TimelineActions.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/TimelineActions.cs.meta
new file mode 100644
index 0000000..39295c4
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/TimelineActions.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b1c789407b55e3a4c9cc86135a714e33
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/TrackActions.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/TrackActions.cs
new file mode 100644
index 0000000..d379bd0
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/TrackActions.cs
@@ -0,0 +1,521 @@
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using JetBrains.Annotations;
+using UnityEngine;
+using UnityEngine.Timeline;
+
+namespace UnityEditor.Timeline
+{
+ [ActiveInMode(TimelineModes.Default)]
+ abstract class TrackAction : MenuItemActionBase
+ {
+ public abstract bool Execute(WindowState state, TrackAsset[] tracks);
+
+ protected virtual MenuActionDisplayState GetDisplayState(WindowState state, TrackAsset[] tracks)
+ {
+ return tracks.Length > 0 ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled;
+ }
+
+ protected virtual bool IsChecked(WindowState state, TrackAsset[] tracks)
+ {
+ return false;
+ }
+
+ protected virtual string GetDisplayName(TrackAsset[] tracks)
+ {
+ return menuName;
+ }
+
+ public static void Invoke<T>(WindowState state, TrackAsset[] tracks) where T : TrackAction
+ {
+ actions.First(x => x.GetType() == typeof(T)).Execute(state, tracks);
+ }
+
+ static List<TrackAction> s_ActionClasses;
+
+ static List<TrackAction> actions
+ {
+ get
+ {
+ if (s_ActionClasses == null)
+ s_ActionClasses =
+ GetActionsOfType(typeof(TrackAction))
+ .Select(x => (TrackAction)x.GetConstructors()[0].Invoke(null))
+ .OrderBy(x => x.priority).ThenBy(x => x.category)
+ .ToList();
+
+ return s_ActionClasses;
+ }
+ }
+
+ public static void GetMenuEntries(WindowState state, Vector2? mousePos, TrackAsset[] tracks, List<MenuActionItem> items)
+ {
+ var mode = TimelineWindow.instance.currentMode.mode;
+ foreach (var action in actions)
+ {
+ if (!action.showInMenu)
+ continue;
+
+ var actionItem = action;
+ items.Add(
+ new MenuActionItem()
+ {
+ category = action.category,
+ entryName = action.GetDisplayName(tracks),
+ shortCut = action.shortCut,
+ isChecked = action.IsChecked(state, tracks),
+ isActiveInMode = IsActionActiveInMode(action, mode),
+ priority = action.priority,
+ state = action.GetDisplayState(state, tracks),
+ callback = () =>
+ {
+ actionItem.mousePosition = mousePos;
+ actionItem.Execute(state, tracks);
+ actionItem.mousePosition = null;
+ }
+ }
+ );
+ }
+ }
+
+ public static bool HandleShortcut(WindowState state, Event evt, TrackAsset[] tracks)
+ {
+ foreach (var action in actions)
+ {
+ var attr = action.GetType().GetCustomAttributes(typeof(ShortcutAttribute), true);
+
+ foreach (ShortcutAttribute shortcut in attr)
+ {
+ if (shortcut.MatchesEvent(evt))
+ {
+ if (s_ShowActionTriggeredByShortcut)
+ Debug.Log(action.GetType().Name);
+
+ if (!IsActionActiveInMode(action, TimelineWindow.instance.currentMode.mode))
+ return false;
+
+ return action.Execute(state, tracks);
+ }
+ }
+ }
+
+ return false;
+ }
+
+ // For testing
+ internal MenuActionDisplayState InternalGetDisplayState(WindowState state, TrackAsset[] tracks)
+ {
+ return GetDisplayState(state, tracks);
+ }
+ }
+
+ [MenuEntry("Edit in Animation Window", MenuOrder.TrackAction.EditInAnimationWindow)]
+ class EditTrackInAnimationWindow : TrackAction
+ {
+ public static bool Do(WindowState state, TrackAsset track)
+ {
+ AnimationClip clipToEdit = null;
+
+ AnimationTrack animationTrack = track as AnimationTrack;
+ if (animationTrack != null)
+ {
+ if (!animationTrack.CanConvertToClipMode())
+ return false;
+
+ clipToEdit = animationTrack.infiniteClip;
+ }
+ else if (track.hasCurves)
+ {
+ clipToEdit = track.curves;
+ }
+
+ if (clipToEdit == null)
+ return false;
+
+ var gameObject = state.GetSceneReference(track);
+ var timeController = TimelineAnimationUtilities.CreateTimeController(state, CreateTimeControlClipData(track));
+ TimelineAnimationUtilities.EditAnimationClipWithTimeController(clipToEdit, timeController, gameObject);
+
+ return true;
+ }
+
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TrackAsset[] tracks)
+ {
+ if (tracks.Length == 0)
+ return MenuActionDisplayState.Hidden;
+
+ if (tracks[0] is AnimationTrack)
+ {
+ var animTrack = tracks[0] as AnimationTrack;
+ if (animTrack.CanConvertToClipMode())
+ return MenuActionDisplayState.Visible;
+ }
+ else if (tracks[0].hasCurves)
+ {
+ return MenuActionDisplayState.Visible;
+ }
+
+ return MenuActionDisplayState.Hidden;
+ }
+
+ public override bool Execute(WindowState state, TrackAsset[] tracks)
+ {
+ return Do(state, tracks[0]);
+ }
+
+ static TimelineWindowTimeControl.ClipData CreateTimeControlClipData(TrackAsset track)
+ {
+ var data = new TimelineWindowTimeControl.ClipData();
+ data.track = track;
+ data.start = track.start;
+ data.duration = track.duration;
+ return data;
+ }
+ }
+
+ [MenuEntry("Lock selected track only", MenuOrder.TrackAction.LockSelected)]
+ class LockSelectedTrack : TrackAction
+ {
+ public static readonly string LockSelectedTrackOnlyText = L10n.Tr("Lock selected track only");
+ public static readonly string UnlockSelectedTrackOnlyText = L10n.Tr("Unlock selected track only");
+
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TrackAsset[] tracks)
+ {
+ if (tracks.Any(track => TimelineUtility.IsLockedFromGroup(track) || track is GroupTrack ||
+ !track.subTracksObjects.Any()))
+ return MenuActionDisplayState.Hidden;
+ return MenuActionDisplayState.Visible;
+ }
+
+ public override bool Execute(WindowState state, TrackAsset[] tracks)
+ {
+ if (!tracks.Any()) return false;
+
+ var hasUnlockedTracks = tracks.Any(x => !x.locked);
+ Lock(state, tracks.Where(p => !(p is GroupTrack)).ToArray(), hasUnlockedTracks);
+ return true;
+ }
+
+ protected override string GetDisplayName(TrackAsset[] tracks)
+ {
+ return tracks.All(t => t.locked) ? UnlockSelectedTrackOnlyText : LockSelectedTrackOnlyText;
+ }
+
+ public static void Lock(WindowState state, TrackAsset[] tracks, bool shouldlock)
+ {
+ if (tracks.Length == 0)
+ return;
+
+ foreach (var track in tracks.Where(t => !TimelineUtility.IsLockedFromGroup(t)))
+ {
+ TimelineUndo.PushUndo(track, "Lock Tracks");
+ track.locked = shouldlock;
+ }
+ TimelineEditor.Refresh(RefreshReason.WindowNeedsRedraw);
+ }
+ }
+
+ [MenuEntry("Lock", MenuOrder.TrackAction.LockTrack)]
+ [Shortcut(Shortcuts.Timeline.toggleLock)]
+ class LockTrack : TrackAction
+ {
+ public static readonly string UnlockText = L10n.Tr("Unlock");
+
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TrackAsset[] tracks)
+ {
+ bool hasUnlockableTracks = tracks.Any(x => TimelineUtility.IsLockedFromGroup(x));
+ if (hasUnlockableTracks)
+ return MenuActionDisplayState.Disabled;
+ return MenuActionDisplayState.Visible;
+ }
+
+ protected override string GetDisplayName(TrackAsset[] tracks)
+ {
+ return tracks.Any(x => !x.locked) ? base.GetDisplayName(tracks) : UnlockText;
+ }
+
+ public override bool Execute(WindowState state, TrackAsset[] tracks)
+ {
+ if (!tracks.Any()) return false;
+
+ var hasUnlockedTracks = tracks.Any(x => !x.locked);
+ SetLockState(tracks, hasUnlockedTracks, state);
+ return true;
+ }
+
+ public static void SetLockState(TrackAsset[] tracks, bool shouldLock, WindowState state = null)
+ {
+ if (tracks.Length == 0)
+ return;
+
+ foreach (var track in tracks)
+ {
+ if (TimelineUtility.IsLockedFromGroup(track))
+ continue;
+
+ if (track as GroupTrack == null)
+ SetLockState(track.GetChildTracks().ToArray(), shouldLock, state);
+
+ TimelineUndo.PushUndo(track, "Lock Tracks");
+ track.locked = shouldLock;
+ }
+
+ if (state != null)
+ {
+ // find the tracks we've locked. unselect anything locked and remove recording.
+ foreach (var track in tracks)
+ {
+ if (TimelineUtility.IsLockedFromGroup(track) || !track.locked)
+ continue;
+
+ var flattenedChildTracks = track.GetFlattenedChildTracks();
+ foreach (var i in track.clips)
+ SelectionManager.Remove(i);
+ state.UnarmForRecord(track);
+ foreach (var child in flattenedChildTracks)
+ {
+ SelectionManager.Remove(child);
+ state.UnarmForRecord(child);
+ foreach (var clip in child.GetClips())
+ SelectionManager.Remove(clip);
+ }
+ }
+
+ // no need to rebuild, just repaint (including inspectors)
+ InspectorWindow.RepaintAllInspectors();
+ state.editorWindow.Repaint();
+ }
+ }
+ }
+
+ [UsedImplicitly]
+ [MenuEntry("Show Markers", MenuOrder.TrackAction.ShowHideMarkers)]
+ [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
+ class ShowHideMarkers : TrackAction
+ {
+ protected override bool IsChecked(WindowState state, TrackAsset[] tracks)
+ {
+ return tracks.All(x => x.GetShowMarkers());
+ }
+
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TrackAsset[] tracks)
+ {
+ if (tracks.Any(x => x is GroupTrack) || tracks.Any(t => t.GetMarkerCount() == 0))
+ return MenuActionDisplayState.Hidden;
+
+ if (tracks.Any(t => t.lockedInHierarchy))
+ return MenuActionDisplayState.Disabled;
+
+ return MenuActionDisplayState.Visible;
+ }
+
+ public override bool Execute(WindowState state, TrackAsset[] tracks)
+ {
+ if (!tracks.Any()) return false;
+
+ var hasUnlockedTracks = tracks.Any(x => !x.GetShowMarkers());
+ ShowHide(state, tracks, hasUnlockedTracks);
+ return true;
+ }
+
+ static void ShowHide(WindowState state, TrackAsset[] tracks, bool shouldLock)
+ {
+ if (tracks.Length == 0)
+ return;
+
+ var window = state.GetWindow();
+ foreach (var track in tracks)
+ {
+ window.SetShowTrackMarkers(track, shouldLock);
+ }
+
+ TimelineEditor.Refresh(RefreshReason.WindowNeedsRedraw);
+ }
+ }
+
+ [MenuEntry("Mute selected track only", MenuOrder.TrackAction.MuteSelected), UsedImplicitly]
+ class MuteSelectedTrack : TrackAction
+ {
+ public static readonly string UnmuteSelectedText = L10n.Tr("Unmute selected track only");
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TrackAsset[] tracks)
+ {
+ if (tracks.Any(track => TimelineUtility.IsParentMuted(track) || track is GroupTrack ||
+ !track.subTracksObjects.Any()))
+ return MenuActionDisplayState.Hidden;
+ return MenuActionDisplayState.Visible;
+ }
+
+ public override bool Execute(WindowState state, TrackAsset[] tracks)
+ {
+ if (!tracks.Any())
+ return false;
+
+ var hasUnmutedTracks = tracks.Any(x => !x.muted);
+ Mute(state, tracks.Where(p => !(p is GroupTrack)).ToArray(), hasUnmutedTracks);
+ return true;
+ }
+
+ protected override string GetDisplayName(TrackAsset[] tracks)
+ {
+ return tracks.All(t => t.muted) ? UnmuteSelectedText : base.GetDisplayName(tracks);
+ }
+
+ public static void Mute(WindowState state, TrackAsset[] tracks, bool shouldMute)
+ {
+ if (tracks.Length == 0)
+ return;
+
+ foreach (var track in tracks.Where(t => !TimelineUtility.IsParentMuted(t)))
+ {
+ TimelineUndo.PushUndo(track, "Mute Tracks");
+ track.muted = shouldMute;
+ }
+
+ state.Refresh();
+ }
+ }
+
+ [MenuEntry("Mute", MenuOrder.TrackAction.MuteTrack)]
+ [Shortcut(Shortcuts.Timeline.toggleMute)]
+ class MuteTrack : TrackAction
+ {
+ public static readonly string UnMuteText = L10n.Tr("Unmute");
+
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TrackAsset[] tracks)
+ {
+ if (tracks.Any(track => TimelineUtility.IsParentMuted(track)))
+ return MenuActionDisplayState.Disabled;
+ return MenuActionDisplayState.Visible;
+ }
+
+ protected override string GetDisplayName(TrackAsset[] tracks)
+ {
+ return tracks.Any(x => !x.muted) ? base.GetDisplayName(tracks) : UnMuteText;
+ }
+
+ public override bool Execute(WindowState state, TrackAsset[] tracks)
+ {
+ if (!tracks.Any() || tracks.Any(track => TimelineUtility.IsParentMuted(track)))
+ return false;
+
+ var hasUnmutedTracks = tracks.Any(x => !x.muted);
+ Mute(state, tracks, hasUnmutedTracks);
+ return true;
+ }
+
+ public static void Mute(WindowState state, TrackAsset[] tracks, bool shouldMute)
+ {
+ if (tracks.Length == 0)
+ return;
+
+ foreach (var track in tracks)
+ {
+ if (track as GroupTrack == null)
+ Mute(state, track.GetChildTracks().ToArray(), shouldMute);
+ TimelineUndo.PushUndo(track, "Mute Tracks");
+ track.muted = shouldMute;
+ }
+
+ state.Refresh();
+ }
+ }
+
+ class DeleteTracks : TrackAction
+ {
+ public static void Do(TimelineAsset timeline, TrackAsset track)
+ {
+ SelectionManager.Remove(track);
+ TrackModifier.DeleteTrack(timeline, track);
+ }
+
+ public override bool Execute(WindowState state, TrackAsset[] tracks)
+ {
+ // disable preview mode so deleted tracks revert to default state
+ // Case 956129: Disable preview mode _before_ deleting the tracks, since clip data is still needed
+ state.previewMode = false;
+
+ TimelineAnimationUtilities.UnlinkAnimationWindowFromTracks(tracks);
+
+ foreach (var track in tracks)
+ Do(state.editSequence.asset, track);
+
+ state.Refresh();
+
+ return true;
+ }
+ }
+
+ class CopyTracksToClipboard : TrackAction
+ {
+ public static bool Do(WindowState state, TrackAsset[] tracks)
+ {
+ var action = new CopyTracksToClipboard();
+
+ return action.Execute(state, tracks);
+ }
+
+ public override bool Execute(WindowState state, TrackAsset[] tracks)
+ {
+ TimelineEditor.clipboard.CopyTracks(tracks);
+
+ return true;
+ }
+ }
+
+ class DuplicateTracks : TrackAction
+ {
+ public override bool Execute(WindowState state, TrackAsset[] tracks)
+ {
+ if (tracks.Any())
+ {
+ SelectionManager.RemoveTimelineSelection();
+ }
+
+ foreach (var track in TrackExtensions.FilterTracks(tracks))
+ {
+ var newTrack = track.Duplicate(TimelineEditor.inspectedDirector, TimelineEditor.inspectedDirector);
+ SelectionManager.Add(newTrack);
+ foreach (var childTrack in newTrack.GetFlattenedChildTracks())
+ {
+ SelectionManager.Add(childTrack);
+ }
+ }
+
+ state.Refresh();
+
+ return true;
+ }
+ }
+
+ [MenuEntry("Remove Invalid Markers", MenuOrder.TrackAction.RemoveInvalidMarkers), UsedImplicitly]
+ class RemoveInvalidMarkersAction : TrackAction
+ {
+ protected override MenuActionDisplayState GetDisplayState(WindowState state, TrackAsset[] tracks)
+ {
+ if (tracks.Any(target => target != null && target.GetMarkerCount() != target.GetMarkersRaw().Count()))
+ return MenuActionDisplayState.Visible;
+
+ return MenuActionDisplayState.Hidden;
+ }
+
+ public override bool Execute(WindowState state, TrackAsset[] tracks)
+ {
+ bool anyRemoved = false;
+ foreach (var target in tracks)
+ {
+ var invalids = target.GetMarkersRaw().Where(x => !(x is IMarker)).ToList();
+ foreach (var m in invalids)
+ {
+ anyRemoved = true;
+ target.DeleteMarkerRaw(m);
+ }
+ }
+
+ if (anyRemoved)
+ TimelineEditor.Refresh(RefreshReason.ContentsAddedOrRemoved);
+
+ return anyRemoved;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/TrackActions.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/TrackActions.cs.meta
new file mode 100644
index 0000000..483f9eb
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/TrackActions.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fda82b5ca7a4c5f40b497c4f5f4bd950
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: