Merge branch 'xxSeys1-ToolboxSearchFilterAndControls'
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEditor.GUI.Input;
|
||||
using FlaxEditor.GUI.Tabs;
|
||||
using FlaxEditor.GUI.Tree;
|
||||
@@ -98,10 +99,22 @@ namespace FlaxEditor.Windows
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
private enum SearchFilter
|
||||
{
|
||||
UI = 1,
|
||||
Actors = 2,
|
||||
Primitives = 4,
|
||||
[HideInEditor]
|
||||
Default = UI | Actors | Primitives,
|
||||
}
|
||||
|
||||
private TextBox _searchBox;
|
||||
private ContainerControl _groupSearch;
|
||||
private Tabs _actorGroups;
|
||||
private ContainerControl groupPrimitives;
|
||||
private Button _viewDropdown;
|
||||
private int _searchFilterMask = (int)SearchFilter.Default;
|
||||
|
||||
/// <summary>
|
||||
/// The editor instance.
|
||||
@@ -127,16 +140,25 @@ namespace FlaxEditor.Windows
|
||||
UseScroll = true,
|
||||
AnchorPreset = AnchorPresets.StretchAll,
|
||||
Offsets = Margin.Zero,
|
||||
TabsSize = new Float2(120, 32),
|
||||
TabsSize = new Float2(90, 32),
|
||||
Parent = this,
|
||||
};
|
||||
|
||||
_groupSearch = CreateGroupWithList(_actorGroups, "Search", 26);
|
||||
|
||||
_viewDropdown = new Button(2, 2, 45.0f, TextBoxBase.DefaultHeight)
|
||||
{
|
||||
TooltipText = "Change search filter options.",
|
||||
Text = "Filters",
|
||||
Parent = _groupSearch.Parent.Parent,
|
||||
};
|
||||
_viewDropdown.Clicked += OnViewButtonClicked;
|
||||
|
||||
_searchBox = new SearchBox
|
||||
{
|
||||
AnchorPreset = AnchorPresets.HorizontalStretchTop,
|
||||
Parent = _groupSearch.Parent.Parent,
|
||||
Bounds = new Rectangle(4, 4, _actorGroups.Width - 8, 18),
|
||||
Bounds = new Rectangle(_viewDropdown.Right + 2, 2, _actorGroups.Width - 4, TextBoxBase.DefaultHeight),
|
||||
};
|
||||
_searchBox.TextChanged += OnSearchBoxTextChanged;
|
||||
|
||||
@@ -145,10 +167,38 @@ namespace FlaxEditor.Windows
|
||||
_actorGroups.SelectedTabIndex = 1;
|
||||
}
|
||||
|
||||
private void OnViewButtonClicked()
|
||||
{
|
||||
var menu = new ContextMenu();
|
||||
AddSearchFilterButton(menu, SearchFilter.UI, "UI");
|
||||
AddSearchFilterButton(menu, SearchFilter.Actors, "Actors");
|
||||
AddSearchFilterButton(menu, SearchFilter.Primitives, "Primitives");
|
||||
menu.Show(_viewDropdown.Parent, _viewDropdown.BottomLeft);
|
||||
}
|
||||
|
||||
private void AddSearchFilterButton(ContextMenu menu, SearchFilter value, string name)
|
||||
{
|
||||
var button = menu.AddButton(name);
|
||||
button.AutoCheck = true;
|
||||
button.Checked = (_searchFilterMask & (int)value) != 0;
|
||||
button.Clicked += () =>
|
||||
{
|
||||
_searchFilterMask ^= (int)value;
|
||||
OnSearchBoxTextChanged();
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void PerformLayoutBeforeChildren()
|
||||
{
|
||||
base.PerformLayoutBeforeChildren();
|
||||
|
||||
_searchBox.Width = _groupSearch.Width - _viewDropdown.Right - 4;
|
||||
}
|
||||
|
||||
private void OnScriptsReload()
|
||||
{
|
||||
// Prevent any references to actor types from the game assemblies that will be reloaded
|
||||
_searchBox.Clear();
|
||||
_groupSearch.DisposeChildren();
|
||||
_groupSearch.PerformLayout();
|
||||
|
||||
@@ -172,6 +222,7 @@ namespace FlaxEditor.Windows
|
||||
private void OnScriptsReloadEnd()
|
||||
{
|
||||
RefreshActorTabs();
|
||||
OnSearchBoxTextChanged();
|
||||
}
|
||||
|
||||
private void RefreshActorTabs()
|
||||
@@ -192,14 +243,21 @@ namespace FlaxEditor.Windows
|
||||
group.Dispose();
|
||||
}
|
||||
|
||||
// Setup primitives tabs
|
||||
// Add primitives to primtives and search tab
|
||||
groupPrimitives = CreateGroupWithList(_actorGroups, "Primitives");
|
||||
|
||||
groupPrimitives.AddChild(CreateEditorAssetItem("Cube", "Primitives/Cube.flax"));
|
||||
_groupSearch.AddChild(CreateEditorAssetItem("Cube", "Primitives/Cube.flax"));
|
||||
groupPrimitives.AddChild(CreateEditorAssetItem("Sphere", "Primitives/Sphere.flax"));
|
||||
_groupSearch.AddChild(CreateEditorAssetItem("Sphere", "Primitives/Sphere.flax"));
|
||||
groupPrimitives.AddChild(CreateEditorAssetItem("Plane", "Primitives/Plane.flax"));
|
||||
_groupSearch.AddChild(CreateEditorAssetItem("Plane", "Primitives/Plane.flax"));
|
||||
groupPrimitives.AddChild(CreateEditorAssetItem("Cylinder", "Primitives/Cylinder.flax"));
|
||||
_groupSearch.AddChild(CreateEditorAssetItem("Cylinder", "Primitives/Cylinder.flax"));
|
||||
groupPrimitives.AddChild(CreateEditorAssetItem("Cone", "Primitives/Cone.flax"));
|
||||
_groupSearch.AddChild(CreateEditorAssetItem("Cone", "Primitives/Cone.flax"));
|
||||
groupPrimitives.AddChild(CreateEditorAssetItem("Capsule", "Primitives/Capsule.flax"));
|
||||
_groupSearch.AddChild(CreateEditorAssetItem("Capsule", "Primitives/Capsule.flax"));
|
||||
|
||||
// Created first to order specific tabs
|
||||
CreateGroupWithList(_actorGroups, "Lights");
|
||||
@@ -312,57 +370,115 @@ namespace FlaxEditor.Windows
|
||||
_groupSearch.LockChildrenRecursive();
|
||||
_groupSearch.DisposeChildren();
|
||||
|
||||
foreach (var actorType in Editor.CodeEditing.Actors.Get())
|
||||
if (((int)SearchFilter.Actors & _searchFilterMask) != 0)
|
||||
{
|
||||
ActorToolboxAttribute attribute = null;
|
||||
foreach (var e in actorType.GetAttributes(false))
|
||||
foreach (var actorType in Editor.CodeEditing.Actors.Get())
|
||||
{
|
||||
if (e is ActorToolboxAttribute actorToolboxAttribute)
|
||||
ActorToolboxAttribute attribute = null;
|
||||
foreach (var e in actorType.GetAttributes(false))
|
||||
{
|
||||
attribute = actorToolboxAttribute;
|
||||
break;
|
||||
if (e is ActorToolboxAttribute actorToolboxAttribute)
|
||||
{
|
||||
attribute = actorToolboxAttribute;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var text = (attribute == null) ? actorType.Name : string.IsNullOrEmpty(attribute.Name) ? actorType.Name : attribute.Name;
|
||||
var text = (attribute == null) ? actorType.Name : string.IsNullOrEmpty(attribute.Name) ? actorType.Name : attribute.Name;
|
||||
|
||||
// Display all actors on no search
|
||||
if (string.IsNullOrEmpty(filterText))
|
||||
_groupSearch.AddChild(CreateActorItem(Utilities.Utils.GetPropertyNameUI(text), actorType));
|
||||
|
||||
if (!QueryFilterHelper.Match(filterText, text, out QueryFilterHelper.Range[] ranges))
|
||||
continue;
|
||||
|
||||
var item = CreateActorItem(Utilities.Utils.GetPropertyNameUI(text), actorType);
|
||||
SearchFilterHighlights(item, text, ranges);
|
||||
}
|
||||
|
||||
// Hack primitive models into the search results
|
||||
foreach (var child in groupPrimitives.Children)
|
||||
{
|
||||
if (child is Item primitiveAssetItem)
|
||||
{
|
||||
var text = primitiveAssetItem.Text;
|
||||
// Display all actors on no search
|
||||
if (string.IsNullOrEmpty(filterText))
|
||||
_groupSearch.AddChild(CreateActorItem(Utilities.Utils.GetPropertyNameUI(text), actorType));
|
||||
|
||||
if (!QueryFilterHelper.Match(filterText, text, out QueryFilterHelper.Range[] ranges))
|
||||
continue;
|
||||
|
||||
// Rebuild the path based on item name (it would be better to convert the drag data back to a string somehow)
|
||||
string path = $"Primitives/{text}.flax";
|
||||
|
||||
var item = CreateEditorAssetItem(text, path);
|
||||
var item = CreateActorItem(Utilities.Utils.GetPropertyNameUI(text), actorType);
|
||||
SearchFilterHighlights(item, text, ranges);
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(filterText))
|
||||
_groupSearch.SortChildren();
|
||||
if (((int)SearchFilter.Primitives & _searchFilterMask) != 0)
|
||||
{
|
||||
// Hack primitive models into the search results
|
||||
foreach (var child in groupPrimitives.Children)
|
||||
{
|
||||
if (child is Item primitiveAssetItem)
|
||||
{
|
||||
var text = primitiveAssetItem.Text;
|
||||
|
||||
// Rebuild the path based on item name (it would be better to convert the drag data back to a string somehow)
|
||||
string path = $"Primitives/{text}.flax";
|
||||
|
||||
// Display all primitives on no search
|
||||
if (string.IsNullOrEmpty(filterText))
|
||||
_groupSearch.AddChild(CreateEditorAssetItem(text, path));
|
||||
|
||||
if (!QueryFilterHelper.Match(filterText, text, out QueryFilterHelper.Range[] ranges))
|
||||
continue;
|
||||
|
||||
var item = CreateEditorAssetItem(text, path);
|
||||
SearchFilterHighlights(item, text, ranges);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (((int)SearchFilter.UI & _searchFilterMask) != 0)
|
||||
{
|
||||
foreach (var controlType in Editor.Instance.CodeEditing.Controls.Get())
|
||||
{
|
||||
if (controlType.IsAbstract)
|
||||
continue;
|
||||
|
||||
ActorToolboxAttribute attribute = null;
|
||||
foreach (var e in controlType.GetAttributes(false))
|
||||
{
|
||||
if (e is ActorToolboxAttribute actorToolboxAttribute)
|
||||
{
|
||||
attribute = actorToolboxAttribute;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var text = (attribute == null) ? controlType.Name : string.IsNullOrEmpty(attribute.Name) ? controlType.Name : attribute.Name;
|
||||
|
||||
// Display all controls on no search
|
||||
if (string.IsNullOrEmpty(filterText))
|
||||
_groupSearch.AddChild(CreateControlItem(Utilities.Utils.GetPropertyNameUI(controlType.Name), controlType));
|
||||
|
||||
if (!QueryFilterHelper.Match(filterText, text, out QueryFilterHelper.Range[] ranges))
|
||||
continue;
|
||||
|
||||
var item = CreateControlItem(Utilities.Utils.GetPropertyNameUI(controlType.Name), controlType);
|
||||
SearchFilterHighlights(item, text, ranges);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the search results alphabetically
|
||||
_groupSearch.SortChildren();
|
||||
|
||||
_groupSearch.UnlockChildrenRecursive();
|
||||
PerformLayout();
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Draw()
|
||||
{
|
||||
base.Draw();
|
||||
|
||||
// Show a text to hint the user that either no filter is active or the search does not return any results
|
||||
bool noSearchResults = _groupSearch.Children.Count == 0 && !string.IsNullOrEmpty(_searchBox.Text);
|
||||
bool showHint = _searchFilterMask == 0 || noSearchResults;
|
||||
if (showHint)
|
||||
{
|
||||
string hint = noSearchResults ? "No results" : "No search filter active, please enable at least one filter";
|
||||
var textRect = _groupSearch.Parent.Parent.Bounds;
|
||||
var style = Style.Current;
|
||||
Render2D.DrawText(style.FontMedium, hint, textRect, style.ForegroundGrey, TextAlignment.Center, TextAlignment.Center, TextWrapping.WrapWords);
|
||||
}
|
||||
}
|
||||
|
||||
private void SearchFilterHighlights(Item item, string text, QueryFilterHelper.Range[] ranges)
|
||||
{
|
||||
_groupSearch.AddChild(item);
|
||||
|
||||
Reference in New Issue
Block a user