Fix ReadOnly attribute handling in collection editors
This commit is contained in:
@@ -57,17 +57,18 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
menu.ItemsContainer.RemoveChildren();
|
menu.ItemsContainer.RemoveChildren();
|
||||||
|
|
||||||
menu.AddButton("Copy", linkedEditor.Copy);
|
menu.AddButton("Copy", linkedEditor.Copy);
|
||||||
var paste = menu.AddButton("Paste", linkedEditor.Paste);
|
var b = menu.AddButton("Paste", linkedEditor.Paste);
|
||||||
paste.Enabled = linkedEditor.CanPaste;
|
b.Enabled = linkedEditor.CanPaste && !Editor._readOnly;
|
||||||
|
|
||||||
menu.AddSeparator();
|
menu.AddSeparator();
|
||||||
var moveUpButton = menu.AddButton("Move up", OnMoveUpClicked);
|
b = menu.AddButton("Move up", OnMoveUpClicked);
|
||||||
moveUpButton.Enabled = Index > 0;
|
b.Enabled = Index > 0 && !Editor._readOnly;
|
||||||
|
|
||||||
var moveDownButton = menu.AddButton("Move down", OnMoveDownClicked);
|
b = menu.AddButton("Move down", OnMoveDownClicked);
|
||||||
moveDownButton.Enabled = Index + 1 < Editor.Count;
|
b.Enabled = Index + 1 < Editor.Count && !Editor._readOnly;
|
||||||
|
|
||||||
menu.AddButton("Remove", OnRemoveClicked);
|
b = menu.AddButton("Remove", OnRemoveClicked);
|
||||||
|
b.Enabled = !Editor._readOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMoveUpClicked()
|
private void OnMoveUpClicked()
|
||||||
@@ -177,6 +178,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
private IntValueBox _sizeBox;
|
private IntValueBox _sizeBox;
|
||||||
private Color _background;
|
private Color _background;
|
||||||
private int _elementsCount, _minCount, _maxCount;
|
private int _elementsCount, _minCount, _maxCount;
|
||||||
|
private bool _readOnly;
|
||||||
private bool _canResize;
|
private bool _canResize;
|
||||||
private bool _canReorderItems;
|
private bool _canReorderItems;
|
||||||
private CollectionAttribute.DisplayType _displayType;
|
private CollectionAttribute.DisplayType _displayType;
|
||||||
@@ -209,6 +211,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var size = Count;
|
var size = Count;
|
||||||
|
_readOnly = false;
|
||||||
_canResize = true;
|
_canResize = true;
|
||||||
_canReorderItems = true;
|
_canReorderItems = true;
|
||||||
_minCount = 0;
|
_minCount = 0;
|
||||||
@@ -225,6 +228,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
if (collection != null)
|
if (collection != null)
|
||||||
{
|
{
|
||||||
_canResize = !collection.ReadOnly;
|
_canResize = !collection.ReadOnly;
|
||||||
|
_readOnly = collection.ReadOnly;
|
||||||
_minCount = collection.MinCount;
|
_minCount = collection.MinCount;
|
||||||
_maxCount = collection.MaxCount;
|
_maxCount = collection.MaxCount;
|
||||||
_canReorderItems = collection.CanReorderItems;
|
_canReorderItems = collection.CanReorderItems;
|
||||||
@@ -235,6 +239,12 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
spacing = collection.Spacing;
|
spacing = collection.Spacing;
|
||||||
_displayType = collection.Display;
|
_displayType = collection.Display;
|
||||||
}
|
}
|
||||||
|
if (attributes != null && attributes.Any(x => x is ReadOnlyAttribute))
|
||||||
|
{
|
||||||
|
_readOnly = true;
|
||||||
|
_canResize = false;
|
||||||
|
_canReorderItems = false;
|
||||||
|
}
|
||||||
if (_maxCount == 0)
|
if (_maxCount == 0)
|
||||||
_maxCount = ushort.MaxValue;
|
_maxCount = ushort.MaxValue;
|
||||||
_canResize &= _minCount < _maxCount;
|
_canResize &= _minCount < _maxCount;
|
||||||
@@ -243,8 +253,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
dragArea.CustomControl.Editor = this;
|
dragArea.CustomControl.Editor = this;
|
||||||
dragArea.CustomControl.ElementType = ElementType;
|
dragArea.CustomControl.ElementType = ElementType;
|
||||||
|
|
||||||
// Check for the AssetReferenceAttribute. In JSON assets, it can be used to filter
|
// Check for the AssetReferenceAttribute. In JSON assets, it can be used to filter which scripts can be dragged over and dropped on this collection editor
|
||||||
// which scripts can be dragged over and dropped on this collection editor.
|
|
||||||
var assetReference = (AssetReferenceAttribute)attributes?.FirstOrDefault(x => x is AssetReferenceAttribute);
|
var assetReference = (AssetReferenceAttribute)attributes?.FirstOrDefault(x => x is AssetReferenceAttribute);
|
||||||
if (assetReference != null)
|
if (assetReference != null)
|
||||||
{
|
{
|
||||||
@@ -333,6 +342,8 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
var property = panel.AddPropertyItem(itemLabel);
|
var property = panel.AddPropertyItem(itemLabel);
|
||||||
var itemLayout = (LayoutElementsContainer)property;
|
var itemLayout = (LayoutElementsContainer)property;
|
||||||
itemLabel.LinkedEditor = itemLayout.Object(new ListValueContainer(elementType, i, Values, attributes), overrideEditor);
|
itemLabel.LinkedEditor = itemLayout.Object(new ListValueContainer(elementType, i, Values, attributes), overrideEditor);
|
||||||
|
if (_readOnly && itemLayout.Children.Count > 0)
|
||||||
|
GenericEditor.OnReadOnlyProperty(itemLayout);
|
||||||
}
|
}
|
||||||
else if (_displayType == CollectionAttribute.DisplayType.Header || (_displayType == CollectionAttribute.DisplayType.Default && !single))
|
else if (_displayType == CollectionAttribute.DisplayType.Header || (_displayType == CollectionAttribute.DisplayType.Default && !single))
|
||||||
{
|
{
|
||||||
@@ -340,13 +351,15 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
cdp.CustomControl.Setup(this, i, _canReorderItems);
|
cdp.CustomControl.Setup(this, i, _canReorderItems);
|
||||||
var itemLayout = cdp.VerticalPanel();
|
var itemLayout = cdp.VerticalPanel();
|
||||||
cdp.CustomControl.LinkedEditor = itemLayout.Object(new ListValueContainer(elementType, i, Values, attributes), overrideEditor);
|
cdp.CustomControl.LinkedEditor = itemLayout.Object(new ListValueContainer(elementType, i, Values, attributes), overrideEditor);
|
||||||
|
if (_readOnly && itemLayout.Children.Count > 0)
|
||||||
|
GenericEditor.OnReadOnlyProperty(itemLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_elementsCount = size;
|
_elementsCount = size;
|
||||||
|
|
||||||
// Add/Remove buttons
|
// Add/Remove buttons
|
||||||
if (_canResize)
|
if (_canResize && !_readOnly)
|
||||||
{
|
{
|
||||||
var panel = dragArea.HorizontalPanel();
|
var panel = dragArea.HorizontalPanel();
|
||||||
panel.Panel.Size = new Float2(0, 20);
|
panel.Panel.Size = new Float2(0, 20);
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
|
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
|
||||||
{
|
{
|
||||||
if (button == MouseButton.Left)
|
if (button == MouseButton.Left && _editor._canEditKeys)
|
||||||
{
|
{
|
||||||
OnEditClicked(null);
|
OnEditClicked(null);
|
||||||
return true;
|
return true;
|
||||||
@@ -156,6 +156,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
private bool _readOnly;
|
private bool _readOnly;
|
||||||
private bool _notNullItems;
|
private bool _notNullItems;
|
||||||
private bool _canEditKeys;
|
private bool _canEditKeys;
|
||||||
|
private bool _canEditValues;
|
||||||
private bool _keyEdited;
|
private bool _keyEdited;
|
||||||
private CollectionAttribute.DisplayType _displayType;
|
private CollectionAttribute.DisplayType _displayType;
|
||||||
|
|
||||||
@@ -197,6 +198,11 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
spacing = collection.Spacing;
|
spacing = collection.Spacing;
|
||||||
_displayType = collection.Display;
|
_displayType = collection.Display;
|
||||||
}
|
}
|
||||||
|
if (attributes != null && attributes.Any(x => x is ReadOnlyAttribute))
|
||||||
|
{
|
||||||
|
_readOnly = true;
|
||||||
|
_canEditKeys = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Size
|
// Size
|
||||||
if (layout.ContainerControl is DropPanel dropPanel)
|
if (layout.ContainerControl is DropPanel dropPanel)
|
||||||
@@ -239,14 +245,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
var keysEnumerable = ((IDictionary)Values[0]).Keys.OfType<object>();
|
var keysEnumerable = ((IDictionary)Values[0]).Keys.OfType<object>();
|
||||||
var keys = keysEnumerable as object[] ?? keysEnumerable.ToArray();
|
var keys = keysEnumerable as object[] ?? keysEnumerable.ToArray();
|
||||||
var valuesType = new ScriptType(valueType);
|
var valuesType = new ScriptType(valueType);
|
||||||
|
|
||||||
bool single = valuesType.IsPrimitive ||
|
|
||||||
valuesType.Equals(new ScriptType(typeof(string))) ||
|
|
||||||
valuesType.IsEnum ||
|
|
||||||
(valuesType.GetFields().Length == 1 && valuesType.GetProperties().Length == 0) ||
|
|
||||||
(valuesType.GetProperties().Length == 1 && valuesType.GetFields().Length == 0) ||
|
|
||||||
valuesType.Equals(new ScriptType(typeof(JsonAsset))) ||
|
|
||||||
valuesType.Equals(new ScriptType(typeof(SettingsBase)));
|
|
||||||
|
|
||||||
// Use separate layout cells for each collection items to improve layout updates for them in separation
|
// Use separate layout cells for each collection items to improve layout updates for them in separation
|
||||||
var useSharedLayout = valueType.IsPrimitive || valueType.IsEnum;
|
var useSharedLayout = valueType.IsPrimitive || valueType.IsEnum;
|
||||||
@@ -263,6 +261,8 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
var property = panel.AddPropertyItem(new DictionaryItemLabel(this, key));
|
var property = panel.AddPropertyItem(new DictionaryItemLabel(this, key));
|
||||||
var itemLayout = useSharedLayout ? (LayoutElementsContainer)property : property.VerticalPanel();
|
var itemLayout = useSharedLayout ? (LayoutElementsContainer)property : property.VerticalPanel();
|
||||||
itemLayout.Object(new DictionaryValueContainer(valuesType, key, Values), overrideEditor);
|
itemLayout.Object(new DictionaryValueContainer(valuesType, key, Values), overrideEditor);
|
||||||
|
if (_readOnly && itemLayout.Children.Count > 0)
|
||||||
|
GenericEditor.OnReadOnlyProperty(itemLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_elementsCount = size;
|
_elementsCount = size;
|
||||||
|
|||||||
@@ -581,6 +581,43 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static void OnReadOnlyProperty(LayoutElementsContainer itemLayout, int labelIndex = -1)
|
||||||
|
{
|
||||||
|
PropertiesListElement list = null;
|
||||||
|
int firstChildControlIndex = 0;
|
||||||
|
bool disableSingle = true;
|
||||||
|
var control = itemLayout.Children[itemLayout.Children.Count - 1];
|
||||||
|
if (control is GroupElement group && group.Children.Count > 0)
|
||||||
|
{
|
||||||
|
list = group.Children[0] as PropertiesListElement;
|
||||||
|
disableSingle = false; // Disable all nested editors
|
||||||
|
}
|
||||||
|
else if (control is PropertiesListElement list1 && labelIndex != -1)
|
||||||
|
{
|
||||||
|
list = list1;
|
||||||
|
firstChildControlIndex = list.Labels[labelIndex].FirstChildControlIndex;
|
||||||
|
}
|
||||||
|
else if (control?.Control != null)
|
||||||
|
{
|
||||||
|
control.Control.Enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list != null)
|
||||||
|
{
|
||||||
|
// Disable controls added to the editor
|
||||||
|
var count = list.Properties.Children.Count;
|
||||||
|
for (int j = firstChildControlIndex; j < count; j++)
|
||||||
|
{
|
||||||
|
var child = list.Properties.Children[j];
|
||||||
|
if (disableSingle && child is PropertyNameLabel)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (child != null)
|
||||||
|
child.Enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Evaluate the <see cref="VisibleIfAttribute"/> cache for a given property item.
|
/// Evaluate the <see cref="VisibleIfAttribute"/> cache for a given property item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -660,35 +697,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
if (item.IsReadOnly && itemLayout.Children.Count > 0)
|
if (item.IsReadOnly && itemLayout.Children.Count > 0)
|
||||||
{
|
{
|
||||||
PropertiesListElement list = null;
|
OnReadOnlyProperty(itemLayout, labelIndex);
|
||||||
int firstChildControlIndex = 0;
|
|
||||||
bool disableSingle = true;
|
|
||||||
var control = itemLayout.Children[itemLayout.Children.Count - 1];
|
|
||||||
if (control is GroupElement group && group.Children.Count > 0)
|
|
||||||
{
|
|
||||||
list = group.Children[0] as PropertiesListElement;
|
|
||||||
disableSingle = false; // Disable all nested editors
|
|
||||||
}
|
|
||||||
else if (control is PropertiesListElement list1)
|
|
||||||
{
|
|
||||||
list = list1;
|
|
||||||
firstChildControlIndex = list.Labels[labelIndex].FirstChildControlIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (list != null)
|
|
||||||
{
|
|
||||||
// Disable controls added to the editor
|
|
||||||
var count = list.Properties.Children.Count;
|
|
||||||
for (int j = firstChildControlIndex; j < count; j++)
|
|
||||||
{
|
|
||||||
var child = list.Properties.Children[j];
|
|
||||||
if (disableSingle && child is PropertyNameLabel)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (child != null)
|
|
||||||
child.Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EvaluateVisibleIf(itemLayout, item, labelIndex);
|
EvaluateVisibleIf(itemLayout, item, labelIndex);
|
||||||
|
|||||||
Reference in New Issue
Block a user