copy multiple nodes

This commit is contained in:
Matt Parker
2025-10-21 21:27:15 +10:00
parent 475ef08ee2
commit 0f259fa4c7
3 changed files with 52 additions and 21 deletions

View File

@@ -7,37 +7,54 @@ namespace SharpIDE.Godot.Features.SolutionExplorer;
public partial class SolutionExplorerPanel
{
private void CopySelectedNodeToSlnExplorerClipboard()
private void CopySelectedNodesToSlnExplorerClipboard() => AddSelectedNodesToSlnExplorerClipboard(ClipboardOperation.Copy);
private void CutSelectedNodeToSlnExplorerClipboard() => AddSelectedNodesToSlnExplorerClipboard(ClipboardOperation.Cut);
private void AddSelectedNodesToSlnExplorerClipboard(ClipboardOperation clipboardOperation)
{
var selected = _tree.GetSelected();
if (selected is null) return;
var genericMetadata = selected.GetMetadata(0).As<RefCounted?>();
if (genericMetadata is RefCountedContainer<SharpIdeFile> fileContainer)
{
_itemOnClipboard = (fileContainer.Item, ClipboardOperation.Copy);
}
var selectedItems = GetSelectedTreeItems();
if (selectedItems.Count is 0) return;
_itemsOnClipboard = (selectedItems
.Select(item => item.GetMetadata(0).As<RefCounted?>())
.OfType<RefCountedContainer<SharpIdeFile>>()
.Select(s => s.Item)
.ToList(),
ClipboardOperation.Copy);
}
private void CutSelectedNodeToSlnExplorerClipboard()
private List<TreeItem> GetSelectedTreeItems()
{
var selected = _tree.GetSelected();
if (selected is null) return;
var genericMetadata = selected.GetMetadata(0).As<RefCounted?>();
if (genericMetadata is RefCountedContainer<SharpIdeFile> fileContainer)
var selectedItems = new List<TreeItem>();
var currentItem = _tree.GetNextSelected(null);
while (currentItem != null)
{
_itemOnClipboard = (fileContainer.Item, ClipboardOperation.Cut);
selectedItems.Add(currentItem);
currentItem = _tree.GetNextSelected(currentItem);
}
return selectedItems;
}
private bool HasMultipleNodesSelected()
{
var selectedCount = 0;
var currentItem = _tree.GetNextSelected(null);
while (currentItem != null)
{
selectedCount++;
if (selectedCount > 1) return true;
currentItem = _tree.GetNextSelected(currentItem);
}
return false;
}
private void ClearSlnExplorerClipboard()
{
_itemOnClipboard = null;
_itemsOnClipboard = null;
}
private void CopyNodeFromClipboardToSelectedNode()
{
var selected = _tree.GetSelected();
if (selected is null || _itemOnClipboard is null) return;
if (selected is null || _itemsOnClipboard is null) return;
var genericMetadata = selected.GetMetadata(0).As<RefCounted?>();
IFolderOrProject? folderOrProject = genericMetadata switch
{
@@ -47,13 +64,16 @@ public partial class SolutionExplorerPanel
};
if (folderOrProject is null) return;
var (fileToPaste, operation) = _itemOnClipboard.Value;
_itemOnClipboard = null;
var (filesToPaste, operation) = _itemsOnClipboard.Value;
_itemsOnClipboard = null;
_ = Task.GodotRun(async () =>
{
if (operation is ClipboardOperation.Copy)
{
await _ideFileOperationsService.CopyFile(folderOrProject, fileToPaste.Path, fileToPaste.Name);
foreach (var fileToPaste in filesToPaste)
{
await _ideFileOperationsService.CopyFile(folderOrProject, fileToPaste.Path, fileToPaste.Name);
}
}
});
}

View File

@@ -28,7 +28,8 @@ public partial class SolutionExplorerPanel : MarginContainer
private Tree _tree = null!;
private TreeItem _rootItem = null!;
private enum ClipboardOperation { Cut, Copy }
private (SharpIdeFile, ClipboardOperation)? _itemOnClipboard;
private (List<SharpIdeFile>, ClipboardOperation)? _itemsOnClipboard;
public override void _Ready()
{
_tree = GetNode<Tree>("Tree");
@@ -41,7 +42,7 @@ public partial class SolutionExplorerPanel : MarginContainer
// Copy
if (@event is InputEventKey { Pressed: true, Keycode: Key.C, CtrlPressed: true })
{
CopySelectedNodeToSlnExplorerClipboard();
CopySelectedNodesToSlnExplorerClipboard();
}
// Cut
else if (@event is InputEventKey { Pressed: true, Keycode: Key.X, CtrlPressed: true })
@@ -53,12 +54,21 @@ public partial class SolutionExplorerPanel : MarginContainer
{
CopyNodeFromClipboardToSelectedNode();
}
else if (@event is InputEventKey { Pressed: true, Keycode: Key.Delete })
{
// TODO: DeleteSelectedNodes();
}
else if (@event is InputEventKey { Pressed: true, Keycode: Key.Escape })
{
ClearSlnExplorerClipboard();
}
}
private void TreeOnItemMouseSelected(Vector2 mousePosition, long mouseButtonIndex)
{
var selected = _tree.GetSelected();
if (selected is null) return;
if (HasMultipleNodesSelected()) return;
var mouseButtonMask = (MouseButtonMask)mouseButtonIndex;

View File

@@ -27,3 +27,4 @@ theme_override_constants/v_separation = 1
theme_override_constants/inner_item_margin_left = 2
theme_override_constants/draw_guides = 0
allow_rmb_select = true
select_mode = 2