Add utility UI Control spawn menu inside scene/prefab context-menu

This commit is contained in:
2026-10-06 13:43:10 +02:00
parent d21227e5c1
commit cced40a87d
4 changed files with 49 additions and 24 deletions
+42 -4
View File
@@ -1,6 +1,7 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using FlaxEditor.GUI.ContextMenu;
using FlaxEditor.Scripting;
using FlaxEngine;
using System;
@@ -12,6 +13,22 @@ namespace FlaxEditor
/// <seealso cref="ISceneEditingContext"/>
internal static class SceneEditingTools
{
public static Actor SpawnActorMenu(ContextMenuButton button)
{
var type = (ScriptType)button.Tag;
if (new ScriptType(typeof(FlaxEngine.GUI.Control)).IsAssignableFrom(type))
{
// UI Control
var actor = new UIControl();
actor.Name = type.Name;
actor.Control = (FlaxEngine.GUI.Control)type.CreateInstance();
return actor;
}
// Create actor
return (Actor)FlaxEngine.Object.New(type.TypeName);
}
public static void AddActorContextMenu(ContextMenu contextMenu, Action<ContextMenuButton> spawn, bool isConvert = false)
{
// Go through each actor and add it to the context menu if it has the ActorContextMenu attribute
@@ -33,17 +50,38 @@ namespace FlaxEditor
bool mainCM = true;
for (int i = 0; i < splitPath?.Length; i++)
{
var name = splitPath[i].Trim();
if (i == splitPath.Length - 1)
{
// Hardcoded UI Controls toolbox
if (!isConvert && childCM != null && actorType.Type == typeof(UIControl))
{
var menu = childCM.ContextMenu.GetOrAddChildMenu(name);
menu.ButtonClicked += spawn;
menu.Tag = actorType;
menu.ContextMenu.AutoSort = true;
var b = menu.ContextMenu.AddButton("Empty", spawn);
b.Tag = actorType;
foreach (var controlType in Editor.Instance.CodeEditing.Controls.Get())
{
if (controlType.IsAbstract)
continue;
name = Utilities.Utils.GetPropertyNameUI(controlType.Name);
b = menu.ContextMenu.AddButton(name, spawn);
b.Tag = controlType;
}
continue;
}
if (mainCM)
{
var b = contextMenu.AddButton(splitPath[i].Trim(), spawn);
var b = contextMenu.AddButton(name, spawn);
b.Tag = actorType;
mainCM = false;
}
else if (childCM != null)
{
var b = childCM.ContextMenu.AddButton(splitPath[i].Trim(), spawn);
var b = childCM.ContextMenu.AddButton(name, spawn);
b.Tag = actorType;
}
}
@@ -55,13 +93,13 @@ namespace FlaxEditor
if (mainCM)
{
childCM = contextMenu.GetOrAddChildMenu(splitPath[i].Trim());
childCM = contextMenu.GetOrAddChildMenu(name);
childCM.ContextMenu.AutoSort = true;
mainCM = false;
}
else if (childCM != null)
{
childCM = childCM.ContextMenu.GetOrAddChildMenu(splitPath[i].Trim());
childCM = childCM.ContextMenu.GetOrAddChildMenu(name);
childCM.ContextMenu.AutoSort = true;
}
}
@@ -325,7 +325,10 @@ namespace FlaxEditor.Windows.Assets
// Spawning actors
contextMenu.AddSeparator();
SceneEditingTools.AddActorContextMenu(contextMenu, b => Spawn(((ScriptType)b.Tag).Type));
SceneEditingTools.AddActorContextMenu(contextMenu, b => {
Spawn(SceneEditingTools.SpawnActorMenu(b));
RenameSelection();
});
// Custom options
bool showCustomNodeOptions = Selection.Count == 1;
@@ -417,20 +420,6 @@ namespace FlaxEditor.Windows.Assets
Spawn(actor, parentActor);
}
/// <summary>
/// Spawns the actor of the specified type to the prefab (adds actor to root).
/// </summary>
/// <param name="type">The actor type.</param>
public void Spawn(Type type)
{
// Create actor
Actor actor = (Actor)FlaxEngine.Object.New(type);
// Spawn it
Spawn(actor);
RenameSelection();
}
/// <summary>
/// Spawns the specified actor.
/// </summary>
@@ -120,7 +120,7 @@ namespace FlaxEditor.Windows
// Spawning actors
contextMenu.AddSeparator();
SceneEditingTools.AddActorContextMenu(contextMenu, b => Spawn(((ScriptType)b.Tag).Type));
SceneEditingTools.AddActorContextMenu(contextMenu, b => Spawn(SceneEditingTools.SpawnActorMenu(b)));
// Custom options
bool showCustomNodeOptions = Editor.SceneEditing.Selection.Count == 1;
+2 -4
View File
@@ -198,10 +198,8 @@ namespace FlaxEditor.Windows
PerformLayout();
}
private void Spawn(Type type)
private void Spawn(Actor actor)
{
// Create actor
Actor actor = (Actor)FlaxEngine.Object.New(type);
Actor parentActor = null;
if (Editor.SceneEditing.HasSthSelected && Editor.SceneEditing.Selection[0] is ActorNode actorNode)
{
@@ -220,7 +218,7 @@ namespace FlaxEditor.Windows
actor.Transform = parentActor.Transform;
// Rename actor to identify it easily
actor.Name = Utilities.Utils.IncrementNameNumber(type.Name, x => parentActor.GetChild(x) == null);
actor.Name = Utilities.Utils.IncrementNameNumber(actor.Name, x => parentActor.GetChild(x) == null);
}
// Spawn it