From 5b4eac6d5c064426b62b393d9535bb550258678b Mon Sep 17 00:00:00 2001 From: Hendrik Mennen Date: Thu, 17 Oct 2024 10:56:41 -0500 Subject: [PATCH 1/7] library explorer init --- OneWare.sln | 7 + src/OneWare.Core/App.axaml.cs | 2 + src/OneWare.Core/OneWare.Core.csproj | 1 + .../LibraryExplorerModule.cs | 37 ++++++ .../OneWare.LibraryExplorer.csproj | 16 +++ .../ViewModels/LibraryExplorerViewModel.cs | 20 +++ .../Views/LibraryExplorerView.axaml | 124 ++++++++++++++++++ .../Views/LibraryExplorerView.axaml.cs | 30 +++++ .../ViewModels/ProjectExplorerViewModel.cs | 10 +- .../ViewModels/ProjectViewModelBase.cs | 7 + 10 files changed, 245 insertions(+), 9 deletions(-) create mode 100644 src/OneWare.LibraryExplorer/LibraryExplorerModule.cs create mode 100644 src/OneWare.LibraryExplorer/OneWare.LibraryExplorer.csproj create mode 100644 src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs create mode 100644 src/OneWare.LibraryExplorer/Views/LibraryExplorerView.axaml create mode 100644 src/OneWare.LibraryExplorer/Views/LibraryExplorerView.axaml.cs diff --git a/OneWare.sln b/OneWare.sln index 06379d06..51aa216f 100644 --- a/OneWare.sln +++ b/OneWare.sln @@ -170,6 +170,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OneWare.UniversalFpgaProjec EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OneWare.CruviAdapterExtensions", "src\OneWare.CruviAdapterExtensions\OneWare.CruviAdapterExtensions.csproj", "{01BC6288-6AD8-4D70-9360-F84601CCBA56}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OneWare.LibraryExplorer", "src\OneWare.LibraryExplorer\OneWare.LibraryExplorer.csproj", "{2E44F2EC-6C27-4E44-8F03-E6D95C9B8B34}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -360,6 +362,10 @@ Global {01BC6288-6AD8-4D70-9360-F84601CCBA56}.Debug|Any CPU.Build.0 = Debug|Any CPU {01BC6288-6AD8-4D70-9360-F84601CCBA56}.Release|Any CPU.ActiveCfg = Release|Any CPU {01BC6288-6AD8-4D70-9360-F84601CCBA56}.Release|Any CPU.Build.0 = Release|Any CPU + {2E44F2EC-6C27-4E44-8F03-E6D95C9B8B34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2E44F2EC-6C27-4E44-8F03-E6D95C9B8B34}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2E44F2EC-6C27-4E44-8F03-E6D95C9B8B34}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2E44F2EC-6C27-4E44-8F03-E6D95C9B8B34}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {F08B36E8-AB80-42CD-BD47-6B05E96DA390} = {0761690C-7DA0-4554-9F6B-211088412DCD} @@ -416,5 +422,6 @@ Global {AAC4D6FA-4F94-4616-93B3-3BB47E4A0BB1} = {EB783E04-C3C8-45F8-B810-24798DAE2450} {484F3E48-EF14-4801-B896-41BDB67A54E6} = {EB783E04-C3C8-45F8-B810-24798DAE2450} {01BC6288-6AD8-4D70-9360-F84601CCBA56} = {53C7F88A-3B98-4AB4-992B-71C1F91F1BA7} + {2E44F2EC-6C27-4E44-8F03-E6D95C9B8B34} = {0761690C-7DA0-4554-9F6B-211088412DCD} EndGlobalSection EndGlobal diff --git a/src/OneWare.Core/App.axaml.cs b/src/OneWare.Core/App.axaml.cs index 0196f93d..5fecdf30 100644 --- a/src/OneWare.Core/App.axaml.cs +++ b/src/OneWare.Core/App.axaml.cs @@ -24,6 +24,7 @@ using OneWare.FolderProjectSystem; using OneWare.ImageViewer; using OneWare.Json; +using OneWare.LibraryExplorer; using OneWare.Output; using OneWare.ProjectExplorer; using OneWare.ProjectSystem.Services; @@ -300,6 +301,7 @@ protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog) moduleCatalog.AddModule(); moduleCatalog.AddModule(); moduleCatalog.AddModule(); + moduleCatalog.AddModule(); moduleCatalog.AddModule(); moduleCatalog.AddModule(); moduleCatalog.AddModule(); diff --git a/src/OneWare.Core/OneWare.Core.csproj b/src/OneWare.Core/OneWare.Core.csproj index 52154c16..f7c968dc 100644 --- a/src/OneWare.Core/OneWare.Core.csproj +++ b/src/OneWare.Core/OneWare.Core.csproj @@ -23,6 +23,7 @@ + diff --git a/src/OneWare.LibraryExplorer/LibraryExplorerModule.cs b/src/OneWare.LibraryExplorer/LibraryExplorerModule.cs new file mode 100644 index 00000000..c5c43004 --- /dev/null +++ b/src/OneWare.LibraryExplorer/LibraryExplorerModule.cs @@ -0,0 +1,37 @@ +using Avalonia; +using Avalonia.Controls; +using CommunityToolkit.Mvvm.Input; +using OneWare.Essentials.Enums; +using OneWare.Essentials.Services; +using OneWare.Essentials.ViewModels; +using OneWare.LibraryExplorer.ViewModels; +using OneWare.ProjectExplorer.ViewModels; +using Prism.Ioc; +using Prism.Modularity; + +namespace OneWare.LibraryExplorer; + +public class LibraryExplorerModule : IModule +{ + public void RegisterTypes(IContainerRegistry containerRegistry) + { + containerRegistry.RegisterSingleton(); + } + + public void OnInitialized(IContainerProvider containerProvider) + { + var dockService = containerProvider.Resolve(); + var windowService = containerProvider.Resolve(); + + dockService.RegisterLayoutExtension(DockShowLocation.Left); + + windowService.RegisterMenuItem("MainWindow_MainMenu/View/Tool Windows", + new MenuItemViewModel("Library Explorer") + { + Header = "Library Explorer", + Command = + new RelayCommand(() => dockService.Show(containerProvider.Resolve())), + IconObservable = Application.Current!.GetResourceObservable(LibraryExplorerViewModel.IconKey) + }); + } +} \ No newline at end of file diff --git a/src/OneWare.LibraryExplorer/OneWare.LibraryExplorer.csproj b/src/OneWare.LibraryExplorer/OneWare.LibraryExplorer.csproj new file mode 100644 index 00000000..d49458bd --- /dev/null +++ b/src/OneWare.LibraryExplorer/OneWare.LibraryExplorer.csproj @@ -0,0 +1,16 @@ + + + + + + + + + + + + ProjectExplorerView.axaml + Code + + + diff --git a/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs b/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs new file mode 100644 index 00000000..877e7b63 --- /dev/null +++ b/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs @@ -0,0 +1,20 @@ +using OneWare.Essentials.Models; +using OneWare.ProjectExplorer.ViewModels; + +namespace OneWare.LibraryExplorer.ViewModels; + +public class LibraryExplorerViewModel : ProjectViewModelBase +{ + public const string IconKey = "BoxIcons.RegularLibrary"; + + public LibraryExplorerViewModel() : base(IconKey) + { + Id = "LibraryExplorer"; + Title = "Library Explorer"; + } + + public void DoubleTab(IProjectEntry entry) + { + + } +} \ No newline at end of file diff --git a/src/OneWare.LibraryExplorer/Views/LibraryExplorerView.axaml b/src/OneWare.LibraryExplorer/Views/LibraryExplorerView.axaml new file mode 100644 index 00000000..fa88a5d6 --- /dev/null +++ b/src/OneWare.LibraryExplorer/Views/LibraryExplorerView.axaml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/OneWare.LibraryExplorer/Views/LibraryExplorerView.axaml.cs b/src/OneWare.LibraryExplorer/Views/LibraryExplorerView.axaml.cs new file mode 100644 index 00000000..0ac41aae --- /dev/null +++ b/src/OneWare.LibraryExplorer/Views/LibraryExplorerView.axaml.cs @@ -0,0 +1,30 @@ +using Avalonia.Controls; +using Avalonia.Interactivity; +using DynamicData.Binding; +using OneWare.Essentials.Controls; +using OneWare.ProjectExplorer.ViewModels; + +namespace OneWare.LibraryExplorer.Views; + +public partial class LibraryExplorerView : UserControl +{ + public LibraryExplorerView() + { + InitializeComponent(); + + this.WhenValueChanged(x => x.DataContext).Subscribe(x => + { + var vm = x as ProjectExplorerViewModel; + if (vm == null) return; + + AddHandler(SearchBox.SearchEvent, (o, i) => { vm.OnSearch(); }, RoutingStrategies.Bubble); + }); + + TreeViewContextMenu.Opening += (sender, args) => + { + var topLevel = TopLevel.GetTopLevel(this); + if (topLevel != null && DataContext is ProjectExplorerViewModel vm) + vm.ConstructContextMenu(topLevel); + }; + } +} \ No newline at end of file diff --git a/src/OneWare.ProjectExplorer/ViewModels/ProjectExplorerViewModel.cs b/src/OneWare.ProjectExplorer/ViewModels/ProjectExplorerViewModel.cs index 4912137e..d44cd68d 100644 --- a/src/OneWare.ProjectExplorer/ViewModels/ProjectExplorerViewModel.cs +++ b/src/OneWare.ProjectExplorer/ViewModels/ProjectExplorerViewModel.cs @@ -37,9 +37,7 @@ public class ProjectExplorerViewModel : ProjectViewModelBase, IProjectExplorerSe private readonly IWindowService _windowService; private IProjectRoot? _activeProject; - - private IEnumerable? _treeViewContextMenu; - + public ProjectExplorerViewModel(IApplicationStateService applicationStateService, IPaths paths, IDockService dockService, IWindowService windowService, ISettingsService settingsService, @@ -66,12 +64,6 @@ public ProjectExplorerViewModel(IApplicationStateService applicationStateService private Dictionary TemporaryFiles { get; } = new(); - public IEnumerable? TreeViewContextMenu - { - get => _treeViewContextMenu; - set => SetProperty(ref _treeViewContextMenu, value); - } - public IProjectRoot? ActiveProject { get => _activeProject; diff --git a/src/OneWare.ProjectExplorer/ViewModels/ProjectViewModelBase.cs b/src/OneWare.ProjectExplorer/ViewModels/ProjectViewModelBase.cs index 32317f37..f086928d 100644 --- a/src/OneWare.ProjectExplorer/ViewModels/ProjectViewModelBase.cs +++ b/src/OneWare.ProjectExplorer/ViewModels/ProjectViewModelBase.cs @@ -15,7 +15,14 @@ public abstract class ProjectViewModelBase(string iconKey) : ExtendedTool(iconKe { private string _searchString = ""; public bool EnableDragDrop = true; + private IEnumerable? _treeViewContextMenu; + public IEnumerable? TreeViewContextMenu + { + get => _treeViewContextMenu; + set => SetProperty(ref _treeViewContextMenu, value); + } + public string SearchString { get => _searchString; From 8e69edcc89b6156d0cd2f2c7a98b28bc34ea4e31 Mon Sep 17 00:00:00 2001 From: Hendrik Mennen Date: Fri, 18 Oct 2024 13:35:19 -0500 Subject: [PATCH 2/7] libraryexplorer progress --- .../ViewModels/DockViews/EditViewModel.cs | 3 +- .../Views/DockViews/EditView.axaml | 1 + .../OneWare.LibraryExplorer.csproj | 1 + .../ViewModels/LibraryExplorerViewModel.cs | 79 ++++++++++++++++++- .../Views/LibraryExplorerView.axaml | 7 +- .../Views/LibraryExplorerView.axaml.cs | 5 +- 6 files changed, 87 insertions(+), 9 deletions(-) diff --git a/src/OneWare.Core/ViewModels/DockViews/EditViewModel.cs b/src/OneWare.Core/ViewModels/DockViews/EditViewModel.cs index 379439f6..4b9a8ffe 100644 --- a/src/OneWare.Core/ViewModels/DockViews/EditViewModel.cs +++ b/src/OneWare.Core/ViewModels/DockViews/EditViewModel.cs @@ -34,8 +34,7 @@ public class EditViewModel : ExtendedDocument, IEditor private readonly IWindowService _windowService; private CompositeDisposable _composite = new(); - - + private IEnumerable? _diagnostics; private ITypeAssistance? _typeAssistance; diff --git a/src/OneWare.Core/Views/DockViews/EditView.axaml b/src/OneWare.Core/Views/DockViews/EditView.axaml index 2608df13..8fcd7cd9 100644 --- a/src/OneWare.Core/Views/DockViews/EditView.axaml +++ b/src/OneWare.Core/Views/DockViews/EditView.axaml @@ -85,6 +85,7 @@ + diff --git a/src/OneWare.LibraryExplorer/OneWare.LibraryExplorer.csproj b/src/OneWare.LibraryExplorer/OneWare.LibraryExplorer.csproj index d49458bd..cdb32cd6 100644 --- a/src/OneWare.LibraryExplorer/OneWare.LibraryExplorer.csproj +++ b/src/OneWare.LibraryExplorer/OneWare.LibraryExplorer.csproj @@ -4,6 +4,7 @@ + diff --git a/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs b/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs index 877e7b63..417286d4 100644 --- a/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs +++ b/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs @@ -1,5 +1,14 @@ +using Avalonia; +using Avalonia.Controls; +using CommunityToolkit.Mvvm.Input; +using Dock.Model.Core; using OneWare.Essentials.Models; +using OneWare.Essentials.Services; +using OneWare.Essentials.ViewModels; +using OneWare.FolderProjectSystem; +using OneWare.ProjectExplorer.Services; using OneWare.ProjectExplorer.ViewModels; +using Prism.Ioc; namespace OneWare.LibraryExplorer.ViewModels; @@ -7,14 +16,82 @@ public class LibraryExplorerViewModel : ProjectViewModelBase { public const string IconKey = "BoxIcons.RegularLibrary"; - public LibraryExplorerViewModel() : base(IconKey) + private readonly IPaths _paths; + private readonly IFileWatchService _fileWatchService; + private readonly IDockService _dockService; + + public LibraryExplorerViewModel(IPaths paths, IFileWatchService fileWatchService, IDockService dockService) : base(IconKey) { Id = "LibraryExplorer"; Title = "Library Explorer"; + + _paths = paths; + _fileWatchService = fileWatchService; + _dockService = dockService; + + _ = LoadAsync(); + } + + public override void Insert(IProjectRoot project) + { + base.Insert(project); + _fileWatchService.Register(project); } public void DoubleTab(IProjectEntry entry) { + if (entry is IProjectFile file) + _ = PreviewFileAsync(file); + else + entry.IsExpanded = !entry.IsExpanded; + } + + public async Task LoadAsync() + { + var manager = ContainerLocator.Container.Resolve(); + var libraryPath = Path.Combine(_paths.PackagesDirectory, "Libraries"); + + Directory.CreateDirectory(libraryPath); + var directories = Directory.EnumerateDirectories(libraryPath); + + foreach (var dir in directories) + { + var root = await manager.LoadProjectAsync(libraryPath); + Insert(root!); + } + } + + public void ConstructContextMenu(TopLevel topLevel) + { + var menuItems = new List(); + + if (SelectedItems is [{ } item]) + { + switch (item) + { + case IProjectFile file: + menuItems.Add(new MenuItemViewModel("Open") + { + Header = "Open", + Command = new AsyncRelayCommand(() => PreviewFileAsync(file)) + }); + break; + case IProjectFolder folder: + + break; + } + } + TreeViewContextMenu = menuItems; + } + + private async Task PreviewFileAsync(IProjectFile file) + { + var extendedDocument = await _dockService.OpenFileAsync(file); + if (extendedDocument != null) + { + extendedDocument.IsReadOnly = true; + extendedDocument.Title = "PREVIEW: " + extendedDocument.CurrentFile?.Name; + } } } \ No newline at end of file diff --git a/src/OneWare.LibraryExplorer/Views/LibraryExplorerView.axaml b/src/OneWare.LibraryExplorer/Views/LibraryExplorerView.axaml index fa88a5d6..eeff191a 100644 --- a/src/OneWare.LibraryExplorer/Views/LibraryExplorerView.axaml +++ b/src/OneWare.LibraryExplorer/Views/LibraryExplorerView.axaml @@ -2,17 +2,16 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:viewModels="clr-namespace:OneWare.ProjectExplorer.ViewModels" xmlns:controls="clr-namespace:OneWare.Essentials.Controls;assembly=OneWare.Essentials" xmlns:models="clr-namespace:OneWare.Essentials.Models;assembly=OneWare.Essentials" xmlns:behaviors="clr-namespace:OneWare.Essentials.Behaviors;assembly=OneWare.Essentials" xmlns:behaviors1="clr-namespace:OneWare.ProjectExplorer.Behaviors" - xmlns:viewModels1="clr-namespace:OneWare.LibraryExplorer.ViewModels" + xmlns:viewModels="clr-namespace:OneWare.LibraryExplorer.ViewModels" mc:Ignorable="d" d:DesignWidth="300" d:DesignHeight="450" x:Class="OneWare.LibraryExplorer.Views.LibraryExplorerView" Background="{DynamicResource ThemeControlLowBrush}" BorderBrush="{DynamicResource ThemeBorderLowBrush}" - x:CompileBindings="True" x:DataType="viewModels1:LibraryExplorerViewModel" + x:CompileBindings="True" x:DataType="viewModels:LibraryExplorerViewModel" Name="ProjectExplorerViewView" Foreground="{DynamicResource ThemeForegroundColor}" BorderThickness="0"> @@ -77,7 +76,7 @@ diff --git a/src/OneWare.LibraryExplorer/Views/LibraryExplorerView.axaml.cs b/src/OneWare.LibraryExplorer/Views/LibraryExplorerView.axaml.cs index 0ac41aae..ded96ae5 100644 --- a/src/OneWare.LibraryExplorer/Views/LibraryExplorerView.axaml.cs +++ b/src/OneWare.LibraryExplorer/Views/LibraryExplorerView.axaml.cs @@ -2,6 +2,7 @@ using Avalonia.Interactivity; using DynamicData.Binding; using OneWare.Essentials.Controls; +using OneWare.LibraryExplorer.ViewModels; using OneWare.ProjectExplorer.ViewModels; namespace OneWare.LibraryExplorer.Views; @@ -14,7 +15,7 @@ public LibraryExplorerView() this.WhenValueChanged(x => x.DataContext).Subscribe(x => { - var vm = x as ProjectExplorerViewModel; + var vm = x as LibraryExplorerViewModel; if (vm == null) return; AddHandler(SearchBox.SearchEvent, (o, i) => { vm.OnSearch(); }, RoutingStrategies.Bubble); @@ -23,7 +24,7 @@ public LibraryExplorerView() TreeViewContextMenu.Opening += (sender, args) => { var topLevel = TopLevel.GetTopLevel(this); - if (topLevel != null && DataContext is ProjectExplorerViewModel vm) + if (topLevel != null && DataContext is LibraryExplorerViewModel vm) vm.ConstructContextMenu(topLevel); }; } From c0dc6ac971612fdc2dd9c42de2765a8b29c81d30 Mon Sep 17 00:00:00 2001 From: Hendrik Mennen Date: Sun, 20 Oct 2024 09:14:11 -0400 Subject: [PATCH 3/7] allow adding plugin manifest directly as source --- .../Services/PackageService.cs | 81 ++++++++++++------- 1 file changed, 52 insertions(+), 29 deletions(-) diff --git a/src/OneWare.PackageManager/Services/PackageService.cs b/src/OneWare.PackageManager/Services/PackageService.cs index e0c7315a..58a5c948 100644 --- a/src/OneWare.PackageManager/Services/PackageService.cs +++ b/src/OneWare.PackageManager/Services/PackageService.cs @@ -2,6 +2,7 @@ using System.Reactive.Disposables; using System.Reactive.Linq; using System.Text.Json; +using System.Text.RegularExpressions; using Avalonia.Media; using Avalonia.Threading; using OneWare.Essentials.Enums; @@ -13,7 +14,7 @@ namespace OneWare.PackageManager.Services; -public class PackageService : IPackageService +public partial class PackageService : IPackageService { private static readonly JsonSerializerOptions SerializerOptions = new() { @@ -192,46 +193,65 @@ private async Task LoadPackageRepositoryAsync(string url, CancellationToke var repositoryString = await _httpService.DownloadTextAsync(url, TimeSpan.FromSeconds(10), cancellationToken); if (repositoryString == null) return false; - try + var trimmed = MyRegex().Replace(repositoryString, ""); + + if (trimmed.StartsWith("{\"packages\":")) { - var repository = JsonSerializer.Deserialize(repositoryString, SerializerOptions); + try + { + var repository = JsonSerializer.Deserialize(repositoryString, SerializerOptions); - if (repository is { Packages: not null }) - foreach (var manifest in repository.Packages) - { - try + if (repository is { Packages: not null }) + foreach (var manifest in repository.Packages) { - if (manifest.ManifestUrl == null) continue; + try + { + if (manifest.ManifestUrl == null) continue; + + var downloadManifest = + await _httpService.DownloadTextAsync(manifest.ManifestUrl, + cancellationToken: cancellationToken); - var downloadManifest = - await _httpService.DownloadTextAsync(manifest.ManifestUrl, - cancellationToken: cancellationToken); + var package = JsonSerializer.Deserialize(downloadManifest!, SerializerOptions); - var package = JsonSerializer.Deserialize(downloadManifest!, SerializerOptions); + if (package == null) continue; - if (package == null) continue; + if (package.Id != null && Packages.TryGetValue(package.Id, out var pkg)) + { + pkg.Package = package; + continue; + } - if (package.Id != null && Packages.TryGetValue(package.Id, out var pkg)) + AddPackage(package); + } + catch (Exception e) { - pkg.Package = package; - continue; + _logger.Error(e.Message, e); } - - AddPackage(package); - } - catch (Exception e) - { - _logger.Error(e.Message, e); } - } - else throw new Exception("Packages empty"); - } - catch (Exception e) - { - _logger.Error(e.Message, e); - return false; + else throw new Exception("Packages empty"); + } + catch (Exception e) + { + _logger.Error(e.Message, e); + return false; + } } + else + { //In case link is a plugin manifest directly + var package = JsonSerializer.Deserialize(repositoryString!, SerializerOptions); + + if (package == null) return false; + if (package.Id != null && Packages.TryGetValue(package.Id, out var pkg)) + { + pkg.Package = package; + return true; + } + + AddPackage(package); + } + return true; } @@ -331,4 +351,7 @@ private void FinishInstall(Package package) _activeInstalls.Remove(package); } } + + [GeneratedRegex(@"\s+")] + private static partial Regex MyRegex(); } \ No newline at end of file From 4773abcd67e4980716a005fe0bec63ae99b5f1ea Mon Sep 17 00:00:00 2001 From: Hendrik Mennen Date: Sun, 20 Oct 2024 10:05:15 -0400 Subject: [PATCH 4/7] progress --- .../Services/IProjectExplorerService.cs | 1 + .../ViewModels/LibraryExplorerViewModel.cs | 44 +++++++++++++++---- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/OneWare.Essentials/Services/IProjectExplorerService.cs b/src/OneWare.Essentials/Services/IProjectExplorerService.cs index 448e0934..8803838d 100644 --- a/src/OneWare.Essentials/Services/IProjectExplorerService.cs +++ b/src/OneWare.Essentials/Services/IProjectExplorerService.cs @@ -32,6 +32,7 @@ public Task public Task RenameAsync(IProjectEntry entry, string newName); public void ExpandToRoot(IProjectExplorerNode node); public Task ImportFolderDialogAsync(IProjectFolder? destination = null); + public Task ImportAsync(IProjectFolder destination, bool copy, bool askForInclude, params string[] paths); public Task ReloadAsync(IProjectEntry entry); public Task SaveProjectAsync(IProjectRoot project); public Task SaveLastProjectsFileAsync(); diff --git a/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs b/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs index 417286d4..15ceb9fe 100644 --- a/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs +++ b/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs @@ -2,6 +2,7 @@ using Avalonia.Controls; using CommunityToolkit.Mvvm.Input; using Dock.Model.Core; +using OneWare.Essentials.Helpers; using OneWare.Essentials.Models; using OneWare.Essentials.Services; using OneWare.Essentials.ViewModels; @@ -16,18 +17,22 @@ public class LibraryExplorerViewModel : ProjectViewModelBase { public const string IconKey = "BoxIcons.RegularLibrary"; - private readonly IPaths _paths; + private string _libraryFolderPath; + private readonly IFileWatchService _fileWatchService; private readonly IDockService _dockService; + private readonly IProjectExplorerService _projectExplorerService; - public LibraryExplorerViewModel(IPaths paths, IFileWatchService fileWatchService, IDockService dockService) : base(IconKey) + public LibraryExplorerViewModel(IPaths paths, IFileWatchService fileWatchService, IDockService dockService, IProjectExplorerService projectExplorerService) : base(IconKey) { Id = "LibraryExplorer"; Title = "Library Explorer"; - - _paths = paths; + _fileWatchService = fileWatchService; _dockService = dockService; + _projectExplorerService = projectExplorerService; + + _libraryFolderPath = Path.Combine(paths.PackagesDirectory, "Libraries"); _ = LoadAsync(); } @@ -49,14 +54,13 @@ public void DoubleTab(IProjectEntry entry) public async Task LoadAsync() { var manager = ContainerLocator.Container.Resolve(); - var libraryPath = Path.Combine(_paths.PackagesDirectory, "Libraries"); - Directory.CreateDirectory(libraryPath); - var directories = Directory.EnumerateDirectories(libraryPath); + Directory.CreateDirectory(_libraryFolderPath); + var directories = Directory.EnumerateDirectories(_libraryFolderPath); foreach (var dir in directories) { - var root = await manager.LoadProjectAsync(libraryPath); + var root = await manager.LoadProjectAsync(dir); Insert(root!); } } @@ -75,12 +79,25 @@ public void ConstructContextMenu(TopLevel topLevel) Header = "Open", Command = new AsyncRelayCommand(() => PreviewFileAsync(file)) }); + menuItems.Add(new MenuItemViewModel("Copy to Project") + { + Header = "Copy to Active Project", + Command = new AsyncRelayCommand(() => CopyLibraryAsync(file), () => _projectExplorerService.ActiveProject != null) + }); break; case IProjectFolder folder: break; } } + else + { + menuItems.Add(new MenuItemViewModel("Open Library Folder") + { + Header = "Open Library Folder", + Command = new RelayCommand(() => PlatformHelper.OpenExplorerPath(_libraryFolderPath)) + }); + } TreeViewContextMenu = menuItems; } @@ -94,4 +111,15 @@ private async Task PreviewFileAsync(IProjectFile file) extendedDocument.Title = "PREVIEW: " + extendedDocument.CurrentFile?.Name; } } + + private async Task CopyLibraryAsync(params IProjectEntry[] entries) + { + var proj = _projectExplorerService.ActiveProject; + + if(proj == null) return; + + var libFolder = proj.AddFolder("lib", true); + + await _projectExplorerService.ImportAsync(libFolder, true, true, entries.Select(x => x.FullPath).ToArray()); + } } \ No newline at end of file From 5203ee141e09d33399f85b9ae0ffee04852ceaea Mon Sep 17 00:00:00 2001 From: Hendrik Mennen Date: Sun, 20 Oct 2024 09:17:48 -0500 Subject: [PATCH 5/7] . --- .../ViewModels/LibraryExplorerViewModel.cs | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs b/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs index 15ceb9fe..6c72903d 100644 --- a/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs +++ b/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs @@ -58,6 +58,8 @@ public async Task LoadAsync() Directory.CreateDirectory(_libraryFolderPath); var directories = Directory.EnumerateDirectories(_libraryFolderPath); + Projects.Clear(); + foreach (var dir in directories) { var root = await manager.LoadProjectAsync(dir); @@ -79,19 +81,25 @@ public void ConstructContextMenu(TopLevel topLevel) Header = "Open", Command = new AsyncRelayCommand(() => PreviewFileAsync(file)) }); - menuItems.Add(new MenuItemViewModel("Copy to Project") - { - Header = "Copy to Active Project", - Command = new AsyncRelayCommand(() => CopyLibraryAsync(file), () => _projectExplorerService.ActiveProject != null) - }); - break; - case IProjectFolder folder: - break; } } + if (SelectedItems.Count > 0) + { + menuItems.Add(new MenuItemViewModel("Copy to Project") + { + Header = "Copy to Active Project", + Command = new AsyncRelayCommand(() => CopyLibraryAsync(SelectedItems.Cast() + .ToArray()), () => _projectExplorerService.ActiveProject != null) + }); + } else { + menuItems.Add(new MenuItemViewModel("Refresh") + { + Header = "Refresh", + Command = new RelayCommand(() => PlatformHelper.OpenExplorerPath(_libraryFolderPath)) + }); menuItems.Add(new MenuItemViewModel("Open Library Folder") { Header = "Open Library Folder", From 27a36610bff23fb7c7b8e7ecbd433e235d400040 Mon Sep 17 00:00:00 2001 From: Hendrik Mennen Date: Tue, 22 Oct 2024 13:19:55 -0500 Subject: [PATCH 6/7] fix --- .../ViewModels/LibraryExplorerViewModel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs b/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs index 6c72903d..e4c9c481 100644 --- a/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs +++ b/src/OneWare.LibraryExplorer/ViewModels/LibraryExplorerViewModel.cs @@ -126,7 +126,7 @@ private async Task CopyLibraryAsync(params IProjectEntry[] entries) if(proj == null) return; - var libFolder = proj.AddFolder("lib", true); + var libFolder = proj.AddFolder("lib"); await _projectExplorerService.ImportAsync(libFolder, true, true, entries.Select(x => x.FullPath).ToArray()); } From 20b763b602abb5e546491324ae274cd88f0ccb67 Mon Sep 17 00:00:00 2001 From: Hendrik Mennen Date: Tue, 22 Oct 2024 13:23:43 -0500 Subject: [PATCH 7/7] add library package --- .../Models/LibraryPackageModel.cs | 26 +++++++++++++++++++ .../Services/PackageService.cs | 1 + 2 files changed, 27 insertions(+) create mode 100644 src/OneWare.PackageManager/Models/LibraryPackageModel.cs diff --git a/src/OneWare.PackageManager/Models/LibraryPackageModel.cs b/src/OneWare.PackageManager/Models/LibraryPackageModel.cs new file mode 100644 index 00000000..c7e53521 --- /dev/null +++ b/src/OneWare.PackageManager/Models/LibraryPackageModel.cs @@ -0,0 +1,26 @@ +using OneWare.Essentials.Enums; +using OneWare.Essentials.Models; +using OneWare.Essentials.PackageManager; +using OneWare.Essentials.Services; + +namespace OneWare.PackageManager.Models; + +public class LibraryPackageModel( + Package package, + IHttpService httpService, + ILogger logger, + IPaths paths, + IApplicationStateService applicationStateService) + : PackageModel(package, "Libraries", Path.Combine(paths.PackagesDirectory, "Libraries", package.Id!), httpService, logger, + applicationStateService) +{ + protected override void Install(PackageTarget target) + { + Status = PackageStatus.Installed; + } + + protected override void Uninstall() + { + Status = PackageStatus.Available; + } +} \ No newline at end of file diff --git a/src/OneWare.PackageManager/Services/PackageService.cs b/src/OneWare.PackageManager/Services/PackageService.cs index 58a5c948..7fe83c27 100644 --- a/src/OneWare.PackageManager/Services/PackageService.cs +++ b/src/OneWare.PackageManager/Services/PackageService.cs @@ -156,6 +156,7 @@ private void AddPackage(Package package, string? installedVersion = null) "Plugin" => ContainerLocator.Container.Resolve((typeof(Package), package)), "NativeTool" => ContainerLocator.Container.Resolve((typeof(Package), package)), "Hardware" => ContainerLocator.Container.Resolve((typeof(Package), package)), + "Library" => ContainerLocator.Container.Resolve((typeof(Package), package)), _ => throw new Exception($"Package Type invalid/missing for {package.Name}!") };