Merge branch 'master' into 1.8

This commit is contained in:
Wojtek Figat
2024-01-05 17:13:51 +01:00
49 changed files with 619 additions and 261 deletions

View File

@@ -3,6 +3,7 @@
using System.Linq;
using FlaxEditor.CustomEditors.Elements;
using FlaxEditor.GUI.Dialogs;
using FlaxEditor.GUI.Input;
using FlaxEngine;
using FlaxEngine.GUI;
@@ -17,6 +18,7 @@ namespace FlaxEditor.CustomEditors.Editors
private FloatValueElement _yElement;
private FloatValueElement _zElement;
private FloatValueElement _wElement;
private ColorValueBox _colorBox;
private CustomElement<ColorSelector> _trackball;
/// <inheritdoc />
@@ -53,7 +55,7 @@ namespace FlaxEditor.CustomEditors.Editors
gridControl.SlotPadding = new Margin(4, 2, 2, 2);
gridControl.ClipChildren = false;
gridControl.SlotsHorizontally = 1;
gridControl.SlotsVertically = 4;
gridControl.SlotsVertically = 5;
LimitAttribute limit = null;
var attributes = Values.GetAttributes();
@@ -61,7 +63,8 @@ namespace FlaxEditor.CustomEditors.Editors
{
limit = (LimitAttribute)attributes.FirstOrDefault(x => x is LimitAttribute);
}
_colorBox = grid.Custom<ColorValueBox>().CustomControl;
_colorBox.ValueChanged += OnColorBoxChanged;
_xElement = CreateFloatEditor(grid, limit, Color.Red);
_yElement = CreateFloatEditor(grid, limit, Color.Green);
_zElement = CreateFloatEditor(grid, limit, Color.Blue);
@@ -93,6 +96,13 @@ namespace FlaxEditor.CustomEditors.Editors
SetValue(value, token);
}
private void OnColorBoxChanged()
{
var token = _colorBox.IsSliding ? this : null;
var color = _colorBox.Value;
SetValue(new Float4(color.R, color.G, color.B, color.A), token);
}
private void OnValueChanged()
{
if (IsSetBlocked)
@@ -130,6 +140,7 @@ namespace FlaxEditor.CustomEditors.Editors
_yElement.Value = color.Y;
_zElement.Value = color.Z;
_wElement.Value = scale;
_colorBox.Value = new Color(color.X, color.Y, color.Z, scale);
_trackball.CustomControl.Color = Float3.Abs(color);
}
}

View File

@@ -88,6 +88,8 @@ namespace FlaxEditor.CustomEditors.Editors
_element.Value = asFloat;
else if (value is double asDouble)
_element.Value = (float)asDouble;
else if (value is int asInt)
_element.Value = (float)asInt;
else
throw new Exception(string.Format("Invalid value type {0}.", value?.GetType().ToString() ?? "<null>"));
}

View File

@@ -66,9 +66,9 @@ namespace FlaxEditor.CustomEditors.Editors
public HeaderAttribute Header;
/// <summary>
/// The visible if attribute.
/// The visible if attributes.
/// </summary>
public VisibleIfAttribute VisibleIf;
public VisibleIfAttribute[] VisibleIfs;
/// <summary>
/// The read-only attribute usage flag.
@@ -128,7 +128,7 @@ namespace FlaxEditor.CustomEditors.Editors
CustomEditorAlias = (CustomEditorAliasAttribute)attributes.FirstOrDefault(x => x is CustomEditorAliasAttribute);
Space = (SpaceAttribute)attributes.FirstOrDefault(x => x is SpaceAttribute);
Header = (HeaderAttribute)attributes.FirstOrDefault(x => x is HeaderAttribute);
VisibleIf = (VisibleIfAttribute)attributes.FirstOrDefault(x => x is VisibleIfAttribute);
VisibleIfs = attributes.OfType<VisibleIfAttribute>().ToArray();
IsReadOnly = attributes.FirstOrDefault(x => x is ReadOnlyAttribute) != null;
ExpandGroups = attributes.FirstOrDefault(x => x is ExpandGroupsAttribute) != null;
@@ -210,17 +210,24 @@ namespace FlaxEditor.CustomEditors.Editors
private struct VisibleIfCache
{
public ScriptMemberInfo Target;
public ScriptMemberInfo Source;
public ScriptMemberInfo[] Sources;
public PropertiesListElement PropertiesList;
public GroupElement Group;
public bool Invert;
public bool[] InversionList;
public int LabelIndex;
public bool GetValue(object instance)
{
var value = (bool)Source.GetValue(instance);
if (Invert)
value = !value;
bool value = true;
for (int i = 0; i < Sources.Length; i++)
{
bool currentValue = (bool)Sources[i].GetValue(instance);
if (InversionList[i])
currentValue = !currentValue;
value = value && currentValue;
}
return value;
}
}
@@ -298,40 +305,48 @@ namespace FlaxEditor.CustomEditors.Editors
return items;
}
private static ScriptMemberInfo GetVisibleIfSource(ScriptType type, VisibleIfAttribute visibleIf)
private static ScriptMemberInfo[] GetVisibleIfSources(ScriptType type, VisibleIfAttribute[] visibleIfs)
{
var property = type.GetProperty(visibleIf.MemberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
if (property != ScriptMemberInfo.Null)
ScriptMemberInfo[] members = Array.Empty<ScriptMemberInfo>();
for (int i = 0; i < visibleIfs.Length; i++)
{
if (!property.HasGet)
var property = type.GetProperty(visibleIfs[i].MemberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
if (property != ScriptMemberInfo.Null)
{
Debug.LogError("Invalid VisibleIf rule. Property has missing getter " + visibleIf.MemberName);
return ScriptMemberInfo.Null;
if (!property.HasGet)
{
Debug.LogError("Invalid VisibleIf rule. Property has missing getter " + visibleIfs[i].MemberName);
continue;
}
if (property.ValueType.Type != typeof(bool))
{
Debug.LogError("Invalid VisibleIf rule. Property has to return bool type " + visibleIfs[i].MemberName);
continue;
}
members = members.Append(property).ToArray();
continue;
}
if (property.ValueType.Type != typeof(bool))
var field = type.GetField(visibleIfs[i].MemberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
if (field != ScriptMemberInfo.Null)
{
Debug.LogError("Invalid VisibleIf rule. Property has to return bool type " + visibleIf.MemberName);
return ScriptMemberInfo.Null;
if (field.ValueType.Type != typeof(bool))
{
Debug.LogError("Invalid VisibleIf rule. Field has to be bool type " + visibleIfs[i].MemberName);
continue;
}
members = members.Append(field).ToArray();
continue;
}
return property;
Debug.LogError("Invalid VisibleIf rule. Cannot find member " + visibleIfs[i].MemberName);
}
var field = type.GetField(visibleIf.MemberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
if (field != ScriptMemberInfo.Null)
{
if (field.ValueType.Type != typeof(bool))
{
Debug.LogError("Invalid VisibleIf rule. Field has to be bool type " + visibleIf.MemberName);
return ScriptMemberInfo.Null;
}
return field;
}
Debug.LogError("Invalid VisibleIf rule. Cannot find member " + visibleIf.MemberName);
return ScriptMemberInfo.Null;
return members;
}
private static void GroupPanelCheckIfCanRevert(LayoutElementsContainer layout, ref bool canRevertReference, ref bool canRevertDefault)
@@ -575,7 +590,7 @@ namespace FlaxEditor.CustomEditors.Editors
protected virtual void SpawnProperty(LayoutElementsContainer itemLayout, ValueContainer itemValues, ItemInfo item)
{
int labelIndex = 0;
if ((item.IsReadOnly || item.VisibleIf != null) &&
if ((item.IsReadOnly || item.VisibleIfs.Length > 0) &&
itemLayout.Children.Count > 0 &&
itemLayout.Children[itemLayout.Children.Count - 1] is PropertiesListElement propertiesListElement)
{
@@ -616,7 +631,7 @@ namespace FlaxEditor.CustomEditors.Editors
}
}
}
if (item.VisibleIf != null && itemLayout.Children.Count > 0)
if (item.VisibleIfs.Length > 0 && itemLayout.Children.Count > 0)
{
PropertiesListElement list = null;
GroupElement group = null;
@@ -628,8 +643,8 @@ namespace FlaxEditor.CustomEditors.Editors
return;
// Get source member used to check rule
var sourceMember = GetVisibleIfSource(item.Info.DeclaringType, item.VisibleIf);
if (sourceMember == ScriptType.Null)
var sourceMembers = GetVisibleIfSources(item.Info.DeclaringType, item.VisibleIfs);
if (sourceMembers.Length == 0)
return;
// Resize cache
@@ -645,11 +660,11 @@ namespace FlaxEditor.CustomEditors.Editors
_visibleIfCaches[count] = new VisibleIfCache
{
Target = item.Info,
Source = sourceMember,
Sources = sourceMembers,
PropertiesList = list,
Group = group,
LabelIndex = labelIndex,
Invert = item.VisibleIf.Invert,
InversionList = item.VisibleIfs.Select((x, i) => x.Invert).ToArray(),
};
}
}

View File

@@ -1,8 +1,12 @@
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
using System;
using System.Linq;
using FlaxEditor.CustomEditors.Elements;
using FlaxEditor.GUI;
using FlaxEditor.Scripting;
using FlaxEngine;
using FlaxEngine.Utilities;
namespace FlaxEditor.CustomEditors.Editors
{
@@ -13,6 +17,9 @@ namespace FlaxEditor.CustomEditors.Editors
public sealed class GuidEditor : CustomEditor
{
private TextBoxElement _element;
private AssetPicker _picker;
private bool _isReference;
private bool _isRefreshing;
/// <inheritdoc />
public override DisplayStyle Style => DisplayStyle.Inline;
@@ -20,8 +27,55 @@ namespace FlaxEditor.CustomEditors.Editors
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
_element = layout.TextBox();
_element.TextBox.EditEnd += OnEditEnd;
var attributes = Values.GetAttributes();
var assetReference = (AssetReferenceAttribute)attributes?.FirstOrDefault(x => x is AssetReferenceAttribute);
if (assetReference != null)
{
_picker = layout.Custom<AssetPicker>().CustomControl;
ScriptType assetType = new ScriptType();
float height = 48;
if (assetReference.UseSmallPicker)
height = 32;
if (string.IsNullOrEmpty(assetReference.TypeName))
{
assetType = ScriptType.Void;
}
else if (assetReference.TypeName.Length > 1 && assetReference.TypeName[0] == '.')
{
// Generic file picker
assetType = ScriptType.Null;
_picker.Validator.FileExtension = assetReference.TypeName;
}
else
{
var customType = TypeUtils.GetType(assetReference.TypeName);
if (customType != ScriptType.Null)
assetType = customType;
else if (!Content.Settings.GameSettings.OptionalPlatformSettings.Contains(assetReference.TypeName))
Debug.LogWarning(string.Format("Unknown asset type '{0}' to use for asset picker filter.", assetReference.TypeName));
else
assetType = ScriptType.Void;
}
_picker.Validator.AssetType = assetType;
_picker.Height = height;
_picker.SelectedItemChanged += OnSelectedItemChanged;
_isReference = true;
}
else
{
_element = layout.TextBox();
_element.TextBox.EditEnd += OnEditEnd;
}
}
private void OnSelectedItemChanged()
{
if (_isRefreshing)
return;
SetValue(_picker.Validator.SelectedID);
}
private void OnEditEnd()
@@ -36,17 +90,32 @@ namespace FlaxEditor.CustomEditors.Editors
public override void Refresh()
{
base.Refresh();
_isRefreshing = true;
if (HasDifferentValues)
{
_element.TextBox.Text = string.Empty;
_element.TextBox.WatermarkText = "Different values";
if (_isReference)
{
// Not supported
}
else
{
_element.TextBox.Text = string.Empty;
_element.TextBox.WatermarkText = "Different values";
}
}
else
{
_element.TextBox.Text = ((Guid)Values[0]).ToString("D");
_element.TextBox.WatermarkText = string.Empty;
if (_isReference)
{
_picker.Validator.SelectedID = (Guid)Values[0];
}
else
{
_element.TextBox.Text = ((Guid)Values[0]).ToString("D");
_element.TextBox.WatermarkText = string.Empty;
}
}
_isRefreshing = false;
}
}
}