diff --git a/Source/Editor/GUI/Drag/DragControlType.cs b/Source/Editor/GUI/Drag/DragControlType.cs
new file mode 100644
index 000000000..d1286053c
--- /dev/null
+++ b/Source/Editor/GUI/Drag/DragControlType.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Collections.Generic;
+using FlaxEditor.SceneGraph;
+using FlaxEditor.Scripting;
+using FlaxEngine;
+using FlaxEngine.GUI;
+using FlaxEngine.Utilities;
+
+namespace FlaxEditor.GUI.Drag;
+
+///
+/// Control type drag handler.
+///
+public sealed class DragControlType : DragActorType
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The validation function
+ public DragControlType(Func validateFunction)
+ : base(validateFunction)
+ {
+ }
+}
+
+///
+/// Helper class for handling control type drag and drop (for spawning).
+///
+///
+///
+public class DragControlType : DragHelper where U : DragEventArgs
+{
+ ///
+ /// The default prefix for drag data used for actor type drag and drop.
+ ///
+ public const string DragPrefix = "CTYPE!?";
+
+ ///
+ /// Creates a new DragHelper
+ ///
+ /// The validation function
+ public DragControlType(Func validateFunction)
+ : base(validateFunction)
+ {
+ }
+
+ ///
+ public override DragData ToDragData(ScriptType item) => GetDragData(item);
+
+ ///
+ public override DragData ToDragData(IEnumerable items)
+ {
+ throw new NotImplementedException();
+ }
+
+ ///
+ /// Gets the drag data.
+ ///
+ /// The control type.
+ /// The data
+ public static DragData GetDragData(Type item)
+ {
+ if (item == null)
+ throw new ArgumentNullException();
+ return new DragDataText(DragPrefix + item.FullName);
+ }
+
+ ///
+ /// Gets the drag data.
+ ///
+ /// The control type.
+ /// The data
+ public static DragData GetDragData(ScriptType item)
+ {
+ if (item == ScriptType.Null)
+ throw new ArgumentNullException();
+ return new DragDataText(DragPrefix + item.TypeName);
+ }
+
+ ///
+ /// Tries to parse the drag data to extract collection.
+ ///
+ /// The data.
+ /// Gathered objects or empty array if cannot get any valid.
+ public override IEnumerable FromDragData(DragData data)
+ {
+ if (data is DragDataText dataText)
+ {
+ if (dataText.Text.StartsWith(DragPrefix))
+ {
+ // Remove prefix and parse spitted names
+ var types = dataText.Text.Remove(0, DragPrefix.Length).Split('\n');
+ var results = new List(types.Length);
+ for (int i = 0; i < types.Length; i++)
+ {
+ // Find type
+ var obj = TypeUtils.GetType(types[i]);
+ if (obj)
+ results.Add(obj);
+ }
+ return results;
+ }
+ }
+ return Utils.GetEmptyArray();
+ }
+}
+
diff --git a/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs b/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs
index 88f6b3ba0..efbc89a72 100644
--- a/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs
+++ b/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs
@@ -29,6 +29,7 @@ namespace FlaxEditor.SceneGraph.GUI
private DragScripts _dragScripts;
private DragAssets _dragAssets;
private DragActorType _dragActorType;
+ private DragControlType _dragControlType;
private DragScriptItems _dragScriptItems;
private DragHandlers _dragHandlers;
private List _highlights;
@@ -439,6 +440,17 @@ namespace FlaxEditor.SceneGraph.GUI
}
if (_dragActorType.OnDragEnter(data))
return _dragActorType.Effect;
+
+ // Check if drag control type
+ if (_dragControlType == null)
+ {
+ _dragControlType = new DragControlType(ValidateDragControlType);
+ _dragHandlers.Add(_dragControlType);
+ }
+ if (_dragControlType.OnDragEnter(data))
+ return _dragControlType.Effect;
+
+ // Check if drag script item
if (_dragScriptItems == null)
{
_dragScriptItems = new DragScriptItems(ValidateDragScriptItem);
@@ -572,7 +584,7 @@ namespace FlaxEditor.SceneGraph.GUI
Editor.LogWarning("Failed to spawn actor of type " + item.TypeName);
continue;
}
- actor.StaticFlags = Actor.StaticFlags;
+ actor.StaticFlags = newParent.StaticFlags;
actor.Name = item.Name;
actor.Transform = Actor.Transform;
ActorNode.Root.Spawn(actor, newParent);
@@ -580,6 +592,29 @@ namespace FlaxEditor.SceneGraph.GUI
}
result = DragDropEffect.Move;
}
+ // Drag control type
+ else if (_dragControlType != null && _dragControlType.HasValidDrag)
+ {
+ for (int i = 0; i < _dragControlType.Objects.Count; i++)
+ {
+ var item = _dragControlType.Objects[i];
+ var control = item.CreateInstance() as Control;
+ if (control == null)
+ {
+ Editor.LogWarning("Failed to spawn UIControl with control type " + item.TypeName);
+ continue;
+ }
+ var uiControl = new UIControl
+ {
+ Control = control,
+ StaticFlags = newParent.StaticFlags,
+ Name = item.Name,
+ };
+ ActorNode.Root.Spawn(uiControl, newParent);
+ uiControl.OrderInParent = newOrder;
+ }
+ result = DragDropEffect.Move;
+ }
// Drag script item
else if (_dragScriptItems != null && _dragScriptItems.HasValidDrag)
{
@@ -657,7 +692,12 @@ namespace FlaxEditor.SceneGraph.GUI
private static bool ValidateDragActorType(ScriptType actorType)
{
- return true;
+ return Editor.Instance.CodeEditing.Actors.Get().Contains(actorType);
+ }
+
+ private static bool ValidateDragControlType(ScriptType controlType)
+ {
+ return Editor.Instance.CodeEditing.Controls.Get().Contains(controlType);
}
private static bool ValidateDragScriptItem(ScriptItem script)
@@ -705,6 +745,7 @@ namespace FlaxEditor.SceneGraph.GUI
_dragScripts = null;
_dragAssets = null;
_dragActorType = null;
+ _dragControlType = null;
_dragScriptItems = null;
_dragHandlers?.Clear();
_dragHandlers = null;
diff --git a/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs b/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs
index f58fef203..d849c9d79 100644
--- a/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs
+++ b/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs
@@ -65,6 +65,7 @@ namespace FlaxEditor.Windows.Assets
private PrefabWindow _window;
private DragAssets _dragAssets;
private DragActorType _dragActorType;
+ private DragControlType _dragControlType;
private DragScriptItems _dragScriptItems;
private DragHandlers _dragHandlers;
@@ -83,7 +84,12 @@ namespace FlaxEditor.Windows.Assets
private static bool ValidateDragActorType(ScriptType actorType)
{
- return true;
+ return Editor.Instance.CodeEditing.Actors.Get().Contains(actorType);
+ }
+
+ private static bool ValidateDragControlType(ScriptType controlType)
+ {
+ return Editor.Instance.CodeEditing.Controls.Get().Contains(controlType);
}
private static bool ValidateDragScriptItem(ScriptItem script)
@@ -113,6 +119,13 @@ namespace FlaxEditor.Windows.Assets
}
if (_dragActorType.OnDragEnter(data))
return _dragActorType.Effect;
+ if (_dragControlType == null)
+ {
+ _dragControlType = new DragControlType(ValidateDragControlType);
+ _dragHandlers.Add(_dragControlType);
+ }
+ if (_dragControlType.OnDragEnter(data))
+ return _dragControlType.Effect;
if (_dragScriptItems == null)
{
_dragScriptItems = new DragScriptItems(ValidateDragScriptItem);
@@ -176,6 +189,27 @@ namespace FlaxEditor.Windows.Assets
}
result = DragDropEffect.Move;
}
+ // Drag control type
+ else if (_dragControlType != null && _dragControlType.HasValidDrag)
+ {
+ for (int i = 0; i < _dragControlType.Objects.Count; i++)
+ {
+ var item = _dragControlType.Objects[i];
+ var control = item.CreateInstance() as Control;
+ if (control == null)
+ {
+ Editor.LogWarning("Failed to spawn UIControl with control type " + item.TypeName);
+ continue;
+ }
+ var uiControl = new UIControl
+ {
+ Control = control,
+ Name = item.Name,
+ };
+ _window.Spawn(uiControl);
+ }
+ result = DragDropEffect.Move;
+ }
// Drag script item
else if (_dragScriptItems != null && _dragScriptItems.HasValidDrag)
{
@@ -207,6 +241,7 @@ namespace FlaxEditor.Windows.Assets
_window = null;
_dragAssets = null;
_dragActorType = null;
+ _dragControlType = null;
_dragScriptItems = null;
_dragHandlers?.Clear();
_dragHandlers = null;
diff --git a/Source/Editor/Windows/SceneTreeWindow.cs b/Source/Editor/Windows/SceneTreeWindow.cs
index a7e4e0e44..fe68896a8 100644
--- a/Source/Editor/Windows/SceneTreeWindow.cs
+++ b/Source/Editor/Windows/SceneTreeWindow.cs
@@ -30,6 +30,7 @@ namespace FlaxEditor.Windows
private DragAssets _dragAssets;
private DragActorType _dragActorType;
+ private DragControlType _dragControlType;
private DragScriptItems _dragScriptItems;
private DragHandlers _dragHandlers;
@@ -275,7 +276,12 @@ namespace FlaxEditor.Windows
private static bool ValidateDragActorType(ScriptType actorType)
{
- return true;
+ return Editor.Instance.CodeEditing.Actors.Get().Contains(actorType);
+ }
+
+ private static bool ValidateDragControlType(ScriptType controlType)
+ {
+ return Editor.Instance.CodeEditing.Controls.Get().Contains(controlType);
}
private static bool ValidateDragScriptItem(ScriptItem script)
@@ -390,6 +396,13 @@ namespace FlaxEditor.Windows
}
if (_dragActorType.OnDragEnter(data) && result == DragDropEffect.None)
return _dragActorType.Effect;
+ if (_dragControlType == null)
+ {
+ _dragControlType = new DragControlType(ValidateDragControlType);
+ _dragHandlers.Add(_dragControlType);
+ }
+ if (_dragControlType.OnDragEnter(data) && result == DragDropEffect.None)
+ return _dragControlType.Effect;
if (_dragScriptItems == null)
{
_dragScriptItems = new DragScriptItems(ValidateDragScriptItem);
@@ -462,6 +475,28 @@ namespace FlaxEditor.Windows
}
result = DragDropEffect.Move;
}
+ // Drag control type
+ else if (_dragControlType != null && _dragControlType.HasValidDrag)
+ {
+ for (int i = 0; i < _dragControlType.Objects.Count; i++)
+ {
+ var item = _dragControlType.Objects[i];
+ var control = item.CreateInstance() as Control;
+ if (control == null)
+ {
+ Editor.LogWarning("Failed to spawn UIControl with control type " + item.TypeName);
+ continue;
+ }
+ var uiControl = new UIControl
+ {
+ Control = control,
+ Name = item.Name,
+ };
+ Level.SpawnActor(uiControl);
+ Editor.Scene.MarkSceneEdited(uiControl.Scene);
+ }
+ result = DragDropEffect.Move;
+ }
// Drag script item
else if (_dragScriptItems != null && _dragScriptItems.HasValidDrag)
{
@@ -495,6 +530,7 @@ namespace FlaxEditor.Windows
{
_dragAssets = null;
_dragActorType = null;
+ _dragControlType = null;
_dragScriptItems = null;
_dragHandlers?.Clear();
_dragHandlers = null;
diff --git a/Source/Editor/Windows/ToolboxWindow.cs b/Source/Editor/Windows/ToolboxWindow.cs
index ab9c218c5..7c15d29c9 100644
--- a/Source/Editor/Windows/ToolboxWindow.cs
+++ b/Source/Editor/Windows/ToolboxWindow.cs
@@ -191,6 +191,52 @@ namespace FlaxEditor.Windows
CreateGroupWithList(_actorGroups, "GUI");
CreateGroupWithList(_actorGroups, "Other");
+ // Add control types to tabs
+ foreach (var controlType in Editor.Instance.CodeEditing.Controls.Get())
+ {
+ if (controlType.IsAbstract)
+ continue;
+ _groupSearch.AddChild(CreateControlItem(Utilities.Utils.GetPropertyNameUI(controlType.Name), controlType));
+ ActorToolboxAttribute attribute = null;
+ foreach (var e in controlType.GetAttributes(false))
+ {
+ if (e is ActorToolboxAttribute actorToolboxAttribute)
+ {
+ attribute = actorToolboxAttribute;
+ break;
+ }
+ }
+ if (attribute == null)
+ continue;
+ var groupName = attribute.Group.Trim();
+
+ // Check if tab already exists and add it to the tab
+ var actorTabExists = false;
+ foreach (var child in _actorGroups.Children)
+ {
+ if (child is Tab tab)
+ {
+ if (string.Equals(tab.Text, groupName, StringComparison.OrdinalIgnoreCase))
+ {
+ var tree = tab.GetChild().GetChild();
+ if (tree != null)
+ {
+ tree.AddChild(string.IsNullOrEmpty(attribute.Name) ? CreateControlItem(Utilities.Utils.GetPropertyNameUI(controlType.Name), controlType) : CreateControlItem(attribute.Name, controlType));
+ tree.SortChildren();
+ }
+ actorTabExists = true;
+ break;
+ }
+ }
+ }
+ if (actorTabExists)
+ continue;
+
+ var group = CreateGroupWithList(_actorGroups, groupName);
+ group.AddChild(string.IsNullOrEmpty(attribute.Name) ? CreateControlItem(Utilities.Utils.GetPropertyNameUI(controlType.Name), controlType) : CreateControlItem(attribute.Name, controlType));
+ group.SortChildren();
+ }
+
// Add other actor types to respective tab based on attribute
foreach (var actorType in Editor.CodeEditing.Actors.Get())
{
@@ -304,6 +350,11 @@ namespace FlaxEditor.Windows
return new ScriptTypeItem(name, type, GUI.Drag.DragActorType.GetDragData(type));
}
+ private Item CreateControlItem(string name, ScriptType type)
+ {
+ return new ScriptTypeItem(name, type, GUI.Drag.DragControlType.GetDragData(type));
+ }
+
private ContainerControl CreateGroupWithList(Tabs parentTabs, string title, float topOffset = 0)
{
var tab = parentTabs.AddTab(new Tab(title));
diff --git a/Source/Engine/UI/GUI/CanvasScaler.cs b/Source/Engine/UI/GUI/CanvasScaler.cs
index 612de3f59..abcd97a38 100644
--- a/Source/Engine/UI/GUI/CanvasScaler.cs
+++ b/Source/Engine/UI/GUI/CanvasScaler.cs
@@ -7,6 +7,7 @@ namespace FlaxEngine.GUI
///
/// UI canvas scaling component for user interface that targets multiple different game resolutions (eg. mobile screens).
///
+ [ActorToolbox("GUI")]
public class CanvasScaler : ContainerControl
{
///
diff --git a/Source/Engine/UI/GUI/Common/Border.cs b/Source/Engine/UI/GUI/Common/Border.cs
index 58c281a3d..8c9433a98 100644
--- a/Source/Engine/UI/GUI/Common/Border.cs
+++ b/Source/Engine/UI/GUI/Common/Border.cs
@@ -5,6 +5,7 @@ namespace FlaxEngine.GUI
///
/// Border control that draws the border around the control edges (inner and outer sides).
///
+ [ActorToolbox("GUI")]
public class Border : ContainerControl
{
///
diff --git a/Source/Engine/UI/GUI/Common/Button.cs b/Source/Engine/UI/GUI/Common/Button.cs
index ff4a5fe79..ff0b776f9 100644
--- a/Source/Engine/UI/GUI/Common/Button.cs
+++ b/Source/Engine/UI/GUI/Common/Button.cs
@@ -7,6 +7,7 @@ namespace FlaxEngine.GUI
///
/// Button control
///
+ [ActorToolbox("GUI")]
public class Button : ContainerControl
{
///
diff --git a/Source/Engine/UI/GUI/Common/CheckBox.cs b/Source/Engine/UI/GUI/Common/CheckBox.cs
index d5ab3483c..de880c039 100644
--- a/Source/Engine/UI/GUI/Common/CheckBox.cs
+++ b/Source/Engine/UI/GUI/Common/CheckBox.cs
@@ -29,6 +29,7 @@ namespace FlaxEngine.GUI
/// Check box control.
///
///
+ [ActorToolbox("GUI")]
public class CheckBox : Control
{
///
diff --git a/Source/Engine/UI/GUI/Common/Dropdown.cs b/Source/Engine/UI/GUI/Common/Dropdown.cs
index 60e8e801b..1dbac95ab 100644
--- a/Source/Engine/UI/GUI/Common/Dropdown.cs
+++ b/Source/Engine/UI/GUI/Common/Dropdown.cs
@@ -9,6 +9,7 @@ namespace FlaxEngine.GUI
/// Dropdown menu control allows to choose one item from the provided collection of options.
///
///
+ [ActorToolbox("GUI")]
public class Dropdown : ContainerControl
{
///
diff --git a/Source/Engine/UI/GUI/Common/Image.cs b/Source/Engine/UI/GUI/Common/Image.cs
index 0a0129db0..897c82b3f 100644
--- a/Source/Engine/UI/GUI/Common/Image.cs
+++ b/Source/Engine/UI/GUI/Common/Image.cs
@@ -8,6 +8,7 @@ namespace FlaxEngine.GUI
/// The basic GUI image control. Shows texture, sprite or render target.
///
///
+ [ActorToolbox("GUI")]
public class Image : ContainerControl
{
///
diff --git a/Source/Engine/UI/GUI/Common/Label.cs b/Source/Engine/UI/GUI/Common/Label.cs
index 46cb7415e..61282e7a5 100644
--- a/Source/Engine/UI/GUI/Common/Label.cs
+++ b/Source/Engine/UI/GUI/Common/Label.cs
@@ -8,6 +8,7 @@ namespace FlaxEngine.GUI
/// The basic GUI label control.
///
///
+ [ActorToolbox("GUI")]
public class Label : ContainerControl
{
///
diff --git a/Source/Engine/UI/GUI/Common/ProgressBar.cs b/Source/Engine/UI/GUI/Common/ProgressBar.cs
index 6a17535b0..ff048600e 100644
--- a/Source/Engine/UI/GUI/Common/ProgressBar.cs
+++ b/Source/Engine/UI/GUI/Common/ProgressBar.cs
@@ -8,6 +8,7 @@ namespace FlaxEngine.GUI
/// Progress bar control shows visual progress of the action or set of actions.
///
///
+ [ActorToolbox("GUI")]
public class ProgressBar : ContainerControl
{
///
diff --git a/Source/Engine/UI/GUI/Common/RenderToTextureControl.cs b/Source/Engine/UI/GUI/Common/RenderToTextureControl.cs
index 499668d93..664a20df9 100644
--- a/Source/Engine/UI/GUI/Common/RenderToTextureControl.cs
+++ b/Source/Engine/UI/GUI/Common/RenderToTextureControl.cs
@@ -5,6 +5,7 @@ namespace FlaxEngine.GUI
///
/// UI container control that can render children to texture and display pre-cached texture instead of drawing children every frame. It can be also used to render part of UI to texture and use it in material or shader.
///
+ [ActorToolbox("GUI")]
public class RenderToTextureControl : ContainerControl
{
private bool _invalid, _redrawRegistered, _isDuringTextureDraw;
diff --git a/Source/Engine/UI/GUI/Common/RichTextBox.cs b/Source/Engine/UI/GUI/Common/RichTextBox.cs
index 77382a5d7..c4a69b08f 100644
--- a/Source/Engine/UI/GUI/Common/RichTextBox.cs
+++ b/Source/Engine/UI/GUI/Common/RichTextBox.cs
@@ -7,6 +7,7 @@ namespace FlaxEngine.GUI
///
/// Rich text box control which can gather text input from the user and present text in highly formatted and stylized way.
///
+ [ActorToolbox("GUI")]
public partial class RichTextBox : RichTextBoxBase
{
private TextBlockStyle _textStyle;
diff --git a/Source/Engine/UI/GUI/Common/Slider.cs b/Source/Engine/UI/GUI/Common/Slider.cs
index a62cbe8ee..39023ee1f 100644
--- a/Source/Engine/UI/GUI/Common/Slider.cs
+++ b/Source/Engine/UI/GUI/Common/Slider.cs
@@ -7,6 +7,7 @@ namespace FlaxEngine.GUI;
///
/// The slider control.
///
+[ActorToolbox("GUI")]
public class Slider : ContainerControl
{
///
diff --git a/Source/Engine/UI/GUI/Common/Spacer.cs b/Source/Engine/UI/GUI/Common/Spacer.cs
index e87cfbabc..005620d7d 100644
--- a/Source/Engine/UI/GUI/Common/Spacer.cs
+++ b/Source/Engine/UI/GUI/Common/Spacer.cs
@@ -6,6 +6,7 @@ namespace FlaxEngine.GUI
/// Helper control used to insert blank space into the layout.
///
///
+ [ActorToolbox("GUI")]
public sealed class Spacer : ContainerControl
{
///
diff --git a/Source/Engine/UI/GUI/Common/TextBox.cs b/Source/Engine/UI/GUI/Common/TextBox.cs
index 70ef77d68..3d0581c4e 100644
--- a/Source/Engine/UI/GUI/Common/TextBox.cs
+++ b/Source/Engine/UI/GUI/Common/TextBox.cs
@@ -5,6 +5,7 @@ namespace FlaxEngine.GUI
///
/// Text box control which can gather text input from the user.
///
+ [ActorToolbox("GUI")]
public class TextBox : TextBoxBase
{
private TextLayoutOptions _layout;
diff --git a/Source/Engine/UI/GUI/Panels/AlphaPanel.cs b/Source/Engine/UI/GUI/Panels/AlphaPanel.cs
index a67d47fac..dd421571a 100644
--- a/Source/Engine/UI/GUI/Panels/AlphaPanel.cs
+++ b/Source/Engine/UI/GUI/Panels/AlphaPanel.cs
@@ -5,6 +5,7 @@ namespace FlaxEngine.GUI
///
/// Changes alpha of all its children
///
+ [ActorToolbox("GUI")]
public class AlphaPanel : ContainerControl
{
///
diff --git a/Source/Engine/UI/GUI/Panels/BlurPanel.cs b/Source/Engine/UI/GUI/Panels/BlurPanel.cs
index 44a9e3b4d..963dadd8e 100644
--- a/Source/Engine/UI/GUI/Panels/BlurPanel.cs
+++ b/Source/Engine/UI/GUI/Panels/BlurPanel.cs
@@ -6,6 +6,7 @@ namespace FlaxEngine.GUI
/// The blur panel that applied the Gaussian-blur to all content beneath the control.
///
///
+ [ActorToolbox("GUI")]
public class BlurPanel : ContainerControl
{
///
diff --git a/Source/Engine/UI/GUI/Panels/DropPanel.cs b/Source/Engine/UI/GUI/Panels/DropPanel.cs
index e0785a99d..e053edd9c 100644
--- a/Source/Engine/UI/GUI/Panels/DropPanel.cs
+++ b/Source/Engine/UI/GUI/Panels/DropPanel.cs
@@ -8,6 +8,7 @@ namespace FlaxEngine.GUI
/// Drop Panel arranges control vertically and provides feature to collapse contents.
///
///
+ [ActorToolbox("GUI")]
public class DropPanel : ContainerControl
{
///
diff --git a/Source/Engine/UI/GUI/Panels/GridPanel.cs b/Source/Engine/UI/GUI/Panels/GridPanel.cs
index 629343f44..2b1a0a123 100644
--- a/Source/Engine/UI/GUI/Panels/GridPanel.cs
+++ b/Source/Engine/UI/GUI/Panels/GridPanel.cs
@@ -8,6 +8,7 @@ namespace FlaxEngine.GUI
/// A panel that divides up available space between all of its children.
///
///
+ [ActorToolbox("GUI")]
public class GridPanel : ContainerControl
{
private Margin _slotPadding;
diff --git a/Source/Engine/UI/GUI/Panels/HorizontalPanel.cs b/Source/Engine/UI/GUI/Panels/HorizontalPanel.cs
index 29bb498dd..6d3256a00 100644
--- a/Source/Engine/UI/GUI/Panels/HorizontalPanel.cs
+++ b/Source/Engine/UI/GUI/Panels/HorizontalPanel.cs
@@ -6,6 +6,7 @@ namespace FlaxEngine.GUI
/// This panel arranges child controls horizontally.
///
///
+ [ActorToolbox("GUI")]
public class HorizontalPanel : PanelWithMargins
{
///
diff --git a/Source/Engine/UI/GUI/Panels/Panel.cs b/Source/Engine/UI/GUI/Panels/Panel.cs
index 8435854f5..61a2d2b8c 100644
--- a/Source/Engine/UI/GUI/Panels/Panel.cs
+++ b/Source/Engine/UI/GUI/Panels/Panel.cs
@@ -8,6 +8,7 @@ namespace FlaxEngine.GUI
/// Panel UI control.
///
///
+ [ActorToolbox("GUI")]
public class Panel : ScrollableControl
{
private bool _layoutChanged;
diff --git a/Source/Engine/UI/GUI/Panels/TilesPanel.cs b/Source/Engine/UI/GUI/Panels/TilesPanel.cs
index 13e40d8bf..8b2148bce 100644
--- a/Source/Engine/UI/GUI/Panels/TilesPanel.cs
+++ b/Source/Engine/UI/GUI/Panels/TilesPanel.cs
@@ -8,6 +8,7 @@ namespace FlaxEngine.GUI
/// Panel that arranges child controls like tiles.
///
///
+ [ActorToolbox("GUI")]
public class TilesPanel : ContainerControl
{
private Margin _tileMargin;
diff --git a/Source/Engine/UI/GUI/Panels/UniformGridPanel.cs b/Source/Engine/UI/GUI/Panels/UniformGridPanel.cs
index ed6ed1d8a..6c112d9d5 100644
--- a/Source/Engine/UI/GUI/Panels/UniformGridPanel.cs
+++ b/Source/Engine/UI/GUI/Panels/UniformGridPanel.cs
@@ -6,6 +6,7 @@ namespace FlaxEngine.GUI
/// A panel that evenly divides up available space between all of its children.
///
///
+ [ActorToolbox("GUI")]
public class UniformGridPanel : ContainerControl
{
private Margin _slotPadding;
diff --git a/Source/Engine/UI/GUI/Panels/VerticalPanel.cs b/Source/Engine/UI/GUI/Panels/VerticalPanel.cs
index 39bd6a294..b2fcdeae9 100644
--- a/Source/Engine/UI/GUI/Panels/VerticalPanel.cs
+++ b/Source/Engine/UI/GUI/Panels/VerticalPanel.cs
@@ -6,6 +6,7 @@ namespace FlaxEngine.GUI
/// This panel arranges child controls vertically.
///
///
+ [ActorToolbox("GUI")]
public class VerticalPanel : PanelWithMargins
{
///
diff --git a/Source/Engine/UI/SpriteRender.h b/Source/Engine/UI/SpriteRender.h
index dbec117e4..d9eb769c2 100644
--- a/Source/Engine/UI/SpriteRender.h
+++ b/Source/Engine/UI/SpriteRender.h
@@ -10,7 +10,7 @@
///
/// Sprite rendering object.
///
-API_CLASS(Attributes="ActorContextMenu(\"New/UI/Sprite Render\"), ActorToolbox(\"GUI\")")
+API_CLASS(Attributes="ActorContextMenu(\"New/UI/Sprite Render\"), ActorToolbox(\"Visuals\")")
class FLAXENGINE_API SpriteRender : public Actor
{
DECLARE_SCENE_OBJECT(SpriteRender);
diff --git a/Source/Engine/UI/TextRender.h b/Source/Engine/UI/TextRender.h
index a99a53318..cc89fbee1 100644
--- a/Source/Engine/UI/TextRender.h
+++ b/Source/Engine/UI/TextRender.h
@@ -18,7 +18,7 @@
///
/// Text rendering object.
///
-API_CLASS(Attributes="ActorContextMenu(\"New/UI/Text Render\"), ActorToolbox(\"GUI\")")
+API_CLASS(Attributes="ActorContextMenu(\"New/UI/Text Render\"), ActorToolbox(\"Visuals\")")
class FLAXENGINE_API TextRender : public Actor
{
DECLARE_SCENE_OBJECT(TextRender);
diff --git a/Source/Engine/UI/UIControl.h b/Source/Engine/UI/UIControl.h
index e76aca65a..7cdbbe7ac 100644
--- a/Source/Engine/UI/UIControl.h
+++ b/Source/Engine/UI/UIControl.h
@@ -8,7 +8,7 @@
///
/// Contains a single GUI control (on C# side).
///
-API_CLASS(Sealed, Attributes="ActorContextMenu(\"New/UI/UI Control\"), ActorToolbox(\"GUI\")")
+API_CLASS(Sealed, Attributes="ActorContextMenu(\"New/UI/UI Control\"), ActorToolbox(\"GUI\", \"Empty UIControl\")")
class FLAXENGINE_API UIControl : public Actor
{
DECLARE_SCENE_OBJECT(UIControl);