Add tree view only shortcuts.

This commit is contained in:
2026-04-17 16:13:36 -05:00
parent cf65c442de
commit 22964255e4
3 changed files with 187 additions and 28 deletions
@@ -128,28 +128,6 @@ public sealed class ContentItemTreeNode : TreeNode, IContentItemOwner
return base.OnMouseDoubleClickHeader(ref location, button);
}
/// <inheritdoc />
public override bool OnKeyDown(KeyboardKeys key)
{
if (IsFocused)
{
switch (key)
{
case KeyboardKeys.Return:
Editor.Instance.Windows.ContentWin.Open(Item);
return true;
case KeyboardKeys.F2:
Editor.Instance.Windows.ContentWin.Rename(Item);
return true;
case KeyboardKeys.Delete:
Editor.Instance.Windows.ContentWin.Delete(Item);
return true;
}
}
return base.OnKeyDown(key);
}
/// <inheritdoc />
protected override void DoDragDrop()
{
+183
View File
@@ -0,0 +1,183 @@
using System.Collections.Generic;
using FlaxEditor.GUI.Tree;
using FlaxEditor.Options;
using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.Content;
/// <summary>
/// The content tree view panel.
/// </summary>
public class TreeViewPanel : Panel
{
/// <summary>
/// The content tree assigned to this panel.
/// </summary>
public Tree ContentTree;
private InputActionsContainer _inputActions;
private bool _isCutting;
private List<ContentItem> _cutItems = new List<ContentItem>();
/// <summary>
/// Initializes a new instance of the <see cref="TreeViewPanel"/> class.
/// </summary>
public TreeViewPanel()
: base(ScrollBars.None)
{
// Setup input actions
_inputActions = new InputActionsContainer(new[]
{
new InputActionsContainer.Binding(options => options.Rename, Rename),
new InputActionsContainer.Binding(options => options.Delete, Delete),
new InputActionsContainer.Binding(options => options.Duplicate, Duplicate),
new InputActionsContainer.Binding(options => options.Copy, Copy),
new InputActionsContainer.Binding(options => options.Paste, Paste),
new InputActionsContainer.Binding(options => options.Cut, Cut),
});
}
private void Rename()
{
if (ContentTree == null || !Visible)
return;
var selection = ContentTree.Selection;
if (selection.Count > 0)
{
var node = selection[0];
if (node is ContentItemTreeNode contentNode)
{
Editor.Instance.Windows.ContentWin.Rename(contentNode.Item);
}
}
}
private void Delete()
{
if (ContentTree == null || !Visible)
return;
var selection = ContentTree.Selection;
if (selection.Count > 0)
{
foreach (var node in selection)
{
if (node is ContentItemTreeNode contentNode)
{
Editor.Instance.Windows.ContentWin.Delete(contentNode.Item);
}
}
}
}
private void Duplicate()
{
if (ContentTree == null || !Visible)
return;
var selection = ContentTree.Selection;
if (selection.Count > 0)
{
foreach (var node in selection)
{
if (node is ContentItemTreeNode contentNode)
{
Editor.Instance.Windows.ContentWin.Duplicate(contentNode.Item);
}
}
}
}
private void Copy()
{
if (ContentTree == null || !Visible)
return;
var selection = ContentTree.Selection;
if (selection.Count == 0)
return;
var filePaths = new List<string>();
foreach (var node in selection)
if (node is ContentItemTreeNode contentNode)
filePaths.Add(contentNode.Item.Path);
Clipboard.Files = filePaths.ToArray();
UpdateContentItemCut(false);
}
private void Paste()
{
if (ContentTree == null || !Visible)
return;
var files = Clipboard.Files;
if (files == null || files.Length == 0)
return;
Editor.Instance.Windows.ContentWin.Paste(files, _isCutting);
UpdateContentItemCut(false);
}
private void Cut()
{
if (ContentTree == null || !Visible)
return;
Copy();
UpdateContentItemCut(true);
}
private void UpdateContentItemCut(bool cut)
{
_isCutting = cut;
// Add selection to cut list
if (cut)
{
var selection = ContentTree.Selection;
foreach (var node in selection)
{
if (node is ContentItemTreeNode contentNode)
_cutItems.Add(contentNode.Item);
}
}
// Update item with if it is being cut.
foreach (var item in _cutItems)
{
item.IsBeingCut = cut;
}
// Clean up cut items
if (!cut)
_cutItems.Clear();
}
/// <inheritdoc />
public override bool OnKeyDown(KeyboardKeys key)
{
if (!Visible)
return false;
if (ContentTree == null)
return base.OnKeyDown(key);
if (_inputActions.Process(Editor.Instance, this, key))
return true;
var selection = ContentTree.Selection;
if (selection.Count > 0)
{
if (key == KeyboardKeys.Return)
{
foreach (var node in selection)
{
if (node is ContentItemTreeNode contentNode)
Editor.Instance.Windows.ContentWin.Open(contentNode.Item);
}
}
}
return base.OnKeyDown(key);
}
}
+4 -6
View File
@@ -32,7 +32,7 @@ namespace FlaxEditor.Windows
private string _workspaceRebuildLocation;
private string _lastViewedFolderBeforeReload;
private SplitPanel _split;
private Panel _treeOnlyPanel;
private TreeViewPanel _treeOnlyPanel;
private ContainerControl _treePanelRoot;
private ContainerControl _treeHeaderPanel;
private Panel _contentItemsSearchPanel;
@@ -186,7 +186,7 @@ namespace FlaxEditor.Windows
};
// Tree-only panel (used when showing all content in the tree)
_treeOnlyPanel = new Panel(ScrollBars.None)
_treeOnlyPanel = new TreeViewPanel
{
AnchorPreset = AnchorPresets.StretchAll,
Offsets = new Margin(0, 0, _toolStrip.Bottom, 0),
@@ -237,6 +237,7 @@ namespace FlaxEditor.Windows
Parent = _contentTreePanel,
};
_tree.SelectedChanged += OnTreeSelectionChanged;
_treeOnlyPanel.ContentTree = _tree;
// Content items searching query input box and filters selector
_contentItemsSearchPanel = new Panel
@@ -632,11 +633,7 @@ namespace FlaxEditor.Windows
var area = node.TextRect;
const float minRenameWidth = 220.0f;
if (area.Width < minRenameWidth)
{
float expand = minRenameWidth - area.Width;
area.X -= expand * 0.5f;
area.Width = minRenameWidth;
}
area.Y -= 2;
area.Height += 4.0f;
popup = RenamePopup.Show(node, area, item.ShortName, true);
@@ -889,6 +886,7 @@ namespace FlaxEditor.Windows
// Refresh this folder now and try to find duplicated item
Editor.ContentDatabase.RefreshFolder(item.ParentFolder, true);
RefreshView();
RefreshTreeItems();
var targetItem = item.ParentFolder.FindChild(targetPath);
// Start renaming it