From 6930139f9af67158846a544eb0e20d17ad73e1f5 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Tue, 27 Aug 2024 11:27:09 -0500 Subject: [PATCH] Add saving collection groups. Add open all and close all menu buttons for collections. --- .../CustomEditors/Editors/CollectionEditor.cs | 104 +++++++++++++++++- .../Elements/Container/GroupElement.cs | 7 ++ .../CustomEditors/LayoutElementsContainer.cs | 5 +- 3 files changed, 113 insertions(+), 3 deletions(-) diff --git a/Source/Editor/CustomEditors/Editors/CollectionEditor.cs b/Source/Editor/CustomEditors/Editors/CollectionEditor.cs index 7c0670010..3c91d1575 100644 --- a/Source/Editor/CustomEditors/Editors/CollectionEditor.cs +++ b/Source/Editor/CustomEditors/Editors/CollectionEditor.cs @@ -2,14 +2,18 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Linq; using FlaxEditor.CustomEditors.GUI; using FlaxEditor.GUI.Input; using FlaxEditor.Content; +using FlaxEditor.CustomEditors.Elements; using FlaxEditor.GUI.ContextMenu; using FlaxEditor.GUI.Drag; using FlaxEditor.SceneGraph; using FlaxEditor.Scripting; +using FlaxEditor.Windows; +using FlaxEditor.Windows.Assets; using FlaxEngine; using FlaxEngine.GUI; using FlaxEngine.Utilities; @@ -228,7 +232,38 @@ namespace FlaxEditor.CustomEditors.Editors ArrowImageClosed = new SpriteBrush(icons.ArrowRight12); ArrowImageOpened = new SpriteBrush(icons.ArrowDown12); HeaderText = $"Element {index}"; - IsClosed = false; + + string saveName = string.Empty; + if (editor.Presenter?.Owner is PropertiesWindow propertiesWindow) + { + var selection = FlaxEditor.Editor.Instance.SceneEditing.Selection[0]; + if (selection != null) + { + saveName += $"{selection.ID},"; + } + } + else if (editor.Presenter?.Owner is PrefabWindow prefabWindow) + { + var selection = prefabWindow.Selection[0]; + if (selection != null) + { + saveName += $"{selection.ID},"; + } + } + if (editor.ParentEditor?.Layout.ContainerControl is DropPanel pdp) + { + saveName += $"{pdp.HeaderText},"; + } + if (editor.Layout.ContainerControl is DropPanel mainGroup) + { + saveName += $"{mainGroup.HeaderText}"; + IsClosed = FlaxEditor.Editor.Instance.ProjectCache.IsGroupToggled($"{saveName}:{index}"); + } + else + { + IsClosed = false; + } + Editor = editor; Index = index; Offsets = new Margin(7, 7, 0, 0); @@ -239,6 +274,37 @@ namespace FlaxEditor.CustomEditors.Editors HeaderTextMargin = new Margin(18, 0, 0, 0); _arrangeButtonRect = new Rectangle(16, 3, 12, 12); } + IsClosedChanged += OnIsClosedChanged; + } + + private void OnIsClosedChanged(DropPanel panel) + { + string saveName = string.Empty; + if (Editor.Presenter?.Owner is PropertiesWindow pw) + { + var selection = FlaxEditor.Editor.Instance.SceneEditing.Selection[0]; + if (selection != null) + { + saveName += $"{selection.ID},"; + } + } + else if (Editor.Presenter?.Owner is PrefabWindow prefabWindow) + { + var selection = prefabWindow.Selection[0]; + if (selection != null) + { + saveName += $"{selection.ID},"; + } + } + if (Editor.ParentEditor?.Layout.ContainerControl is DropPanel pdp) + { + saveName += $"{pdp.HeaderText},"; + } + if (Editor.Layout.ContainerControl is DropPanel mainGroup) + { + saveName += $"{mainGroup.HeaderText}"; + FlaxEditor.Editor.Instance.ProjectCache.SetGroupToggle($"{saveName}:{Index}", panel.IsClosed); + } } private bool ArrangeAreaCheck(out int index, out Rectangle rect) @@ -377,6 +443,7 @@ namespace FlaxEditor.CustomEditors.Editors private bool _canResize; private bool _canReorderItems; private CollectionAttribute.DisplayType _displayType; + private List _cachedDropPanels = new List(); /// /// Gets the length of the collection. @@ -519,6 +586,12 @@ namespace FlaxEditor.CustomEditors.Editors (elementType.GetProperties().Length == 1 && elementType.GetFields().Length == 0) || elementType.Equals(new ScriptType(typeof(JsonAsset))) || elementType.Equals(new ScriptType(typeof(SettingsBase))); + + if (_cachedDropPanels == null) + _cachedDropPanels = new List(); + else + _cachedDropPanels.Clear(); + for (int i = 0; i < size; i++) { // Apply spacing @@ -542,6 +615,7 @@ namespace FlaxEditor.CustomEditors.Editors else if (_displayType == CollectionAttribute.DisplayType.Header || (_displayType == CollectionAttribute.DisplayType.Default && !single)) { var cdp = panel.CustomContainer(); + _cachedDropPanels.Add(cdp.CustomControl); cdp.CustomControl.Setup(this, i, _canReorderItems); var itemLayout = cdp.VerticalPanel(); cdp.CustomControl.LinkedEditor = itemLayout.Object(new ListValueContainer(elementType, i, Values, attributes), overrideEditor); @@ -549,6 +623,12 @@ namespace FlaxEditor.CustomEditors.Editors GenericEditor.OnReadOnlyProperty(itemLayout); } } + + if (_displayType == CollectionAttribute.DisplayType.Header || (_displayType == CollectionAttribute.DisplayType.Default && !single)) + { + if (Layout is GroupElement g) + g.SetupContextMenu += OnSetupContextMenu; + } } _elementsCount = size; @@ -583,6 +663,28 @@ namespace FlaxEditor.CustomEditors.Editors } } + private void OnSetupContextMenu(ContextMenu menu, DropPanel panel) + { + if (menu.Items.Any(x => x is ContextMenuButton b && b.Text.Equals("Open All", StringComparison.Ordinal))) + return; + + menu.AddSeparator(); + menu.AddButton("Open All", () => + { + foreach (var cachedPanel in _cachedDropPanels) + { + cachedPanel.IsClosed = false; + } + }); + menu.AddButton("Close All", () => + { + foreach (var cachedPanel in _cachedDropPanels) + { + cachedPanel.IsClosed = true; + } + }); + } + /// protected override void Deinitialize() { diff --git a/Source/Editor/CustomEditors/Elements/Container/GroupElement.cs b/Source/Editor/CustomEditors/Elements/Container/GroupElement.cs index 58f36737c..972f64ba6 100644 --- a/Source/Editor/CustomEditors/Elements/Container/GroupElement.cs +++ b/Source/Editor/CustomEditors/Elements/Container/GroupElement.cs @@ -1,5 +1,7 @@ // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. +using System; +using FlaxEditor.GUI.ContextMenu; using FlaxEngine; using FlaxEngine.GUI; @@ -24,6 +26,11 @@ namespace FlaxEditor.CustomEditors.Elements EnableContainmentLines = true, }; + /// + /// Event is fired if the group can setup a context menu and the context menu is being setup. + /// + public Action SetupContextMenu; + /// public override ContainerControl ContainerControl => Panel; diff --git a/Source/Editor/CustomEditors/LayoutElementsContainer.cs b/Source/Editor/CustomEditors/LayoutElementsContainer.cs index 0ec88238e..26d469434 100644 --- a/Source/Editor/CustomEditors/LayoutElementsContainer.cs +++ b/Source/Editor/CustomEditors/LayoutElementsContainer.cs @@ -74,11 +74,11 @@ namespace FlaxEditor.CustomEditors { var element = Group(title, useTransparentHeader); element.Panel.Tag = linkedEditor; - element.Panel.MouseButtonRightClicked += OnGroupPanelMouseButtonRightClicked; + element.Panel.MouseButtonRightClicked += (panel, location) => OnGroupPanelMouseButtonRightClicked(element, panel, location); return element; } - private void OnGroupPanelMouseButtonRightClicked(DropPanel groupPanel, Float2 location) + private void OnGroupPanelMouseButtonRightClicked(GroupElement element, DropPanel groupPanel, Float2 location) { var linkedEditor = (CustomEditor)groupPanel.Tag; var menu = new ContextMenu(); @@ -91,6 +91,7 @@ namespace FlaxEditor.CustomEditors menu.AddButton("Copy", linkedEditor.Copy); var paste = menu.AddButton("Paste", linkedEditor.Paste); paste.Enabled = linkedEditor.CanPaste; + element.SetupContextMenu?.Invoke(menu, groupPanel); menu.Show(groupPanel, location); }