diff --git a/Source/Editor/Content/Tree/ContentItemTreeNode.cs b/Source/Editor/Content/Tree/ContentItemTreeNode.cs index 09d1ec01b..6fd2f1ebc 100644 --- a/Source/Editor/Content/Tree/ContentItemTreeNode.cs +++ b/Source/Editor/Content/Tree/ContentItemTreeNode.cs @@ -128,28 +128,6 @@ public sealed class ContentItemTreeNode : TreeNode, IContentItemOwner return base.OnMouseDoubleClickHeader(ref location, button); } - /// - 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); - } - /// protected override void DoDragDrop() { diff --git a/Source/Editor/Content/Tree/TreeViewPanel.cs b/Source/Editor/Content/Tree/TreeViewPanel.cs new file mode 100644 index 000000000..90666b3b6 --- /dev/null +++ b/Source/Editor/Content/Tree/TreeViewPanel.cs @@ -0,0 +1,183 @@ +using System.Collections.Generic; +using FlaxEditor.GUI.Tree; +using FlaxEditor.Options; +using FlaxEngine; +using FlaxEngine.GUI; + +namespace FlaxEditor.Content; + +/// +/// The content tree view panel. +/// +public class TreeViewPanel : Panel +{ + /// + /// The content tree assigned to this panel. + /// + public Tree ContentTree; + + private InputActionsContainer _inputActions; + private bool _isCutting; + private List _cutItems = new List(); + + /// + /// Initializes a new instance of the class. + /// + 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(); + 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(); + } + + /// + 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); + } +} diff --git a/Source/Editor/Windows/ContentWindow.cs b/Source/Editor/Windows/ContentWindow.cs index 2141b283e..5a73530bc 100644 --- a/Source/Editor/Windows/ContentWindow.cs +++ b/Source/Editor/Windows/ContentWindow.cs @@ -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