Merge remote-tracking branch 'origin/master' into 1.13

This commit is contained in:
2026-07-24 18:36:04 +02:00
10 changed files with 86 additions and 24 deletions
+2 -2
View File
@@ -643,7 +643,7 @@ namespace FlaxEditor.CustomEditors
text = text.Remove(idx, endIdx - idx);
}
}
else if (ScriptType.FlaxObject.IsAssignableFrom(Values.Type))
else if (Values.Type.IsScriptingObject)
{
// Object reference
text = JsonSerializer.GetStringID(value as FlaxEngine.Object);
@@ -691,7 +691,7 @@ namespace FlaxEditor.CustomEditors
return false;
}
}
else if (ScriptType.FlaxObject.IsAssignableFrom(Values.Type))
else if (Values.Type.IsScriptingObject)
{
// Object reference
if (text.Length != 32)
@@ -707,30 +707,59 @@ namespace FlaxEditor.CustomEditors.Editors
if (!HasDifferentTypes)
{
var value = Values[0];
var type = Values.Type;
if (value == null)
{
// Check if it's an object type that can be created in editor
var type = Values.Type;
if (type != ScriptMemberInfo.Null && type.CanCreateInstance)
if (type != ScriptMemberInfo.Null)
{
layout = layout.Space(20);
const float ButtonSize = 14.0f;
var button = new Button
ScriptType[] types = null;
if (type.IsAbstract || type.IsInterface)
{
Text = "+",
TooltipText = "Create a new instance of the object",
Size = new Float2(ButtonSize, ButtonSize),
AnchorPreset = AnchorPresets.MiddleRight,
Parent = layout.ContainerControl,
Location = new Float2(layout.ContainerControl.Width - ButtonSize - 4, (layout.ContainerControl.Height - ButtonSize) * 0.5f),
};
button.Clicked += () => SetValue(Values.Type.CreateInstance());
// Show picker with all types that implement specific class/interface but are not abstract
types = Editor.Instance.CodeEditing.All.Get().Where(x => !x.IsAbstract && x.CanCreateInstance && type.IsAssignableFrom(x)).ToArray();
}
else if (type.CanCreateInstance)
{
types = [type];
}
if (types != null && types.Length != 0)
{
layout = layout.Space(20);
const float ButtonSize = 14.0f;
var button = new Button
{
Text = "+",
TooltipText = "Create a new instance of the object",
Size = new Float2(ButtonSize, ButtonSize),
AnchorPreset = AnchorPresets.MiddleRight,
Parent = layout.ContainerControl,
Location = new Float2(layout.ContainerControl.Width - ButtonSize - 4, (layout.ContainerControl.Height - ButtonSize) * 0.5f),
};
if (types.Length == 1)
{
// Single type
button.Clicked += () => SetValue(Values.Type.CreateInstance());
}
else
{
// Picker
button.Clicked += () => FlaxEditor.GUI.TypeSearchPopup.Show(button, new Float2(0, button.Height), types, scriptType => { SetValue(scriptType.CreateInstance()); });
}
}
}
layout.Label("<null>");
return;
}
if (!type.IsArray && !type.IsStructure && !type.IsScriptingObject && (type.IsAbstract || type.IsInterface) && value.GetType() != type.Type && layout is GroupElement group)
{
// Add button to unset the value to null (eg. to edit it to different type)
var button = group.AddHeaderButton("Reset value to null", 0, FlaxEngine.GUI.Style.Current.Cross);
button.Clicked += (_, _) => SetValue(null);
}
items = GetItemsForType(TypeUtils.GetObjectType(value));
}
@@ -55,7 +55,7 @@ namespace FlaxEditor.CustomEditors.Elements
const float padding = 2.0f;
var settingsButtonSize = Panel.HeaderHeight;
Panel.HeaderTextMargin = Panel.HeaderTextMargin with { Right = settingsButtonSize + Utilities.Constants.UIMargin };
; return new Image
return new Image
{
TooltipText = tooltipText,
AutoFocus = true,
@@ -1,6 +1,7 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using FlaxEditor.History;
@@ -131,6 +132,18 @@ namespace FlaxEditor.GUI
SortItems();
}
private TypeSearchPopup(IEnumerable<ScriptType> items, Action<ScriptType> selected)
{
_isValid = null;
_selected = selected;
ItemClicked += OnItemClicked;
foreach (var item in items)
AddItem(new TypeItemView(item));
SortItems();
}
private bool IsHideAttributes(object[] attributes)
{
return attributes.FirstOrDefault(IsHideAttribute) == null;
@@ -162,6 +175,21 @@ namespace FlaxEditor.GUI
return popup;
}
/// <summary>
/// Shows the popup.
/// </summary>
/// <param name="showTarget">The show target.</param>
/// <param name="showTargetLocation">The show target location.</param>
/// <param name="items">Collection of types to display available to pick.</param>
/// <param name="selected">Event called on asset item pick.</param>
/// <returns>The dialog.</returns>
public static TypeSearchPopup Show(Control showTarget, Float2 showTargetLocation, IEnumerable<ScriptType> items, Action<ScriptType> selected)
{
var popup = new TypeSearchPopup(items, selected);
popup.Show(showTarget, showTargetLocation);
return popup;
}
/// <inheritdoc />
public override void OnDestroy()
{
+5
View File
@@ -849,6 +849,11 @@ namespace FlaxEditor.Scripting
/// </summary>
public bool IsVoid => _managed == typeof(void);
/// <summary>
/// Gets a value indicating whether this type is <see cref="FlaxEngine.Object"/> (eg. script or actor).
/// </summary>
public bool IsScriptingObject => FlaxObject.IsAssignableFrom(this);
/// <summary>
/// Gets a value indicating whether the type is static.
/// </summary>
+1 -1
View File
@@ -1544,7 +1544,7 @@ namespace FlaxEditor.Surface.Elements
object obj;
var type = CurrentType;
if (ScriptType.FlaxObject.IsAssignableFrom(type))
if (type.IsScriptingObject)
{
// Object reference
if (text.Length != 32)
+1 -1
View File
@@ -212,7 +212,7 @@ namespace FlaxEditor.Surface
color = Colors.Enum;
else if (type.IsValueType)
color = Colors.Structures;
else if (ScriptType.FlaxObject.IsAssignableFrom(type) || type.IsInterface)
else if (type.IsScriptingObject || type.IsInterface)
color = Colors.Object;
else if (hint == ConnectionsHint.Vector)
color = Colors.Vector;
@@ -72,7 +72,7 @@ namespace FlaxEditor.Surface
// Implicit casting is supported for object reference to test whenever it is valid
var toType = to.Type;
if (supportsImplicitCastFromObjectToBoolean && toType == typeof(bool) && ScriptType.FlaxObject.IsAssignableFrom(from))
if (supportsImplicitCastFromObjectToBoolean && toType == typeof(bool) && from.IsScriptingObject)
{
return true;
}
+3 -3
View File
@@ -65,7 +65,7 @@ namespace FlaxEditor.Utilities
&& memberValue != null
&& !refStack.Contains(memberValue))
{
if (memberType.IsArray && !ScriptType.FlaxObject.IsAssignableFrom(memberType.GetElementType()))
if (memberType.IsArray && !memberType.GetElementType().IsScriptingObject)
{
// Array
var array = (Array)memberValue;
@@ -79,7 +79,7 @@ namespace FlaxEditor.Utilities
}
refStack.Pop();
}
else if (typeof(IList).IsAssignableFrom(memberType.Type) && !ScriptType.FlaxObject.IsAssignableFrom(memberType.GetElementType()))
else if (typeof(IList).IsAssignableFrom(memberType.Type) && !memberType.GetElementType().IsScriptingObject)
{
// List
var list = (IList)memberValue;
@@ -106,7 +106,7 @@ namespace FlaxEditor.Utilities
GetEntries(new MemberInfoPath.Entry(member.Member, key), membersPath, result, values, refStack, valueType, value);
}
}
else if (memberType.IsClass && !ScriptType.FlaxObject.IsAssignableFrom(memberType))
else if (memberType.IsClass && !memberType.IsScriptingObject)
{
// Object
refStack.Push(memberValue);
+1 -1
View File
@@ -81,7 +81,7 @@ namespace FlaxEngine
!type.IsAbstract &&
!type.IsArray &&
!type.IsVoid &&
(type.IsStructure || ScriptType.FlaxObject.IsAssignableFrom(type)) &&
(type.IsStructure || type.IsScriptingObject) &&
type.IsPublic &&
type.CanCreateInstance;
}