diff --git a/src/Artemis.Core/Ninject/CoreModule.cs b/src/Artemis.Core/Ninject/CoreModule.cs index 7168a7ea5..5c572b62c 100644 --- a/src/Artemis.Core/Ninject/CoreModule.cs +++ b/src/Artemis.Core/Ninject/CoreModule.cs @@ -1,5 +1,4 @@ -using System.IO; -using Artemis.Core.Services; +using Artemis.Core.Services; using Artemis.Storage; using Artemis.Storage.Migrations.Interfaces; using Artemis.Storage.Repositories.Interfaces; diff --git a/src/Artemis.Core/Services/PluginManagementService.cs b/src/Artemis.Core/Services/PluginManagementService.cs index 4fc31831c..9524f8a00 100644 --- a/src/Artemis.Core/Services/PluginManagementService.cs +++ b/src/Artemis.Core/Services/PluginManagementService.cs @@ -16,6 +16,7 @@ using McMaster.NETCore.Plugins; using Ninject; using Ninject.Extensions.ChildKernel; using Ninject.Parameters; +using Ninject.Planning.Bindings.Resolvers; using RGB.NET.Core; using Serilog; @@ -410,6 +411,9 @@ namespace Artemis.Core.Services // Create the Ninject child kernel and load the module plugin.Kernel = new ChildKernel(_kernel, new PluginModule(plugin)); + // The kernel used by Core is unforgiving about missing bindings, no need to be so hard on plugin devs + plugin.Kernel.Components.Add(); + OnPluginEnabling(new PluginEventArgs(plugin)); plugin.SetEnabled(true); diff --git a/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.csproj b/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.csproj index f2e68cafb..a13b34d2c 100644 --- a/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.csproj +++ b/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.csproj @@ -5,6 +5,7 @@ enable + bin\ C:\Repos\Artemis\src\Artemis.UI.Avalonia.Shared\Artemis.UI.Avalonia.Shared.xml diff --git a/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.xml b/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.xml index e15cb64cc..569228685 100644 --- a/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.xml +++ b/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.xml @@ -282,9 +282,14 @@ Gets the plugin this configuration view model is associated with - + - A command that closes the window + Closes the window hosting the view model + + + + + Occurs when the the window hosting the view model should close diff --git a/src/Artemis.UI.Avalonia.Shared/Plugins/PluginConfigurationViewModel.cs b/src/Artemis.UI.Avalonia.Shared/Plugins/PluginConfigurationViewModel.cs index 008d8ccb7..194ab7eec 100644 --- a/src/Artemis.UI.Avalonia.Shared/Plugins/PluginConfigurationViewModel.cs +++ b/src/Artemis.UI.Avalonia.Shared/Plugins/PluginConfigurationViewModel.cs @@ -1,6 +1,5 @@ -using System.Reactive; +using System; using Artemis.Core; -using ReactiveUI; namespace Artemis.UI.Avalonia.Shared { @@ -16,7 +15,6 @@ namespace Artemis.UI.Avalonia.Shared protected PluginConfigurationViewModel(Plugin plugin) { Plugin = plugin; - Close = ReactiveCommand.Create(() => { }); } /// @@ -25,8 +23,16 @@ namespace Artemis.UI.Avalonia.Shared public Plugin Plugin { get; } /// - /// A command that closes the window + /// Closes the window hosting the view model /// - public ReactiveCommand Close { get; } + public void Close() + { + CloseRequested?.Invoke(this, EventArgs.Empty); + } + + /// + /// Occurs when the the window hosting the view model should close + /// + public event EventHandler? CloseRequested; } } \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia.Shared/Services/WindowService/WindowService.cs b/src/Artemis.UI.Avalonia.Shared/Services/WindowService/WindowService.cs index 15959fe96..e11416551 100644 --- a/src/Artemis.UI.Avalonia.Shared/Services/WindowService/WindowService.cs +++ b/src/Artemis.UI.Avalonia.Shared/Services/WindowService/WindowService.cs @@ -33,6 +33,8 @@ namespace Artemis.UI.Avalonia.Shared.Services public void ShowWindow(object viewModel) { + Window parent = GetCurrentWindow(); + string name = viewModel.GetType().FullName!.Split('`')[0].Replace("ViewModel", "View"); Type? type = viewModel.GetType().Assembly.GetType(name); @@ -48,7 +50,7 @@ namespace Artemis.UI.Avalonia.Shared.Services Window window = (Window) Activator.CreateInstance(type)!; window.DataContext = viewModel; - window.Show(); + window.Show(parent); } public async Task ShowDialogAsync(params (string name, object value)[] parameters) where TViewModel : DialogViewModelBase @@ -72,10 +74,7 @@ namespace Artemis.UI.Avalonia.Shared.Services public async Task ShowDialogAsync(DialogViewModelBase viewModel) { - if (Application.Current.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime classic) - { - throw new ArtemisSharedUIException("Can't show a dialog when application lifetime is not IClassicDesktopStyleApplicationLifetime."); - } + Window parent = GetCurrentWindow(); string name = viewModel.GetType().FullName!.Split('`')[0].Replace("ViewModel", "View"); Type? type = viewModel.GetType().Assembly.GetType(name); @@ -92,7 +91,6 @@ namespace Artemis.UI.Avalonia.Shared.Services Window window = (Window) Activator.CreateInstance(type)!; window.DataContext = viewModel; - Window parent = classic.Windows.FirstOrDefault(w => w.IsActive) ?? classic.MainWindow; return await window.ShowDialog(parent); } diff --git a/src/Artemis.UI.Avalonia/App.axaml.cs b/src/Artemis.UI.Avalonia/App.axaml.cs index a299455b3..ff5b99efb 100644 --- a/src/Artemis.UI.Avalonia/App.axaml.cs +++ b/src/Artemis.UI.Avalonia/App.axaml.cs @@ -42,6 +42,8 @@ namespace Artemis.UI.Avalonia private void InitializeNinject() { _kernel = new StandardKernel(); + _kernel.Settings.InjectNonPublic = true; + _kernel.Load(); _kernel.Load(); _kernel.Load(); diff --git a/src/Artemis.UI.Avalonia/Artemis.UI.Avalonia.csproj b/src/Artemis.UI.Avalonia/Artemis.UI.Avalonia.csproj index 427d243fd..9b363bcd7 100644 --- a/src/Artemis.UI.Avalonia/Artemis.UI.Avalonia.csproj +++ b/src/Artemis.UI.Avalonia/Artemis.UI.Avalonia.csproj @@ -3,6 +3,7 @@ WinExe net5.0 enable + bin\ diff --git a/src/Artemis.UI.Avalonia/Screens/Device/DevicePropertiesView.axaml b/src/Artemis.UI.Avalonia/Screens/Device/DevicePropertiesView.axaml index 78b19a2da..fbb52cff7 100644 --- a/src/Artemis.UI.Avalonia/Screens/Device/DevicePropertiesView.axaml +++ b/src/Artemis.UI.Avalonia/Screens/Device/DevicePropertiesView.axaml @@ -8,10 +8,13 @@ Title="Artemis | Device Properties" Width="1250" Height="900" - ExtendClientAreaToDecorationsHint="True" - Padding="0 32 0 0"> - - + WindowStartupLocation="CenterOwner" + ExtendClientAreaToDecorationsHint="True"> + + + + + @@ -32,10 +35,10 @@ ShowColors="True" Margin="20" /> - @@ -43,23 +46,25 @@ - + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginSettingsWindowView.axaml b/src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginSettingsWindowView.axaml index a8cc7d65a..2676fac81 100644 --- a/src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginSettingsWindowView.axaml +++ b/src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginSettingsWindowView.axaml @@ -4,6 +4,14 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.UI.Avalonia.Screens.Plugins.Views.PluginSettingsWindowView" - Title="{Binding DisplayName}"> - + Title="{Binding DisplayName}" + ExtendClientAreaToDecorationsHint="True" + Width="800" + Height="800" + WindowStartupLocation="CenterOwner"> + + + + + diff --git a/src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginSettingsWindowView.axaml.cs b/src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginSettingsWindowView.axaml.cs index 0b5b3e2a3..3c8b8166f 100644 --- a/src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginSettingsWindowView.axaml.cs +++ b/src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginSettingsWindowView.axaml.cs @@ -1,7 +1,7 @@ using System; +using System.Reactive.Disposables; using Artemis.UI.Avalonia.Screens.Plugins.ViewModels; using Avalonia; -using Avalonia.Controls.Mixins; using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; using ReactiveUI; @@ -17,7 +17,22 @@ namespace Artemis.UI.Avalonia.Screens.Plugins.Views this.AttachDevTools(); #endif - this.WhenActivated(disposables => { ViewModel!.ConfigurationViewModel.Close.Subscribe(_ => Close()).DisposeWith(disposables); }); + this.WhenActivated(disposables => + { + ViewModel!.ConfigurationViewModel.CloseRequested += ConfigurationViewModelOnCloseRequested; + Disposable.Create(HandleDeactivation).DisposeWith(disposables); + } + ); + } + + private void HandleDeactivation() + { + ViewModel!.ConfigurationViewModel.CloseRequested -= ConfigurationViewModelOnCloseRequested; + } + + private void ConfigurationViewModelOnCloseRequested(object? sender, EventArgs e) + { + Close(); } private void InitializeComponent() diff --git a/src/Artemis.UI.Avalonia/Screens/Root/Views/RootView.axaml b/src/Artemis.UI.Avalonia/Screens/Root/Views/RootView.axaml index 50de48c2e..7b35385ee 100644 --- a/src/Artemis.UI.Avalonia/Screens/Root/Views/RootView.axaml +++ b/src/Artemis.UI.Avalonia/Screens/Root/Views/RootView.axaml @@ -13,7 +13,7 @@ - + diff --git a/src/Artemis.UI.Avalonia/ViewLocator.cs b/src/Artemis.UI.Avalonia/ViewLocator.cs index fde4e39e8..be19a2360 100644 --- a/src/Artemis.UI.Avalonia/ViewLocator.cs +++ b/src/Artemis.UI.Avalonia/ViewLocator.cs @@ -11,8 +11,9 @@ namespace Artemis.UI.Avalonia public IControl Build(object data) { - string name = data.GetType().FullName!.Split('`')[0].Replace("ViewModel", "View"); - Type? type = Type.GetType(name); + Type dataType = data.GetType(); + string name = dataType.FullName!.Split('`')[0].Replace("ViewModel", "View"); + Type? type = dataType.Assembly.GetType(name); if (type != null) return (Control) Activator.CreateInstance(type)!;