diff --git a/GSS2.Test/App.axaml.cs b/GSS2.Test/App.axaml.cs index 85a98a2..dc1ea15 100644 --- a/GSS2.Test/App.axaml.cs +++ b/GSS2.Test/App.axaml.cs @@ -5,6 +5,9 @@ using Avalonia.Threading; using GSS2.Test.ViewModels; using GSS2.Test.Views; +using GSS2.UI.Core; +using GSS2.UI.Core.Services; +using GSS2.UI.Core.ViewModels; namespace GSS2.Test; @@ -20,30 +23,44 @@ public partial class App : Application if (ApplicationLifetime is null) throw new InvalidOperationException("Application framework initialization cannot be fulfilled, ApplicationLifetime is null"); - if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) - { - Console.WriteLine("Application running in classic style"); - desktop.Startup += (_, _) => Program.ApplicationHost.RunAsync(); - desktop.Exit += (_, _) => Program.ApplicationHost.StopAsync(); + var loggerFactory = Program.ApplicationHost.Services.GetRequiredService(); + var navigationService = Program.ApplicationHost.Services.GetRequiredService(); - desktop.MainWindow = new MainWindow() - { - DataContext = Program.ApplicationHost.Services.GetRequiredService() - }; - Program.ShutdownRequested += (_, _) => Dispatcher.UIThread.Invoke(() => desktop.MainWindow.Close()); - } - else if (ApplicationLifetime is ISingleViewApplicationLifetime singleView) + switch (ApplicationLifetime) { - Console.WriteLine("Application running in single view style"); - var loggerFactory = Program.ApplicationHost.Services.GetRequiredService(); - var logger = loggerFactory.CreateLogger(); - singleView.MainView = new MainView(logger) - { - DataContext = Program.ApplicationHost.Services.GetRequiredService() - }; + case IClassicDesktopStyleApplicationLifetime desktop: + Console.WriteLine("Application running in classic style"); + + desktop.Startup += (_, _) => Program.ApplicationHost.RunAsync(); + desktop.Exit += (_, _) => Program.ApplicationHost.StopAsync(); + + var mainWindowViewModelLogger = loggerFactory.CreateLogger(); + var mainWindow = new MainWindow() + { + DataContext = new MainWindowViewModel(mainWindowViewModelLogger) + }; + desktop.MainWindow = mainWindow; + + Program.ShutdownRequested += (_, _) => Dispatcher.UIThread.Invoke(() => desktop.MainWindow?.Close()); + break; + + case ISingleViewApplicationLifetime singleView: + Console.WriteLine("Application running in single view style"); + break; + + default: + throw new InvalidOperationException($"Application framework initialization cannot be fulfilled, ApplicationLifetime has unknown type inherited from: {string.Join(", ", ApplicationLifetime.GetType().GetInterfaces().Select(i => i.FullName))}"); + } - else - throw new InvalidOperationException($"Application framework initialization cannot be fulfilled, ApplicationLifetime has unknown type inherited from: {string.Join(", ", ApplicationLifetime.GetType().GetInterfaces().Select(i => i.FullName))}"); + + var mainViewLogger = loggerFactory.CreateLogger(); + var mainView = new MainView(mainViewLogger) + { + DataContext = Program.ApplicationHost.Services.GetRequiredService() + }; + navigationService.NavigateTo(mainView); + base.OnFrameworkInitializationCompleted(); } + } \ No newline at end of file diff --git a/GSS2.Test/DependencyInjectionHelper.cs b/GSS2.Test/DependencyInjectionHelper.cs index 085944e..4ec6570 100644 --- a/GSS2.Test/DependencyInjectionHelper.cs +++ b/GSS2.Test/DependencyInjectionHelper.cs @@ -2,6 +2,9 @@ using GSS2.UI.Core.Views; using GSS2.UI.Core.ViewModels; using GSS2.Test.Views; using GSS2.Test.ViewModels; +using GSS2.UI.Core.Services; + +using Avalonia; namespace GSS2.Test; @@ -9,6 +12,7 @@ public static class DependencyInjectionHelper { public static IServiceCollection AddViewsAndModels(this IServiceCollection services) => services + .AddSingleton((_) => new NavigationService(Application.Current?.ApplicationLifetime)) .AddSingleton() .AddSingleton() .AddSingleton() diff --git a/GSS2.Test/MainWindow.axaml.cs b/GSS2.Test/MainWindow.axaml.cs deleted file mode 100644 index a77fec3..0000000 --- a/GSS2.Test/MainWindow.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace GSS2.Test; - -public partial class MainWindow : Window -{ - public MainWindow() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/GSS2.Test/ViewModels/MainViewModel.cs b/GSS2.Test/ViewModels/MainViewModel.cs index 2f9d393..96777f8 100644 --- a/GSS2.Test/ViewModels/MainViewModel.cs +++ b/GSS2.Test/ViewModels/MainViewModel.cs @@ -11,6 +11,7 @@ public partial class MainViewModel : ViewModelBase private readonly ILogger _logger; private readonly CameraService _cameraService; private readonly IlluminatorService _illuminatorService; + [ObservableProperty] private CameraViewModel _cameraViewModel; [ObservableProperty] private ResourcesViewModel _resourcesViewModel; [ObservableProperty] private IlluminatorControllerViewModel _illuminatorControllerViewModel; @@ -28,6 +29,8 @@ public partial class MainViewModel : ViewModelBase public MainViewModel(ILogger logger, CameraViewModel cameraViewModel, ResourcesViewModel resourcesViewModel, IlluminatorControllerViewModel illuminatorControllerViewModel, CameraService cameraService, IlluminatorService illuminatorService) { _logger = logger; + _logger.LogInformation("Initialization"); + _cameraService = cameraService; _illuminatorService = illuminatorService; CameraViewModel = cameraViewModel; @@ -53,6 +56,6 @@ public partial class MainViewModel : ViewModelBase ButtonUpClick = new RelayCommand(() => CurrentIndex--); ButtonDownClick = new RelayCommand(() => CurrentIndex++); - _logger.LogInformation("{} initialized", nameof(MainViewModel)); + _logger.LogInformation("Initialized"); } } \ No newline at end of file diff --git a/GSS2.Test/ViewModels/MainWindowViewModel.cs b/GSS2.Test/ViewModels/MainWindowViewModel.cs deleted file mode 100644 index 9e15df5..0000000 --- a/GSS2.Test/ViewModels/MainWindowViewModel.cs +++ /dev/null @@ -1,20 +0,0 @@ -using CommunityToolkit.Mvvm.ComponentModel; - -using GSS2.UI.Core.ViewModels; - -namespace GSS2.Test.ViewModels; - -public partial class MainWindowViewModel : ViewModelBase -{ - [ObservableProperty] private string _title; - [ObservableProperty] private MainViewModel _mainViewModel; - private readonly ILogger _logger; - - public MainWindowViewModel(ILogger logger, MainViewModel mainViewModel) - { - _logger = logger; - MainViewModel = mainViewModel; - Title = "GSS2.Test"; - _logger.LogInformation("{} initialized", nameof(MainWindowViewModel)); - } -} \ No newline at end of file diff --git a/GSS2.Test/MainWindow.axaml b/GSS2.UI.Core/MainWindow.axaml similarity index 69% rename from GSS2.Test/MainWindow.axaml rename to GSS2.UI.Core/MainWindow.axaml index 8a7b77a..525adbc 100644 --- a/GSS2.Test/MainWindow.axaml +++ b/GSS2.UI.Core/MainWindow.axaml @@ -1,13 +1,13 @@ - + diff --git a/GSS2.UI.Core/MainWindow.axaml.cs b/GSS2.UI.Core/MainWindow.axaml.cs new file mode 100644 index 0000000..02f6d49 --- /dev/null +++ b/GSS2.UI.Core/MainWindow.axaml.cs @@ -0,0 +1,16 @@ +using Avalonia.Controls; + +namespace GSS2.UI.Core; + +public partial class MainWindow : Window +{ + public MainWindow() + { + InitializeComponent(); + } + + public void SetControl(UserControl control) + { + MainContent.Content = control; + } +} \ No newline at end of file diff --git a/GSS2.UI.Core/Services/NavigateService.cs b/GSS2.UI.Core/Services/NavigateService.cs new file mode 100644 index 0000000..b943a72 --- /dev/null +++ b/GSS2.UI.Core/Services/NavigateService.cs @@ -0,0 +1,59 @@ + +using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; + +namespace GSS2.UI.Core.Services; + +public class NavigationService +{ + private readonly Stack _navigateControls = new Stack(); + private readonly IApplicationLifetime? _applicationLifetime; + + public NavigationService(IApplicationLifetime? applicationLifetime) + { + _applicationLifetime = applicationLifetime; + } + + public void NavigateTo(UserControl control) + { + _navigateControls.Push(control); + + switch (_applicationLifetime) + { + case IClassicDesktopStyleApplicationLifetime desktop + when desktop.MainWindow is MainWindow mainWindow: + + mainWindow.SetControl(control); + break; + + case ISingleViewApplicationLifetime singleView: + singleView.MainView = control; + break; + } + } + + public void NavigateBack() + { + if (_navigateControls.Count <= 1) + return; + + var lastControl = _navigateControls.Pop(); + var control = _navigateControls.Peek(); + + switch (_applicationLifetime) + { + case IClassicDesktopStyleApplicationLifetime desktop + when desktop.MainWindow is MainWindow mainWindow: + + mainWindow.SetControl(control); + break; + + case ISingleViewApplicationLifetime singleView: + singleView.MainView = control; + break; + } + + if (lastControl is IDisposable disposable) + disposable.Dispose(); + } +}