TimelineWindow_Breadcrumbs.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine;
  5. using UnityEngine.Playables;
  6. using UnityEngine.Timeline;
  7. namespace UnityEditor.Timeline
  8. {
  9. partial class TimelineWindow
  10. {
  11. List<BreadCrumbTitle> m_BreadCrumbLabels = new List<BreadCrumbTitle>(100);
  12. static TitleMode GetTitleMode(ISequenceState sequence)
  13. {
  14. var prefabStage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage();
  15. // Top level
  16. if (sequence.hostClip == null)
  17. {
  18. if (sequence.director != null && prefabStage != null && prefabStage.IsPartOfPrefabContents(sequence.director.gameObject))
  19. return TitleMode.Prefab;
  20. if (sequence.director != null && PrefabUtility.IsPartOfPrefabAsset(sequence.director))
  21. return TitleMode.PrefabOutOfContext;
  22. if (sequence.director != null && !sequence.director.isActiveAndEnabled)
  23. return TitleMode.DisabledComponent;
  24. if (sequence.director != null)
  25. return TitleMode.GameObject;
  26. if (sequence.asset != null)
  27. return TitleMode.Asset;
  28. }
  29. // Subtimelines only get an error icon
  30. else if (sequence.director != null && !sequence.director.isActiveAndEnabled && !PrefabUtility.IsPartOfPrefabAsset(sequence.director))
  31. return TitleMode.DisabledComponent;
  32. return TitleMode.None;
  33. }
  34. void DoBreadcrumbGUI()
  35. {
  36. if (state == null)
  37. return;
  38. int count = 0;
  39. foreach (var sequence in state.GetAllSequences())
  40. {
  41. BreadCrumbTitle title = new BreadCrumbTitle()
  42. {
  43. name = DisplayNameHelper.GetDisplayName(sequence),
  44. mode = GetTitleMode(sequence)
  45. };
  46. if (count >= m_BreadCrumbLabels.Count)
  47. m_BreadCrumbLabels.Add(title);
  48. else
  49. m_BreadCrumbLabels[count] = title;
  50. count++;
  51. }
  52. if (m_BreadCrumbLabels.Count > count)
  53. m_BreadCrumbLabels.RemoveRange(count, m_BreadCrumbLabels.Count - count);
  54. using (new EditorGUI.DisabledScope(currentMode.headerState.breadCrumb == TimelineModeGUIState.Disabled))
  55. {
  56. BreadcrumbDrawer.Draw(breadCrumbAreaWidth, m_BreadCrumbLabels, NavigateToBreadcrumbIndex);
  57. }
  58. }
  59. void NavigateToBreadcrumbIndex(int index)
  60. {
  61. state.PopSequencesUntilCount(index + 1);
  62. }
  63. void DoSequenceSelectorGUI()
  64. {
  65. using (new EditorGUI.DisabledScope(currentMode.headerState.sequenceSelector == TimelineModeGUIState.Disabled))
  66. {
  67. if (EditorGUILayout.DropdownButton(DirectorStyles.timelineSelectorArrow, FocusType.Passive, DirectorStyles.Instance.sequenceSwitcher, GUILayout.Width(WindowConstants.selectorWidth)))
  68. ShowSequenceSelector();
  69. }
  70. }
  71. void ShowSequenceSelector()
  72. {
  73. var allDirectors = TimelineUtility.GetDirectorsInSceneUsingAsset(null);
  74. var formatter = new SequenceMenuNameFormater();
  75. var namesAndDirectors = new List<ValueTuple<string, PlayableDirector>>();
  76. foreach (var d in allDirectors)
  77. {
  78. if (d.playableAsset is TimelineAsset)
  79. {
  80. var text = formatter.Format(DisplayNameHelper.GetDisplayName(d));
  81. namesAndDirectors.Add(new ValueTuple<string, PlayableDirector>(text, d));
  82. }
  83. }
  84. var sequenceMenu = new GenericMenu();
  85. foreach (var (timelineName, playableDirector) in namesAndDirectors.OrderBy(i => i.Item1))
  86. {
  87. var isCurrent = state.masterSequence.director == playableDirector;
  88. sequenceMenu.AddItem(new GUIContent(timelineName), isCurrent, OnSequenceSelected, playableDirector);
  89. }
  90. if (allDirectors.Length == 0)
  91. sequenceMenu.AddDisabledItem(DirectorStyles.noTimelinesInScene);
  92. sequenceMenu.DropDown(EditorGUILayout.s_LastRect);
  93. }
  94. void OnSequenceSelected(object arg)
  95. {
  96. var directorToBindTo = (PlayableDirector)arg;
  97. if (directorToBindTo)
  98. {
  99. // don't just select the object, it may already be selected.
  100. SetCurrentTimeline(directorToBindTo);
  101. }
  102. }
  103. }
  104. }