Fix UI with list of null items when layout gets rebuilt at item level
This commit is contained in:
@@ -101,11 +101,6 @@ namespace FlaxEditor.CustomEditors
|
||||
/// </summary>
|
||||
protected bool IsSetBlocked => _isSetBlocked;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this editor needs value propagation up (value synchronization when one of the child editors changes value, used by the struct types).
|
||||
/// </summary>
|
||||
protected virtual bool NeedsValuePropagationUp => Values.HasValueType;
|
||||
|
||||
/// <summary>
|
||||
/// The linked label used to show this custom editor. Can be null if not used (eg. editor is inlined or is using a very customized UI layout).
|
||||
/// </summary>
|
||||
@@ -281,7 +276,7 @@ namespace FlaxEditor.CustomEditors
|
||||
|
||||
// Propagate values up (eg. when member of structure gets modified, also structure should be updated as a part of the other object)
|
||||
var obj = _parent;
|
||||
while (obj._parent != null && !(obj._parent is SyncPointEditor)) // && obj.NeedsValuePropagationUp)
|
||||
while (obj._parent != null && !(obj._parent is SyncPointEditor))
|
||||
{
|
||||
obj.Values.Set(obj._parent.Values, obj.Values);
|
||||
obj = obj._parent;
|
||||
@@ -301,12 +296,15 @@ namespace FlaxEditor.CustomEditors
|
||||
_isSetBlocked = false;
|
||||
|
||||
// Update children
|
||||
if (_skipChildrenRefresh)
|
||||
{
|
||||
_skipChildrenRefresh = false;
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
var childrenCount = _skipChildrenRefresh ? 0 : _children.Count;
|
||||
for (int i = 0; i < childrenCount; i++)
|
||||
for (int i = 0; i < _children.Count; i++)
|
||||
_children[i].RefreshInternal();
|
||||
_skipChildrenRefresh = false;
|
||||
}
|
||||
catch (TargetException ex)
|
||||
{
|
||||
|
||||
@@ -154,6 +154,10 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
var panel = layout.VerticalPanel();
|
||||
panel.Panel.BackgroundColor = _background;
|
||||
var elementType = ElementType;
|
||||
|
||||
// Use separate layout cells for each collection items to improve layout updates for them in separation
|
||||
var useSharedLayout = elementType.IsPrimitive || elementType.IsEnum;
|
||||
|
||||
if (_canReorderItems)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
@@ -178,7 +182,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
}
|
||||
|
||||
var overrideEditor = overrideEditorType != null ? (CustomEditor)Activator.CreateInstance(overrideEditorType) : null;
|
||||
panel.Object(new CollectionItemLabel(this, i), new ListValueContainer(elementType, i, Values), overrideEditor);
|
||||
var property = panel.AddPropertyItem(new CollectionItemLabel(this, i));
|
||||
var itemLayout = useSharedLayout ? (LayoutElementsContainer)property : property.VerticalPanel();
|
||||
itemLayout.Object(new ListValueContainer(elementType, i, Values), overrideEditor);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -194,7 +200,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
}
|
||||
|
||||
var overrideEditor = overrideEditorType != null ? (CustomEditor)Activator.CreateInstance(overrideEditorType) : null;
|
||||
panel.Object("Element " + i, new ListValueContainer(elementType, i, Values), overrideEditor);
|
||||
var property = panel.AddPropertyItem("Element " + i);
|
||||
var itemLayout = useSharedLayout ? (LayoutElementsContainer)property : property.VerticalPanel();
|
||||
itemLayout.Object(new ListValueContainer(elementType, i, Values), overrideEditor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,6 +216,11 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
panel.Panel.BackgroundColor = _background;
|
||||
var keysEnumerable = ((IDictionary)Values[0]).Keys.OfType<object>();
|
||||
var keys = keysEnumerable as object[] ?? keysEnumerable.ToArray();
|
||||
var valuesType = new ScriptType(valueType);
|
||||
|
||||
// Use separate layout cells for each collection items to improve layout updates for them in separation
|
||||
var useSharedLayout = valueType.IsPrimitive || valueType.IsEnum;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (i != 0 && spacing > 0f)
|
||||
@@ -239,7 +244,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
|
||||
var key = keys.ElementAt(i);
|
||||
var overrideEditor = overrideEditorType != null ? (CustomEditor)Activator.CreateInstance(overrideEditorType) : null;
|
||||
panel.Object(new DictionaryItemLabel(this, key), new DictionaryValueContainer(new ScriptType(valueType), key, Values), overrideEditor);
|
||||
var property = panel.AddPropertyItem(new DictionaryItemLabel(this, key));
|
||||
var itemLayout = useSharedLayout ? (LayoutElementsContainer)property : property.VerticalPanel();
|
||||
itemLayout.Object(new DictionaryValueContainer(valuesType, key, Values), overrideEditor);
|
||||
}
|
||||
}
|
||||
_elementsCount = size;
|
||||
|
||||
@@ -228,6 +228,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
}
|
||||
|
||||
private VisibleIfCache[] _visibleIfCaches;
|
||||
private bool _isNull;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the items for the type
|
||||
@@ -264,7 +265,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
// Skip properties without getter or setter
|
||||
if (!p.HasGet || (!p.HasSet && !showInEditor))
|
||||
continue;
|
||||
|
||||
|
||||
// Skip hidden fields, handle special attributes
|
||||
if ((!p.IsPublic && !showInEditor) || attributes.Any(x => x is HideInEditorAttribute))
|
||||
continue;
|
||||
@@ -421,7 +422,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
var values = Values;
|
||||
_visibleIfCaches = null;
|
||||
_isNull = values != null && values.IsNull;
|
||||
|
||||
// Collect items to edit
|
||||
List<ItemInfo> items;
|
||||
@@ -446,12 +449,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
Parent = layout.ContainerControl,
|
||||
Location = new Vector2(layout.ContainerControl.Width - ButtonSize - 4, (layout.ContainerControl.Height - ButtonSize) * 0.5f),
|
||||
};
|
||||
button.Clicked += () =>
|
||||
{
|
||||
var newType = Values.Type;
|
||||
SetValue(newType.CreateInstance());
|
||||
RebuildLayoutOnRefresh();
|
||||
};
|
||||
button.Clicked += () => SetValue(Values.Type.CreateInstance());
|
||||
}
|
||||
|
||||
layout.Label("<null>");
|
||||
@@ -558,6 +556,13 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// <inheritdoc />
|
||||
public override void Refresh()
|
||||
{
|
||||
// Automatic refresh when value nullability changed
|
||||
if (_isNull != Values.IsNull)
|
||||
{
|
||||
RebuildLayout();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_visibleIfCaches != null)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -30,6 +30,11 @@ namespace FlaxEditor.CustomEditors
|
||||
/// </summary>
|
||||
public readonly List<LayoutElement> Children = new List<LayoutElement>();
|
||||
|
||||
/// <summary>
|
||||
/// The child custom editors.
|
||||
/// </summary>
|
||||
public readonly List<CustomEditor> Editors = new List<CustomEditor>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the control represented by this element.
|
||||
/// </summary>
|
||||
@@ -722,6 +727,7 @@ namespace FlaxEditor.CustomEditors
|
||||
var customEditor = CustomEditor.CurrentCustomEditor;
|
||||
Assert.IsNotNull(customEditor);
|
||||
customEditor.OnChildCreated(editor);
|
||||
Editors.Add(editor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -730,6 +736,7 @@ namespace FlaxEditor.CustomEditors
|
||||
public virtual void ClearLayout()
|
||||
{
|
||||
Children.Clear();
|
||||
Editors.Clear();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -101,6 +101,22 @@ namespace FlaxEditor.CustomEditors
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether all values in the collection are null. Returns true if collection is empty.
|
||||
/// </summary>
|
||||
public bool IsNull
|
||||
{
|
||||
get
|
||||
{
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
if (this[i] != null)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this any value in the collection is of value type (eg. a structure, not a class type). Returns false if collection is empty.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user