diff options
| author | Andrew Lee <alee14498@protonmail.com> | 2020-04-19 17:19:32 -0400 |
|---|---|---|
| committer | Andrew Lee <alee14498@protonmail.com> | 2020-04-19 17:19:32 -0400 |
| commit | c55fba8ab2a1c9d3df65eda4a5a1e957f4aa1f78 (patch) | |
| tree | ee4d51c7c1d633e11f46453ef1edd3c77c4ef9f7 /Library/PackageCache/com.unity.timeline@1.2.13/Editor/treeview/TimelineTreeView.cs | |
| download | Project-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/treeview/TimelineTreeView.cs')
| -rw-r--r-- | Library/PackageCache/com.unity.timeline@1.2.13/Editor/treeview/TimelineTreeView.cs | 439 |
1 files changed, 439 insertions, 0 deletions
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/treeview/TimelineTreeView.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/treeview/TimelineTreeView.cs new file mode 100644 index 0000000..9345d9a --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/treeview/TimelineTreeView.cs @@ -0,0 +1,439 @@ +using System.Collections.Generic; +using System.Linq; +using UnityEditor.IMGUI.Controls; +using UnityEngine; + +namespace UnityEditor.Timeline +{ + class TimelineTreeView : ITreeViewGUI + { + float m_FoldoutWidth; + Rect m_DraggingInsertionMarkerRect; + readonly TreeViewController m_TreeView; + + List<Rect> m_RowRects = new List<Rect>(); + List<Rect> m_ExpandedRowRects = new List<Rect>(); + + float m_MaxWidthOfRows; + readonly WindowState m_State; + + static readonly float kMinTrackHeight = 25.0f; + static readonly float kFoldOutOffset = 14.0f; + + static DirectorStyles m_Styles; + + public bool showInsertionMarker { get; set; } + public virtual float topRowMargin { get; private set; } + public virtual float bottomRowMargin { get; private set; } + + public TimelineTreeView(TimelineWindow sequencerWindow, TreeViewController treeView) + { + m_TreeView = treeView; + m_TreeView.useExpansionAnimation = true; + + m_TreeView.selectionChangedCallback += SelectionChangedCallback; + m_TreeView.contextClickOutsideItemsCallback += ContextClickOutsideItemsCallback; + m_TreeView.itemDoubleClickedCallback += ItemDoubleClickedCallback; + m_TreeView.contextClickItemCallback += ContextClickItemCallback; + + m_TreeView.SetConsumeKeyDownEvents(false); + m_Styles = DirectorStyles.Instance; + m_State = sequencerWindow.state; + + m_FoldoutWidth = DirectorStyles.Instance.foldout.fixedWidth; + } + + void ItemDoubleClickedCallback(int id) + { + var trackGUI = m_TreeView.FindItem(id) as TimelineTrackGUI; + if (trackGUI == null) + return; + + if (trackGUI.track == null || trackGUI.track.lockedInHierarchy) + return; + + var selection = SelectionManager.SelectedItems().ToList(); + var items = ItemsUtils.GetItems(trackGUI.track).ToList(); + var addToSelection = !selection.SequenceEqual(items); + + foreach (var i in items) + { + if (addToSelection) + SelectionManager.Add(i); + else + SelectionManager.Remove(i); + } + } + + void ContextClickOutsideItemsCallback() + { + SequencerContextMenu.ShowNewTracksContextMenu(null, m_State); + Event.current.Use(); + } + + void ContextClickItemCallback(int id) + { + // may not occur if another menu is active + if (!m_TreeView.IsSelected(id)) + SelectionChangedCallback(new[] {id}); + + SequencerContextMenu.ShowTrackContextMenu(SelectionManager.SelectedTracks().ToArray(), Event.current.mousePosition); + + Event.current.Use(); + } + + void SelectionChangedCallback(int[] ids) + { + if (Event.current.button == 1 && PickerUtils.PickedLayerableOfType<ISelectable>() != null) + return; + + if (Event.current.command || Event.current.control || Event.current.shift) + SelectionManager.UnSelectTracks(); + else + SelectionManager.Clear(); + + foreach (var id in ids) + { + var trackGUI = (TimelineTrackBaseGUI)m_TreeView.FindItem(id); + SelectionManager.Add(trackGUI.track); + } + + m_State.GetWindow().Repaint(); + } + + public void OnInitialize() {} + + public Rect GetRectForFraming(int row) + { + return GetRowRect(row, 1); // We ignore width by default when framing (only y scroll is affected) + } + + protected virtual Vector2 GetSizeOfRow(TreeViewItem item) + { + if (item.displayName == "root") + return new Vector2(m_TreeView.GetTotalRect().width, 0.0f); + + var trackGroupGui = item as TimelineGroupGUI; + if (trackGroupGui != null) + { + return new Vector2(m_TreeView.GetTotalRect().width, trackGroupGui.GetHeight(m_State)); + } + + float height = TrackEditor.DefaultTrackHeight; + if (item.hasChildren && m_TreeView.data.IsExpanded(item)) + { + height = Mathf.Min(TrackEditor.DefaultTrackHeight, kMinTrackHeight); + } + + return new Vector2(m_TreeView.GetTotalRect().width, height); + } + + public virtual void BeginRowGUI() + { + if (m_TreeView.GetTotalRect().width != GetRowRect(0).width) + { + CalculateRowRects(); + } + + m_DraggingInsertionMarkerRect.x = -1; + + m_TreeView.SetSelection(SelectionManager.SelectedTrackGUI().Select(t => t.id).ToArray(), false); + } + + public virtual void EndRowGUI() + { + // Draw row marker when dragging + if (m_DraggingInsertionMarkerRect.x >= 0 && Event.current.type == EventType.Repaint) + { + Rect insertionRect = m_DraggingInsertionMarkerRect; + const float insertionHeight = 1.0f; + insertionRect.height = insertionHeight; + + if (m_TreeView.dragging.drawRowMarkerAbove) + insertionRect.y -= insertionHeight * 0.5f + 2.0f; + else + insertionRect.y += m_DraggingInsertionMarkerRect.height - insertionHeight * 0.5f + 1.0f; + + EditorGUI.DrawRect(insertionRect, Color.white); + } + } + + public virtual void OnRowGUI(Rect rowRect, TreeViewItem item, int row, bool selected, bool focused) + { + using (new EditorGUI.DisabledScope(TimelineWindow.instance.currentMode.TrackState(TimelineWindow.instance.state) == TimelineModeGUIState.Disabled)) + { + var sqvi = (TimelineTrackBaseGUI)item; + sqvi.treeViewToWindowTransformation = m_TreeView.GetTotalRect().position - m_TreeView.state.scrollPos; + + // this may be called because an encompassing parent is visible + if (!sqvi.visibleExpanded) + return; + + Rect headerRect = rowRect; + Rect contentRect = rowRect; + + headerRect.width = m_State.sequencerHeaderWidth - 2.0f; + contentRect.xMin += m_State.sequencerHeaderWidth; + contentRect.width = rowRect.width - m_State.sequencerHeaderWidth - 1.0f; + + Rect foldoutRect = rowRect; + + var indent = GetFoldoutIndent(item); + var headerRectWithIndent = headerRect; + headerRectWithIndent.xMin = indent; + var rowRectWithIndent = new Rect(rowRect.x + indent, rowRect.y, rowRect.width - indent, rowRect.height); + sqvi.Draw(headerRectWithIndent, contentRect, m_State); + sqvi.DrawInsertionMarkers(rowRectWithIndent); + + if (Event.current.type == EventType.Repaint) + { + m_State.spacePartitioner.AddBounds(sqvi); + + // Show marker below this Item + if (showInsertionMarker) + { + if (m_TreeView.dragging != null && m_TreeView.dragging.GetRowMarkerControlID() == TreeViewController.GetItemControlID(item)) + m_DraggingInsertionMarkerRect = rowRectWithIndent; + } + } + + // Draw foldout (after text content above to ensure drop down icon is rendered above selection highlight) + DrawFoldout(item, foldoutRect, indent); + + sqvi.ClearDrawFlags(); + } + } + + void DrawFoldout(TreeViewItem item, Rect foldoutRect, float indent) + { + var showFoldout = m_TreeView.data.IsExpandable(item); + if (showFoldout) + { + foldoutRect.x = indent - kFoldOutOffset; + foldoutRect.width = m_FoldoutWidth; + EditorGUI.BeginChangeCheck(); + float foldoutIconHeight = DirectorStyles.Instance.foldout.fixedHeight; + foldoutRect.y += foldoutIconHeight / 2.0f; + foldoutRect.height = foldoutIconHeight; + + if (foldoutRect.xMax > m_State.sequencerHeaderWidth) + return; + + //Override Disable state for TrakGroup toggle button to expand/collapse group. + bool previousEnableState = GUI.enabled; + GUI.enabled = true; + bool newExpandedValue = GUI.Toggle(foldoutRect, m_TreeView.data.IsExpanded(item), GUIContent.none, m_Styles.foldout); + GUI.enabled = previousEnableState; + + if (EditorGUI.EndChangeCheck()) + { + if (Event.current.alt) + m_TreeView.data.SetExpandedWithChildren(item, newExpandedValue); + else + m_TreeView.data.SetExpanded(item, newExpandedValue); + } + } + } + + public Rect GetRenameRect(Rect rowRect, int row, TreeViewItem item) + { + return rowRect; + } + + public void BeginPingItem(TreeViewItem item, float topPixelOfRow, float availableWidth) {} + public void EndPingItem() {} + + public Rect GetRowRect(int row, float rowWidth) + { + return GetRowRect(row); + } + + public Rect GetRowRect(int row) + { + if (m_RowRects.Count == 0) + return new Rect(); + + if (row >= m_RowRects.Count) + return new Rect(); + + return m_RowRects[row]; + } + + static float GetSpacing(TreeViewItem item) + { + var trackBase = item as TimelineTrackBaseGUI; + if (trackBase != null) + return trackBase.GetVerticalSpacingBetweenTracks(); + + return 3.0f; + } + + public void CalculateRowRects() + { + if (m_TreeView.isSearching) + return; + + const float startY = 6.0f; + IList<TreeViewItem> rows = m_TreeView.data.GetRows(); + m_RowRects = new List<Rect>(rows.Count); + m_ExpandedRowRects = new List<Rect>(rows.Count); + + float curY = startY; + m_MaxWidthOfRows = 1f; + + // first pass compute the row rects + for (int i = 0; i < rows.Count; ++i) + { + var item = rows[i]; + + if (i != 0) + curY += GetSpacing(item); + + Vector2 rowSize = GetSizeOfRow(item); + m_RowRects.Add(new Rect(0, curY, rowSize.x, rowSize.y)); + m_ExpandedRowRects.Add(m_RowRects[i]); + + curY += rowSize.y; + + if (rowSize.x > m_MaxWidthOfRows) + m_MaxWidthOfRows = rowSize.x; + + // updated the expanded state + var groupGUI = item as TimelineGroupGUI; + if (groupGUI != null) + groupGUI.SetExpanded(m_TreeView.data.IsExpanded(item)); + } + + float halfHeight = halfDropBetweenHeight; + const float kGroupPad = 1.0f; + const float kSkinPadding = 5.0f * 0.6f; + // work bottom up and compute visible regions for groups + for (int i = rows.Count - 1; i > 0; i--) + { + float height = 0; + TimelineTrackBaseGUI item = (TimelineTrackBaseGUI)rows[i]; + if (item.isExpanded && item.children != null && item.children.Count > 0) + { + for (var j = 0; j < item.children.Count; j++) + { + var child = item.children[j]; + int index = rows.IndexOf(child); + if (index > i) + height += m_ExpandedRowRects[index].height + kSkinPadding; + } + + height += kGroupPad; + } + m_ExpandedRowRects[i] = new Rect(m_RowRects[i].x, m_RowRects[i].y, m_RowRects[i].width, m_RowRects[i].height + height); + + var groupGUI = item as TimelineGroupGUI; + if (groupGUI != null) + { + var spacing = GetSpacing(item) + 1; + groupGUI.expandedRect = m_ExpandedRowRects[i]; + groupGUI.rowRect = m_RowRects[i]; + groupGUI.dropRect = new Rect(m_RowRects[i].x, m_RowRects[i].y - spacing, m_RowRects[i].width, m_RowRects[i].height + Mathf.Max(halfHeight, spacing)); + } + } + } + + public virtual bool BeginRename(TreeViewItem item, float delay) + { + return false; + } + + public virtual void EndRename() {} + + protected virtual float GetFoldoutIndent(TreeViewItem item) + { + // Ignore depth when showing search results + if (item.depth <= 1 || m_TreeView.isSearching) + return DirectorStyles.kBaseIndent; + + int depth = item.depth; + var trackGUI = item as TimelineTrackGUI; + + // first level subtracks are not indented + if (trackGUI != null && trackGUI.track != null && trackGUI.track.isSubTrack) + depth--; + + return depth * DirectorStyles.kBaseIndent; + } + + public virtual float GetContentIndent(TreeViewItem item) + { + return GetFoldoutIndent(item); + } + + public int GetNumRowsOnPageUpDown(TreeViewItem fromItem, bool pageUp, float heightOfTreeView) + { + return (int)Mathf.Floor(heightOfTreeView / 30); // return something + } + + // Should return the row number of the first and last row thats fits in the pixel rect defined by top and height + public void GetFirstAndLastRowVisible(out int firstRowVisible, out int lastRowVisible) + { + int rowCount = m_TreeView.data.rowCount; + if (rowCount == 0) + { + firstRowVisible = lastRowVisible = -1; + return; + } + + if (rowCount != m_ExpandedRowRects.Count) + { + Debug.LogError("Mismatch in state: rows vs cached rects. Did you remember to hook up: dataSource.onVisibleRowsChanged += gui.CalculateRowRects ?"); + CalculateRowRects(); + } + + float topPixel = m_TreeView.state.scrollPos.y; + float heightInPixels = m_TreeView.GetTotalRect().height; + + int firstVisible = -1; + int lastVisible = -1; + + Rect visibleRect = new Rect(0, topPixel, m_ExpandedRowRects[0].width, heightInPixels); + for (int i = 0; i < m_ExpandedRowRects.Count; ++i) + { + bool visible = visibleRect.Overlaps(m_ExpandedRowRects[i]); + if (visible) + { + if (firstVisible == -1) + firstVisible = i; + lastVisible = i; + } + + TimelineTrackBaseGUI gui = m_TreeView.data.GetItem(i) as TimelineTrackBaseGUI; + if (gui != null) + { + gui.visibleExpanded = visible; + gui.visibleRow = visibleRect.Overlaps(m_RowRects[i]); + } + } + + if (firstVisible != -1 && lastVisible != -1) + { + firstRowVisible = firstVisible; + lastRowVisible = lastVisible; + } + else + { + firstRowVisible = 0; + lastRowVisible = rowCount - 1; + } + } + + public Vector2 GetTotalSize() + { + if (m_RowRects.Count == 0) + return new Vector2(0, 0); + + return new Vector2(m_MaxWidthOfRows, m_RowRects[m_RowRects.Count - 1].yMax); + } + + public virtual float halfDropBetweenHeight + { + get { return 8f; } + } + } +} |
