summaryrefslogtreecommitdiff
path: root/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Trackhead.cs
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/Trackhead.cs
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/Trackhead.cs')
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Trackhead.cs363
1 files changed, 363 insertions, 0 deletions
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Trackhead.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Trackhead.cs
new file mode 100644
index 0000000..8a562b6
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Trackhead.cs
@@ -0,0 +1,363 @@
+using System;
+using System.Linq;
+using UnityEngine;
+using UnityEngine.Timeline;
+
+namespace UnityEditor.Timeline
+{
+ static class Gaps
+ {
+ static readonly string kInsertTime = "Insert Time";
+
+ public static void Insert(TimelineAsset asset, double at, double amount, double tolerance)
+ {
+ // gather all clips
+ var clips = asset.flattenedTracks.SelectMany(x => x.clips).Where(x => (x.start - at) >= -tolerance).ToList();
+ var markers = asset.flattenedTracks.SelectMany(x => x.GetMarkers()).Where(x => (x.time - at) >= -tolerance).ToList();
+
+ if (!clips.Any() && !markers.Any())
+ return;
+
+ // push undo on the tracks for the clips that are being modified
+ foreach (var t in clips.Select(x => x.parentTrack).Distinct())
+ {
+ TimelineUndo.PushUndo(t, kInsertTime);
+ }
+
+ // push the clips
+ foreach (var clip in clips)
+ {
+ clip.start += amount;
+ }
+
+ // push undos and move the markers
+ foreach (var marker in markers)
+ {
+ var obj = marker as UnityEngine.Object;
+ if (obj != null)
+ TimelineUndo.PushUndo(obj, kInsertTime);
+ marker.time += amount;
+ }
+
+ TimelineEditor.Refresh(RefreshReason.ContentsModified);
+ }
+ }
+
+ class PlayheadContextMenu : Manipulator
+ {
+ readonly TimeAreaItem m_TimeAreaItem;
+ static readonly int[] kFrameInsertionValues = {5, 10, 25, 100};
+
+ public PlayheadContextMenu(TimeAreaItem timeAreaItem)
+ {
+ m_TimeAreaItem = timeAreaItem;
+ }
+
+ protected override bool ContextClick(Event evt, WindowState state)
+ {
+ if (!m_TimeAreaItem.bounds.Contains(evt.mousePosition))
+ return false;
+
+ var tolerance = TimeUtility.GetEpsilon(state.editSequence.time, state.referenceSequence.frameRate);
+ var menu = new GenericMenu();
+
+ if (!TimelineWindow.instance.state.editSequence.isReadOnly)
+ {
+ menu.AddItem(EditorGUIUtility.TrTextContent("Insert/Frame/Single"), false, () =>
+ Gaps.Insert(state.editSequence.asset, state.editSequence.time, 1.0 / state.referenceSequence.frameRate, tolerance)
+ );
+
+ for (var i = 0; i != kFrameInsertionValues.Length; ++i)
+ {
+ double f = kFrameInsertionValues[i];
+ menu.AddItem(EditorGUIUtility.TrTextContent("Insert/Frame/" + kFrameInsertionValues[i] + " Frames"), false, () =>
+ Gaps.Insert(state.editSequence.asset, state.editSequence.time, f / state.referenceSequence.frameRate, tolerance)
+ );
+ }
+
+ var playRangeTime = state.playRange;
+ if (playRangeTime.y > playRangeTime.x)
+ {
+ menu.AddItem(EditorGUIUtility.TrTextContent("Insert/Selected Time"), false, () =>
+ Gaps.Insert(state.editSequence.asset, playRangeTime.x, playRangeTime.y - playRangeTime.x, TimeUtility.GetEpsilon(playRangeTime.x, state.referenceSequence.frameRate))
+ );
+ }
+ }
+
+ menu.AddItem(EditorGUIUtility.TrTextContent("Select/Clips Ending Before"), false, () => SelectMenuCallback(x => x.end < state.editSequence.time + tolerance, state));
+ menu.AddItem(EditorGUIUtility.TrTextContent("Select/Clips Starting Before"), false, () => SelectMenuCallback(x => x.start < state.editSequence.time + tolerance, state));
+ menu.AddItem(EditorGUIUtility.TrTextContent("Select/Clips Ending After"), false, () => SelectMenuCallback(x => x.end - state.editSequence.time >= -tolerance, state));
+ menu.AddItem(EditorGUIUtility.TrTextContent("Select/Clips Starting After"), false, () => SelectMenuCallback(x => x.start - state.editSequence.time >= -tolerance, state));
+ menu.AddItem(EditorGUIUtility.TrTextContent("Select/Clips Intersecting"), false, () => SelectMenuCallback(x => x.start <= state.editSequence.time && state.editSequence.time <= x.end, state));
+ menu.AddItem(EditorGUIUtility.TrTextContent("Select/Blends Intersecting"), false, () => SelectMenuCallback(x => SelectBlendingIntersecting(x, state.editSequence.time), state));
+ menu.ShowAsContext();
+
+ return true;
+ }
+
+ static bool SelectBlendingIntersecting(TimelineClip clip, double time)
+ {
+ return clip.start <= time && time <= clip.end && (
+ (time <= clip.start + clip.blendInDuration) ||
+ (time >= clip.end - clip.blendOutDuration)
+ );
+ }
+
+ static void SelectMenuCallback(Func<TimelineClip, bool> selector, WindowState state)
+ {
+ var allClips = state.GetWindow().treeView.allClipGuis;
+ if (allClips == null)
+ return;
+
+ SelectionManager.Clear();
+ for (var i = 0; i != allClips.Count; ++i)
+ {
+ var c = allClips[i];
+
+ if (c != null && c.clip != null && selector(c.clip))
+ {
+ SelectionManager.Add(c.clip);
+ }
+ }
+ }
+ }
+
+ class TimeAreaContextMenu : Manipulator
+ {
+ protected override bool ContextClick(Event evt, WindowState state)
+ {
+ if (state.timeAreaRect.Contains(Event.current.mousePosition))
+ {
+ var menu = new GenericMenu();
+ AddTimeAreaMenuItems(menu, state);
+ menu.ShowAsContext();
+ return true;
+ }
+ return false;
+ }
+
+ internal static void AddTimeAreaMenuItems(GenericMenu menu, WindowState state)
+ {
+ foreach (var value in Enum.GetValues(typeof(TimelineAsset.DurationMode)))
+ {
+ var mode = (TimelineAsset.DurationMode)value;
+ var item = EditorGUIUtility.TextContent(string.Format(TimelineWindow.Styles.DurationModeText, L10n.Tr(ObjectNames.NicifyVariableName(mode.ToString()))));
+
+ if (state.recording || state.IsEditingASubTimeline() || state.editSequence.asset == null
+ || state.editSequence.isReadOnly)
+ menu.AddDisabledItem(item);
+ else
+ menu.AddItem(item, state.editSequence.asset.durationMode == mode, () => SelectDurationCallback(state, mode));
+
+ menu.AddItem(DirectorStyles.showMarkersOnTimeline, state.showMarkerHeader, () => new ToggleShowMarkersOnTimeline().Execute(state));
+ }
+ }
+
+ static void SelectDurationCallback(WindowState state, TimelineAsset.DurationMode mode)
+ {
+ if (mode == state.editSequence.asset.durationMode)
+ return;
+
+ TimelineUndo.PushUndo(state.editSequence.asset, "Duration Mode");
+
+
+ // if we switched from Auto to Fixed, use the auto duration as the new fixed duration so the end marker stay in the same position.
+ if (state.editSequence.asset.durationMode == TimelineAsset.DurationMode.BasedOnClips && mode == TimelineAsset.DurationMode.FixedLength)
+ {
+ state.editSequence.asset.fixedDuration = state.editSequence.duration;
+ }
+
+ state.editSequence.asset.durationMode = mode;
+ state.UpdateRootPlayableDuration(state.editSequence.duration);
+ }
+ }
+
+ class Scrub : Manipulator
+ {
+ readonly Func<Event, WindowState, bool> m_OnMouseDown;
+ readonly Action<double> m_OnMouseDrag;
+ readonly Action m_OnMouseUp;
+
+ bool m_IsCaptured;
+
+ public Scrub(Func<Event, WindowState, bool> onMouseDown, Action<double> onMouseDrag, Action onMouseUp)
+ {
+ m_OnMouseDown = onMouseDown;
+ m_OnMouseDrag = onMouseDrag;
+ m_OnMouseUp = onMouseUp;
+ }
+
+ protected override bool MouseDown(Event evt, WindowState state)
+ {
+ if (evt.button != 0)
+ return false;
+
+ if (!m_OnMouseDown(evt, state))
+ return false;
+
+ state.AddCaptured(this);
+ m_IsCaptured = true;
+
+ return true;
+ }
+
+ protected override bool MouseUp(Event evt, WindowState state)
+ {
+ if (!m_IsCaptured)
+ return false;
+
+ m_IsCaptured = false;
+ state.RemoveCaptured(this);
+
+ m_OnMouseUp();
+
+ return true;
+ }
+
+ protected override bool MouseDrag(Event evt, WindowState state)
+ {
+ if (!m_IsCaptured)
+ return false;
+
+ m_OnMouseDrag(state.GetSnappedTimeAtMousePosition(evt.mousePosition));
+
+ return true;
+ }
+ }
+
+ class TimeAreaItem : Control
+ {
+ public Color headColor { get; set; }
+ public Color lineColor { get; set; }
+ public bool drawLine { get; set; }
+ public bool drawHead { get; set; }
+ public bool canMoveHead { get; set; }
+ public string tooltip { get; set; }
+ public Vector2 boundOffset { get; set; }
+
+ readonly GUIContent m_HeaderContent = new GUIContent();
+ readonly GUIStyle m_Style;
+ readonly Tooltip m_Tooltip;
+
+ Rect m_BoundingRect;
+
+ float widgetHeight { get { return m_Style.fixedHeight; } }
+ float widgetWidth { get { return m_Style.fixedWidth; } }
+
+ public Rect bounds
+ {
+ get
+ {
+ Rect r = m_BoundingRect;
+ r.y = TimelineWindow.instance.state.timeAreaRect.yMax - widgetHeight;
+ r.position += boundOffset;
+
+ return r;
+ }
+ }
+
+ public GUIStyle style
+ {
+ get { return m_Style; }
+ }
+
+
+ public bool showTooltip { get; set; }
+
+ // is this the first frame the drag callback is being invoked
+ public bool firstDrag { get; private set; }
+
+ public TimeAreaItem(GUIStyle style, Action<double> onDrag)
+ {
+ m_Style = style;
+ headColor = Color.white;
+ var scrub = new Scrub(
+ (evt, state) =>
+ {
+ firstDrag = true;
+ return state.timeAreaRect.Contains(evt.mousePosition) && bounds.Contains(evt.mousePosition);
+ },
+ (d) =>
+ {
+ if (onDrag != null)
+ onDrag(d);
+ firstDrag = false;
+ },
+ () =>
+ {
+ showTooltip = false;
+ firstDrag = false;
+ }
+ );
+ AddManipulator(scrub);
+ lineColor = m_Style.normal.textColor;
+ drawLine = true;
+ drawHead = true;
+ canMoveHead = false;
+ tooltip = string.Empty;
+ boundOffset = Vector2.zero;
+ m_Tooltip = new Tooltip(DirectorStyles.Instance.displayBackground, DirectorStyles.Instance.tinyFont);
+ }
+
+ public void Draw(Rect rect, WindowState state, double time)
+ {
+ var clipRect = new Rect(0.0f, 0.0f, TimelineWindow.instance.position.width, TimelineWindow.instance.position.height);
+ clipRect.xMin += state.sequencerHeaderWidth;
+
+ using (new GUIViewportScope(clipRect))
+ {
+ Vector2 windowCoordinate = rect.min;
+ windowCoordinate.y += 4.0f;
+
+ windowCoordinate.x = state.TimeToPixel(time);
+
+ m_BoundingRect = new Rect((windowCoordinate.x - widgetWidth / 2.0f), windowCoordinate.y, widgetWidth, widgetHeight);
+
+ // Do not paint if the time cursor goes outside the timeline bounds...
+ if (Event.current.type == EventType.Repaint)
+ {
+ if (m_BoundingRect.xMax < state.timeAreaRect.xMin)
+ return;
+ if (m_BoundingRect.xMin > state.timeAreaRect.xMax)
+ return;
+ }
+
+ var top = new Vector3(windowCoordinate.x, rect.y - DirectorStyles.kDurationGuiThickness);
+ var bottom = new Vector3(windowCoordinate.x, rect.yMax);
+
+ if (drawLine)
+ {
+ Rect lineRect = Rect.MinMaxRect(top.x - 0.5f, top.y, bottom.x + 0.5f, bottom.y);
+ EditorGUI.DrawRect(lineRect, lineColor);
+ }
+
+ if (drawHead)
+ {
+ Color c = GUI.color;
+ GUI.color = headColor;
+ GUI.Box(bounds, m_HeaderContent, m_Style);
+ GUI.color = c;
+
+ if (canMoveHead)
+ EditorGUIUtility.AddCursorRect(bounds, MouseCursor.MoveArrow);
+ }
+
+ if (showTooltip)
+ {
+ m_Tooltip.text = TimeReferenceUtility.ToTimeString(time);
+
+ Vector2 position = bounds.position;
+ position.y = state.timeAreaRect.y;
+ position.y -= m_Tooltip.bounds.height;
+ position.x -= Mathf.Abs(m_Tooltip.bounds.width - bounds.width) / 2.0f;
+
+ Rect tooltipBounds = bounds;
+ tooltipBounds.position = position;
+ m_Tooltip.bounds = tooltipBounds;
+
+ m_Tooltip.Draw();
+ }
+ }
+ }
+ }
+}