Add Find references utility for graph parameters and methods

This commit is contained in:
Wojtek Figat
2022-05-09 18:10:47 +02:00
parent 8b1e0df222
commit 782c3a0e3e
16 changed files with 364 additions and 118 deletions

View File

@@ -149,6 +149,10 @@ namespace FlaxEditor.Modules
_searchWin.ShowFloating(); _searchWin.ShowFloating();
_searchWin.SearchLocation = ContentSearchWindow.SearchLocations.AllAssets; _searchWin.SearchLocation = ContentSearchWindow.SearchLocations.AllAssets;
} }
if (window is ISearchWindow searchWindow)
{
_searchWin.SearchAssets = searchWindow.AssetType;
}
if (query != null) if (query != null)
{ {
_searchWin.Query = query; _searchWin.Query = query;

View File

@@ -38,7 +38,7 @@ namespace FlaxEditor.Scripting
/// <summary> /// <summary>
/// Gets a member name (eg. name of the field or method without leading class name nor namespace prefixes). /// Gets a member name (eg. name of the field or method without leading class name nor namespace prefixes).
/// </summary> /// </summary>
public string Name => _managed?.Name ?? _custom?.Name; public string Name => _managed?.Name ?? _custom?.Name ?? string.Empty;
/// <summary> /// <summary>
/// Gets a metadata token for sorting so it may not be the actual token. /// Gets a metadata token for sorting so it may not be the actual token.

View File

@@ -237,6 +237,9 @@ namespace FlaxEditor.Surface.Archetypes
base.OnDestroy(); base.OnDestroy();
} }
/// <inheritdoc />
public Asset SurfaceAsset => null;
/// <inheritdoc /> /// <inheritdoc />
public string SurfaceName => StateMachineTitle; public string SurfaceName => StateMachineTitle;
@@ -1295,6 +1298,9 @@ namespace FlaxEditor.Surface.Archetypes
base.OnDestroy(); base.OnDestroy();
} }
/// <inheritdoc />
public Asset SurfaceAsset => null;
/// <inheritdoc /> /// <inheritdoc />
public string SurfaceName => StateTitle; public string SurfaceName => StateTitle;
@@ -1662,6 +1668,9 @@ namespace FlaxEditor.Surface.Archetypes
data = _data; data = _data;
} }
/// <inheritdoc />
public Asset SurfaceAsset => null;
/// <inheritdoc /> /// <inheritdoc />
public string SurfaceName => string.Format("{0} to {1}", SourceState.StateTitle, DestinationState.StateTitle); public string SurfaceName => string.Format("{0} to {1}", SourceState.StateTitle, DestinationState.StateTitle);

View File

@@ -1079,12 +1079,28 @@ namespace FlaxEditor.Surface.Archetypes
base.OnShowSecondaryContextMenu(menu, location); base.OnShowSecondaryContextMenu(menu, location);
var method = GetMethod(out _, out _, out _); var method = GetMethod(out _, out _, out _);
if (method && !method.ValueType.IsVoid) if (method)
{ {
menu.AddSeparator(); menu.AddSeparator();
menu.AddButton((bool)Values[3] ? "Convert to method call" : "Convert to pure node", () => SetValue(3, !(bool)Values[3])).Enabled = Surface.CanEdit; if (!method.ValueType.IsVoid)
menu.AddButton((bool)Values[3] ? "Convert to method call" : "Convert to pure node", () => SetValue(3, !(bool)Values[3])).Enabled = Surface.CanEdit;
menu.AddButton("Find references...", OnFindReferences);
}
}
private void OnFindReferences()
{
Editor.Instance.ContentFinding.ShowSearch(Surface, '\"' + ContentSearchText + '\"');
}
/// <inheritdoc />
public override string ContentSearchText
{
get
{
var method = GetMethod(out var scriptType, out _, out _);
return scriptType.TypeName + '.' + method.Name;
} }
// TODO: add Find References option to search Visual Script function usages in the whole project
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -1547,7 +1563,7 @@ namespace FlaxEditor.Surface.Archetypes
menu.AddButton("Add return node", OnAddReturnNode).Enabled = _signature.ReturnType != ScriptType.Null && Surface.CanEdit; menu.AddButton("Add return node", OnAddReturnNode).Enabled = _signature.ReturnType != ScriptType.Null && Surface.CanEdit;
menu.AddButton("Edit signature...", OnEditSignature).Enabled = Surface.CanEdit; menu.AddButton("Edit signature...", OnEditSignature).Enabled = Surface.CanEdit;
menu.AddButton("Edit attributes...", OnEditAttributes).Enabled = Surface.CanEdit; menu.AddButton("Edit attributes...", OnEditAttributes).Enabled = Surface.CanEdit;
// TODO: add Find References option to search Visual Script function usages in the whole project menu.AddButton("Find references...", OnFindReferences);
} }
private void OnAddReturnNode() private void OnAddReturnNode()
@@ -1638,6 +1654,11 @@ namespace FlaxEditor.Surface.Archetypes
editor.Show(this, Vector2.Zero); editor.Show(this, Vector2.Zero);
} }
private void OnFindReferences()
{
Editor.Instance.ContentFinding.ShowSearch(Surface, '\"' + ContentSearchText + '\"');
}
private void CheckFunctionName(ref string name) private void CheckFunctionName(ref string name)
{ {
if (string.IsNullOrEmpty(name)) if (string.IsNullOrEmpty(name))
@@ -1651,6 +1672,20 @@ namespace FlaxEditor.Surface.Archetypes
name = value; name = value;
} }
/// <inheritdoc />
public override string ContentSearchText
{
get
{
var visualScript = Context.Context.SurfaceAsset as VisualScript;
if (visualScript == null && Surface is VisualScriptSurface visualScriptSurface)
visualScript = visualScriptSurface.Script;
if (visualScript != null)
return visualScript.ScriptTypeName + '.' + _signature.Name;
return _signature.Name;
}
}
/// <inheritdoc /> /// <inheritdoc />
public override bool OnMouseDoubleClick(Vector2 location, MouseButton button) public override bool OnMouseDoubleClick(Vector2 location, MouseButton button)
{ {
@@ -1743,20 +1778,19 @@ namespace FlaxEditor.Surface.Archetypes
} }
} }
private sealed class GetFieldNode : SurfaceNode private abstract class FieldNodeBase : SurfaceNode
{ {
private bool _isTypesChangedEventRegistered; private bool _isTypesChangedEventRegistered;
/// <inheritdoc /> protected FieldNodeBase(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch)
public GetFieldNode(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch)
: base(id, context, nodeArch, groupArch) : base(id, context, nodeArch, groupArch)
{ {
} }
private void UpdateSignature() protected ScriptMemberInfo GetField(out ScriptType scriptType)
{ {
var fieldInfo = ScriptMemberInfo.Null; var fieldInfo = ScriptMemberInfo.Null;
var scriptType = TypeUtils.GetType((string)Values[0]); scriptType = TypeUtils.GetType((string)Values[0]);
if (scriptType != ScriptType.Null) if (scriptType != ScriptType.Null)
{ {
var members = scriptType.GetMembers((string)Values[1], MemberTypes.Field, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); var members = scriptType.GetMembers((string)Values[1], MemberTypes.Field, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
@@ -1774,6 +1808,68 @@ namespace FlaxEditor.Surface.Archetypes
_isTypesChangedEventRegistered = true; _isTypesChangedEventRegistered = true;
Editor.Instance.CodeEditing.TypesChanged += UpdateSignature; Editor.Instance.CodeEditing.TypesChanged += UpdateSignature;
} }
return fieldInfo;
}
protected abstract void UpdateSignature();
/// <inheritdoc />
public override void OnShowSecondaryContextMenu(FlaxEditor.GUI.ContextMenu.ContextMenu menu, Vector2 location)
{
base.OnShowSecondaryContextMenu(menu, location);
if (GetField(out _) == ScriptMemberInfo.Null)
return;
menu.AddSeparator();
menu.AddButton("Find references...", OnFindReferences);
}
private void OnFindReferences()
{
Editor.Instance.ContentFinding.ShowSearch(Surface, '\"' + ContentSearchText + '\"');
}
/// <inheritdoc />
public override string ContentSearchText
{
get
{
var fieldInfo = GetField(out var scriptType);
return scriptType.TypeName + '.' + fieldInfo.Name;
}
}
/// <inheritdoc />
public override void OnValuesChanged()
{
base.OnValuesChanged();
UpdateSignature();
}
/// <inheritdoc />
public override void OnDestroy()
{
if (_isTypesChangedEventRegistered)
{
_isTypesChangedEventRegistered = false;
Editor.Instance.CodeEditing.TypesChanged -= UpdateSignature;
}
base.OnDestroy();
}
}
private sealed class GetFieldNode : FieldNodeBase
{
public GetFieldNode(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch)
: base(id, context, nodeArch, groupArch)
{
}
protected override void UpdateSignature()
{
var fieldInfo = GetField(out var scriptType);
ScriptType type; ScriptType type;
bool isStatic; bool isStatic;
if (fieldInfo) if (fieldInfo)
@@ -1816,58 +1912,18 @@ namespace FlaxEditor.Surface.Archetypes
Title = "Get " + SurfaceUtils.GetMethodDisplayName((string)Values[1]); Title = "Get " + SurfaceUtils.GetMethodDisplayName((string)Values[1]);
UpdateSignature(); UpdateSignature();
} }
/// <inheritdoc />
public override void OnValuesChanged()
{
base.OnValuesChanged();
UpdateSignature();
}
/// <inheritdoc />
public override void OnDestroy()
{
if (_isTypesChangedEventRegistered)
{
_isTypesChangedEventRegistered = false;
Editor.Instance.CodeEditing.TypesChanged -= UpdateSignature;
}
base.OnDestroy();
}
} }
private sealed class SetFieldNode : SurfaceNode private sealed class SetFieldNode : FieldNodeBase
{ {
private bool _isTypesChangedEventRegistered;
public SetFieldNode(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch) public SetFieldNode(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch)
: base(id, context, nodeArch, groupArch) : base(id, context, nodeArch, groupArch)
{ {
} }
private void UpdateSignature() protected override void UpdateSignature()
{ {
var fieldInfo = ScriptMemberInfo.Null; var fieldInfo = GetField(out var scriptType);
var scriptType = TypeUtils.GetType((string)Values[0]);
if (scriptType != ScriptType.Null)
{
var members = scriptType.GetMembers((string)Values[1], MemberTypes.Field, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
foreach (var member in members)
{
if (SurfaceUtils.IsValidVisualScriptField(member))
{
fieldInfo = member;
break;
}
}
}
if (!_isTypesChangedEventRegistered)
{
_isTypesChangedEventRegistered = true;
Editor.Instance.CodeEditing.TypesChanged += UpdateSignature;
}
ScriptType type; ScriptType type;
bool isStatic; bool isStatic;
if (fieldInfo) if (fieldInfo)
@@ -1909,26 +1965,6 @@ namespace FlaxEditor.Surface.Archetypes
Title = "Set " + SurfaceUtils.GetMethodDisplayName((string)Values[1]); Title = "Set " + SurfaceUtils.GetMethodDisplayName((string)Values[1]);
UpdateSignature(); UpdateSignature();
} }
/// <inheritdoc />
public override void OnValuesChanged()
{
base.OnValuesChanged();
UpdateSignature();
}
/// <inheritdoc />
public override void OnDestroy()
{
if (_isTypesChangedEventRegistered)
{
_isTypesChangedEventRegistered = false;
Editor.Instance.CodeEditing.TypesChanged -= UpdateSignature;
}
base.OnDestroy();
}
} }
private abstract class EventBaseNode : SurfaceNode, IFunctionsDependantNode private abstract class EventBaseNode : SurfaceNode, IFunctionsDependantNode

View File

@@ -267,8 +267,12 @@ namespace FlaxEditor.Surface.Archetypes
private SurfaceParameter GetSelected() private SurfaceParameter GetSelected()
{ {
var selectedIndex = _combobox.SelectedIndex; if (Surface != null)
return selectedIndex >= 0 && selectedIndex < Surface.Parameters.Count ? Surface.Parameters[selectedIndex] : null; {
var selectedIndex = _combobox.SelectedIndex;
return selectedIndex >= 0 && selectedIndex < Surface.Parameters.Count ? Surface.Parameters[selectedIndex] : null;
}
return Context.GetParameter((Guid)Values[0]);
} }
private void ClearDynamicElements() private void ClearDynamicElements()
@@ -278,6 +282,46 @@ namespace FlaxEditor.Surface.Archetypes
_dynamicChildren.Clear(); _dynamicChildren.Clear();
} }
/// <inheritdoc />
public override void OnShowSecondaryContextMenu(FlaxEditor.GUI.ContextMenu.ContextMenu menu, Vector2 location)
{
base.OnShowSecondaryContextMenu(menu, location);
if (GetSelected() == null)
return;
menu.AddSeparator();
menu.AddButton("Find references...", OnFindReferences);
}
private void OnFindReferences()
{
var selected = GetSelected();
var query = ContentSearchText ?? FlaxEngine.Json.JsonSerializer.GetStringID(selected.ID);
Editor.Instance.ContentFinding.ShowSearch(Surface, '\"' + query + '\"');
}
/// <inheritdoc />
public override string ContentSearchText
{
get
{
if (Surface is VisualScriptSurface visualScriptSurface)
{
// Override with parameter typename
var selected = GetSelected();
return visualScriptSurface.Script.ScriptTypeName + '.' + selected.Name;
}
if (Context.Context.SurfaceAsset is VisualScript visualScript)
{
// Override with parameter typename
var selected = Context.GetParameter((Guid)Values[0]);
if (selected != null)
return visualScript.ScriptTypeName + '.' + selected.Name;
}
return null;
}
}
/// <inheritdoc /> /// <inheritdoc />
public void OnParamCreated(SurfaceParameter param) public void OnParamCreated(SurfaceParameter param)
{ {
@@ -324,10 +368,7 @@ namespace FlaxEditor.Surface.Archetypes
{ {
base.OnSurfaceLoaded(); base.OnSurfaceLoaded();
if (Surface != null) UpdateTitle();
{
UpdateTitle();
}
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -369,8 +410,11 @@ namespace FlaxEditor.Surface.Archetypes
{ {
var selected = GetSelected(); var selected = GetSelected();
Title = selected != null ? "Get " + selected.Name : "Get Parameter"; Title = selected != null ? "Get " + selected.Name : "Get Parameter";
ResizeAuto(); if (_combobox != null)
_combobox.Width = Width - 30; {
ResizeAuto();
_combobox.Width = Width - 30;
}
} }
} }
@@ -567,8 +611,52 @@ namespace FlaxEditor.Surface.Archetypes
private SurfaceParameter GetSelected() private SurfaceParameter GetSelected()
{ {
var selectedIndex = _combobox.SelectedIndex; if (Surface != null)
return selectedIndex >= 0 && selectedIndex < Surface.Parameters.Count ? Surface.Parameters[selectedIndex] : null; {
var selectedIndex = _combobox.SelectedIndex;
return selectedIndex >= 0 && selectedIndex < Surface.Parameters.Count ? Surface.Parameters[selectedIndex] : null;
}
return Context.GetParameter((Guid)Values[0]);
}
/// <inheritdoc />
public override void OnShowSecondaryContextMenu(FlaxEditor.GUI.ContextMenu.ContextMenu menu, Vector2 location)
{
base.OnShowSecondaryContextMenu(menu, location);
if (GetSelected() == null)
return;
menu.AddSeparator();
menu.AddButton("Find references...", OnFindReferences);
}
private void OnFindReferences()
{
var selected = GetSelected();
var query = ContentSearchText ?? FlaxEngine.Json.JsonSerializer.GetStringID(selected.ID);
Editor.Instance.ContentFinding.ShowSearch(Surface, '\"' + query + '\"');
}
/// <inheritdoc />
public override string ContentSearchText
{
get
{
if (Surface is VisualScriptSurface visualScriptSurface)
{
// Override with parameter typename
var selected = GetSelected();
return visualScriptSurface.Script.ScriptTypeName + '.' + selected.Name;
}
if (Context.Context.SurfaceAsset is VisualScript visualScript)
{
// Override with parameter typename
var selected = Context.GetParameter((Guid)Values[0]);
if (selected != null)
return visualScript.ScriptTypeName + '.' + selected.Name;
}
return null;
}
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -608,10 +696,8 @@ namespace FlaxEditor.Surface.Archetypes
base.OnLoaded(); base.OnLoaded();
if (Surface != null) if (Surface != null)
{
UpdateCombo(); UpdateCombo();
UpdateUI(); UpdateUI();
}
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -641,8 +727,11 @@ namespace FlaxEditor.Surface.Archetypes
box.Enabled = selected != null; box.Enabled = selected != null;
box.CurrentType = selected?.Type ?? ScriptType.Null; box.CurrentType = selected?.Type ?? ScriptType.Null;
Title = selected != null ? "Set " + selected.Name : "Set Parameter"; Title = selected != null ? "Set " + selected.Name : "Set Parameter";
ResizeAuto(); if (_combobox != null)
_combobox.Width = Width - 50; {
ResizeAuto();
_combobox.Width = Width - 50;
}
} }
} }

View File

@@ -10,6 +10,11 @@ namespace FlaxEditor.Surface
[HideInEditor] [HideInEditor]
public interface ISurfaceContext public interface ISurfaceContext
{ {
/// <summary>
/// Gets the asset containing the surface (optional, null by default).
/// </summary>
Asset SurfaceAsset { get; }
/// <summary> /// <summary>
/// Gets the name of the surface (for UI). /// Gets the name of the surface (for UI).
/// </summary> /// </summary>

View File

@@ -135,6 +135,11 @@ namespace FlaxEditor.Surface
} }
} }
/// <summary>
/// Gets the custom text for Content Search. Can be used to include node in search results for a specific text query.
/// </summary>
public virtual string ContentSearchText => null;
/// <summary> /// <summary>
/// Gets the color of the footer of the node. /// Gets the color of the footer of the node.
/// </summary> /// </summary>

View File

@@ -577,6 +577,15 @@ namespace FlaxEditor.Surface
/// <param name="menu">The context menu.</param> /// <param name="menu">The context menu.</param>
protected virtual void OnParamContextMenu(int index, FlaxEditor.GUI.ContextMenu.ContextMenu menu) protected virtual void OnParamContextMenu(int index, FlaxEditor.GUI.ContextMenu.ContextMenu menu)
{ {
menu.AddSeparator();
menu.AddButton("Find references...", () => OnFindReferences(index));
}
private void OnFindReferences(int index)
{
var window = (IVisjectSurfaceWindow)Values[0];
var param = window.VisjectSurface.Parameters[index];
Editor.Instance.ContentFinding.ShowSearch(window.VisjectSurface, '\"' + FlaxEngine.Json.JsonSerializer.GetStringID(param.ID) + '\"');
} }
} }
@@ -890,6 +899,9 @@ namespace FlaxEditor.Surface
base.OnAssetLinked(); base.OnAssetLinked();
} }
/// <inheritdoc />
public Asset SurfaceAsset => Asset;
/// <inheritdoc /> /// <inheritdoc />
public abstract string SurfaceName { get; } public abstract string SurfaceName { get; }

View File

@@ -341,6 +341,9 @@ namespace FlaxEditor.Viewport.Previews
base.OnDestroy(); base.OnDestroy();
} }
/// <inheritdoc />
public Asset SurfaceAsset => null;
/// <inheritdoc /> /// <inheritdoc />
string ISurfaceContext.SurfaceName => string.Empty; string ISurfaceContext.SurfaceName => string.Empty;

View File

@@ -399,6 +399,9 @@ namespace FlaxEditor.Windows
base.OnDestroy(); base.OnDestroy();
} }
/// <inheritdoc />
public Asset SurfaceAsset => null;
/// <inheritdoc /> /// <inheritdoc />
public string SurfaceName => "References"; public string SurfaceName => "References";

View File

@@ -13,6 +13,7 @@ using FlaxEditor.Viewport.Cameras;
using FlaxEditor.Viewport.Previews; using FlaxEditor.Viewport.Previews;
using FlaxEngine; using FlaxEngine;
using FlaxEngine.GUI; using FlaxEngine.GUI;
using FlaxEngine.Windows.Search;
using Object = FlaxEngine.Object; using Object = FlaxEngine.Object;
// ReSharper disable UnusedMember.Local // ReSharper disable UnusedMember.Local
@@ -27,7 +28,7 @@ namespace FlaxEditor.Windows.Assets
/// <seealso cref="AnimationGraph" /> /// <seealso cref="AnimationGraph" />
/// <seealso cref="AnimGraphSurface" /> /// <seealso cref="AnimGraphSurface" />
/// <seealso cref="AnimatedModelPreview" /> /// <seealso cref="AnimatedModelPreview" />
public sealed class AnimationGraphWindow : VisjectSurfaceWindow<AnimationGraph, AnimGraphSurface, AnimatedModelPreview> public sealed class AnimationGraphWindow : VisjectSurfaceWindow<AnimationGraph, AnimGraphSurface, AnimatedModelPreview>, ISearchWindow
{ {
internal static Guid BaseModelId = new Guid(1000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); internal static Guid BaseModelId = new Guid(1000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
@@ -426,5 +427,8 @@ namespace FlaxEditor.Windows.Assets
base.OnDestroy(); base.OnDestroy();
} }
/// <inheritdoc />
public SearchAssetTypes AssetType => SearchAssetTypes.AnimGraph;
} }
} }

View File

@@ -8,6 +8,7 @@ using FlaxEditor.Scripting;
using FlaxEditor.Surface; using FlaxEditor.Surface;
using FlaxEditor.Viewport.Previews; using FlaxEditor.Viewport.Previews;
using FlaxEngine; using FlaxEngine;
using FlaxEngine.Windows.Search;
// ReSharper disable UnusedMember.Local // ReSharper disable UnusedMember.Local
// ReSharper disable UnusedMember.Global // ReSharper disable UnusedMember.Global
@@ -21,7 +22,7 @@ namespace FlaxEditor.Windows.Assets
/// <seealso cref="Material" /> /// <seealso cref="Material" />
/// <seealso cref="MaterialSurface" /> /// <seealso cref="MaterialSurface" />
/// <seealso cref="MaterialPreview" /> /// <seealso cref="MaterialPreview" />
public sealed class MaterialWindow : VisjectSurfaceWindow<Material, MaterialSurface, MaterialPreview> public sealed class MaterialWindow : VisjectSurfaceWindow<Material, MaterialSurface, MaterialPreview>, ISearchWindow
{ {
private readonly ScriptType[] _newParameterTypes = private readonly ScriptType[] _newParameterTypes =
{ {
@@ -385,5 +386,8 @@ namespace FlaxEditor.Windows.Assets
return base.SaveToOriginal(); return base.SaveToOriginal();
} }
/// <inheritdoc />
public SearchAssetTypes AssetType => SearchAssetTypes.Material;
} }
} }

View File

@@ -8,6 +8,7 @@ using FlaxEditor.Scripting;
using FlaxEditor.Surface; using FlaxEditor.Surface;
using FlaxEditor.Viewport.Previews; using FlaxEditor.Viewport.Previews;
using FlaxEngine; using FlaxEngine;
using FlaxEngine.Windows.Search;
// ReSharper disable UnusedMember.Local // ReSharper disable UnusedMember.Local
// ReSharper disable UnusedMember.Global // ReSharper disable UnusedMember.Global
@@ -21,7 +22,7 @@ namespace FlaxEditor.Windows.Assets
/// <seealso cref="ParticleEmitter" /> /// <seealso cref="ParticleEmitter" />
/// <seealso cref="ParticleEmitterSurface" /> /// <seealso cref="ParticleEmitterSurface" />
/// <seealso cref="ParticleEmitterPreview" /> /// <seealso cref="ParticleEmitterPreview" />
public sealed class ParticleEmitterWindow : VisjectSurfaceWindow<ParticleEmitter, ParticleEmitterSurface, ParticleEmitterPreview> public sealed class ParticleEmitterWindow : VisjectSurfaceWindow<ParticleEmitter, ParticleEmitterSurface, ParticleEmitterPreview>, ISearchWindow
{ {
private readonly ScriptType[] _newParameterTypes = private readonly ScriptType[] _newParameterTypes =
{ {
@@ -271,5 +272,8 @@ namespace FlaxEditor.Windows.Assets
return base.SaveToOriginal(); return base.SaveToOriginal();
} }
/// <inheritdoc />
public SearchAssetTypes AssetType => SearchAssetTypes.ParticleEmitter;
} }
} }

View File

@@ -170,6 +170,9 @@ namespace FlaxEditor.Windows.Assets
base.OnAssetLinked(); base.OnAssetLinked();
} }
/// <inheritdoc />
public Asset SurfaceAsset => Asset;
/// <inheritdoc /> /// <inheritdoc />
public abstract string SurfaceName { get; } public abstract string SurfaceName { get; }

View File

@@ -16,6 +16,7 @@ using FlaxEditor.Surface;
using FlaxEngine; using FlaxEngine;
using FlaxEngine.GUI; using FlaxEngine.GUI;
using FlaxEngine.Json; using FlaxEngine.Json;
using FlaxEngine.Windows.Search;
#pragma warning disable 649 #pragma warning disable 649
@@ -30,7 +31,7 @@ namespace FlaxEditor.Windows.Assets
/// </summary> /// </summary>
/// <seealso cref="VisualScript" /> /// <seealso cref="VisualScript" />
/// <seealso cref="VisualScriptSurface" /> /// <seealso cref="VisualScriptSurface" />
public sealed class VisualScriptWindow : AssetEditorWindowBase<VisualScript>, IVisjectSurfaceWindow public sealed class VisualScriptWindow : AssetEditorWindowBase<VisualScript>, IVisjectSurfaceWindow, ISearchWindow
{ {
private struct BreakpointData private struct BreakpointData
{ {
@@ -238,6 +239,9 @@ namespace FlaxEditor.Windows.Assets
b.Enabled = window._canEdit; b.Enabled = window._canEdit;
b.TooltipText = "Changes parameter type to a dictionary."; b.TooltipText = "Changes parameter type to a dictionary.";
} }
menu.AddSeparator();
menu.AddButton("Find references...", () => OnFindReferences(index));
} }
private void OnChangeType(Action<ItemsListContextMenu.Item> itemClicked) private void OnChangeType(Action<ItemsListContextMenu.Item> itemClicked)
@@ -257,6 +261,13 @@ namespace FlaxEditor.Windows.Assets
cm.SortChildren(); cm.SortChildren();
cm.Show(window, window.PointFromScreen(Input.MouseScreenPosition)); cm.Show(window, window.PointFromScreen(Input.MouseScreenPosition));
} }
private void OnFindReferences(int index)
{
var window = (VisualScriptWindow)Values[0];
var param = window.Surface.Parameters[index];
Editor.Instance.ContentFinding.ShowSearch(window, '\"' + window.Asset.ScriptTypeName + '.' + param.Name + '\"');
}
} }
private sealed class PropertiesProxy private sealed class PropertiesProxy
@@ -1097,6 +1108,9 @@ namespace FlaxEditor.Windows.Assets
Surface.FocusNode(node); Surface.FocusNode(node);
} }
/// <inheritdoc />
public Asset SurfaceAsset => Asset;
/// <inheritdoc /> /// <inheritdoc />
public string SurfaceName => "Visual Script"; public string SurfaceName => "Visual Script";
@@ -1431,5 +1445,8 @@ namespace FlaxEditor.Windows.Assets
/// <inheritdoc /> /// <inheritdoc />
public VisjectSurface VisjectSurface => _surface; public VisjectSurface VisjectSurface => _surface;
/// <inheritdoc />
public SearchAssetTypes AssetType => SearchAssetTypes.VisualScript;
} }
} }

View File

@@ -19,6 +19,54 @@ using FlaxEngine.GUI;
namespace FlaxEngine.Windows.Search namespace FlaxEngine.Windows.Search
{ {
/// <summary>
/// Content searching asset types.
/// </summary>
[Flags]
public enum SearchAssetTypes
{
/// <summary>
/// The none.
/// </summary>
None = 0,
/// <summary>
/// The visual script.
/// </summary>
VisualScript = 1 << 0,
/// <summary>
/// The material.
/// </summary>
Material = 1 << 1,
/// <summary>
/// The animation graph.
/// </summary>
AnimGraph = 1 << 2,
/// <summary>
/// The particle emitter.
/// </summary>
ParticleEmitter = 1 << 3,
/// <summary>
/// All types.
/// </summary>
All = VisualScript | Material | AnimGraph | ParticleEmitter,
}
/// <summary>
/// Interface for Editor windows to customize search.
/// </summary>
public interface ISearchWindow
{
/// <summary>
/// Gets the type of the asset for the search.
/// </summary>
SearchAssetTypes AssetType { get; }
}
/// <summary> /// <summary>
/// The content searching window. Allows to search inside Visual Scripts, Materials, Particles and other assets. /// The content searching window. Allows to search inside Visual Scripts, Materials, Particles and other assets.
/// </summary> /// </summary>
@@ -45,22 +93,11 @@ namespace FlaxEngine.Windows.Search
AllAssets, AllAssets,
} }
/// <summary>
/// Content searching asset types.
/// </summary>
[Flags]
public enum SearchAssetTypes
{
None = 0,
VisualScript = 1 << 0,
Material = 1 << 1,
AnimGraph = 1 << 2,
ParticleEmitter = 1 << 3,
All = VisualScript | Material | AnimGraph | ParticleEmitter,
}
private sealed class SearchSurfaceContext : ISurfaceContext private sealed class SearchSurfaceContext : ISurfaceContext
{ {
/// <inheritdoc />
public Asset SurfaceAsset { get; set; }
/// <inheritdoc /> /// <inheritdoc />
public string SurfaceName => string.Empty; public string SurfaceName => string.Empty;
@@ -223,6 +260,7 @@ namespace FlaxEngine.Windows.Search
if (_loadingLabel.Visible) if (_loadingLabel.Visible)
_loadingLabel.Text = string.Format("Searching {0}%...", (int)_progress); _loadingLabel.Text = string.Format("Searching {0}%...", (int)_progress);
_resultsTreeRoot.Expand(true);
lock (_pendingResults) lock (_pendingResults)
{ {
@@ -488,6 +526,7 @@ namespace FlaxEngine.Windows.Search
// Load Visject surface from data // Load Visject surface from data
if (surfaceData == null || surfaceData.Length == 0) if (surfaceData == null || surfaceData.Length == 0)
return; return;
_searchSurfaceContext.SurfaceAsset = asset;
_searchSurfaceContext.SurfaceData = surfaceData; _searchSurfaceContext.SurfaceData = surfaceData;
if (_visjectSurfaceContext.Load()) if (_visjectSurfaceContext.Load())
{ {
@@ -522,32 +561,41 @@ namespace FlaxEngine.Windows.Search
} }
// Search nodes // Search nodes
var newTreeNodes = new List<SearchResultTreeNode>();
foreach (var node in _visjectSurfaceContext.Nodes) foreach (var node in _visjectSurfaceContext.Nodes)
{ {
SearchResultTreeNode nodeTreeNode = null; newTreeNodes.Clear();
if (node.Values != null) if (node.Values != null)
{ {
foreach (var value in node.Values) foreach (var value in node.Values)
{ {
SearchVisjectMatch(value, (matchedValue, matchedText) => SearchVisjectMatch(value, (matchedValue, matchedText) =>
{ {
AddAssetSearchResult(ref assetTreeNode, asset);
if (nodeTreeNode == null)
nodeTreeNode = new SearchResultTreeNode
{
Text = node.Title,
TooltipText = node.TooltipText,
Tag = node.ID,
Navigate = OnNavigateVisjectNode,
Parent = assetTreeNode,
};
var valueTreeNode = AddVisjectSearchResult(matchedValue, matchedText, node.Archetype.ConnectionsHints); var valueTreeNode = AddVisjectSearchResult(matchedValue, matchedText, node.Archetype.ConnectionsHints);
valueTreeNode.Tag = node.ID; valueTreeNode.Tag = node.ID;
valueTreeNode.Navigate = OnNavigateVisjectNode; valueTreeNode.Navigate = OnNavigateVisjectNode;
valueTreeNode.Parent = nodeTreeNode; newTreeNodes.Add(valueTreeNode);
}); });
} }
} }
var nodeSearchText = node.ContentSearchText;
if (newTreeNodes.Count != 0 || (nodeSearchText != null && IsSearchMatch(ref nodeSearchText)))
{
AddAssetSearchResult(ref assetTreeNode, asset);
var nodeTreeNode = new SearchResultTreeNode
{
Text = node.Title,
TooltipText = node.TooltipText,
Tag = node.ID,
Navigate = OnNavigateVisjectNode,
Parent = assetTreeNode,
};
foreach (var newTreeNode in newTreeNodes)
{
newTreeNode.Parent = nodeTreeNode;
}
}
} }
if (assetTreeNode != null) if (assetTreeNode != null)