From 416f208ae0a75da5ccaaabdd2381ffb8dfcbe8f2 Mon Sep 17 00:00:00 2001 From: Matt Parker <61717342+MattParkerDev@users.noreply.github.com> Date: Fri, 10 Oct 2025 19:08:28 +1000 Subject: [PATCH] more context menus --- .../SolutionExplorer/SolutionExplorerPanel.cs | 138 +++++++++++++----- 1 file changed, 102 insertions(+), 36 deletions(-) diff --git a/src/SharpIDE.Godot/Features/SolutionExplorer/SolutionExplorerPanel.cs b/src/SharpIDE.Godot/Features/SolutionExplorer/SolutionExplorerPanel.cs index fb88cfa..ef63b48 100644 --- a/src/SharpIDE.Godot/Features/SolutionExplorer/SolutionExplorerPanel.cs +++ b/src/SharpIDE.Godot/Features/SolutionExplorer/SolutionExplorerPanel.cs @@ -33,48 +33,114 @@ public partial class SolutionExplorerPanel : MarginContainer { var selected = _tree.GetSelected(); if (selected is null) return; - var sharpIdeFileContainer = selected.GetTypedMetadata?>(0); - if (sharpIdeFileContainer is null) return; - var sharpIdeFile = sharpIdeFileContainer.Item; - Guard.Against.Null(sharpIdeFile, nameof(sharpIdeFile)); - if (mouseButtonIndex is (int)MouseButtonMask.Left) + var mouseButtonMask = (MouseButtonMask)mouseButtonIndex; + + var genericMetadata = selected.GetMetadata(0).As(); + switch (mouseButtonMask, genericMetadata) { - GodotGlobalEvents.Instance.FileSelected.InvokeParallelFireAndForget(sharpIdeFile, null); + case (MouseButtonMask.Left, RefCountedContainer fileContainer): GodotGlobalEvents.Instance.FileSelected.InvokeParallelFireAndForget(fileContainer.Item, null); break; + case (MouseButtonMask.Right, RefCountedContainer fileContainer): OpenContextMenuFile(fileContainer.Item); break; + case (MouseButtonMask.Left, RefCountedContainer): break; + case (MouseButtonMask.Right, RefCountedContainer projectContainer): OpenContextMenuProject(projectContainer.Item); break; + case (MouseButtonMask.Left, RefCountedContainer): break; + case (MouseButtonMask.Right, RefCountedContainer folderContainer): OpenContextMenuFolder(folderContainer.Item); break; + case (MouseButtonMask.Left, RefCountedContainer): break; + default: break; } - else if (mouseButtonIndex is (int)MouseButtonMask.Right) + } + + private void OpenContextMenuFolder(SharpIdeFolder folder) + { + var menu = new PopupMenu(); + AddChild(menu); + menu.AddItem("Reveal in File Explorer", 0); + menu.PopupHide += () => menu.QueueFree(); + menu.IdPressed += id => { - var menu = new PopupMenu(); - AddChild(menu); - menu.AddItem("Open", 0); - menu.AddItem("Reveal in File Explorer", 1); - menu.AddSeparator(); - menu.AddItem("Copy Full Path", 2); - menu.PopupHide += () => + if (id is 0) { - GD.Print("QueueFree menu"); - menu.QueueFree(); - }; - menu.IdPressed += id => - { - if (id is 0) - { - GodotGlobalEvents.Instance.FileSelected.InvokeParallelFireAndForget(sharpIdeFile, null); - } - else if (id is 1) - { - OS.ShellOpen(Path.GetDirectoryName(sharpIdeFile.Path)!); - } - else if (id is 2) - { - DisplayServer.ClipboardSet(sharpIdeFile.Path); - } - }; + // Reveal in File Explorer + OS.ShellOpen(folder.Path); + } + }; - var globalMousePosition = GetGlobalMousePosition(); - menu.Position = new Vector2I((int)globalMousePosition.X, (int)globalMousePosition.Y); - menu.Popup(); - } + var globalMousePosition = GetGlobalMousePosition(); + menu.Position = new Vector2I((int)globalMousePosition.X, (int)globalMousePosition.Y); + menu.Popup(); + } + + private void OpenContextMenuProject(SharpIdeProjectModel project) + { + var menu = new PopupMenu(); + AddChild(menu); + menu.AddItem("Run", 0); + menu.AddSeparator(); + menu.AddItem("Build", 1); + menu.AddItem("Rebuild", 2); + menu.AddItem("Clean", 3); + menu.PopupHide += () => + { + GD.Print("QueueFree menu"); + menu.QueueFree(); + }; + menu.IdPressed += id => + { + if (id is 0) + { + // Run project + } + if (id is 1) + { + // Build project + } + else if (id is 2) + { + // Rebuild project + } + else if (id is 3) + { + // Clean project + } + }; + + var globalMousePosition = GetGlobalMousePosition(); + menu.Position = new Vector2I((int)globalMousePosition.X, (int)globalMousePosition.Y); + menu.Popup(); + } + + private void OpenContextMenuFile(SharpIdeFile file) + { + var menu = new PopupMenu(); + AddChild(menu); + menu.AddItem("Open", 0); + menu.AddItem("Reveal in File Explorer", 1); + menu.AddSeparator(); + menu.AddItem("Copy Full Path", 2); + menu.PopupHide += () => + { + GD.Print("QueueFree menu"); + menu.QueueFree(); + }; + menu.IdPressed += id => + { + if (id is 0) + { + GodotGlobalEvents.Instance.FileSelected.InvokeParallelFireAndForget(file, null); + } + else if (id is 1) + { + OS.ShellOpen(Path.GetDirectoryName(file.Path)!); + } + else if (id is 2) + { + DisplayServer.ClipboardSet(file.Path); + } + }; + + var globalMousePosition = GetGlobalMousePosition(); + menu.Position = new Vector2I((int)globalMousePosition.X, (int)globalMousePosition.Y); + menu.Popup(); } private async Task OnFileExternallySelected(SharpIdeFile file, SharpIdeFileLinePosition? fileLinePosition)