Add support for displaying and reverting array values to prefab value in properties panel

#1548
This commit is contained in:
Wojtek Figat
2023-12-14 13:57:16 +01:00
parent 190bafea28
commit fe1a655654
2 changed files with 63 additions and 45 deletions

View File

@@ -7,9 +7,8 @@ using FlaxEditor.CustomEditors.GUI;
using FlaxEditor.Scripting; using FlaxEditor.Scripting;
using FlaxEngine; using FlaxEngine;
using FlaxEngine.GUI; using FlaxEngine.GUI;
using FlaxEngine.Json;
using FlaxEngine.Utilities; using FlaxEngine.Utilities;
using Newtonsoft.Json;
using JsonSerializer = FlaxEngine.Json.JsonSerializer;
namespace FlaxEditor.CustomEditors namespace FlaxEditor.CustomEditors
{ {
@@ -386,22 +385,22 @@ namespace FlaxEditor.CustomEditors
LinkedLabel = label; LinkedLabel = label;
} }
private void RevertDiffToDefault(CustomEditor editor) /// <summary>
{ /// If true, the value reverting to default/reference will be handled via iteration over children editors, instead of for a whole object at once.
if (editor.ChildrenEditors.Count == 0) /// </summary>
{ public virtual bool RevertValueWithChildren => ChildrenEditors.Count != 0;
// Skip if no change detected
if (!editor.Values.IsDefaultValueModified)
return;
editor.SetValueToDefault(); private void RevertDiffToDefault()
{
if (RevertValueWithChildren)
{
foreach (var child in ChildrenEditors)
child.RevertDiffToDefault();
} }
else else
{ {
for (int i = 0; i < editor.ChildrenEditors.Count; i++) if (Values.IsDefaultValueModified)
{ SetValueToDefault();
RevertDiffToDefault(editor.ChildrenEditors[i]);
}
} }
} }
@@ -414,11 +413,6 @@ namespace FlaxEditor.CustomEditors
{ {
if (!Values.IsDefaultValueModified) if (!Values.IsDefaultValueModified)
return false; return false;
// Skip array items (show diff only on a bottom level properties and fields)
if (ParentEditor is Editors.ArrayEditor)
return false;
return true; return true;
} }
} }
@@ -430,7 +424,7 @@ namespace FlaxEditor.CustomEditors
{ {
if (!Values.HasDefaultValue) if (!Values.HasDefaultValue)
return; return;
RevertDiffToDefault(this); RevertDiffToDefault();
} }
/// <summary> /// <summary>
@@ -468,22 +462,17 @@ namespace FlaxEditor.CustomEditors
} }
} }
private void RevertDiffToReference(CustomEditor editor) private void RevertDiffToReference()
{ {
if (editor.ChildrenEditors.Count == 0) if (RevertValueWithChildren)
{ {
// Skip if no change detected foreach (var child in ChildrenEditors)
if (!editor.Values.IsReferenceValueModified) child.RevertDiffToReference();
return;
editor.SetValueToReference();
} }
else else
{ {
for (int i = 0; i < editor.ChildrenEditors.Count; i++) if (Values.IsReferenceValueModified)
{ SetValueToReference();
RevertDiffToReference(editor.ChildrenEditors[i]);
}
} }
} }
@@ -496,11 +485,6 @@ namespace FlaxEditor.CustomEditors
{ {
if (!Values.IsReferenceValueModified) if (!Values.IsReferenceValueModified)
return false; return false;
// Skip array items (show diff only on a bottom level properties and fields)
if (ParentEditor is Editors.ArrayEditor)
return false;
return true; return true;
} }
} }
@@ -512,7 +496,7 @@ namespace FlaxEditor.CustomEditors
{ {
if (!Values.HasReferenceValue) if (!Values.HasReferenceValue)
return; return;
RevertDiffToReference(this); RevertDiffToReference();
} }
/// <summary> /// <summary>
@@ -657,7 +641,7 @@ namespace FlaxEditor.CustomEditors
// Default // Default
try try
{ {
obj = JsonConvert.DeserializeObject(text, TypeUtils.GetType(Values.Type), JsonSerializer.Settings); obj = Newtonsoft.Json.JsonConvert.DeserializeObject(text, TypeUtils.GetType(Values.Type), JsonSerializer.Settings);
} }
catch catch
{ {
@@ -762,7 +746,7 @@ namespace FlaxEditor.CustomEditors
/// </summary> /// </summary>
public void SetValueToDefault() public void SetValueToDefault()
{ {
SetValue(Values.DefaultValue); SetValueCloned(Values.DefaultValue);
} }
/// <summary> /// <summary>
@@ -799,7 +783,19 @@ namespace FlaxEditor.CustomEditors
return; return;
} }
SetValue(Values.ReferenceValue); SetValueCloned(Values.ReferenceValue);
}
private void SetValueCloned(object value)
{
// For objects (eg. arrays) we need to clone them to prevent editing default/reference value within editor
if (value != null && !value.GetType().IsValueType)
{
var json = JsonSerializer.Serialize(value);
value = JsonSerializer.Deserialize(json, value.GetType());
}
SetValue(value);
} }
/// <summary> /// <summary>
@@ -811,7 +807,6 @@ namespace FlaxEditor.CustomEditors
{ {
if (_isSetBlocked) if (_isSetBlocked)
return; return;
if (OnDirty(this, value, token)) if (OnDirty(this, value, token))
{ {
_hasValueDirty = true; _hasValueDirty = true;

View File

@@ -87,6 +87,7 @@ namespace FlaxEditor.CustomEditors.Editors
protected bool NotNullItems; protected bool NotNullItems;
private IntegerValueElement _size; private IntegerValueElement _size;
private PropertyNameLabel _sizeLabel;
private Color _background; private Color _background;
private int _elementsCount; private int _elementsCount;
private bool _readOnly; private bool _readOnly;
@@ -109,6 +110,9 @@ namespace FlaxEditor.CustomEditors.Editors
} }
} }
/// <inheritdoc />
public override bool RevertValueWithChildren => false; // Always revert value for a whole collection
/// <inheritdoc /> /// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout) public override void Initialize(LayoutElementsContainer layout)
{ {
@@ -174,7 +178,9 @@ namespace FlaxEditor.CustomEditors.Editors
} }
else else
{ {
_size = dragArea.IntegerValue("Size"); var sizeProperty = dragArea.AddPropertyItem("Size");
_sizeLabel = sizeProperty.Labels.Last();
_size = sizeProperty.IntegerValue();
_size.IntValue.MinValue = 0; _size.IntValue.MinValue = 0;
_size.IntValue.MaxValue = ushort.MaxValue; _size.IntValue.MaxValue = ushort.MaxValue;
_size.IntValue.Value = size; _size.IntValue.Value = size;
@@ -274,6 +280,15 @@ namespace FlaxEditor.CustomEditors.Editors
} }
} }
/// <inheritdoc />
protected override void Deinitialize()
{
_size = null;
_sizeLabel = null;
base.Deinitialize();
}
/// <summary> /// <summary>
/// Rebuilds the parent layout if its collection. /// Rebuilds the parent layout if its collection.
/// </summary> /// </summary>
@@ -296,7 +311,6 @@ namespace FlaxEditor.CustomEditors.Editors
{ {
if (IsSetBlocked) if (IsSetBlocked)
return; return;
Resize(_size.IntValue.Value); Resize(_size.IntValue.Value);
} }
@@ -311,11 +325,9 @@ namespace FlaxEditor.CustomEditors.Editors
return; return;
var cloned = CloneValues(); var cloned = CloneValues();
var tmp = cloned[dstIndex]; var tmp = cloned[dstIndex];
cloned[dstIndex] = cloned[srcIndex]; cloned[dstIndex] = cloned[srcIndex];
cloned[srcIndex] = tmp; cloned[srcIndex] = tmp;
SetValue(cloned); SetValue(cloned);
} }
@@ -371,6 +383,17 @@ namespace FlaxEditor.CustomEditors.Editors
if (HasDifferentValues || HasDifferentTypes) if (HasDifferentValues || HasDifferentTypes)
return; return;
// Update reference/default value indicator
if (_sizeLabel != null)
{
var color = Color.Transparent;
if (Values.HasReferenceValue && Values.ReferenceValue is IList referenceValue && referenceValue.Count != Count)
color = FlaxEngine.GUI.Style.Current.BackgroundSelected;
else if (Values.HasDefaultValue && Values.DefaultValue is IList defaultValue && defaultValue.Count != Count)
color = Color.Yellow * 0.8f;
_sizeLabel.HighlightStripColor = color;
}
// Check if collection has been resized (by UI or from external source) // Check if collection has been resized (by UI or from external source)
if (Count != _elementsCount) if (Count != _elementsCount)
{ {