HierarchyWindow.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. using System.Collections.Generic;
  4. using bs;
  5. namespace bs.Editor
  6. {
  7. /** @addtogroup Windows
  8. * @{
  9. */
  10. /// <summary>
  11. /// Editor window that displays the scene hierarchy tree view, displaying all scene objects in the current scene.
  12. /// </summary>
  13. public class HierarchyWindow : EditorWindow, IGlobalShortcuts
  14. {
  15. private GUIScrollArea treeScrollArea;
  16. private GUISceneTreeView treeView;
  17. private GUILayout progressLayout;
  18. private GUIProgressBar loadProgressBar;
  19. private GUILabel loadLabel;
  20. private bool loadingProgressShown = false;
  21. private UUID sceneUUID = UUID.Empty;
  22. /// <summary>
  23. /// Opens the hierarchy window.
  24. /// </summary>
  25. [MenuItem("Windows/Hierarchy", ButtonModifier.CtrlAlt, ButtonCode.H, 6000)]
  26. private static void OpenHierarchyWindow()
  27. {
  28. OpenWindow<HierarchyWindow>();
  29. }
  30. /// <inheritdoc/>
  31. protected override LocString GetDisplayName()
  32. {
  33. return new LocEdString("Hierarchy");
  34. }
  35. /// <inheritdoc/>
  36. void IGlobalShortcuts.OnDeletePressed()
  37. {
  38. treeView.DeleteSelection();
  39. }
  40. /// <inheritdoc/>
  41. void IGlobalShortcuts.OnRenamePressed()
  42. {
  43. treeView.RenameSelection();
  44. }
  45. /// <inheritdoc/>
  46. void IGlobalShortcuts.OnDuplicatePressed()
  47. {
  48. treeView.DuplicateSelection();
  49. }
  50. /// <inheritdoc/>
  51. void IGlobalShortcuts.OnCopyPressed()
  52. {
  53. treeView.CopySelection();
  54. }
  55. /// <inheritdoc/>
  56. void IGlobalShortcuts.OnCutPressed()
  57. {
  58. treeView.CutSelection();
  59. }
  60. /// <inheritdoc/>
  61. void IGlobalShortcuts.OnPastePressed()
  62. {
  63. treeView.PasteToSelection();
  64. }
  65. private void OnInitialize()
  66. {
  67. treeScrollArea = new GUIScrollArea();
  68. GUI.AddElement(treeScrollArea);
  69. treeView = new GUISceneTreeView(GUIOption.FlexibleHeight(20), GUIOption.FlexibleWidth(20));
  70. treeScrollArea.Layout.AddElement(treeView);
  71. // Loading progress
  72. loadLabel = new GUILabel(new LocEdString("Loading scene..."));
  73. loadProgressBar = new GUIProgressBar();
  74. progressLayout = GUI.AddLayoutY();
  75. progressLayout.AddFlexibleSpace();
  76. GUILayout loadLabelLayout = progressLayout.AddLayoutX();
  77. loadLabelLayout.AddFlexibleSpace();
  78. loadLabelLayout.AddElement(loadLabel);
  79. loadLabelLayout.AddFlexibleSpace();
  80. GUILayout progressBarLayout = progressLayout.AddLayoutX();
  81. progressBarLayout.AddFlexibleSpace();
  82. progressBarLayout.AddElement(loadProgressBar);
  83. progressBarLayout.AddFlexibleSpace();
  84. progressLayout.AddFlexibleSpace();
  85. progressLayout.Active = false;
  86. EditorVirtualInput.OnButtonUp += OnButtonUp;
  87. }
  88. private void OnEditorUpdate()
  89. {
  90. UpdateLoadingProgress();
  91. treeView.Update();
  92. if (Scene.ActiveSceneUUID != sceneUUID)
  93. {
  94. if(EditorApplication.EditorSceneData != null)
  95. LoadHierarchyState(EditorApplication.EditorSceneData);
  96. sceneUUID = Scene.ActiveSceneUUID;
  97. }
  98. }
  99. private void OnDestroy()
  100. {
  101. EditorVirtualInput.OnButtonUp -= OnButtonUp;
  102. }
  103. /// <summary>
  104. /// Updates the scene data with data from the hierarchy view.
  105. /// </summary>
  106. /// <param name="sceneData">Scene data to append hierarchy state to.</param>
  107. internal void SaveHierarchyState(EditorSceneData sceneData)
  108. {
  109. if (treeView == null)
  110. return;
  111. SceneTreeViewState state = treeView.State;
  112. Dictionary<UUID, EditorSceneObject> lookup = sceneData.GetLookup();
  113. foreach (var entry in state.Elements)
  114. {
  115. if (lookup.TryGetValue(entry.sceneObject.UUID, out EditorSceneObject editorSO))
  116. editorSO.IsExpanded = entry.isExpanded;
  117. }
  118. }
  119. /// <summary>
  120. /// Loads hierarchy state from the stored scene data.
  121. /// </summary>
  122. /// <param name="sceneData">Scene data to restore the hierarcy state from.</param>
  123. internal void LoadHierarchyState(EditorSceneData sceneData)
  124. {
  125. SceneTreeViewState state = treeView.State;
  126. Dictionary<UUID, EditorSceneObject> lookup = sceneData.GetLookup();
  127. SceneTreeViewElement[] elements = state.Elements;
  128. for(int i = 0; i < elements.Length; i++)
  129. {
  130. if (lookup.TryGetValue(elements[i].sceneObject.UUID, out EditorSceneObject editorSO))
  131. elements[i].isExpanded = editorSO.IsExpanded;
  132. }
  133. state.Elements = elements;
  134. treeView.State = state;
  135. }
  136. /// <summary>
  137. /// Checks if the load progress bar needs to be shown, shows/hides it and updates the progress accordingly.
  138. /// </summary>
  139. private void UpdateLoadingProgress()
  140. {
  141. bool needsProgress = EditorApplication.IsSceneLoading;
  142. if (needsProgress && !loadingProgressShown)
  143. {
  144. progressLayout.Active = true;
  145. treeScrollArea.Active = false;
  146. loadingProgressShown = true;
  147. }
  148. else if(!needsProgress && loadingProgressShown)
  149. {
  150. progressLayout.Active = false;
  151. treeScrollArea.Active = true;
  152. loadingProgressShown = false;
  153. }
  154. if (needsProgress)
  155. loadProgressBar.Percent = EditorApplication.SceneLoadProgress;
  156. }
  157. /// <summary>
  158. /// Triggered when the user presses a virtual button.
  159. /// </summary>
  160. /// <param name="btn">Button that was pressed.</param>
  161. /// <param name="deviceIdx">Index of the device it was pressed on. </param>
  162. private void OnButtonUp(VirtualButton btn, int deviceIdx)
  163. {
  164. if (!HasFocus)
  165. return;
  166. IGlobalShortcuts shortcuts = this;
  167. if (btn == EditorApplication.CopyKey)
  168. shortcuts.OnCopyPressed();
  169. else if (btn == EditorApplication.CutKey)
  170. shortcuts.OnCutPressed();
  171. else if (btn == EditorApplication.PasteKey)
  172. shortcuts.OnPastePressed();
  173. else if (btn == EditorApplication.DuplicateKey)
  174. shortcuts.OnDuplicatePressed();
  175. else if (btn == EditorApplication.RenameKey)
  176. shortcuts.OnRenamePressed();
  177. else if (btn == EditorApplication.DeleteKey)
  178. shortcuts.OnDeletePressed();
  179. else if(btn == EditorApplication.PasteKey)
  180. shortcuts.OnPastePressed();
  181. }
  182. }
  183. /** @} */
  184. }