//********************************** Banshee Engine (www.banshee3d.com) **************************************************// //**************** Copyright (c) 2016 Marko Pintera (marko.pintera@gmail.com). All rights reserved. **********************// using System.Collections.Generic; using bs; namespace bs.Editor { /** @addtogroup Windows * @{ */ /// /// Editor window that displays the scene hierarchy tree view, displaying all scene objects in the current scene. /// public class HierarchyWindow : EditorWindow, IGlobalShortcuts { private GUIScrollArea treeScrollArea; private GUISceneTreeView treeView; private GUILayout progressLayout; private GUIProgressBar loadProgressBar; private GUILabel loadLabel; private bool loadingProgressShown = false; private UUID sceneUUID = UUID.Empty; /// /// Opens the hierarchy window. /// [MenuItem("Windows/Hierarchy", ButtonModifier.CtrlAlt, ButtonCode.H, 6000)] private static void OpenHierarchyWindow() { OpenWindow(); } /// protected override LocString GetDisplayName() { return new LocEdString("Hierarchy"); } /// void IGlobalShortcuts.OnDeletePressed() { treeView.DeleteSelection(); } /// void IGlobalShortcuts.OnRenamePressed() { treeView.RenameSelection(); } /// void IGlobalShortcuts.OnDuplicatePressed() { treeView.DuplicateSelection(); } /// void IGlobalShortcuts.OnCopyPressed() { treeView.CopySelection(); } /// void IGlobalShortcuts.OnCutPressed() { treeView.CutSelection(); } /// void IGlobalShortcuts.OnPastePressed() { treeView.PasteToSelection(); } private void OnInitialize() { treeScrollArea = new GUIScrollArea(); GUI.AddElement(treeScrollArea); treeView = new GUISceneTreeView(GUIOption.FlexibleHeight(20), GUIOption.FlexibleWidth(20)); treeScrollArea.Layout.AddElement(treeView); // Loading progress loadLabel = new GUILabel(new LocEdString("Loading scene...")); loadProgressBar = new GUIProgressBar(); progressLayout = GUI.AddLayoutY(); progressLayout.AddFlexibleSpace(); GUILayout loadLabelLayout = progressLayout.AddLayoutX(); loadLabelLayout.AddFlexibleSpace(); loadLabelLayout.AddElement(loadLabel); loadLabelLayout.AddFlexibleSpace(); GUILayout progressBarLayout = progressLayout.AddLayoutX(); progressBarLayout.AddFlexibleSpace(); progressBarLayout.AddElement(loadProgressBar); progressBarLayout.AddFlexibleSpace(); progressLayout.AddFlexibleSpace(); progressLayout.Active = false; EditorVirtualInput.OnButtonUp += OnButtonUp; } private void OnEditorUpdate() { UpdateLoadingProgress(); treeView.Update(); if (Scene.ActiveSceneUUID != sceneUUID) { if(EditorApplication.EditorSceneData != null) LoadHierarchyState(EditorApplication.EditorSceneData); sceneUUID = Scene.ActiveSceneUUID; } } private void OnDestroy() { EditorVirtualInput.OnButtonUp -= OnButtonUp; } /// /// Updates the scene data with data from the hierarchy view. /// /// Scene data to append hierarchy state to. internal void SaveHierarchyState(EditorSceneData sceneData) { if (treeView == null) return; SceneTreeViewState state = treeView.State; Dictionary lookup = sceneData.GetLookup(); foreach (var entry in state.Elements) { if (lookup.TryGetValue(entry.sceneObject.UUID, out EditorSceneObject editorSO)) editorSO.IsExpanded = entry.isExpanded; } } /// /// Loads hierarchy state from the stored scene data. /// /// Scene data to restore the hierarcy state from. internal void LoadHierarchyState(EditorSceneData sceneData) { SceneTreeViewState state = treeView.State; Dictionary lookup = sceneData.GetLookup(); SceneTreeViewElement[] elements = state.Elements; for(int i = 0; i < elements.Length; i++) { if (lookup.TryGetValue(elements[i].sceneObject.UUID, out EditorSceneObject editorSO)) elements[i].isExpanded = editorSO.IsExpanded; } state.Elements = elements; treeView.State = state; } /// /// Checks if the load progress bar needs to be shown, shows/hides it and updates the progress accordingly. /// private void UpdateLoadingProgress() { bool needsProgress = EditorApplication.IsSceneLoading; if (needsProgress && !loadingProgressShown) { progressLayout.Active = true; treeScrollArea.Active = false; loadingProgressShown = true; } else if(!needsProgress && loadingProgressShown) { progressLayout.Active = false; treeScrollArea.Active = true; loadingProgressShown = false; } if (needsProgress) loadProgressBar.Percent = EditorApplication.SceneLoadProgress; } /// /// Triggered when the user presses a virtual button. /// /// Button that was pressed. /// Index of the device it was pressed on. private void OnButtonUp(VirtualButton btn, int deviceIdx) { if (!HasFocus) return; IGlobalShortcuts shortcuts = this; if (btn == EditorApplication.CopyKey) shortcuts.OnCopyPressed(); else if (btn == EditorApplication.CutKey) shortcuts.OnCutPressed(); else if (btn == EditorApplication.PasteKey) shortcuts.OnPastePressed(); else if (btn == EditorApplication.DuplicateKey) shortcuts.OnDuplicatePressed(); else if (btn == EditorApplication.RenameKey) shortcuts.OnRenamePressed(); else if (btn == EditorApplication.DeleteKey) shortcuts.OnDeletePressed(); else if(btn == EditorApplication.PasteKey) shortcuts.OnPastePressed(); } } /** @} */ }