//#define PERF_PROFILE using System.Linq; using UnityEditorInternal; using UnityEngine; using UnityEngine.Timeline; namespace UnityEditor.Timeline { [CustomEditor(typeof(GroupTrack)), CanEditMultipleObjects] class GroupTrackInspector : TrackAssetInspector { static class Styles { public static readonly GUIContent GroupSubTrackHeaderName = L10n.TextContent("Name"); public static readonly GUIContent GroupSubTrackHeaderType = L10n.TextContent("Type"); public static readonly GUIContent GroupSubTrackHeaderDuration = L10n.TextContent("Duration"); public static readonly GUIContent GroupSubTrackHeaderFrames = L10n.TextContent("Frames"); public static readonly GUIContent GroupInvalidTrack = L10n.TextContent("Invalid Track"); } ReorderableList m_SubTracks; public override void OnInspectorGUI() { foreach (var group in targets) { var groupTrack = group as GroupTrack; if (groupTrack == null) return; var childrenTracks = groupTrack.GetChildTracks(); var groupTrackName = groupTrack.name; GUILayout.Label(childrenTracks.Count() > 0 ? groupTrackName + " (" + childrenTracks.Count() + ")" : groupTrackName, EditorStyles.boldLabel); GUILayout.Space(3.0f); // the subTrackObjects is used because it's the internal list m_SubTracks.list = groupTrack.subTracksObjects; m_SubTracks.DoLayoutList(); m_SubTracks.index = -1; } } public override void OnEnable() { base.OnEnable(); m_SubTracks = new ReorderableList(new string[] { }, typeof(string), false, true, false, false) { drawElementCallback = OnDrawSubTrack, drawHeaderCallback = OnDrawHeader, showDefaultBackground = true, index = 0, elementHeight = 20 }; } static void OnDrawHeader(Rect rect) { int sections = 4; float sectionWidth = rect.width / sections; rect.width = sectionWidth; GUI.Label(rect, Styles.GroupSubTrackHeaderName, EditorStyles.label); rect.x += sectionWidth; GUI.Label(rect, Styles.GroupSubTrackHeaderType, EditorStyles.label); rect.x += sectionWidth; GUI.Label(rect, Styles.GroupSubTrackHeaderDuration, EditorStyles.label); rect.x += sectionWidth; GUI.Label(rect, Styles.GroupSubTrackHeaderFrames, EditorStyles.label); } void OnDrawSubTrack(Rect rect, int index, bool selected, bool focused) { int sections = 4; float sectionWidth = rect.width / sections; var childrenTrack = m_SubTracks.list[index] as TrackAsset; if (childrenTrack == null) { object o = m_SubTracks.list[index]; rect.width = sectionWidth; if (o != null) // track is loaded, but has broken script { string name = ((UnityEngine.Object)m_SubTracks.list[index]).name; GUI.Label(rect, name, EditorStyles.label); } rect.x += sectionWidth; using (new GUIColorOverride(DirectorStyles.kClipErrorColor)) GUI.Label(rect, Styles.GroupInvalidTrack.text, EditorStyles.label); return; } rect.width = sectionWidth; GUI.Label(rect, childrenTrack.name, EditorStyles.label); rect.x += sectionWidth; GUI.Label(rect, childrenTrack.GetType().Name, EditorStyles.label); rect.x += sectionWidth; GUI.Label(rect, childrenTrack.duration.ToString(), EditorStyles.label); rect.x += sectionWidth; double exactFrames = TimeUtility.ToExactFrames(childrenTrack.duration, TimelineWindow.instance.state.referenceSequence.frameRate); GUI.Label(rect, exactFrames.ToString(), EditorStyles.label); } } }