diff --git a/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs b/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs
index ffe4ce585..8a6ae54a9 100644
--- a/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs
+++ b/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs
@@ -68,19 +68,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
var cm = new ItemsListContextMenu(180);
for (int i = 0; i < scripts.Count; i++)
{
- var scriptType = scripts[i];
- var item = new ItemsListContextMenu.Item(scriptType.Name, scriptType)
- {
- TooltipText = scriptType.TypeName,
- };
- var attributes = scriptType.GetAttributes(false);
- var tooltipAttribute = (TooltipAttribute)attributes.FirstOrDefault(x => x is TooltipAttribute);
- if (tooltipAttribute != null)
- {
- item.TooltipText += '\n';
- item.TooltipText += tooltipAttribute.Text;
- }
- cm.AddItem(item);
+ cm.AddItem(new TypeSearchPopup.TypeItemView(scripts[i]));
}
cm.ItemClicked += item => AddScript((ScriptType)item.Tag);
cm.SortChildren();
diff --git a/Source/Editor/CustomEditors/Dedicated/UIControlEditor.cs b/Source/Editor/CustomEditors/Dedicated/UIControlEditor.cs
index b860d9826..d7a6f2617 100644
--- a/Source/Editor/CustomEditors/Dedicated/UIControlEditor.cs
+++ b/Source/Editor/CustomEditors/Dedicated/UIControlEditor.cs
@@ -639,21 +639,8 @@ namespace FlaxEditor.CustomEditors.Dedicated
var cm = new ItemsListContextMenu(180);
for (int i = 0; i < controlTypes.Count; i++)
{
- var controlType = controlTypes[i];
- var item = new ItemsListContextMenu.Item(controlType.Name, controlType)
- {
- TooltipText = controlType.TypeName,
- };
- var attributes = controlType.GetAttributes(false);
- var tooltipAttribute = (TooltipAttribute)attributes.FirstOrDefault(x => x is TooltipAttribute);
- if (tooltipAttribute != null)
- {
- item.TooltipText += '\n';
- item.TooltipText += tooltipAttribute.Text;
- }
- cm.AddItem(item);
+ cm.AddItem(new TypeSearchPopup.TypeItemView(controlTypes[i]));
}
-
cm.ItemClicked += controlType => SetType((ScriptType)controlType.Tag);
cm.SortChildren();
cm.Show(button.Parent, button.BottomLeft);
diff --git a/Source/Editor/GUI/ClickableLabel.cs b/Source/Editor/GUI/ClickableLabel.cs
index f8940e714..325d8822a 100644
--- a/Source/Editor/GUI/ClickableLabel.cs
+++ b/Source/Editor/GUI/ClickableLabel.cs
@@ -10,6 +10,7 @@ namespace FlaxEditor.GUI
/// The label that contains events for mouse interaction.
///
///
+ [HideInEditor]
public class ClickableLabel : Label
{
private bool _leftClick;
diff --git a/Source/Editor/GUI/ItemsListContextMenu.cs b/Source/Editor/GUI/ItemsListContextMenu.cs
index 8c4dd723d..4abe39f0b 100644
--- a/Source/Editor/GUI/ItemsListContextMenu.cs
+++ b/Source/Editor/GUI/ItemsListContextMenu.cs
@@ -32,9 +32,14 @@ namespace FlaxEditor.GUI
protected List _highlights;
///
- /// Gets or sets the name.
+ /// The item name.
///
- public string Name { get; set; }
+ public string Name;
+
+ ///
+ /// The item category name (optional).
+ ///
+ public string Category;
///
/// Occurs when items gets clicked by the user.
@@ -49,18 +54,6 @@ namespace FlaxEditor.GUI
{
}
- ///
- /// Initializes a new instance of the class.
- ///
- /// The item name.
- /// The item tag object.
- public Item(string name, object tag = null)
- : base(0, 0, 120, 12)
- {
- Name = name;
- Tag = tag;
- }
-
///
/// Updates the filter.
///
@@ -181,6 +174,7 @@ namespace FlaxEditor.GUI
}
private readonly TextBox _searchBox;
+ private List _categoryPanels;
private bool _waitingForInput;
///
@@ -242,6 +236,23 @@ namespace FlaxEditor.GUI
if (items[i] is Item item)
item.UpdateFilter(_searchBox.Text);
}
+ if (_categoryPanels != null)
+ {
+ for (int i = 0; i < _categoryPanels.Count; i++)
+ {
+ var category = _categoryPanels[i];
+ bool anyVisible = false;
+ for (int j = 0; j < category.Children.Count; j++)
+ {
+ if (category.Children[j] is Item item2)
+ {
+ item2.UpdateFilter(_searchBox.Text);
+ anyVisible |= item2.Visible;
+ }
+ }
+ category.Visible = anyVisible;
+ }
+ }
UnlockChildrenRecursive();
PerformLayout(true);
@@ -254,8 +265,33 @@ namespace FlaxEditor.GUI
/// The item.
public void AddItem(Item item)
{
- item.Parent = ItemsPanel;
item.Clicked += OnClickItem;
+ ContainerControl parent = ItemsPanel;
+ if (!string.IsNullOrEmpty(item.Category))
+ {
+ if (_categoryPanels == null)
+ _categoryPanels = new List();
+ for (int i = 0; i < _categoryPanels.Count; i++)
+ {
+ if (string.Equals(_categoryPanels[i].HeaderText, item.Category, StringComparison.Ordinal))
+ {
+ parent = _categoryPanels[i];
+ break;
+ }
+ }
+ if (parent == ItemsPanel)
+ {
+ var categoryPanel = new DropPanel
+ {
+ HeaderText = item.Category,
+ Parent = parent,
+ };
+ categoryPanel.Open(false);
+ _categoryPanels.Add(categoryPanel);
+ parent = categoryPanel;
+ }
+ }
+ item.Parent = parent;
}
///
@@ -281,6 +317,19 @@ namespace FlaxEditor.GUI
if (items[i] is Item item)
item.UpdateFilter(null);
}
+ if (_categoryPanels != null)
+ {
+ for (int i = 0; i < _categoryPanels.Count; i++)
+ {
+ var category = _categoryPanels[i];
+ for (int j = 0; j < category.Children.Count; j++)
+ {
+ if (category.Children[j] is Item item2)
+ item2.UpdateFilter(null);
+ }
+ category.Visible = true;
+ }
+ }
_searchBox.Clear();
UnlockChildrenRecursive();
diff --git a/Source/Editor/GUI/Popups/TypeSearchPopup.cs b/Source/Editor/GUI/Popups/TypeSearchPopup.cs
index a35b2a1c5..71a97ed05 100644
--- a/Source/Editor/GUI/Popups/TypeSearchPopup.cs
+++ b/Source/Editor/GUI/Popups/TypeSearchPopup.cs
@@ -27,6 +27,15 @@ namespace FlaxEditor.GUI
///
public ScriptType Type => _type;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The type.
+ public TypeItemView(ScriptType type)
+ : this(type, type.GetAttributes(false))
+ {
+ }
+
///
/// Initializes a new instance of the class.
///
@@ -38,12 +47,18 @@ namespace FlaxEditor.GUI
Name = type.Name;
TooltipText = type.TypeName;
+ Tag = type;
var tooltipAttribute = (TooltipAttribute)attributes.FirstOrDefault(x => x is TooltipAttribute);
if (tooltipAttribute != null)
{
TooltipText += '\n';
TooltipText += tooltipAttribute.Text;
}
+ var categoryAttribute = (CategoryAttribute)attributes.FirstOrDefault(x => x is CategoryAttribute);
+ if (categoryAttribute != null)
+ {
+ Category = categoryAttribute.Name;
+ }
}
///
diff --git a/Source/Editor/Surface/Archetypes/Particles.cs b/Source/Editor/Surface/Archetypes/Particles.cs
index 28d6dce6a..f6fd2d003 100644
--- a/Source/Editor/Surface/Archetypes/Particles.cs
+++ b/Source/Editor/Surface/Archetypes/Particles.cs
@@ -118,8 +118,10 @@ namespace FlaxEditor.Surface.Archetypes
var cm = new ItemsListContextMenu(180);
foreach (var module in modules)
{
- cm.AddItem(new ItemsListContextMenu.Item(module.Title, module.TypeID)
+ cm.AddItem(new ItemsListContextMenu.Item
{
+ Name = module.Title,
+ Tag = module.TypeID,
TooltipText = module.Description,
});
}
diff --git a/Source/Editor/Surface/VisjectSurfaceWindow.cs b/Source/Editor/Surface/VisjectSurfaceWindow.cs
index 810f125ae..119c01c30 100644
--- a/Source/Editor/Surface/VisjectSurfaceWindow.cs
+++ b/Source/Editor/Surface/VisjectSurfaceWindow.cs
@@ -447,18 +447,13 @@ namespace FlaxEditor.Surface
var cm = new ItemsListContextMenu(180);
foreach (var newParameterType in newParameterTypes)
{
- var name = newParameterType.Type != null ? window.VisjectSurface.GetTypeName(newParameterType) : newParameterType.Name;
- var item = new ItemsListContextMenu.Item(name, newParameterType)
+ var item = new TypeSearchPopup.TypeItemView(newParameterType)
{
+ Tag = newParameterType,
TooltipText = newParameterType.TypeName,
};
- var attributes = newParameterType.GetAttributes(false);
- var tooltipAttribute = (TooltipAttribute)attributes.FirstOrDefault(x => x is TooltipAttribute);
- if (tooltipAttribute != null)
- {
- item.TooltipText += '\n';
- item.TooltipText += tooltipAttribute.Text;
- }
+ if (newParameterType.Type != null)
+ item.Name = window.VisjectSurface.GetTypeName(newParameterType);
cm.AddItem(item);
}
cm.ItemClicked += OnAddParameterItemClicked;
diff --git a/Source/Engine/Scripting/Attributes/Editor/CategoryAttribute.cs b/Source/Engine/Scripting/Attributes/Editor/CategoryAttribute.cs
new file mode 100644
index 000000000..e5f4f9794
--- /dev/null
+++ b/Source/Engine/Scripting/Attributes/Editor/CategoryAttribute.cs
@@ -0,0 +1,27 @@
+// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+
+using System;
+
+namespace FlaxEngine
+{
+ ///
+ /// Describes the category name for a type.
+ ///
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
+ public sealed class CategoryAttribute : Attribute
+ {
+ ///
+ /// The category name.
+ ///
+ public string Name;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The category name.
+ public CategoryAttribute(string name)
+ {
+ Name = name;
+ }
+ }
+}