Merge branch 'Crawcik-fix-collections'

This commit is contained in:
Wojtek Figat
2021-06-09 09:54:32 +02:00
9 changed files with 98 additions and 31 deletions

View File

@@ -52,7 +52,7 @@ namespace FlaxEditor.CustomEditors.Editors
else else
{ {
// Initialize new entries with default values // Initialize new entries with default values
var defaultValue = TypeUtils.GetDefaultValue(new ScriptType(elementType)); var defaultValue = TypeUtils.GetDefaultValue(new ScriptType(elementType), NotNullItems);
for (int i = oldSize; i < newSize; i++) for (int i = oldSize; i < newSize; i++)
newValues.SetValue(defaultValue, i); newValues.SetValue(defaultValue, i);
} }
@@ -60,7 +60,7 @@ namespace FlaxEditor.CustomEditors.Editors
else if (newSize > 0) else if (newSize > 0)
{ {
// Initialize new entries with default values // Initialize new entries with default values
var defaultValue = TypeUtils.GetDefaultValue(new ScriptType(elementType)); var defaultValue = TypeUtils.GetDefaultValue(new ScriptType(elementType), NotNullItems);
for (int i = 0; i < newSize; i++) for (int i = 0; i < newSize; i++)
newValues.SetValue(defaultValue, i); newValues.SetValue(defaultValue, i);
} }

View File

@@ -77,11 +77,15 @@ namespace FlaxEditor.CustomEditors.Editors
} }
} }
/// <summary>
/// Determines if value of collection can be null.
/// </summary>
protected bool NotNullItems;
private IntegerValueElement _size; private IntegerValueElement _size;
private Color _background;
private int _elementsCount; private int _elementsCount;
private bool _readOnly; private bool _readOnly;
private bool _canReorderItems; private bool _canReorderItems;
private bool _notNullItems;
/// <summary> /// <summary>
/// Gets the length of the collection. /// Gets the length of the collection.
@@ -105,7 +109,7 @@ namespace FlaxEditor.CustomEditors.Editors
{ {
_readOnly = false; _readOnly = false;
_canReorderItems = true; _canReorderItems = true;
_notNullItems = false; NotNullItems = false;
// No support for different collections for now // No support for different collections for now
if (HasDifferentValues || HasDifferentTypes) if (HasDifferentValues || HasDifferentTypes)
@@ -118,13 +122,19 @@ namespace FlaxEditor.CustomEditors.Editors
Type overrideEditorType = null; Type overrideEditorType = null;
float spacing = 10.0f; float spacing = 10.0f;
var collection = (CollectionAttribute)attributes?.FirstOrDefault(x => x is CollectionAttribute); var collection = (CollectionAttribute)attributes?.FirstOrDefault(x => x is CollectionAttribute);
if (collection != null) if (collection is null)
{
_readOnly = false;
NotNullItems = false;
_background = FlaxEngine.GUI.Style.Current.CollectionBackgroundColor;
}
else
{ {
// TODO: handle NotNullItems by filtering child editors SetValue // TODO: handle NotNullItems by filtering child editors SetValue
_readOnly = collection.ReadOnly; _readOnly = collection.ReadOnly;
_canReorderItems = collection.CanReorderItems; _canReorderItems = collection.CanReorderItems;
_notNullItems = collection.NotNullItems; NotNullItems = collection.NotNullItems;
_background = collection.BackgroundColor;
overrideEditorType = TypeUtils.GetType(collection.OverrideEditorTypeName).Type; overrideEditorType = TypeUtils.GetType(collection.OverrideEditorTypeName).Type;
spacing = collection.Spacing; spacing = collection.Spacing;
} }
@@ -146,6 +156,8 @@ namespace FlaxEditor.CustomEditors.Editors
// Elements // Elements
if (size > 0) if (size > 0)
{ {
var panel = layout.VerticalPanel();
panel.Panel.BackgroundColor = _background;
var elementType = ElementType; var elementType = ElementType;
if (_canReorderItems) if (_canReorderItems)
{ {
@@ -153,7 +165,7 @@ namespace FlaxEditor.CustomEditors.Editors
{ {
if (i != 0 && spacing > 0f) if (i != 0 && spacing > 0f)
{ {
if (layout.Children.Count > 0 && layout.Children[layout.Children.Count - 1] is PropertiesListElement propertiesListElement) if (panel.Children.Count > 0 && panel.Children[panel.Children.Count - 1] is PropertiesListElement propertiesListElement)
{ {
if (propertiesListElement.Labels.Count > 0) if (propertiesListElement.Labels.Count > 0)
{ {
@@ -166,12 +178,12 @@ namespace FlaxEditor.CustomEditors.Editors
} }
else else
{ {
layout.Space(spacing); panel.Space(spacing);
} }
} }
var overrideEditor = overrideEditorType != null ? (CustomEditor)Activator.CreateInstance(overrideEditorType) : null; var overrideEditor = overrideEditorType != null ? (CustomEditor)Activator.CreateInstance(overrideEditorType) : null;
layout.Object(new CollectionItemLabel(this, i), new ListValueContainer(elementType, i, Values), overrideEditor); panel.Object(new CollectionItemLabel(this, i), new ListValueContainer(elementType, i, Values), overrideEditor);
} }
} }
else else
@@ -180,14 +192,14 @@ namespace FlaxEditor.CustomEditors.Editors
{ {
if (i != 0 && spacing > 0f) if (i != 0 && spacing > 0f)
{ {
if (layout.Children.Count > 0 && layout.Children[layout.Children.Count - 1] is PropertiesListElement propertiesListElement) if (panel.Children.Count > 0 && panel.Children[panel.Children.Count - 1] is PropertiesListElement propertiesListElement)
propertiesListElement.Space(spacing); propertiesListElement.Space(spacing);
else else
layout.Space(spacing); panel.Space(spacing);
} }
var overrideEditor = overrideEditorType != null ? (CustomEditor)Activator.CreateInstance(overrideEditorType) : null; var overrideEditor = overrideEditorType != null ? (CustomEditor)Activator.CreateInstance(overrideEditorType) : null;
layout.Object("Element " + i, new ListValueContainer(elementType, i, Values), overrideEditor); panel.Object("Element " + i, new ListValueContainer(elementType, i, Values), overrideEditor);
} }
} }
} }
@@ -229,6 +241,24 @@ namespace FlaxEditor.CustomEditors.Editors
} }
} }
/// <summary>
/// Rebuilds the parent layout if its collection.
/// </summary>
public void RebuildParentCollection()
{
if (ParentEditor is DictionaryEditor dictionaryEditor)
{
dictionaryEditor.RebuildParentCollection();
dictionaryEditor.RebuildLayout();
return;
}
if (ParentEditor is CollectionEditor collectionEditor)
{
collectionEditor.RebuildParentCollection();
collectionEditor.RebuildLayout();
}
}
private void OnSizeChanged() private void OnSizeChanged()
{ {
if (IsSetBlocked) if (IsSetBlocked)
@@ -312,6 +342,7 @@ namespace FlaxEditor.CustomEditors.Editors
if (Count != _elementsCount) if (Count != _elementsCount)
{ {
RebuildLayout(); RebuildLayout();
RebuildParentCollection();
} }
} }
} }

View File

@@ -135,6 +135,7 @@ namespace FlaxEditor.CustomEditors.Editors
} }
private IntegerValueElement _size; private IntegerValueElement _size;
private Color _background;
private int _elementsCount; private int _elementsCount;
private bool _readOnly; private bool _readOnly;
private bool _notNullItems; private bool _notNullItems;
@@ -164,8 +165,6 @@ namespace FlaxEditor.CustomEditors.Editors
/// <inheritdoc /> /// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout) public override void Initialize(LayoutElementsContainer layout)
{ {
_readOnly = false;
_notNullItems = false;
// No support for different collections for now // No support for different collections for now
if (HasDifferentValues || HasDifferentTypes) if (HasDifferentValues || HasDifferentTypes)
@@ -185,12 +184,18 @@ namespace FlaxEditor.CustomEditors.Editors
if (attributes != null) if (attributes != null)
{ {
var collection = (CollectionAttribute)attributes.FirstOrDefault(x => x is CollectionAttribute); var collection = (CollectionAttribute)attributes.FirstOrDefault(x => x is CollectionAttribute);
if (collection != null) if (collection is null)
{
_readOnly = false;
_notNullItems = false;
_background = FlaxEngine.GUI.Style.Current.CollectionBackgroundColor;
}
else
{ {
// TODO: handle ReadOnly and NotNullItems by filtering child editors SetValue // TODO: handle ReadOnly and NotNullItems by filtering child editors SetValue
_readOnly = collection.ReadOnly; _readOnly = collection.ReadOnly;
_notNullItems = collection.NotNullItems; _notNullItems = collection.NotNullItems;
_background = collection.BackgroundColor;
overrideEditorType = TypeUtils.GetType(collection.OverrideEditorTypeName).Type; overrideEditorType = TypeUtils.GetType(collection.OverrideEditorTypeName).Type;
spacing = collection.Spacing; spacing = collection.Spacing;
} }
@@ -213,13 +218,15 @@ namespace FlaxEditor.CustomEditors.Editors
// Elements // Elements
if (size > 0) if (size > 0)
{ {
var panel = layout.VerticalPanel();
panel.Panel.BackgroundColor = _background;
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();
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{ {
if (i != 0 && spacing > 0f) if (i != 0 && spacing > 0f)
{ {
if (layout.Children.Count > 0 && layout.Children[layout.Children.Count - 1] is PropertiesListElement propertiesListElement) if (panel.Children.Count > 0 && panel.Children[panel.Children.Count - 1] is PropertiesListElement propertiesListElement)
{ {
if (propertiesListElement.Labels.Count > 0) if (propertiesListElement.Labels.Count > 0)
{ {
@@ -232,13 +239,13 @@ namespace FlaxEditor.CustomEditors.Editors
} }
else else
{ {
layout.Space(spacing); panel.Space(spacing);
} }
} }
var key = keys.ElementAt(i); var key = keys.ElementAt(i);
var overrideEditor = overrideEditorType != null ? (CustomEditor)Activator.CreateInstance(overrideEditorType) : null; var overrideEditor = overrideEditorType != null ? (CustomEditor)Activator.CreateInstance(overrideEditorType) : null;
layout.Object(new DictionaryItemLabel(this, key), new DictionaryValueContainer(new ScriptType(valueType), key, Values), overrideEditor); panel.Object(new DictionaryItemLabel(this, key), new DictionaryValueContainer(new ScriptType(valueType), key, Values), overrideEditor);
} }
} }
_elementsCount = size; _elementsCount = size;
@@ -279,6 +286,24 @@ namespace FlaxEditor.CustomEditors.Editors
} }
} }
/// <summary>
/// Rebuilds the parent layout if its collection.
/// </summary>
public void RebuildParentCollection()
{
if (ParentEditor is DictionaryEditor dictionaryEditor)
{
dictionaryEditor.RebuildParentCollection();
dictionaryEditor.RebuildLayout();
return;
}
if (ParentEditor is CollectionEditor collectionEditor)
{
collectionEditor.RebuildParentCollection();
collectionEditor.RebuildLayout();
}
}
private void OnSizeChanged() private void OnSizeChanged()
{ {
if (IsSetBlocked) if (IsSetBlocked)
@@ -389,7 +414,7 @@ namespace FlaxEditor.CustomEditors.Editors
} }
} while (!isUnique); } while (!isUnique);
newValues[Convert.ChangeType(uniqueKey, keyType)] = TypeUtils.GetDefaultValue(new ScriptType(valueType)); newValues[Convert.ChangeType(uniqueKey, keyType)] = TypeUtils.GetDefaultValue(new ScriptType(valueType), _notNullItems);
} }
else if (keyType.IsEnum) else if (keyType.IsEnum)
{ {
@@ -410,7 +435,7 @@ namespace FlaxEditor.CustomEditors.Editors
} }
} while (!isUnique && uniqueKeyIndex < enumValues.Length); } while (!isUnique && uniqueKeyIndex < enumValues.Length);
newValues[enumValues.GetValue(uniqueKeyIndex)] = TypeUtils.GetDefaultValue(new ScriptType(valueType)); newValues[enumValues.GetValue(uniqueKeyIndex)] = TypeUtils.GetDefaultValue(new ScriptType(valueType), _notNullItems);
} }
else if (keyType == typeof(string)) else if (keyType == typeof(string))
{ {
@@ -430,7 +455,7 @@ namespace FlaxEditor.CustomEditors.Editors
} }
} while (!isUnique); } while (!isUnique);
newValues[uniqueKey] = TypeUtils.GetDefaultValue(new ScriptType(valueType)); newValues[uniqueKey] = TypeUtils.GetDefaultValue(new ScriptType(valueType), _notNullItems);
} }
else else
{ {
@@ -454,6 +479,7 @@ namespace FlaxEditor.CustomEditors.Editors
if (Count != _elementsCount) if (Count != _elementsCount)
{ {
RebuildLayout(); RebuildLayout();
RebuildParentCollection();
} }
} }
} }

View File

@@ -22,9 +22,7 @@ namespace FlaxEditor.CustomEditors.Editors
var list = (IList)listType.CreateInstance(); var list = (IList)listType.CreateInstance();
var defaultValue = Scripting.TypeUtils.GetDefaultValue(ElementType); var defaultValue = Scripting.TypeUtils.GetDefaultValue(ElementType);
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{
list.Add(defaultValue); list.Add(defaultValue);
}
return list; return list;
} }
@@ -57,7 +55,7 @@ namespace FlaxEditor.CustomEditors.Editors
else else
{ {
// Initialize new entries with default values // Initialize new entries with default values
var defaultValue = Scripting.TypeUtils.GetDefaultValue(elementType); var defaultValue = Scripting.TypeUtils.GetDefaultValue(elementType, NotNullItems);
for (int i = oldSize; i < newSize; i++) for (int i = oldSize; i < newSize; i++)
newValues.Add(defaultValue); newValues.Add(defaultValue);
} }
@@ -65,7 +63,7 @@ namespace FlaxEditor.CustomEditors.Editors
else if (newSize > 0) else if (newSize > 0)
{ {
// Fill new entries with default value // Fill new entries with default value
var defaultValue = Scripting.TypeUtils.GetDefaultValue(elementType); var defaultValue = Scripting.TypeUtils.GetDefaultValue(elementType, NotNullItems);
for (int i = oldSize; i < newSize; i++) for (int i = oldSize; i < newSize; i++)
newValues.Add(defaultValue); newValues.Add(defaultValue);
} }
@@ -86,9 +84,7 @@ namespace FlaxEditor.CustomEditors.Editors
var cloned = (IList)listType.CreateInstance(); var cloned = (IList)listType.CreateInstance();
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{
cloned.Add(list[i]); cloned.Add(list[i]);
}
return cloned; return cloned;
} }

View File

@@ -232,6 +232,7 @@ namespace FlaxEditor.Options
BorderNormal = Color.FromBgra(0xFF54545C), BorderNormal = Color.FromBgra(0xFF54545C),
TextBoxBackground = Color.FromBgra(0xFF333337), TextBoxBackground = Color.FromBgra(0xFF333337),
TextBoxBackgroundSelected = Color.FromBgra(0xFF3F3F46), TextBoxBackgroundSelected = Color.FromBgra(0xFF3F3F46),
CollectionBackgroundColor = Color.FromBgra(0x16FFFFFF),
ProgressNormal = Color.FromBgra(0xFF0ad328), ProgressNormal = Color.FromBgra(0xFF0ad328),
// Fonts // Fonts

View File

@@ -37,8 +37,9 @@ namespace FlaxEditor.Scripting
/// Gets the default value for the given type (can be value type or reference type). /// Gets the default value for the given type (can be value type or reference type).
/// </summary> /// </summary>
/// <param name="type">The type.</param> /// <param name="type">The type.</param>
/// <param name="notNull">Whether the value can be empty. If that's true, it can't.</param>
/// <returns>The created instance.</returns> /// <returns>The created instance.</returns>
public static object GetDefaultValue(ScriptType type) public static object GetDefaultValue(ScriptType type, bool notNull = false)
{ {
if (type.Type == typeof(string)) if (type.Type == typeof(string))
return string.Empty; return string.Empty;
@@ -64,7 +65,7 @@ namespace FlaxEditor.Scripting
Utilities.Utils.InitDefaultValues(value); Utilities.Utils.InitDefaultValues(value);
return value; return value;
} }
if (new ScriptType(typeof(object)).IsAssignableFrom(type)) if (!notNull && new ScriptType(typeof(object)).IsAssignableFrom(type))
return null; return null;
if (type.CanCreateInstance) if (type.CanCreateInstance)
{ {

View File

@@ -1,6 +1,7 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. // Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
using System; using System;
using FlaxEngine.GUI;
namespace FlaxEngine namespace FlaxEngine
{ {
@@ -34,5 +35,10 @@ namespace FlaxEngine
/// The spacing amount between collection items in the UI. /// The spacing amount between collection items in the UI.
/// </summary> /// </summary>
public float Spacing; public float Spacing;
/// <summary>
/// The collection background color.
/// </summary>
public Color BackgroundColor = Style.Current.CollectionBackgroundColor;
} }
} }

View File

@@ -221,6 +221,7 @@ namespace FlaxEngine
TextBoxBackground = Color.FromBgra(0xFF333337), TextBoxBackground = Color.FromBgra(0xFF333337),
ProgressNormal = Color.FromBgra(0xFF0ad328), ProgressNormal = Color.FromBgra(0xFF0ad328),
TextBoxBackgroundSelected = Color.FromBgra(0xFF3F3F46), TextBoxBackgroundSelected = Color.FromBgra(0xFF3F3F46),
CollectionBackgroundColor = Color.FromBgra(0x16FFFFFF),
SharedTooltip = new Tooltip(), SharedTooltip = new Tooltip(),
}; };
style.DragWindow = style.BackgroundSelected * 0.7f; style.DragWindow = style.BackgroundSelected * 0.7f;

View File

@@ -152,6 +152,11 @@ namespace FlaxEngine.GUI
[EditorOrder(190)] [EditorOrder(190)]
public Color TextBoxBackgroundSelected; public Color TextBoxBackgroundSelected;
/// <summary>
/// The collection background color.
/// </summary>
[EditorOrder(195)]
public Color CollectionBackgroundColor;
/// <summary> /// <summary>
/// The progress normal color. /// The progress normal color.
/// </summary> /// </summary>