Initial commit

This commit is contained in:
AbstractConcept 2022-09-13 00:36:34 -05:00
commit 3c7cc0c973
8391 changed files with 704313 additions and 0 deletions

View file

@ -0,0 +1,146 @@
using System;
using System.Text;
using UnityEngine;
using UnityEngine.Timeline;
namespace UnityEditor.Timeline
{
class EaseClip : Manipulator
{
bool m_IsCaptured;
bool m_UndoSaved;
TimelineClipHandle m_EaseClipHandler;
ManipulateEdges m_Edges;
TimelineClip m_Clip;
StringBuilder m_OverlayText = new StringBuilder("");
double m_OriginalValue;
public static readonly string EaseInClipText = L10n.Tr("Ease In Clip");
public static readonly string EaseOutClipText = L10n.Tr("Ease Out Clip");
public static readonly string EaseInText = L10n.Tr("Ease In");
public static readonly string EaseOutText = L10n.Tr("Ease Out");
public static readonly string DurationFrameText = L10n.Tr(" Duration {0:0.00;-0.00} frames ");
public static readonly string DurationSecText = L10n.Tr(" Duration {0:0.00;-0.00} s ");
public static readonly string DeltaFrameText = L10n.Tr("({0:+0.00;-0.00} frames)");
public static readonly string DeltaSecText = L10n.Tr("({0:+0.00;-0.00} s)");
protected override bool MouseDown(Event evt, WindowState state)
{
if (evt.modifiers != ManipulatorsUtils.actionModifier)
return false;
return MouseDownInternal(evt, state, PickerUtils.PickedLayerableOfType<TimelineClipHandle>());
}
protected bool MouseDownInternal(Event evt, WindowState state, TimelineClipHandle handle)
{
if (handle == null)
return false;
if (handle.clipGUI.clip != null && !handle.clipGUI.clip.clipCaps.HasAny(ClipCaps.Blending))
return false;
m_Edges = ManipulateEdges.Right;
if (handle.trimDirection == TrimEdge.Start)
m_Edges = ManipulateEdges.Left;
if (m_Edges == ManipulateEdges.Left && handle.clipGUI.clip.hasBlendIn || m_Edges == ManipulateEdges.Right && handle.clipGUI.clip.hasBlendOut)
return false;
m_IsCaptured = true;
m_UndoSaved = false;
m_EaseClipHandler = handle;
m_Clip = handle.clipGUI.clip;
m_OriginalValue = m_Edges == ManipulateEdges.Left ? m_Clip.easeInDuration : m_Clip.easeOutDuration;
// Change cursor only when OnGUI Process (not in test)
if (GUIUtility.guiDepth > 0)
TimelineCursors.SetCursor(m_Edges == ManipulateEdges.Left ? TimelineCursors.CursorType.MixRight : TimelineCursors.CursorType.MixLeft);
state.AddCaptured(this);
return true;
}
protected override bool MouseUp(Event evt, WindowState state)
{
if (!m_IsCaptured)
return false;
m_IsCaptured = false;
m_UndoSaved = false;
state.captured.Clear();
// Clear cursor only when OnGUI Process (not in test)
if (GUIUtility.guiDepth > 0)
TimelineCursors.ClearCursor();
return true;
}
protected override bool MouseDrag(Event evt, WindowState state)
{
if (!m_IsCaptured)
return false;
if (!m_UndoSaved)
{
var uiClip = m_EaseClipHandler.clipGUI;
string undoName = m_Edges == ManipulateEdges.Left ? EaseInClipText : EaseOutClipText;
TimelineUndo.PushUndo(uiClip.clip.parentTrack, undoName);
m_UndoSaved = true;
}
double d = state.PixelDeltaToDeltaTime(evt.delta.x);
if (m_Edges == ManipulateEdges.Left)
{
m_Clip.easeInDuration = Math.Max(0, m_Clip.easeInDuration + d);
}
else if (m_Edges == ManipulateEdges.Right)
{
m_Clip.easeOutDuration = Math.Max(0, m_Clip.easeOutDuration - d);
}
RefreshOverlayStrings(m_EaseClipHandler, state);
return true;
}
public override void Overlay(Event evt, WindowState state)
{
if (!m_IsCaptured)
return;
if (m_OverlayText.Length > 0)
{
int stringLength = m_OverlayText.Length;
var r = new Rect(evt.mousePosition.x - (stringLength / 2.0f),
m_EaseClipHandler.clipGUI.rect.yMax,
stringLength, 20);
GUI.Label(r, m_OverlayText.ToString(), TimelineWindow.styles.tinyFont);
}
}
void RefreshOverlayStrings(TimelineClipHandle handle, WindowState state)
{
m_OverlayText.Length = 0;
m_OverlayText.Append(m_Edges == ManipulateEdges.Left ? EaseInText : EaseOutText);
double easeDuration = m_Edges == ManipulateEdges.Left ? m_Clip.easeInDuration : m_Clip.easeOutDuration;
double deltaDuration = easeDuration - m_OriginalValue;
bool hasDurationDelta = Math.Abs(deltaDuration) > double.Epsilon;
if (state.timeInFrames)
{
easeDuration *= state.editSequence.frameRate;
deltaDuration *= state.editSequence.frameRate;
m_OverlayText.AppendFormat(DurationFrameText, easeDuration);
if (hasDurationDelta)
{
m_OverlayText.AppendFormat(DeltaFrameText, deltaDuration);
}
}
else
{
m_OverlayText.AppendFormat(DurationSecText, easeDuration);
if (hasDurationDelta)
{
m_OverlayText.AppendFormat(DeltaSecText, deltaDuration);
}
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b7cabea05434bb9479aee1e121b0d103
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,61 @@
using UnityEditor.ShortcutManagement;
using UnityEngine;
using UnityEngine.Timeline;
namespace UnityEditor.Timeline
{
class Jog : Manipulator
{
Vector2 m_MouseDownOrigin = Vector2.zero;
[ClutchShortcut("Timeline/Jog", typeof(TimelineWindow), KeyCode.J)]
static void JogShortcut(ShortcutArguments args)
{
if (args.stage == ShortcutStage.Begin)
{
(args.context as TimelineWindow).state.isJogging = true;
}
else if (args.stage == ShortcutStage.End)
{
(args.context as TimelineWindow).state.isJogging = false;
}
}
protected override bool MouseDown(Event evt, WindowState state)
{
if (!state.isJogging)
return false;
m_MouseDownOrigin = evt.mousePosition;
state.playbackSpeed = 0.0f;
state.Play();
return true;
}
protected override bool MouseUp(Event evt, WindowState state)
{
if (!state.isJogging)
{
return false;
}
m_MouseDownOrigin = evt.mousePosition;
state.playbackSpeed = 0.0f;
state.Play();
return false;
}
protected override bool MouseDrag(Event evt, WindowState state)
{
if (!state.isJogging)
return false;
var distance = evt.mousePosition - m_MouseDownOrigin;
state.playbackSpeed = distance.x * 0.002f;
state.Play();
return true;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 949b7e126b3f27940885a6808a15458e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,24 @@
using System;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
using Object = UnityEngine.Object;
namespace UnityEditor.Timeline
{
class TimelineMarkerHeaderContextMenu : Manipulator
{
protected override bool ContextClick(Event evt, WindowState state)
{
if (!state.showMarkerHeader)
return false;
if (!(state.GetWindow().markerHeaderRect.Contains(evt.mousePosition)
|| state.GetWindow().markerContentRect.Contains(evt.mousePosition)))
return false;
SequencerContextMenu.ShowMarkerHeaderContextMenu(evt.mousePosition, state);
return true;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e74ddf4132f3401409c824bed60280ee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,36 @@
using System.Linq;
using UnityEngine;
namespace UnityEditor.Timeline
{
class RectangleSelect : RectangleTool
{
protected override bool enableAutoPan { get { return false; } }
protected override bool CanStartRectangle(Event evt, Vector2 mousePosition, WindowState state)
{
if (evt.button != 0 || evt.alt)
return false;
return PickerUtils.pickedElements.All(e => e is IRowGUI);
}
protected override bool OnFinish(Event evt, WindowState state, Rect rect)
{
var selectables = state.spacePartitioner.GetItemsInArea<ISelectable>(rect).ToList();
if (!selectables.Any())
return false;
if (ItemSelection.CanClearSelection(evt))
SelectionManager.Clear();
foreach (var selectable in selectables)
{
ItemSelection.HandleItemSelection(evt, selectable);
}
return true;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: edd4f4b395430604d935bcf0b14c7d42
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,169 @@
using System;
using UnityEngine;
namespace UnityEditor.Timeline
{
abstract class RectangleTool
{
struct TimelinePoint
{
readonly double m_Time;
readonly float m_YPos;
readonly float m_YScrollPos;
readonly WindowState m_State;
readonly TimelineTreeViewGUI m_TreeViewGUI;
public TimelinePoint(WindowState state, Vector2 mousePosition)
{
m_State = state;
m_TreeViewGUI = state.GetWindow().treeView;
m_Time = m_State.PixelToTime(mousePosition.x);
m_YPos = mousePosition.y;
m_YScrollPos = m_TreeViewGUI.scrollPosition.y;
}
public Vector2 ToPixel()
{
return new Vector2(m_State.TimeToPixel(m_Time), m_YPos - (m_TreeViewGUI.scrollPosition.y - m_YScrollPos));
}
}
TimeAreaAutoPanner m_TimeAreaAutoPanner;
TimelinePoint m_StartPoint;
Vector2 m_EndPixel = Vector2.zero;
Rect m_ActiveRect;
protected abstract bool enableAutoPan { get; }
protected abstract bool CanStartRectangle(Event evt, Vector2 mousePosition, WindowState state);
protected abstract bool OnFinish(Event evt, WindowState state, Rect rect);
int m_Id;
public void OnGUI(WindowState state, EventType rawType, Vector2 mousePosition)
{
if (m_Id == 0)
m_Id = GUIUtility.GetPermanentControlID();
if (state == null || state.GetWindow().treeView == null)
return;
var evt = Event.current;
if (rawType == EventType.MouseDown || evt.type == EventType.MouseDown)
{
if (state.IsCurrentEditingASequencerTextField())
return;
m_ActiveRect = TimelineWindow.instance.sequenceContentRect;
if (!m_ActiveRect.Contains(mousePosition))
return;
if (!CanStartRectangle(evt, mousePosition, state))
return;
if (enableAutoPan)
m_TimeAreaAutoPanner = new TimeAreaAutoPanner(state);
m_StartPoint = new TimelinePoint(state, mousePosition);
m_EndPixel = mousePosition;
GUIUtility.hotControl = m_Id; //HACK: Because the treeView eats all the events, steal the hotControl if necessary...
evt.Use();
return;
}
switch (evt.GetTypeForControl(m_Id))
{
case EventType.KeyDown:
{
if (GUIUtility.hotControl == m_Id)
{
if (evt.keyCode == KeyCode.Escape)
{
m_TimeAreaAutoPanner = null;
GUIUtility.hotControl = 0;
evt.Use();
}
}
return;
}
case EventType.MouseDrag:
{
if (GUIUtility.hotControl != m_Id)
return;
m_EndPixel = mousePosition;
evt.Use();
return;
}
case EventType.MouseUp:
{
if (GUIUtility.hotControl != m_Id)
return;
m_TimeAreaAutoPanner = null;
var rect = CurrentRectangle();
if (IsValidRect(rect))
OnFinish(evt, state, rect);
GUIUtility.hotControl = 0;
evt.Use();
return;
}
}
if (GUIUtility.hotControl == m_Id)
{
if (evt.type == EventType.Repaint)
{
var r = CurrentRectangle();
if (IsValidRect(r))
{
using (new GUIViewportScope(m_ActiveRect))
{
DrawRectangle(r);
}
}
}
if (m_TimeAreaAutoPanner != null)
m_TimeAreaAutoPanner.OnGUI(evt);
}
}
protected virtual void DrawRectangle(Rect rect)
{
EditorStyles.selectionRect.Draw(rect, GUIContent.none, false, false, false, false);
}
static bool IsValidRect(Rect rect)
{
return rect.width >= 1.0f && rect.height >= 1.0f;
}
Rect CurrentRectangle()
{
var startPixel = m_StartPoint.ToPixel();
return Rect.MinMaxRect(
Math.Min(startPixel.x, m_EndPixel.x),
Math.Min(startPixel.y, m_EndPixel.y),
Math.Max(startPixel.x, m_EndPixel.x),
Math.Max(startPixel.y, m_EndPixel.y));
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 24a7ce8b48db53747a4e8abbda77eac4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,23 @@
using UnityEngine;
namespace UnityEditor.Timeline
{
class RectangleZoom : RectangleTool
{
protected override bool enableAutoPan { get { return true; } }
protected override bool CanStartRectangle(Event evt, Vector2 mousePosition, WindowState state)
{
return evt.button == 1 && evt.modifiers == (EventModifiers.Alt | EventModifiers.Shift);
}
protected override bool OnFinish(Event evt, WindowState state, Rect rect)
{
var x = state.PixelToTime(rect.xMin);
var y = state.PixelToTime(rect.xMax);
state.SetTimeAreaShownRange(x, y);
return true;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5aa8f57287fc17149bcd798be813180b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,297 @@
using System;
using System.Linq;
using UnityEngine;
using UnityEngine.Timeline;
namespace UnityEditor.Timeline
{
class ClearSelection : Manipulator
{
protected override bool MouseDown(Event evt, WindowState state)
{
// If we hit this point this means no one used the mouse down events. We can safely clear the selection if needed
if (evt.button != 0)
return false;
var window = state.GetWindow();
if (!window.sequenceRect.Contains(evt.mousePosition))
return false;
if (ItemSelection.CanClearSelection(evt))
{
SelectionManager.Clear();
return true;
}
return false;
}
}
static class ItemSelection
{
public static bool CanClearSelection(Event evt)
{
return !evt.control && !evt.command && !evt.shift;
}
public static void RangeSelectItems(ITimelineItem lastItemToSelect)
{
var selectSorted = SelectionManager.SelectedItems().ToList();
var firstSelect = selectSorted.FirstOrDefault();
if (firstSelect == null)
{
SelectionManager.Add(lastItemToSelect);
return;
}
var allTracks = TimelineEditor.inspectedAsset.flattenedTracks;
var allItems = allTracks.SelectMany(ItemsUtils.GetItems).ToList();
TimelineHelpers.RangeSelect(allItems, selectSorted, lastItemToSelect, SelectionManager.Add, SelectionManager.Remove);
}
public static ISelectable HandleSingleSelection(Event evt)
{
var item = PickerUtils.PickedLayerableOfType<ISelectable>();
if (item != null)
{
var selected = item.IsSelected();
if (!selected && CanClearSelection(evt))
SelectionManager.Clear();
if (evt.modifiers == EventModifiers.Shift)
{
if (!selected)
RangeSelectItems((item as TimelineItemGUI).item);
}
else
{
HandleItemSelection(evt, item);
}
}
return item;
}
public static void HandleItemSelection(Event evt, ISelectable item)
{
if (evt.modifiers == ManipulatorsUtils.actionModifier)
{
if (item.IsSelected())
item.Deselect();
else
item.Select();
}
else
{
if (!item.IsSelected())
item.Select();
}
}
}
class SelectAndMoveItem : Manipulator
{
bool m_Dragged;
SnapEngine m_SnapEngine;
TimeAreaAutoPanner m_TimeAreaAutoPanner;
Vector2 m_MouseDownPosition;
bool m_HorizontalMovementDone;
bool m_VerticalMovementDone;
MoveItemHandler m_MoveItemHandler;
bool m_CycleMarkersPending;
protected override bool MouseDown(Event evt, WindowState state)
{
if (evt.alt || evt.button != 0)
return false;
m_Dragged = false;
// Cycling markers and selection are mutually exclusive operations
if (!HandleMarkerCycle() && !HandleSingleSelection(evt))
return false;
m_MouseDownPosition = evt.mousePosition;
m_VerticalMovementDone = false;
m_HorizontalMovementDone = false;
return true;
}
protected override bool MouseUp(Event evt, WindowState state)
{
if (!m_Dragged)
{
var item = PickerUtils.PickedLayerableOfType<ISelectable>();
if (item == null)
return false;
if (!item.IsSelected())
return false;
// Re-selecting an item part of a multi-selection should only keep this item selected.
if (SelectionManager.Count() > 1 && ItemSelection.CanClearSelection(evt))
{
SelectionManager.Clear();
item.Select();
return true;
}
if (m_CycleMarkersPending)
{
m_CycleMarkersPending = false;
TimelineMarkerClusterGUI.CycleMarkers();
return true;
}
return false;
}
m_TimeAreaAutoPanner = null;
DropItems();
m_SnapEngine = null;
m_MoveItemHandler = null;
state.Evaluate();
state.RemoveCaptured(this);
m_Dragged = false;
TimelineCursors.ClearCursor();
return true;
}
protected override bool DoubleClick(Event evt, WindowState state)
{
return MouseDown(evt, state) && MouseUp(evt, state);
}
protected override bool MouseDrag(Event evt, WindowState state)
{
if (state.editSequence.isReadOnly)
return false;
// case 1099285 - ctrl-click can cause no clips to be selected
var selectedItemsGUI = SelectionManager.SelectedItems();
if (!selectedItemsGUI.Any())
{
m_Dragged = false;
return false;
}
const float hDeadZone = 5.0f;
const float vDeadZone = 5.0f;
bool vDone = m_VerticalMovementDone || Math.Abs(evt.mousePosition.y - m_MouseDownPosition.y) > vDeadZone;
bool hDone = m_HorizontalMovementDone || Math.Abs(evt.mousePosition.x - m_MouseDownPosition.x) > hDeadZone;
m_CycleMarkersPending = false;
if (!m_Dragged)
{
var canStartMove = vDone || hDone;
if (canStartMove)
{
state.AddCaptured(this);
m_Dragged = true;
var referenceTrack = GetTrackDropTargetAt(state, m_MouseDownPosition);
foreach (var item in selectedItemsGUI)
item.gui.StartDrag();
m_MoveItemHandler = new MoveItemHandler(state);
m_MoveItemHandler.Grab(selectedItemsGUI, referenceTrack, m_MouseDownPosition);
m_SnapEngine = new SnapEngine(m_MoveItemHandler, m_MoveItemHandler, ManipulateEdges.Both,
state, m_MouseDownPosition);
m_TimeAreaAutoPanner = new TimeAreaAutoPanner(state);
}
}
if (!m_VerticalMovementDone)
{
m_VerticalMovementDone = vDone;
if (m_VerticalMovementDone)
m_MoveItemHandler.OnTrackDetach();
}
if (!m_HorizontalMovementDone)
{
m_HorizontalMovementDone = hDone;
}
if (m_Dragged)
{
if (m_HorizontalMovementDone)
m_SnapEngine.Snap(evt.mousePosition, evt.modifiers);
if (m_VerticalMovementDone)
{
var track = GetTrackDropTargetAt(state, evt.mousePosition);
m_MoveItemHandler.UpdateTrackTarget(track);
}
state.Evaluate();
}
return true;
}
public override void Overlay(Event evt, WindowState state)
{
if (!m_Dragged)
return;
if (m_TimeAreaAutoPanner != null)
m_TimeAreaAutoPanner.OnGUI(evt);
m_MoveItemHandler.OnGUI(evt);
if (!m_MoveItemHandler.allowTrackSwitch || m_MoveItemHandler.targetTrack != null)
{
TimeIndicator.Draw(state, m_MoveItemHandler.start, m_MoveItemHandler.end);
m_SnapEngine.OnGUI();
}
}
bool HandleMarkerCycle()
{
m_CycleMarkersPending = TimelineMarkerClusterGUI.CanCycleMarkers();
return m_CycleMarkersPending;
}
bool HandleSingleSelection(Event evt)
{
return ItemSelection.HandleSingleSelection(evt) != null;
}
void DropItems()
{
// Order matters here: m_MoveItemHandler.movingItems is destroyed during call to Drop()
foreach (var movingItem in m_MoveItemHandler.movingItems)
{
foreach (var item in movingItem.items)
item.gui.StopDrag();
}
m_MoveItemHandler.Drop();
}
static TrackAsset GetTrackDropTargetAt(WindowState state, Vector2 point)
{
var track = state.spacePartitioner.GetItemsAtPosition<IRowGUI>(point).FirstOrDefault();
return track != null ? track.asset : null;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f4f988528bbbb0846a4cb50efb4587a5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,20 @@
using UnityEngine;
using UnityEngine.Timeline;
namespace UnityEditor.Timeline
{
class TrackZoom : Manipulator
{
// only handles 'vertical' zoom. horizontal is handled in timelineGUI
protected override bool MouseWheel(Event evt, WindowState state)
{
if (EditorGUI.actionKey)
{
state.trackScale = Mathf.Min(Mathf.Max(state.trackScale + (evt.delta.y * 0.1f), 1.0f), 100.0f);
return true;
}
return false;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6e7c80eefe2def5459e0b486b3ab96e2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,232 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.Timeline;
namespace UnityEditor.Timeline
{
class TrimClip : Manipulator
{
class TrimClipAttractionHandler : IAttractionHandler
{
public void OnAttractedEdge(IAttractable attractable, ManipulateEdges manipulateEdges, AttractedEdge edge, double time)
{
var clipGUI = attractable as TimelineClipGUI;
if (clipGUI == null)
return;
var clipItem = ItemsUtils.ToItem(clipGUI.clip);
if (manipulateEdges == ManipulateEdges.Right)
{
bool affectTimeScale = Event.current.modifiers == EventModifiers.Shift; // TODO Do not use Event.current from here.
EditMode.TrimEnd(clipItem, time, affectTimeScale);
}
else if (manipulateEdges == ManipulateEdges.Left)
{
EditMode.TrimStart(clipItem, time);
}
}
}
bool m_IsCaptured;
TimelineClipHandle m_TrimClipHandler;
double m_OriginalDuration;
double m_OriginalTimeScale;
bool m_UndoSaved;
SnapEngine m_SnapEngine;
readonly StringBuilder m_OverlayText = new StringBuilder();
readonly List<string> m_OverlayStrings = new List<string>();
static readonly double kEpsilon = 0.0000001;
protected override bool MouseDown(Event evt, WindowState state)
{
var handle = PickerUtils.PickedLayerableOfType<TimelineClipHandle>();
if (handle == null)
return false;
if (handle.clipGUI.clip.parentTrack != null && handle.clipGUI.clip.parentTrack.lockedInHierarchy)
return false;
if (ItemSelection.CanClearSelection(evt))
SelectionManager.Clear();
if (!SelectionManager.Contains(handle.clipGUI.clip))
SelectionManager.Add(handle.clipGUI.clip);
m_TrimClipHandler = handle;
m_IsCaptured = true;
state.AddCaptured(this);
m_UndoSaved = false;
var clip = m_TrimClipHandler.clipGUI.clip;
m_OriginalDuration = clip.duration;
m_OriginalTimeScale = clip.timeScale;
RefreshOverlayStrings(m_TrimClipHandler, state);
// in ripple trim, the right edge moves and needs to snap
var edges = ManipulateEdges.Right;
if (EditMode.editType != EditMode.EditType.Ripple && m_TrimClipHandler.trimDirection == TrimEdge.Start)
edges = ManipulateEdges.Left;
m_SnapEngine = new SnapEngine(m_TrimClipHandler.clipGUI, new TrimClipAttractionHandler(), edges, state,
evt.mousePosition);
EditMode.BeginTrim(ItemsUtils.ToItem(clip), m_TrimClipHandler.trimDirection);
return true;
}
protected override bool MouseUp(Event evt, WindowState state)
{
if (!m_IsCaptured)
return false;
m_IsCaptured = false;
m_TrimClipHandler = null;
m_UndoSaved = false;
m_SnapEngine = null;
EditMode.FinishTrim();
state.captured.Clear();
return true;
}
protected override bool MouseDrag(Event evt, WindowState state)
{
if (state.editSequence.isReadOnly)
return false;
if (!m_IsCaptured)
return false;
if (!m_UndoSaved)
{
var uiClip = m_TrimClipHandler.clipGUI;
TimelineUndo.PushUndo(uiClip.clip.parentTrack, "Trim Clip");
if (TimelineUtility.IsRecordableAnimationClip(uiClip.clip))
{
TimelineUndo.PushUndo(uiClip.clip.animationClip, "Trim Clip");
}
m_UndoSaved = true;
}
if (m_SnapEngine != null)
m_SnapEngine.Snap(evt.mousePosition, evt.modifiers);
RefreshOverlayStrings(m_TrimClipHandler, state);
if (Selection.activeObject != null)
EditorUtility.SetDirty(Selection.activeObject);
// updates the duration of the graph without rebuilding
state.UpdateRootPlayableDuration(state.editSequence.duration);
return true;
}
public override void Overlay(Event evt, WindowState state)
{
if (!m_IsCaptured)
return;
EditMode.DrawTrimGUI(state, m_TrimClipHandler.clipGUI, m_TrimClipHandler.trimDirection);
bool trimStart = m_TrimClipHandler.trimDirection == TrimEdge.Start;
TimeIndicator.Draw(state, trimStart ? m_TrimClipHandler.clipGUI.start : m_TrimClipHandler.clipGUI.end);
if (m_SnapEngine != null)
m_SnapEngine.OnGUI(trimStart, !trimStart);
if (m_OverlayStrings.Count > 0)
{
const float padding = 4.0f;
var labelStyle = TimelineWindow.styles.tinyFont;
var longestLine = labelStyle.CalcSize(
new GUIContent(m_OverlayStrings.Aggregate("", (max, cur) => max.Length > cur.Length ? max : cur)));
var stringLength = longestLine.x + padding;
var lineHeight = longestLine.y + padding;
var r = new Rect(evt.mousePosition.x - (stringLength / 2.0f),
m_TrimClipHandler.clipGUI.rect.yMax,
stringLength, lineHeight);
foreach (var s in m_OverlayStrings)
{
GUI.Label(r, s, labelStyle);
r.y += lineHeight;
}
}
}
void RefreshOverlayStrings(TimelineClipHandle handle, WindowState state)
{
m_OverlayStrings.Clear();
m_OverlayText.Length = 0;
var differenceDuration = handle.clipGUI.clip.duration - m_OriginalDuration;
bool hasDurationDelta = Math.Abs(differenceDuration) > kEpsilon;
if (state.timeInFrames)
{
var durationInFrame = handle.clipGUI.clip.duration * state.referenceSequence.frameRate;
m_OverlayText.Append("duration: ").Append(durationInFrame.ToString("f2")).Append(" frames");
if (hasDurationDelta)
{
m_OverlayText.Append(" (");
if (differenceDuration > 0.0)
m_OverlayText.Append("+");
var valueInFrame = differenceDuration * state.referenceSequence.frameRate;
m_OverlayText.Append(valueInFrame.ToString("f2")).Append(" frames)");
}
}
else
{
m_OverlayText.Append("duration: ").Append(handle.clipGUI.clip.duration.ToString("f2")).Append("s");
if (hasDurationDelta)
{
m_OverlayText.Append(" (");
if (differenceDuration > 0.0)
m_OverlayText.Append("+");
m_OverlayText.Append(differenceDuration.ToString("f2")).Append("s)");
}
}
m_OverlayStrings.Add(m_OverlayText.ToString());
m_OverlayText.Length = 0;
var differenceSpeed = m_OriginalTimeScale - handle.clipGUI.clip.timeScale;
if (Math.Abs(differenceSpeed) > kEpsilon)
{
m_OverlayText.Append("speed: ").Append(handle.clipGUI.clip.timeScale.ToString("p2"));
m_OverlayText.Append(" (");
if (differenceSpeed > 0.0)
m_OverlayText.Append("+");
m_OverlayText.Append(differenceSpeed.ToString("p2")).Append(")");
m_OverlayStrings.Add(m_OverlayText.ToString());
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 511aa760b8728a940a41c29837945292
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: