diff options
Diffstat (limited to 'Library/PackageCache/com.unity.timeline@1.2.13/Editor/treeview/InlineCurveEditor.cs')
| -rw-r--r-- | Library/PackageCache/com.unity.timeline@1.2.13/Editor/treeview/InlineCurveEditor.cs | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/treeview/InlineCurveEditor.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/treeview/InlineCurveEditor.cs new file mode 100644 index 0000000..0bff23f --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/treeview/InlineCurveEditor.cs @@ -0,0 +1,299 @@ +using System.Linq; +using JetBrains.Annotations; +using UnityEngine; +using UnityEngine.Timeline; + +namespace UnityEditor.Timeline +{ + interface IClipCurveEditorOwner + { + ClipCurveEditor clipCurveEditor { get; } + bool inlineCurvesSelected { get; set; } + bool showLoops { get; } + TrackAsset owner { get; } + } + + class InlineCurveResizeHandle : IBounds + { + public Rect boundingRect { get; private set; } + + public TimelineTrackGUI trackGUI { get; } + + public InlineCurveResizeHandle(TimelineTrackGUI trackGUI) + { + this.trackGUI = trackGUI; + } + + public void Draw(Rect headerRect, Rect trackRect, WindowState state) + { + var rect = new Rect(headerRect.xMax + 4, headerRect.yMax - 5.0f, trackRect.width - 4, 5.0f); + + var handleColor = Handles.color; + Handles.color = Color.black; + Handles.DrawAAPolyLine(1.0f, + new Vector3(rect.x, rect.yMax, 0.0f), + new Vector3(rect.xMax, rect.yMax, 0.0f)); + Handles.color = handleColor; + + EditorGUIUtility.AddCursorRect(rect, MouseCursor.SplitResizeUpDown); + + boundingRect = trackGUI.ToWindowSpace(rect); + + if (Event.current.type == EventType.Repaint) + { + state.spacePartitioner.AddBounds(this); + + var dragStyle = new GUIStyle("RL DragHandle"); + dragStyle.Draw(rect, GUIContent.none, false, false, false, false); + } + } + } + + class InlineCurveEditor : IBounds + { + Rect m_TrackRect; + Rect m_HeaderRect; + readonly TimelineTrackGUI m_TrackGUI; + readonly InlineCurveResizeHandle m_ResizeHandle; + + bool m_LastSelectionWasClip; + TimelineClipGUI m_LastSelectedClipGUI; + + Rect IBounds.boundingRect { get { return m_TrackGUI.ToWindowSpace(m_TrackRect); } } + + [UsedImplicitly] // Used in tests + public TimelineClipGUI currentClipGui + { + get { return m_LastSelectedClipGUI; } + } + + public IClipCurveEditorOwner currentCurveEditor + { + get { return m_LastSelectionWasClip ? (IClipCurveEditorOwner)m_LastSelectedClipGUI : (IClipCurveEditorOwner)m_TrackGUI; } + } + + public InlineCurveEditor(TimelineTrackGUI trackGUI) + { + m_TrackGUI = trackGUI; + m_ResizeHandle = new InlineCurveResizeHandle(trackGUI); + } + + static bool MouseOverTrackArea(Rect curveRect, Rect trackRect) + { + curveRect.y = trackRect.y; + curveRect.height = trackRect.height; + + // clamp the curve editor to the track. this allows the menu to scroll properly + curveRect.xMin = Mathf.Max(curveRect.xMin, trackRect.xMin); + curveRect.xMax = trackRect.xMax; + + return curveRect.Contains(Event.current.mousePosition); + } + + static bool MouseOverHeaderArea(Rect headerRect, Rect trackRect) + { + headerRect.y = trackRect.y; + headerRect.height = trackRect.height; + + return headerRect.Contains(Event.current.mousePosition); + } + + static void DrawCurveEditor(IClipCurveEditorOwner clipCurveEditorOwner, WindowState state, Rect headerRect, Rect trackRect, Vector2 activeRange, bool locked) + { + ClipCurveEditor clipCurveEditor = clipCurveEditorOwner.clipCurveEditor; + CurveDataSource dataSource = clipCurveEditor.dataSource; + Rect curveRect = dataSource.GetBackgroundRect(state); + + bool newlySelected = false; + + if (Event.current.type == EventType.MouseDown || Event.current.type == EventType.ContextClick) + newlySelected = MouseOverTrackArea(curveRect, trackRect) || MouseOverHeaderArea(headerRect, trackRect); + + // make sure to not use any event before drawing the curve. + bool prevEnabledState = GUI.enabled; + GUI.enabled = true; + clipCurveEditorOwner.clipCurveEditor.DrawHeader(headerRect); + GUI.enabled = prevEnabledState; + + bool displayAsSelected = !locked && (clipCurveEditorOwner.inlineCurvesSelected || newlySelected); + + using (new EditorGUI.DisabledScope(locked)) + clipCurveEditor.DrawCurveEditor(trackRect, state, activeRange, clipCurveEditorOwner.showLoops, displayAsSelected); + + if (newlySelected && !locked) + { + clipCurveEditorOwner.inlineCurvesSelected = true; + HandleCurrentEvent(); + } + } + + public void Draw(Rect headerRect, Rect trackRect, WindowState state) + { + m_TrackRect = trackRect; + m_TrackRect.height -= 5.0f; + + if (Event.current.type == EventType.Repaint) + state.spacePartitioner.AddBounds(this); + + // Remove the indentation of this track to render it properly, otherwise every GUI elements will be offsetted. + headerRect.x -= DirectorStyles.kBaseIndent; + headerRect.width += DirectorStyles.kBaseIndent; + + // Remove the width of the color swatch. + headerRect.x += 4.0f; + headerRect.width -= 4.0f; + + m_HeaderRect = headerRect; + + EditorGUI.DrawRect(m_HeaderRect, DirectorStyles.Instance.customSkin.colorAnimEditorBinding); + + if (ShouldShowClipCurves(state)) + { + DrawCurveEditorsForClipsOnTrack(m_HeaderRect, m_TrackRect, state); + } + else if (ShouldShowTrackCurves()) + { + DrawCurveEditorForTrack(m_HeaderRect, m_TrackRect, state); + } + else + { + DrawCurvesEditorForNothingSelected(m_HeaderRect, m_TrackRect, state); + } + + m_ResizeHandle.Draw(headerRect, trackRect, state); + + // If MouseDown or ContextClick are not consumed by the curves, use the event to prevent it from going deeper into the treeview. + if (Event.current.type == EventType.ContextClick) + { + var r = Rect.MinMaxRect(m_HeaderRect.xMin, m_HeaderRect.yMin, m_TrackRect.xMax, m_TrackRect.yMax); + if (r.Contains(Event.current.mousePosition)) + Event.current.Use(); + } + + UpdateViewModel(); + } + + public void Refresh() + { + if (m_LastSelectionWasClip) + RefreshInlineCurves(m_LastSelectedClipGUI); + else + RefreshInlineCurves(m_TrackGUI); + } + + static void RefreshInlineCurves(IClipCurveEditorOwner guiItem) + { + if (guiItem.clipCurveEditor != null && guiItem.clipCurveEditor.dataSource != null) + guiItem.clipCurveEditor.dataSource.RebuildCurves(); + } + + void DrawCurveEditorForTrack(Rect headerRect, Rect trackRect, WindowState state) + { + if (m_TrackGUI.clipCurveEditor == null) + return; + + var activeRange = new Vector2(state.TimeToPixel(0.0d), state.TimeToPixel(state.editSequence.duration)); + DrawCurveEditor(m_TrackGUI, state, headerRect, trackRect, activeRange, m_TrackGUI.locked); + m_LastSelectionWasClip = false; + } + + void DrawCurveEditorsForClipsOnTrack(Rect headerRect, Rect trackRect, WindowState state) + { + if (m_TrackGUI.clips.Count == 0) + return; + + if (Event.current.type == EventType.Layout) + { + TimelineClipGUI selectedClip = SelectionManager.SelectedClipGUI().FirstOrDefault(x => x.parent == m_TrackGUI); + if (selectedClip != null) + { + m_LastSelectedClipGUI = selectedClip; + } + else if (state.recording && state.IsArmedForRecord(m_TrackGUI.track)) + { + if (m_LastSelectedClipGUI == null || !m_TrackGUI.track.IsRecordingToClip(m_LastSelectedClipGUI.clip)) + { + var clip = m_TrackGUI.clips.FirstOrDefault(x => m_TrackGUI.track.IsRecordingToClip(x.clip)); + if (clip != null) + m_LastSelectedClipGUI = clip; + } + } + + if (m_LastSelectedClipGUI == null) + m_LastSelectedClipGUI = m_TrackGUI.clips[0]; + } + + if (m_LastSelectedClipGUI == null || m_LastSelectedClipGUI.clipCurveEditor == null || m_LastSelectedClipGUI.isInvalid) + return; + + var activeRange = new Vector2(state.TimeToPixel(m_LastSelectedClipGUI.clip.start), state.TimeToPixel(m_LastSelectedClipGUI.clip.end)); + DrawCurveEditor(m_LastSelectedClipGUI, state, headerRect, trackRect, activeRange, m_TrackGUI.locked); + m_LastSelectionWasClip = true; + } + + void DrawCurvesEditorForNothingSelected(Rect headerRect, Rect trackRect, WindowState state) + { + if (m_LastSelectionWasClip || !TrackHasCurvesToShow() && m_TrackGUI.clips.Count > 0) + { + DrawCurveEditorsForClipsOnTrack(headerRect, trackRect, state); + } + else + { + DrawCurveEditorForTrack(headerRect, trackRect, state); + } + } + + bool ShouldShowClipCurves(WindowState state) + { + if (m_TrackGUI.clips.Count == 0) + return false; + + // Is a clip selected or being recorded to? + return SelectionManager.SelectedClipGUI().FirstOrDefault(x => x.parent == m_TrackGUI) != null || + state.recording && state.IsArmedForRecord(m_TrackGUI.track) && m_TrackGUI.clips.FirstOrDefault(x => m_TrackGUI.track.IsRecordingToClip(x.clip)) != null; + } + + bool ShouldShowTrackCurves() + { + if (m_TrackGUI == null) + return false; + + var isTrackSelected = SelectionManager.SelectedTrackGUI().FirstOrDefault(x => x == m_TrackGUI) != null; + + if (!isTrackSelected) + return false; + + return TrackHasCurvesToShow(); + } + + bool TrackHasCurvesToShow() + { + var animTrack = m_TrackGUI.track as AnimationTrack; + if (animTrack != null && !animTrack.inClipMode) + return true; + + return m_TrackGUI.track.HasAnyAnimatableParameters(); + } + + void UpdateViewModel() + { + var curveEditor = currentCurveEditor.clipCurveEditor; + if (curveEditor == null || curveEditor.bindingHierarchy.treeViewController == null) + return; + + var vm = TimelineWindowViewPrefs.GetTrackViewModelData(m_TrackGUI.track); + vm.inlineCurvesState = curveEditor.bindingHierarchy.treeViewController.state; + vm.inlineCurvesShownAreaInsideMargins = curveEditor.shownAreaInsideMargins; + vm.lastInlineCurveDataID = curveEditor.dataSource.id; + } + + static void HandleCurrentEvent() + { +#if UNITY_EDITOR_OSX + Event.current.type = EventType.Ignore; +#else + Event.current.Use(); +#endif + } + } +} |
