From c55fba8ab2a1c9d3df65eda4a5a1e957f4aa1f78 Mon Sep 17 00:00:00 2001 From: Andrew Lee Date: Sun, 19 Apr 2020 17:19:32 -0400 Subject: Inital commit --- .../Editor/Actions/TimelineActions.cs | 946 +++++++++++++++++++++ 1 file changed, 946 insertions(+) create mode 100644 Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/TimelineActions.cs (limited to 'Library/PackageCache/com.unity.timeline@1.2.13/Editor/Actions/TimelineActions.cs') 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; + +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(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 actions, Vector2? mousePos, List 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.Invoke(state, clips); + } + var markers = SelectionManager.SelectedMarkers().ToArray(); + if (markers.Length > 0) + { + ItemAction.Invoke(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 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 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 items) + { + if (track == null || track.lockedInHierarchy) return false; + return items.All(i => i.IsCompatibleWithTrack(track)); + } + + static TrackAsset GetPickedTrack() + { + var rowGUI = PickerUtils.pickedElements.OfType().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 { 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 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(state, tracks); + + state.Refresh(); + return true; + } + + static double CalculateDuplicateTime(IEnumerable duplicatedItems, Func 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(state, tracks); + + state.Refresh(); + return selectedItems.Any() || tracks.Length > 0; + } + + internal static void DeleteItems(IEnumerable items) + { + var tracks = items.GroupBy(c => c.parentTrack); + + foreach (var track in tracks) + TimelineUndo.PushUndo(track.Key, "Delete Items"); + + TimelineAnimationUtilities.UnlinkAnimationWindowFromClips(items.OfType().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); + } + } +} -- cgit v1.2.3