// Copyright (c) Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using FlaxEditor.Content;
using FlaxEditor.GUI.Docking;
using FlaxEditor.SceneGraph;
using FlaxEditor.Windows.Search;
using FlaxEngine;
using FlaxEngine.GUI;
using FlaxEngine.Windows.Search;
namespace FlaxEditor.Modules
{
internal struct QuickAction
{
public string Name;
public Action Action;
}
///
/// The search result.
///
[HideInEditor]
public struct SearchResult
{
///
/// The name.
///
public string Name;
///
/// The type name.
///
public string Type;
///
/// The item.
///
public object Item;
}
///
/// The content finding module.
///
public class ContentFindingModule : EditorModule
{
private List _quickActions;
private ContentFinder _finder;
private ContentSearchWindow _searchWin;
///
/// Initializes a new instance of the class.
///
/// The editor.
internal ContentFindingModule(Editor editor)
: base(editor)
{
}
///
public override void OnExit()
{
if (_quickActions != null)
{
_quickActions.Clear();
_quickActions = null;
}
if (_finder != null)
{
_finder.Dispose();
_finder = null;
}
if (_searchWin != null)
{
_searchWin.Dispose();
_searchWin = null;
}
base.OnExit();
}
///
/// Shows the content search window.
///
public void ShowSearch()
{
// Try to find the currently focused editor window that might call this
DockWindow window = null;
foreach (var editorWindow in Editor.Windows.Windows)
{
if (editorWindow.Visible && editorWindow.ContainsFocus && editorWindow.Parent != null)
{
window = editorWindow;
break;
}
}
ShowSearch(window);
}
///
/// Shows the content search window.
///
/// The target control to show search for it.
/// The initial query for the search.
public void ShowSearch(Control control, string query = null)
{
// Try to find the owning window
DockWindow window = null;
while (control != null && window == null)
{
window = control as DockWindow;
control = control.Parent;
}
ShowSearch(window, query);
}
///
/// Shows the content search window.
///
/// The target window to show search next to it.
/// The initial query for the search.
public void ShowSearch(DockWindow window, string query = null)
{
if (_searchWin == null)
_searchWin = new ContentSearchWindow(Editor);
_searchWin.TargetWindow = window;
if (!_searchWin.IsHidden)
{
// Focus
_searchWin.SelectTab();
_searchWin.Focus();
}
else if (window != null)
{
// Show docked to the target window
_searchWin.Show(DockState.DockBottom, window);
_searchWin.SearchLocation = ContentSearchWindow.SearchLocations.CurrentAsset;
}
else
{
// Show floating
_searchWin.ShowFloating();
_searchWin.SearchLocation = ContentSearchWindow.SearchLocations.AllAssets;
}
if (window is ISearchWindow searchWindow)
{
_searchWin.SearchAssets = searchWindow.AssetType;
}
if (query != null)
{
_searchWin.Query = query;
_searchWin.Search();
}
}
///
/// Shows the content finder popup.
///
/// The target control to show finder over it.
public void ShowFinder(Control control)
{
var finder = _finder ?? (_finder = new ContentFinder());
if (control == null)
control = Editor.Instance.Windows.MainWindow.GUI;
var position = (control.Size - new Float2(finder.Width, 300.0f)) * 0.5f;
finder.Show(control, position);
}
///
/// Adds to quick action list.
///
/// The action's name.
/// The actual action callback.
public void AddQuickAction(string name, Action action)
{
if (_quickActions == null)
_quickActions = new List();
_quickActions.Add(new QuickAction
{
Name = name,
Action = action,
});
}
///
/// Removes a quick action by name.
///
/// The action's name.
/// True when it succeeds, false if there is no Quick Action with this name.
public bool RemoveQuickAction(string name)
{
if (_quickActions == null)
return false;
foreach (var action in _quickActions)
{
if (action.Name.Equals(name))
{
_quickActions.Remove(action);
return true;
}
}
return false;
}
///
/// Searches any assets/scripts/quick actions that match the provided type and name.
///
/// Two pattern can be used, the first one will just take a string without ':' and will only match names.
/// The second looks like this "name:type", it will match name and type. Experimental : You can use regular expressions, might break if you are using ':' character.
/// The results list.
public List Search(string charsToFind)
{
// Special case if searching by object id
if (charsToFind.Length == 32)
{
FlaxEngine.Json.JsonSerializer.ParseID(charsToFind, out var id);
var item = Editor.Instance.ContentDatabase.Find(id);
if (item is AssetItem assetItem)
{
return new List
{
new SearchResult { Name = item.ShortName, Type = assetItem.TypeName, Item = item }
};
}
var actor = FlaxEngine.Object.Find(ref id, true);
if (actor != null)
{
return new List
{
new SearchResult { Name = actor.Name, Type = actor.TypeName, Item = actor }
};
}
var script = FlaxEngine.Object.Find