Fix auto-selecting newly imported or created assets in Editor

This commit is contained in:
2026-06-30 08:48:24 +02:00
parent 7f18d04ed4
commit 5cd6c98ff3
6 changed files with 140 additions and 105 deletions
+1 -1
View File
@@ -384,7 +384,7 @@ namespace FlaxEditor.Content.GUI
/// Selects the specified item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="additive">If set to <c>true</c> item will be added to the current selection. Otherwise selection will be cleared before.</param>
/// <param name="additive">If set to <c>true</c> item will be added to the current selection. Otherwise, selection will be cleared before.</param>
public void Select(ContentItem item, bool additive = false)
{
if (item == null)
+12 -3
View File
@@ -138,7 +138,8 @@ namespace FlaxEditor.GUI.Tree
/// Selects single tree node.
/// </summary>
/// <param name="node">Node to select.</param>
public void Select(TreeNode node)
/// <param name="additive">If set to <c>true</c> item will be added to the current selection. Otherwise, selection will be cleared before.</param>
public void Select(TreeNode node, bool additive = false)
{
if (node == null)
throw new ArgumentNullException();
@@ -151,8 +152,16 @@ namespace FlaxEditor.GUI.Tree
var prev = new List<TreeNode>(Selection);
// Update selection
Selection.Clear();
Selection.Add(node);
if (additive)
{
if (!Selection.Contains(node))
Selection.Add(node);
}
else
{
Selection.Clear();
Selection.Add(node);
}
// Ensure that node can be visible (all it's parents are expanded)
node.ExpandAllParents();
@@ -1261,7 +1261,6 @@ namespace FlaxEditor.Modules
private void OnImportFileDone(string path)
{
// Check if already has that element
var item = Find(path);
if (item is BinaryAssetItem binaryAssetItem)
{
@@ -1284,9 +1283,6 @@ namespace FlaxEditor.Modules
binaryAssetItem.OnReimport(ref assetInfo.ID);
}
}
// Refresh content view (not the best design because window could also track this event but it gives better performance)
Editor.Windows.ContentWin?.RefreshView();
}
}
@@ -252,6 +252,8 @@ namespace FlaxEditor.Modules
/// <param name="settings">Import settings to override. Use null to skip this value.</param>
private void Import(string inputPath, string outputPath, bool isInBuilt, bool skipSettingsDialog = false, object settings = null)
{
inputPath = StringUtils.NormalizePath(inputPath);
outputPath = StringUtils.NormalizePath(outputPath);
lock (_requests)
{
_requests.Add(new Request
@@ -311,7 +313,9 @@ namespace FlaxEditor.Modules
}
_importBatchDone++;
Profiler.BeginEvent("ImportFileEnd");
ImportFileEnd?.Invoke(entry, failed);
Profiler.EndEvent();
}
}
else
@@ -81,28 +81,10 @@ namespace FlaxEditor.Windows
_navigationUndo.Push(source);
}
// Show folder contents and select tree node
if (!_showAllContentInTree)
RefreshView(target);
_tree.Select(target);
target.ExpandAllParents();
// Clear redo list
_navigationRedo.Clear();
// Set valid sizes for stacks
//RedoList.SetSize(32);
//UndoList.SetSize(32);
// Update search
if (!_showAllContentInTree)
UpdateItemsSearch();
// Unlock navigation
_navigationUnlocked = true;
// Update UI
UpdateUI();
DoNavigate(target);
}
}
@@ -123,25 +105,7 @@ namespace FlaxEditor.Windows
// Add to Redo list
_navigationRedo.Push(SelectedNode);
// Select node
if (!_showAllContentInTree)
RefreshView(node);
_tree.Select(node);
node.ExpandAllParents();
// Set valid sizes for stacks
//RedoList.SetSize(32);
//UndoList.SetSize(32);
// Update search
if (!_showAllContentInTree)
UpdateItemsSearch();
// Unlock navigation
_navigationUnlocked = true;
// Update UI
UpdateUI();
DoNavigate(node);
if (!_showAllContentInTree)
_view.SelectFirstItem();
}
@@ -164,25 +128,7 @@ namespace FlaxEditor.Windows
// Add to Undo list
_navigationUndo.Push(SelectedNode);
// Select node
if (!_showAllContentInTree)
RefreshView(node);
_tree.Select(node);
node.ExpandAllParents();
// Set valid sizes for stacks
//RedoList.SetSize(32);
//UndoList.SetSize(32);
// Update search
if (!_showAllContentInTree)
UpdateItemsSearch();
// Unlock navigation
_navigationUnlocked = true;
// Update UI
UpdateUI();
DoNavigate(node);
if (!_showAllContentInTree)
_view.SelectFirstItem();
}
@@ -214,6 +160,32 @@ namespace FlaxEditor.Windows
UpdateUI();
}
private void DoNavigate(ContentFolderTreeNode node)
{
// Select node
if (!_showAllContentInTree)
RefreshView(node);
_tree.Select(node);
node.ExpandAllParents();
// Set valid sizes for stacks
//RedoList.SetSize(32);
//UndoList.SetSize(32);
// Update search
if (!_showAllContentInTree)
UpdateItemsSearch();
// Unlock navigation
_navigationUnlocked = true;
UpdateUI();
// Clear auto-select cache for new/imported files
_newFilesCache?.Clear();
_newFilesCacheSize = 0;
}
private void UpdateNavigationBar()
{
if (_navigationBar == null)
+94 -40
View File
@@ -67,6 +67,8 @@ namespace FlaxEditor.Windows
private readonly Stack<ContentFolderTreeNode> _navigationRedo = new Stack<ContentFolderTreeNode>(32);
private NewItem _newElement;
private List<string> _newFilesCache;
private int _newFilesCacheSize;
/// <summary>
/// Gets the toolstrip.
@@ -598,21 +600,9 @@ namespace FlaxEditor.Windows
// Disable scrolling in proper view
_renameInTree = _showAllContentInTree;
if (_renameInTree)
{
if (_contentTreePanel.VScrollBar != null)
_contentTreePanel.VScrollBar.ThumbEnabled = false;
if (_contentTreePanel.HScrollBar != null)
_contentTreePanel.HScrollBar.ThumbEnabled = false;
ScrollingOnTreeView(false);
}
else
{
if (_contentViewPanel.VScrollBar != null)
_contentViewPanel.VScrollBar.ThumbEnabled = false;
if (_contentViewPanel.HScrollBar != null)
_contentViewPanel.HScrollBar.ThumbEnabled = false;
ScrollingOnContentView(false);
}
// Show rename popup
RenamePopup popup;
@@ -664,21 +654,9 @@ namespace FlaxEditor.Windows
{
// Restore scrolling in proper view
if (_renameInTree)
{
if (_contentTreePanel.VScrollBar != null)
_contentTreePanel.VScrollBar.ThumbEnabled = true;
if (_contentTreePanel.HScrollBar != null)
_contentTreePanel.HScrollBar.ThumbEnabled = true;
ScrollingOnTreeView(true);
}
else
{
if (_contentViewPanel.VScrollBar != null)
_contentViewPanel.VScrollBar.ThumbEnabled = true;
if (_contentViewPanel.HScrollBar != null)
_contentViewPanel.HScrollBar.ThumbEnabled = true;
ScrollingOnContentView(true);
}
_renameInTree = false;
// Check if was creating new element
@@ -704,7 +682,6 @@ namespace FlaxEditor.Windows
// Check if can rename this item
if (!item.CanRename)
{
// Cannot
MessageBox.Show("Cannot rename this item.", "Cannot rename", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
@@ -718,7 +695,6 @@ namespace FlaxEditor.Windows
// Check if name is valid
if (!Editor.ContentEditing.IsValidAssetName(item, newShortName, out string hint))
{
// Invalid name
MessageBox.Show("Given asset name is invalid. " + hint, "Invalid name", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
@@ -740,6 +716,7 @@ namespace FlaxEditor.Windows
// Note: we create `_newElement` and then rename it to create new asset
var itemFolder = item.ParentFolder;
Action<ContentItem> endEvent = null;
bool lazyCreation = false;
if (_newElement == item)
{
try
@@ -750,6 +727,9 @@ namespace FlaxEditor.Windows
var proxy = _newElement.Proxy;
Editor.Log(string.Format("Creating asset {0} in {1}", proxy.Name, newPath));
proxy.Create(newPath, _newElement.Argument);
// When creating item with options dialog deffer processing
lazyCreation = !File.Exists(newPath);
}
catch (Exception ex)
{
@@ -773,6 +753,16 @@ namespace FlaxEditor.Windows
if (_newElement.Proxy is ScriptProxy && Editor.Instance.Options.Options.General.AutoReloadScriptsOnMainWindowFocus)
ScriptsBuilder.MarkWorkspaceDirty();
// Cache new file to be auto-selected after actual creation
_newFilesCache?.Clear();
_newFilesCacheSize = 0;
if (lazyCreation)
{
_newFilesCache ??= new List<string>();
_newFilesCache.Add(newPath);
_newFilesCacheSize = 1;
}
// Destroy mock control
_newElement.ParentFolder = null;
_newElement.Dispose();
@@ -789,7 +779,8 @@ namespace FlaxEditor.Windows
var newItem = itemFolder.FindChild(newPath);
if (newItem == null)
{
Editor.LogWarning("Failed to find the created new item.");
if (!lazyCreation)
Editor.LogWarning("Failed to find the created new item.");
return;
}
@@ -1143,11 +1134,12 @@ namespace FlaxEditor.Windows
}
/// <summary>
/// Selects the specified item in the content view.
/// Selects the specified item in the content view. Does nothing if the current view doesn't show the folder containing that item.
/// </summary>
/// <param name="item">The item to select.</param>
/// <param name="fastScroll">True of scroll to the item quickly without smoothing.</param>
public void Select(ContentItem item, bool fastScroll = false)
/// <param name="additive">True of select item in additive mode with existing selection preservation, otherwise current selection will be cleared.</param>
public void Select(ContentItem item, bool fastScroll = false, bool additive = false)
{
if (item == null)
throw new ArgumentNullException();
@@ -1169,7 +1161,7 @@ namespace FlaxEditor.Windows
targetNode.ExpandAllParents();
if (item is ContentFolder)
{
_tree.Select(targetNode);
_tree.Select(targetNode, additive);
_contentTreePanel.ScrollViewTo(targetNode, fastScroll);
targetNode.Focus();
}
@@ -1178,13 +1170,13 @@ namespace FlaxEditor.Windows
var itemNode = FindTreeItemNode(targetNode, item);
if (itemNode != null)
{
_tree.Select(itemNode);
_tree.Select(itemNode, additive);
_contentTreePanel.ScrollViewTo(itemNode, fastScroll);
itemNode.Focus();
}
else
{
_tree.Select(targetNode);
_tree.Select(targetNode, additive);
}
}
}
@@ -1195,7 +1187,7 @@ namespace FlaxEditor.Windows
Navigate(parent.Node);
// Select and scroll to cover in view
_view.Select(item);
_view.Select(item, additive);
_contentViewPanel.ScrollViewTo(item, fastScroll);
// Focus
@@ -1574,7 +1566,7 @@ namespace FlaxEditor.Windows
/// <inheritdoc />
public override void OnInit()
{
// Content database events
// Content events
Editor.ContentDatabase.WorkspaceModified += () => _isWorkspaceDirty = true;
Editor.ContentDatabase.ItemAdded += OnContentDatabaseItemAdded;
Editor.ContentDatabase.ItemRemoved += OnContentDatabaseItemRemoved;
@@ -1594,6 +1586,9 @@ namespace FlaxEditor.Windows
else if (_root != null)
ShowRoot();
};
Editor.ContentImporting.ImportFileBegin += OnImportFileBegin;
Editor.ContentImporting.ImportFileEnd += OnImportFileEnd;
Editor.ContentImporting.ImportingQueueBegin += OnImportingQueueBegin;
LoadExpandedFolders();
Refresh();
@@ -1631,6 +1626,64 @@ namespace FlaxEditor.Windows
OnFoldersSearchBoxTextChanged();
}
private void OnImportFileBegin(IFileEntryAction entry)
{
// Add to auto-select cache
_newFilesCache ??= new List<string>();
_newFilesCache.Add(entry.ResultUrl);
_newFilesCacheSize++;
}
private void OnImportFileEnd(IFileEntryAction entry, bool failed)
{
if (failed)
return;
if (!Platform.IsInMainThread)
{
FlaxEngine.Scripting.InvokeOnUpdate(() => OnImportFileEnd(entry, false));
return;
}
// Refresh view (gives faster response than waiting for filesystem event)
//RefreshView(); // TODO: is this still needed?
// Auto-select pending items
if (_newFilesCache != null && _newFilesCache.Contains(entry.ResultUrl))
{
var item = EnsureItem(entry.ResultUrl);
if (item != null)
{
bool additive = _newFilesCache.Count != _newFilesCacheSize;
Select(item, true, additive);
}
_newFilesCache.Remove(entry.ResultUrl);
}
}
private void OnImportingQueueBegin()
{
// Clear cache to auto-select all imported files
_newFilesCache?.Clear();
_newFilesCacheSize = 0;
}
private ContentItem EnsureItem(string path)
{
var item = Editor.ContentDatabase.Find(path);
if (item == null)
{
// Cannot find the item (eg. just created file, content database event not yet handled) so refresh to take effect quickly
var parentPath = Path.GetDirectoryName(path);
var parentItem = Editor.ContentDatabase.Find(parentPath);
if (parentItem != null)
{
Editor.ContentDatabase.RefreshFolder(parentItem, false);
item = Editor.ContentDatabase.Find(path);
}
}
return item;
}
private void Refresh()
{
// Setup content root node
@@ -1774,16 +1827,11 @@ namespace FlaxEditor.Windows
return base.OnMouseUp(location, button);
}
/// <inheritdoc />
protected override void PerformLayoutBeforeChildren()
{
base.PerformLayoutBeforeChildren();
}
/// <inheritdoc />
protected override void PerformLayoutAfterChildren()
{
base.PerformLayoutAfterChildren();
UpdateNavigationBarBounds();
}
@@ -1846,12 +1894,18 @@ namespace FlaxEditor.Windows
_treeHeaderPanel = null;
_treeOnlyPanel = null;
_contentItemsSearchPanel = null;
_newFilesCache = null;
Editor.Options.OptionsChanged -= OnOptionsChanged;
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
ScriptsBuilder.ScriptsReloadEnd -= OnScriptsReloadEnd;
if (Editor?.ContentDatabase != null)
{
Editor.ContentDatabase.ItemAdded -= OnContentDatabaseItemAdded;
Editor.ContentImporting.ImportFileBegin -= OnImportFileBegin;
Editor.ContentImporting.ImportFileEnd -= OnImportFileEnd;
Editor.ContentImporting.ImportingQueueBegin -= OnImportingQueueBegin;
}
base.OnDestroy();
}