Merge remote-tracking branch 'origin/master' into 1.8
# Conflicts: # Source/Editor/Utilities/EditorUtilities.cpp # Source/Editor/Utilities/EditorUtilities.h
This commit is contained in:
@@ -543,10 +543,11 @@ namespace FlaxEditor.CustomEditors
|
||||
try
|
||||
{
|
||||
string text;
|
||||
var value = Values[0];
|
||||
if (ParentEditor is Dedicated.ScriptsEditor)
|
||||
{
|
||||
// Script
|
||||
text = JsonSerializer.Serialize(Values[0]);
|
||||
text = JsonSerializer.Serialize(value);
|
||||
|
||||
// Remove properties that should be ignored when copy/pasting data
|
||||
if (text == null)
|
||||
@@ -576,12 +577,12 @@ namespace FlaxEditor.CustomEditors
|
||||
else if (ScriptType.FlaxObject.IsAssignableFrom(Values.Type))
|
||||
{
|
||||
// Object reference
|
||||
text = JsonSerializer.GetStringID(Values[0] as FlaxEngine.Object);
|
||||
text = JsonSerializer.GetStringID(value as FlaxEngine.Object);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default
|
||||
text = JsonSerializer.Serialize(Values[0]);
|
||||
text = JsonSerializer.Serialize(value, TypeUtils.GetType(Values.Type));
|
||||
}
|
||||
Clipboard.Text = text;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using FlaxEditor.Actions;
|
||||
using FlaxEditor.Content;
|
||||
using FlaxEditor.GUI;
|
||||
@@ -16,6 +18,27 @@ using Object = FlaxEngine.Object;
|
||||
|
||||
namespace FlaxEditor.CustomEditors.Dedicated
|
||||
{
|
||||
internal class NewScriptItem : ItemsListContextMenu.Item
|
||||
{
|
||||
private string _scriptName;
|
||||
|
||||
public string ScriptName
|
||||
{
|
||||
get => _scriptName;
|
||||
set
|
||||
{
|
||||
_scriptName = value;
|
||||
Name = $"Create script '{value}'";
|
||||
}
|
||||
}
|
||||
|
||||
public NewScriptItem(string scriptName)
|
||||
{
|
||||
ScriptName = scriptName;
|
||||
TooltipText = "Create a new script";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Drag and drop scripts area control.
|
||||
/// </summary>
|
||||
@@ -74,7 +97,43 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
{
|
||||
cm.AddItem(new TypeSearchPopup.TypeItemView(scripts[i]));
|
||||
}
|
||||
cm.ItemClicked += item => AddScript((ScriptType)item.Tag);
|
||||
cm.TextChanged += text =>
|
||||
{
|
||||
if (!IsValidScriptName(text))
|
||||
return;
|
||||
if (!cm.ItemsPanel.Children.Any(x => x.Visible && x is not NewScriptItem))
|
||||
{
|
||||
// If there are no visible items, that means the search failed so we can find the create script button or create one if it's the first time
|
||||
var newScriptItem = (NewScriptItem)cm.ItemsPanel.Children.FirstOrDefault(x => x is NewScriptItem);
|
||||
if (newScriptItem != null)
|
||||
{
|
||||
newScriptItem.Visible = true;
|
||||
newScriptItem.ScriptName = text;
|
||||
}
|
||||
else
|
||||
{
|
||||
cm.AddItem(new NewScriptItem(text));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make sure to hide the create script button if there
|
||||
var newScriptItem = cm.ItemsPanel.Children.FirstOrDefault(x => x is NewScriptItem);
|
||||
if (newScriptItem != null)
|
||||
newScriptItem.Visible = false;
|
||||
}
|
||||
};
|
||||
cm.ItemClicked += item =>
|
||||
{
|
||||
if (item.Tag is ScriptType script)
|
||||
{
|
||||
AddScript(script);
|
||||
}
|
||||
else if (item is NewScriptItem newScriptItem)
|
||||
{
|
||||
CreateScript(newScriptItem);
|
||||
}
|
||||
};
|
||||
cm.SortItems();
|
||||
cm.Show(this, button.BottomLeft - new Float2((cm.Width - button.Width) / 2, 0));
|
||||
}
|
||||
@@ -113,6 +172,19 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsValidScriptName(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return false;
|
||||
if (text.Contains(' '))
|
||||
return false;
|
||||
if (char.IsDigit(text[0]))
|
||||
return false;
|
||||
if (text.Any(c => !char.IsLetterOrDigit(c) && c != '_'))
|
||||
return false;
|
||||
return Editor.Instance.ContentDatabase.GetProxy("cs").IsFileNameValid(text);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override DragDropEffect OnDragEnter(ref Float2 location, DragData data)
|
||||
{
|
||||
@@ -163,6 +235,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
if (_dragScripts.HasValidDrag)
|
||||
{
|
||||
result = _dragScripts.Effect;
|
||||
|
||||
AddScripts(_dragScripts.Objects);
|
||||
}
|
||||
else if (_dragAssets.HasValidDrag)
|
||||
@@ -177,7 +250,43 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
return result;
|
||||
}
|
||||
|
||||
private void AddScript(ScriptType item)
|
||||
private void CreateScript(NewScriptItem item)
|
||||
{
|
||||
ScriptsEditor.NewScriptName = item.ScriptName;
|
||||
var paths = Directory.GetFiles(Globals.ProjectSourceFolder, "*.Build.cs");
|
||||
|
||||
string moduleName = null;
|
||||
foreach (var p in paths)
|
||||
{
|
||||
var file = File.ReadAllText(p);
|
||||
if (!file.Contains("GameProjectTarget"))
|
||||
continue; // Skip
|
||||
|
||||
if (file.Contains("Modules.Add(\"Game\")"))
|
||||
{
|
||||
// Assume Game represents the main game module
|
||||
moduleName = "Game";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the path slashes are correct for the OS
|
||||
var correctedPath = Path.GetFullPath(Globals.ProjectSourceFolder);
|
||||
if (string.IsNullOrEmpty(moduleName))
|
||||
{
|
||||
var error = FileSystem.ShowBrowseFolderDialog(Editor.Instance.Windows.MainWindow, correctedPath, "Select a module folder to put the new script in", out moduleName);
|
||||
if (error)
|
||||
return;
|
||||
}
|
||||
var path = Path.Combine(Globals.ProjectSourceFolder, moduleName, item.ScriptName + ".cs");
|
||||
Editor.Instance.ContentDatabase.GetProxy("cs").Create(path, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attach a script to the actor.
|
||||
/// </summary>
|
||||
/// <param name="item">The script.</param>
|
||||
public void AddScript(ScriptType item)
|
||||
{
|
||||
var list = new List<ScriptType>(1) { item };
|
||||
AddScripts(list);
|
||||
@@ -224,16 +333,67 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
|
||||
private void AddScripts(List<ScriptType> items)
|
||||
{
|
||||
var actions = new List<IUndoAction>(4);
|
||||
var actions = new List<IUndoAction>();
|
||||
|
||||
for (int i = 0; i < items.Count; i++)
|
||||
{
|
||||
var scriptType = items[i];
|
||||
RequireScriptAttribute scriptAttribute = null;
|
||||
if (scriptType.HasAttribute(typeof(RequireScriptAttribute), false))
|
||||
{
|
||||
foreach (var e in scriptType.GetAttributes(false))
|
||||
{
|
||||
if (e is not RequireScriptAttribute requireScriptAttribute)
|
||||
continue;
|
||||
scriptAttribute = requireScriptAttribute;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// See if script requires a specific actor type
|
||||
RequireActorAttribute actorAttribute = null;
|
||||
if (scriptType.HasAttribute(typeof(RequireActorAttribute), false))
|
||||
{
|
||||
foreach (var e in scriptType.GetAttributes(false))
|
||||
{
|
||||
if (e is not RequireActorAttribute requireActorAttribute)
|
||||
continue;
|
||||
actorAttribute = requireActorAttribute;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var actors = ScriptsEditor.ParentEditor.Values;
|
||||
for (int j = 0; j < actors.Count; j++)
|
||||
{
|
||||
var actor = (Actor)actors[j];
|
||||
|
||||
// If required actor exists but is not this actor type then skip adding to actor
|
||||
if (actorAttribute != null)
|
||||
{
|
||||
if (actor.GetType() != actorAttribute.RequiredType && !actor.GetType().IsSubclassOf(actorAttribute.RequiredType))
|
||||
{
|
||||
Editor.LogWarning($"`{Utilities.Utils.GetPropertyNameUI(scriptType.Name)}` not added to `{actor}` due to script requiring an Actor type of `{actorAttribute.RequiredType}`.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
actions.Add(AddRemoveScript.Add(actor, scriptType));
|
||||
// Check if actor has required scripts and add them if the actor does not.
|
||||
if (scriptAttribute != null)
|
||||
{
|
||||
foreach (var type in scriptAttribute.RequiredTypes)
|
||||
{
|
||||
if (!type.IsSubclassOf(typeof(Script)))
|
||||
{
|
||||
Editor.LogWarning($"`{Utilities.Utils.GetPropertyNameUI(type.Name)}` not added to `{actor}` due to the class not being a subclass of Script.");
|
||||
continue;
|
||||
}
|
||||
if (actor.GetScript(type) != null)
|
||||
continue;
|
||||
actions.Add(AddRemoveScript.Add(actor, new ScriptType(type)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,6 +600,11 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<object> UndoObjects => _scripts;
|
||||
|
||||
/// <summary>
|
||||
/// Cached the newly created script name - used to add script after compilation.
|
||||
/// </summary>
|
||||
internal static string NewScriptName;
|
||||
|
||||
private void AddMissingScript(int index, LayoutElementsContainer layout)
|
||||
{
|
||||
var group = layout.Group("Missing script");
|
||||
@@ -548,6 +713,21 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
var dragArea = layout.CustomContainer<DragAreaControl>();
|
||||
dragArea.CustomControl.ScriptsEditor = this;
|
||||
|
||||
// If the initialization is triggered by an editor recompilation, check if it was due to script generation from DragAreaControl
|
||||
if (NewScriptName != null)
|
||||
{
|
||||
var script = Editor.Instance.CodeEditing.Scripts.Get().FirstOrDefault(x => x.Name == NewScriptName);
|
||||
NewScriptName = null;
|
||||
if (script != null)
|
||||
{
|
||||
dragArea.CustomControl.AddScript(script);
|
||||
}
|
||||
else
|
||||
{
|
||||
Editor.LogWarning("Failed to find newly created script.");
|
||||
}
|
||||
}
|
||||
|
||||
// No support for showing scripts from multiple actors that have different set of scripts
|
||||
var scripts = (Script[])Values[0];
|
||||
_scripts.Clear();
|
||||
@@ -586,19 +766,71 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
var scriptType = TypeUtils.GetObjectType(script);
|
||||
var editor = CustomEditorsUtil.CreateEditor(scriptType, false);
|
||||
|
||||
// Check if actor has all the required scripts
|
||||
bool hasAllRequirements = true;
|
||||
if (scriptType.HasAttribute(typeof(RequireScriptAttribute), false))
|
||||
{
|
||||
RequireScriptAttribute scriptAttribute = null;
|
||||
foreach (var e in scriptType.GetAttributes(false))
|
||||
{
|
||||
if (e is not RequireScriptAttribute requireScriptAttribute)
|
||||
continue;
|
||||
scriptAttribute = requireScriptAttribute;
|
||||
}
|
||||
|
||||
if (scriptAttribute != null)
|
||||
{
|
||||
foreach (var type in scriptAttribute.RequiredTypes)
|
||||
{
|
||||
if (!type.IsSubclassOf(typeof(Script)))
|
||||
continue;
|
||||
var requiredScript = script.Actor.GetScript(type);
|
||||
if (requiredScript == null)
|
||||
{
|
||||
Editor.LogWarning($"`{Utilities.Utils.GetPropertyNameUI(scriptType.Name)}` on `{script.Actor}` is missing a required Script of type `{type}`.");
|
||||
hasAllRequirements = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (scriptType.HasAttribute(typeof(RequireActorAttribute), false))
|
||||
{
|
||||
RequireActorAttribute attribute = null;
|
||||
foreach (var e in scriptType.GetAttributes(false))
|
||||
{
|
||||
if (e is not RequireActorAttribute requireActorAttribute)
|
||||
continue;
|
||||
attribute = requireActorAttribute;
|
||||
break;
|
||||
}
|
||||
|
||||
if (attribute != null)
|
||||
{
|
||||
var actor = script.Actor;
|
||||
if (actor.GetType() != attribute.RequiredType && !actor.GetType().IsSubclassOf(attribute.RequiredType))
|
||||
{
|
||||
Editor.LogWarning($"`{Utilities.Utils.GetPropertyNameUI(scriptType.Name)}` on `{script.Actor}` is missing a required Actor of type `{attribute.RequiredType}`.");
|
||||
hasAllRequirements = false;
|
||||
// Maybe call to remove script here?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create group
|
||||
var title = Utilities.Utils.GetPropertyNameUI(scriptType.Name);
|
||||
var group = layout.Group(title, editor);
|
||||
if (!hasAllRequirements)
|
||||
group.Panel.HeaderTextColor = FlaxEngine.GUI.Style.Current.Statusbar.Failed;
|
||||
if ((Presenter.Features & FeatureFlags.CacheExpandedGroups) != 0)
|
||||
{
|
||||
if (Editor.Instance.ProjectCache.IsCollapsedGroup(title))
|
||||
group.Panel.Close(false);
|
||||
if (Editor.Instance.ProjectCache.IsGroupToggled(title))
|
||||
group.Panel.Close();
|
||||
else
|
||||
group.Panel.Open(false);
|
||||
group.Panel.IsClosedChanged += panel => Editor.Instance.ProjectCache.SetCollapsedGroup(panel.HeaderText, panel.IsClosed);
|
||||
group.Panel.Open();
|
||||
group.Panel.IsClosedChanged += panel => Editor.Instance.ProjectCache.SetGroupToggle(panel.HeaderText, panel.IsClosed);
|
||||
}
|
||||
else
|
||||
group.Panel.Open(false);
|
||||
group.Panel.Open();
|
||||
|
||||
// Customize
|
||||
group.Panel.TooltipText = Editor.Instance.CodeDocs.GetTooltip(scriptType);
|
||||
|
||||
@@ -51,10 +51,13 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
return;
|
||||
Picker = layout.Custom<AssetPicker>().CustomControl;
|
||||
|
||||
_valueType = Values.Type.Type != typeof(object) || Values[0] == null ? Values.Type : TypeUtils.GetObjectType(Values[0]);
|
||||
var value = Values[0];
|
||||
_valueType = Values.Type.Type != typeof(object) || value == null ? Values.Type : TypeUtils.GetObjectType(value);
|
||||
var assetType = _valueType;
|
||||
if (assetType == typeof(string))
|
||||
assetType = new ScriptType(typeof(Asset));
|
||||
else if (_valueType.Type != null && _valueType.Type.Name == typeof(JsonAssetReference<>).Name)
|
||||
assetType = new ScriptType(_valueType.Type.GenericTypeArguments[0]);
|
||||
|
||||
float height = 48;
|
||||
var attributes = Values.GetAttributes();
|
||||
@@ -102,6 +105,12 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
SetValue(new SceneReference(Picker.Validator.SelectedID));
|
||||
else if (_valueType.Type == typeof(string))
|
||||
SetValue(Picker.Validator.SelectedPath);
|
||||
else if (_valueType.Type.Name == typeof(JsonAssetReference<>).Name)
|
||||
{
|
||||
var value = Values[0];
|
||||
value.GetType().GetField("Asset").SetValue(value, Picker.Validator.SelectedAsset as JsonAsset);
|
||||
SetValue(value);
|
||||
}
|
||||
else
|
||||
SetValue(Picker.Validator.SelectedAsset);
|
||||
}
|
||||
@@ -114,16 +123,19 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
if (!HasDifferentValues)
|
||||
{
|
||||
_isRefreshing = true;
|
||||
if (Values[0] is AssetItem assetItem)
|
||||
var value = Values[0];
|
||||
if (value is AssetItem assetItem)
|
||||
Picker.Validator.SelectedItem = assetItem;
|
||||
else if (Values[0] is Guid guid)
|
||||
else if (value is Guid guid)
|
||||
Picker.Validator.SelectedID = guid;
|
||||
else if (Values[0] is SceneReference sceneAsset)
|
||||
else if (value is SceneReference sceneAsset)
|
||||
Picker.Validator.SelectedItem = Editor.Instance.ContentDatabase.FindAsset(sceneAsset.ID);
|
||||
else if (Values[0] is string path)
|
||||
else if (value is string path)
|
||||
Picker.Validator.SelectedPath = path;
|
||||
else if (value != null && value.GetType().Name == typeof(JsonAssetReference<>).Name)
|
||||
Picker.Validator.SelectedAsset = value.GetType().GetField("Asset").GetValue(value) as JsonAsset;
|
||||
else
|
||||
Picker.Validator.SelectedAsset = Values[0] as Asset;
|
||||
Picker.Validator.SelectedAsset = value as Asset;
|
||||
_isRefreshing = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,8 +176,8 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
|
||||
private IntValueBox _sizeBox;
|
||||
private Color _background;
|
||||
private int _elementsCount;
|
||||
private bool _readOnly;
|
||||
private int _elementsCount, _minCount, _maxCount;
|
||||
private bool _canResize;
|
||||
private bool _canReorderItems;
|
||||
private CollectionAttribute.DisplayType _displayType;
|
||||
|
||||
@@ -209,8 +209,10 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
return;
|
||||
|
||||
var size = Count;
|
||||
_readOnly = false;
|
||||
_canResize = true;
|
||||
_canReorderItems = true;
|
||||
_minCount = 0;
|
||||
_maxCount = 0;
|
||||
_background = FlaxEngine.GUI.Style.Current.CollectionBackgroundColor;
|
||||
_displayType = CollectionAttribute.DisplayType.Header;
|
||||
NotNullItems = false;
|
||||
@@ -222,7 +224,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
var collection = (CollectionAttribute)attributes?.FirstOrDefault(x => x is CollectionAttribute);
|
||||
if (collection != null)
|
||||
{
|
||||
_readOnly = collection.ReadOnly;
|
||||
_canResize = !collection.ReadOnly;
|
||||
_minCount = collection.MinCount;
|
||||
_maxCount = collection.MaxCount;
|
||||
_canReorderItems = collection.CanReorderItems;
|
||||
NotNullItems = collection.NotNullItems;
|
||||
if (collection.BackgroundColor.HasValue)
|
||||
@@ -231,6 +235,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
spacing = collection.Spacing;
|
||||
_displayType = collection.Display;
|
||||
}
|
||||
if (_maxCount == 0)
|
||||
_maxCount = ushort.MaxValue;
|
||||
_canResize &= _minCount < _maxCount;
|
||||
|
||||
var dragArea = layout.CustomContainer<DragAreaControl>();
|
||||
dragArea.CustomControl.Editor = this;
|
||||
@@ -268,8 +275,8 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
var y = -dropPanel.HeaderHeight + dropPanel.HeaderTextMargin.Top;
|
||||
_sizeBox = new IntValueBox(size)
|
||||
{
|
||||
MinValue = 0,
|
||||
MaxValue = ushort.MaxValue,
|
||||
MinValue = _minCount,
|
||||
MaxValue = _maxCount,
|
||||
AnchorPreset = AnchorPresets.TopRight,
|
||||
Bounds = new Rectangle(-40 - dropPanel.ItemsMargin.Right, y, 40, height),
|
||||
Parent = dropPanel,
|
||||
@@ -283,7 +290,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
Parent = dropPanel
|
||||
};
|
||||
|
||||
if (_readOnly || (NotNullItems && size == 0))
|
||||
if (!_canResize || (NotNullItems && size == 0))
|
||||
{
|
||||
_sizeBox.IsReadOnly = true;
|
||||
_sizeBox.Enabled = false;
|
||||
@@ -339,7 +346,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
_elementsCount = size;
|
||||
|
||||
// Add/Remove buttons
|
||||
if (!_readOnly)
|
||||
if (_canResize)
|
||||
{
|
||||
var panel = dragArea.HorizontalPanel();
|
||||
panel.Panel.Size = new Float2(0, 20);
|
||||
@@ -347,25 +354,23 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
|
||||
var removeButton = panel.Button("-", "Remove last item");
|
||||
removeButton.Button.Size = new Float2(16, 16);
|
||||
removeButton.Button.Enabled = size > 0;
|
||||
removeButton.Button.Enabled = size > _minCount;
|
||||
removeButton.Button.AnchorPreset = AnchorPresets.TopRight;
|
||||
removeButton.Button.Clicked += () =>
|
||||
{
|
||||
if (IsSetBlocked)
|
||||
return;
|
||||
|
||||
Resize(Count - 1);
|
||||
};
|
||||
|
||||
var addButton = panel.Button("+", "Add new item");
|
||||
addButton.Button.Size = new Float2(16, 16);
|
||||
addButton.Button.Enabled = !NotNullItems || size > 0;
|
||||
addButton.Button.Enabled = (!NotNullItems || size > 0) && size < _maxCount;
|
||||
addButton.Button.AnchorPreset = AnchorPresets.TopRight;
|
||||
addButton.Button.Clicked += () =>
|
||||
{
|
||||
if (IsSetBlocked)
|
||||
return;
|
||||
|
||||
Resize(Count + 1);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -25,6 +25,11 @@ namespace FlaxEditor.CustomEditors
|
||||
/// </summary>
|
||||
internal bool isRootGroup = true;
|
||||
|
||||
/// <summary>
|
||||
/// Parent container who created this one.
|
||||
/// </summary>
|
||||
internal LayoutElementsContainer _parent;
|
||||
|
||||
/// <summary>
|
||||
/// The children.
|
||||
/// </summary>
|
||||
@@ -40,6 +45,24 @@ namespace FlaxEditor.CustomEditors
|
||||
/// </summary>
|
||||
public abstract ContainerControl ContainerControl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Custom Editors layout presenter.
|
||||
/// </summary>
|
||||
internal CustomEditorPresenter Presenter
|
||||
{
|
||||
get
|
||||
{
|
||||
CustomEditorPresenter result;
|
||||
var container = this;
|
||||
do
|
||||
{
|
||||
result = container as CustomEditorPresenter;
|
||||
container = container._parent;
|
||||
} while (container != null);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds new group element.
|
||||
/// </summary>
|
||||
@@ -81,17 +104,31 @@ namespace FlaxEditor.CustomEditors
|
||||
public GroupElement Group(string title, bool useTransparentHeader = false)
|
||||
{
|
||||
var element = new GroupElement();
|
||||
if (!isRootGroup)
|
||||
var presenter = Presenter;
|
||||
var isSubGroup = !isRootGroup;
|
||||
if (isSubGroup)
|
||||
element.Panel.Close();
|
||||
if (presenter != null && (presenter.Features & FeatureFlags.CacheExpandedGroups) != 0)
|
||||
{
|
||||
element.Panel.Close(false);
|
||||
}
|
||||
else if (this is CustomEditorPresenter presenter && (presenter.Features & FeatureFlags.CacheExpandedGroups) != 0)
|
||||
{
|
||||
if (Editor.Instance.ProjectCache.IsCollapsedGroup(title))
|
||||
element.Panel.Close(false);
|
||||
element.Panel.IsClosedChanged += OnPanelIsClosedChanged;
|
||||
// Build group identifier (made of path from group titles)
|
||||
var expandPath = title;
|
||||
var container = this;
|
||||
while (container != null && !(container is CustomEditorPresenter))
|
||||
{
|
||||
if (container.ContainerControl is DropPanel dropPanel)
|
||||
expandPath = dropPanel.HeaderText + "/" + expandPath;
|
||||
container = container._parent;
|
||||
}
|
||||
|
||||
// Caching/restoring expanded groups (non-root groups cache expanded state so invert boolean expression)
|
||||
if (Editor.Instance.ProjectCache.IsGroupToggled(expandPath) ^ isSubGroup)
|
||||
element.Panel.Close();
|
||||
else
|
||||
element.Panel.Open();
|
||||
element.Panel.IsClosedChanged += panel => Editor.Instance.ProjectCache.SetGroupToggle(expandPath, panel.IsClosed ^ isSubGroup);
|
||||
}
|
||||
element.isRootGroup = false;
|
||||
element._parent = this;
|
||||
element.Panel.HeaderText = title;
|
||||
if (useTransparentHeader)
|
||||
{
|
||||
@@ -103,11 +140,6 @@ namespace FlaxEditor.CustomEditors
|
||||
return element;
|
||||
}
|
||||
|
||||
private void OnPanelIsClosedChanged(DropPanel panel)
|
||||
{
|
||||
Editor.Instance.ProjectCache.SetCollapsedGroup(panel.HeaderText, panel.IsClosed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds new horizontal panel element.
|
||||
/// </summary>
|
||||
@@ -627,7 +659,6 @@ namespace FlaxEditor.CustomEditors
|
||||
if (style == DisplayStyle.Group)
|
||||
{
|
||||
var group = Group(name, editor, true);
|
||||
group.Panel.Close(false);
|
||||
group.Panel.TooltipText = tooltip;
|
||||
return group.Object(values, editor);
|
||||
}
|
||||
@@ -657,7 +688,6 @@ namespace FlaxEditor.CustomEditors
|
||||
if (style == DisplayStyle.Group)
|
||||
{
|
||||
var group = Group(label.Text, editor, true);
|
||||
group.Panel.Close(false);
|
||||
group.Panel.TooltipText = tooltip;
|
||||
return group.Object(values, editor);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user