diff --git a/src/SharpIDE.Application/Features/FileWatching/SharpIdeSolutionModificationService.cs b/src/SharpIDE.Application/Features/FileWatching/SharpIdeSolutionModificationService.cs index 1dc21df..1ac1e74 100644 --- a/src/SharpIDE.Application/Features/FileWatching/SharpIdeSolutionModificationService.cs +++ b/src/SharpIDE.Application/Features/FileWatching/SharpIdeSolutionModificationService.cs @@ -143,7 +143,7 @@ public class SharpIdeSolutionModificationService(FileChangedService fileChangedS public async Task CreateFile(IFolderOrProject parentNode, string newFilePath, string fileName, string contents) { - var sharpIdeFile = new SharpIdeFile(newFilePath, fileName, parentNode, []); + var sharpIdeFile = new SharpIdeFile(newFilePath, fileName, Path.GetExtension(newFilePath), parentNode, []); var correctInsertionPosition = GetInsertionPosition(parentNode, sharpIdeFile); diff --git a/src/SharpIDE.Application/Features/SolutionDiscovery/SharpIdeFile.cs b/src/SharpIDE.Application/Features/SolutionDiscovery/SharpIdeFile.cs index 68eadd7..60ad24b 100644 --- a/src/SharpIDE.Application/Features/SolutionDiscovery/SharpIdeFile.cs +++ b/src/SharpIDE.Application/Features/SolutionDiscovery/SharpIdeFile.cs @@ -12,6 +12,7 @@ public class SharpIdeFile : ISharpIdeNode, IChildSharpIdeNode, IFileOrFolder public required IExpandableSharpIdeNode Parent { get; set; } public required string Path { get; set; } public required string Name { get; set; } + public required string Extension { get; set; } public bool IsRazorFile => Path.EndsWith(".razor", StringComparison.OrdinalIgnoreCase); public bool IsCsprojFile => Path.EndsWith(".csproj", StringComparison.OrdinalIgnoreCase); public bool IsCshtmlFile => Path.EndsWith(".cshtml", StringComparison.OrdinalIgnoreCase); @@ -25,10 +26,11 @@ public class SharpIdeFile : ISharpIdeNode, IChildSharpIdeNode, IFileOrFolder public EventWrapper FileDeleted { get; } = new(() => Task.CompletedTask); [SetsRequiredMembers] - internal SharpIdeFile(string fullPath, string name, IExpandableSharpIdeNode parent, ConcurrentBag allFiles) + internal SharpIdeFile(string fullPath, string name, string extension, IExpandableSharpIdeNode parent, ConcurrentBag allFiles) { Path = fullPath; Name = name; + Extension = extension; Parent = parent; IsDirty = new ReactiveProperty(false); SuppressDiskChangeEvents = false; diff --git a/src/SharpIDE.Application/Features/SolutionDiscovery/TreeMapperV2.cs b/src/SharpIDE.Application/Features/SolutionDiscovery/TreeMapperV2.cs index c8a2d07..842a460 100644 --- a/src/SharpIDE.Application/Features/SolutionDiscovery/TreeMapperV2.cs +++ b/src/SharpIDE.Application/Features/SolutionDiscovery/TreeMapperV2.cs @@ -75,7 +75,7 @@ public static class TreeMapperV2 return []; } - var sharpIdeFiles = fileInfos.Select(f => new SharpIdeFile(f.FullName, f.Name, parent, allFiles) + var sharpIdeFiles = fileInfos.Select(f => new SharpIdeFile(f.FullName, f.Name, f.Extension, parent, allFiles) { Path = f.FullName, Name = f.Name, diff --git a/src/SharpIDE.Application/Features/SolutionDiscovery/VsPersistence/IntermediateMapper.cs b/src/SharpIDE.Application/Features/SolutionDiscovery/VsPersistence/IntermediateMapper.cs index cb7ffee..8165f2b 100644 --- a/src/SharpIDE.Application/Features/SolutionDiscovery/VsPersistence/IntermediateMapper.cs +++ b/src/SharpIDE.Application/Features/SolutionDiscovery/VsPersistence/IntermediateMapper.cs @@ -14,7 +14,7 @@ public static class IntermediateMapper var serializer = SolutionSerializers.GetSerializerByMoniker(solutionFilePath); Guard.Against.Null(serializer, nameof(serializer)); var vsSolution = await serializer.OpenAsync(solutionFilePath, cancellationToken); - + // Remove any projects that aren't csproj, TODO: Instead of removing, display in the solution explorer that the project type isn't supported foreach (var vsSolutionSolutionProject in vsSolution.SolutionProjects.Where(s => s.Extension is not ".csproj").ToList()) { @@ -59,10 +59,15 @@ public static class IntermediateMapper .ToList(); var filesInFolder = folder.Files? - .Select(f => new IntermediateSlnFolderFileModel + .Select(f => { - Name = Path.GetFileName(f), - FullPath = new FileInfo(Path.Join(Path.GetDirectoryName(solutionFilePath), f)).FullName + var fileInfo = new FileInfo(Path.Join(Path.GetDirectoryName(solutionFilePath), f)); + return new IntermediateSlnFolderFileModel + { + Name = Path.GetFileName(f), + FullPath = fileInfo.FullName, + Extension = fileInfo.Extension + }; }) .ToList() ?? []; diff --git a/src/SharpIDE.Application/Features/SolutionDiscovery/VsPersistence/IntermediateModels.cs b/src/SharpIDE.Application/Features/SolutionDiscovery/VsPersistence/IntermediateModels.cs index 4b2261a..5c72bb6 100644 --- a/src/SharpIDE.Application/Features/SolutionDiscovery/VsPersistence/IntermediateModels.cs +++ b/src/SharpIDE.Application/Features/SolutionDiscovery/VsPersistence/IntermediateModels.cs @@ -29,4 +29,5 @@ internal class IntermediateSlnFolderFileModel { public required string Name { get; set; } public required string FullPath { get; set; } + public required string Extension { get; set; } } diff --git a/src/SharpIDE.Application/Features/SolutionDiscovery/VsPersistence/SharpIdeModels.cs b/src/SharpIDE.Application/Features/SolutionDiscovery/VsPersistence/SharpIdeModels.cs index d79ec15..9195cab 100644 --- a/src/SharpIDE.Application/Features/SolutionDiscovery/VsPersistence/SharpIdeModels.cs +++ b/src/SharpIDE.Application/Features/SolutionDiscovery/VsPersistence/SharpIdeModels.cs @@ -90,7 +90,7 @@ public class SharpIdeSolutionFolder : ISharpIdeNode, IExpandableSharpIdeNode, IC { Name = intermediateModel.Model.Name; Parent = parent; - Files = new ObservableHashSet(intermediateModel.Files.Select(s => new SharpIdeFile(s.FullPath, s.Name, this, allFiles))); + Files = new ObservableHashSet(intermediateModel.Files.Select(s => new SharpIdeFile(s.FullPath, s.Name, s.Extension, this, allFiles))); Folders = new ObservableHashSet(intermediateModel.Folders.Select(x => new SharpIdeSolutionFolder(x, allProjects, allFiles, allFolders, this))); Projects = new ObservableHashSet(intermediateModel.Projects.Select(x => new SharpIdeProjectModel(x, allProjects, allFiles, allFolders, this))); } diff --git a/src/SharpIDE.Godot/Features/SolutionExplorer/Resources/FileExtensions/RazorFile.svg b/src/SharpIDE.Godot/Features/SolutionExplorer/Resources/FileExtensions/RazorFile.svg new file mode 100644 index 0000000..600d12c --- /dev/null +++ b/src/SharpIDE.Godot/Features/SolutionExplorer/Resources/FileExtensions/RazorFile.svg @@ -0,0 +1,82 @@ + + diff --git a/src/SharpIDE.Godot/Features/SolutionExplorer/Resources/FileExtensions/RazorFile.svg.import b/src/SharpIDE.Godot/Features/SolutionExplorer/Resources/FileExtensions/RazorFile.svg.import new file mode 100644 index 0000000..b1028cc --- /dev/null +++ b/src/SharpIDE.Godot/Features/SolutionExplorer/Resources/FileExtensions/RazorFile.svg.import @@ -0,0 +1,18 @@ +[remap] + +importer="svg" +type="DPITexture" +uid="uid://cff7jlvj2tlg2" +path="res://.godot/imported/RazorFile.svg-08f0ff289353f8dee724d8123b417b7b.dpitex" + +[deps] + +source_file="res://Features/SolutionExplorer/Resources/FileExtensions/RazorFile.svg" +dest_files=["res://.godot/imported/RazorFile.svg-08f0ff289353f8dee724d8123b417b7b.dpitex"] + +[params] + +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/src/SharpIDE.Godot/Features/SolutionExplorer/SolutionExplorerPanel.FileIcons.cs b/src/SharpIDE.Godot/Features/SolutionExplorer/SolutionExplorerPanel.FileIcons.cs new file mode 100644 index 0000000..fe66c6c --- /dev/null +++ b/src/SharpIDE.Godot/Features/SolutionExplorer/SolutionExplorerPanel.FileIcons.cs @@ -0,0 +1,21 @@ + +using Godot; + +namespace SharpIDE.Godot.Features.SolutionExplorer; + +public partial class SolutionExplorerPanel +{ + private readonly Texture2D _csIcon = ResourceLoader.Load("uid://do0edciarrnp0"); + private readonly Texture2D _razorIcon = ResourceLoader.Load("uid://cff7jlvj2tlg2"); + + private Texture2D GetIconForFileExtension(string fileExtension) + { + var texture = fileExtension switch + { + ".cs" => _csIcon, + ".razor" or ".cshtml" => _razorIcon, + _ => _csIcon + }; + return texture; + } +} \ No newline at end of file diff --git a/src/SharpIDE.Godot/Features/SolutionExplorer/SolutionExplorerPanel.FileIcons.cs.uid b/src/SharpIDE.Godot/Features/SolutionExplorer/SolutionExplorerPanel.FileIcons.cs.uid new file mode 100644 index 0000000..6cc9825 --- /dev/null +++ b/src/SharpIDE.Godot/Features/SolutionExplorer/SolutionExplorerPanel.FileIcons.cs.uid @@ -0,0 +1 @@ +uid://bwr8t3txvnnux diff --git a/src/SharpIDE.Godot/Features/SolutionExplorer/SolutionExplorerPanel.cs b/src/SharpIDE.Godot/Features/SolutionExplorer/SolutionExplorerPanel.cs index 2569267..7c8607b 100644 --- a/src/SharpIDE.Godot/Features/SolutionExplorer/SolutionExplorerPanel.cs +++ b/src/SharpIDE.Godot/Features/SolutionExplorer/SolutionExplorerPanel.cs @@ -299,7 +299,7 @@ public partial class SolutionExplorerPanel : MarginContainer } var fileItem = tree.CreateItem(parent, newStartingIndex); fileItem.SetText(0, sharpIdeFile.Name); - fileItem.SetIcon(0, CsharpFileIcon); + fileItem.SetIcon(0, GetIconForFileExtension(sharpIdeFile.Extension)); fileItem.SetCustomColor(0, GetColorForGitStatus(sharpIdeFile.GitStatus)); fileItem.SetMetadata(0, new RefCountedContainer(sharpIdeFile));