From fc7cdceb05820607d13b211883c0c9d27c491c08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20B=C3=B6rchers?= Date: Sun, 2 Apr 2023 22:49:00 +0200 Subject: [PATCH] file-scoped namespaces and other cleanup stuff --- src/App.axaml.cs | 173 +++++++++--------- src/ApplicationTheme.cs | 17 +- src/AvaloniaCoreRTDemo.csproj | 3 +- src/Controls/MainControl.axaml.cs | 35 ++-- .../ViewModels/MainControlViewModel.cs | 71 ++++--- src/Interfaces/IMainWindow.cs | 21 +-- src/Interfaces/IMainWindowState.cs | 19 +- src/Interfaces/IThemeSwitch.cs | 13 +- src/Program.cs | 25 ++- src/Utilities.cs | 77 ++++---- src/Windows/AboutWindow.axaml.cs | 39 ++-- src/Windows/MainWindow.axaml.cs | 63 ++++--- src/Windows/ViewModels/AboutViewModel.cs | 101 +++++----- .../ViewModels/ApplicationModelBase.cs | 163 ++++++++--------- src/Windows/ViewModels/MainViewModel.cs | 38 ++-- 15 files changed, 415 insertions(+), 443 deletions(-) diff --git a/src/App.axaml.cs b/src/App.axaml.cs index 1434c89..286c19a 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -1,5 +1,3 @@ -using System; - using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; @@ -11,100 +9,99 @@ using Avalonia.Themes.Simple; using AvaloniaCoreRTDemo.Interfaces; using AvaloniaCoreRTDemo.Windows; -namespace AvaloniaCoreRTDemo +namespace AvaloniaCoreRTDemo; + +public sealed class App : Application, IThemeSwitch { - public sealed class App : Application, IThemeSwitch + private FluentTheme _fluentTheme = default!; + private SimpleTheme _simpleTheme = default!; + private IStyle _fluentDataGrid = default!; + private IStyle _simpleDataGrid = default!; + + private ApplicationTheme _currentTheme; + + public override void Initialize() { - private FluentTheme _fluentTheme = default!; - private SimpleTheme _simpleTheme = default!; - private IStyle _fluentDataGrid = default!; - private IStyle _simpleDataGrid = default!; + AvaloniaXamlLoader.Load(this); + Name = "AvaloniaCoreRTDemo"; + } - private ApplicationTheme _currentTheme; - - public override void Initialize() + public override void OnFrameworkInitializationCompleted() + { + InitializeThemes(); + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { - AvaloniaXamlLoader.Load(this); - Name = "AvaloniaCoreRTDemo"; + desktop.MainWindow = new MainWindow(); + DataContext = desktop.MainWindow.DataContext; + } + base.OnFrameworkInitializationCompleted(); + } + + private void InitializeThemes() + { + _simpleTheme = new SimpleTheme(); + _fluentTheme = new FluentTheme(); + + _fluentDataGrid = (IStyle)Resources["fluentDataGrid"]!; + _simpleDataGrid = (IStyle)Resources["simpleDataGrid"]!; + + Styles.Add(_fluentTheme); + Styles.Add(_fluentDataGrid); + _currentTheme = ApplicationTheme.FluentLight; + } + + ApplicationTheme IThemeSwitch.Current => _currentTheme; + + void IThemeSwitch.ChangeTheme(ApplicationTheme theme) + { + if (theme == _currentTheme) + return; + + bool themeChanged = theme switch + { + ApplicationTheme.SimpleLight => _currentTheme is ApplicationTheme.FluentDark or ApplicationTheme.FluentLight, + ApplicationTheme.SimpleDark => _currentTheme is ApplicationTheme.FluentDark or ApplicationTheme.FluentLight, + ApplicationTheme.FluentLight => _currentTheme is ApplicationTheme.SimpleLight or ApplicationTheme.SimpleDark, + ApplicationTheme.FluentDark => _currentTheme is ApplicationTheme.SimpleLight or ApplicationTheme.SimpleDark, + _ => throw new ArgumentOutOfRangeException(nameof(theme), theme, null) + }; + + _currentTheme = theme; + switch (theme) + { + case ApplicationTheme.SimpleLight: + SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Light); + Styles[0] = _simpleTheme; + Styles[1] = _simpleDataGrid; + break; + case ApplicationTheme.SimpleDark: + SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Dark); + Styles[0] = _simpleTheme; + Styles[1] = _simpleDataGrid; + break; + case ApplicationTheme.FluentLight: + SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Light); + Styles[0] = _fluentTheme; + Styles[1] = _fluentDataGrid; + break; + case ApplicationTheme.FluentDark: + SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Dark); + Styles[0] = _fluentTheme; + Styles[1] = _fluentDataGrid; + break; } - public override void OnFrameworkInitializationCompleted() + if (themeChanged && ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { - InitializeThemes(); - if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) - { - desktop.MainWindow = new MainWindow(); - DataContext = desktop.MainWindow.DataContext; - } - base.OnFrameworkInitializationCompleted(); - } + MainWindow oldWindow = (desktop.MainWindow as MainWindow)!; + MainWindow newWindow = new MainWindow(oldWindow); - private void InitializeThemes() - { - _simpleTheme = new SimpleTheme(); - _fluentTheme = new FluentTheme(); + desktop.MainWindow = newWindow; + DataContext = newWindow.DataContext; - _fluentDataGrid = (IStyle)Resources["fluentDataGrid"]!; - _simpleDataGrid = (IStyle)Resources["simpleDataGrid"]!; - - Styles.Add(_fluentTheme); - Styles.Add(_fluentDataGrid); - _currentTheme = ApplicationTheme.FluentLight; - } - - ApplicationTheme IThemeSwitch.Current => _currentTheme; - - void IThemeSwitch.ChangeTheme(ApplicationTheme theme) - { - if (theme == _currentTheme) - return; - - bool themeChanged = theme switch - { - ApplicationTheme.SimpleLight => _currentTheme is ApplicationTheme.FluentDark or ApplicationTheme.FluentLight, - ApplicationTheme.SimpleDark => _currentTheme is ApplicationTheme.FluentDark or ApplicationTheme.FluentLight, - ApplicationTheme.FluentLight => _currentTheme is ApplicationTheme.SimpleLight or ApplicationTheme.SimpleDark, - ApplicationTheme.FluentDark => _currentTheme is ApplicationTheme.SimpleLight or ApplicationTheme.SimpleDark, - _ => throw new ArgumentOutOfRangeException(nameof(theme), theme, null) - }; - - _currentTheme = theme; - switch (theme) - { - case ApplicationTheme.SimpleLight: - SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Light); - Styles[0] = _simpleTheme; - Styles[1] = _simpleDataGrid; - break; - case ApplicationTheme.SimpleDark: - SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Dark); - Styles[0] = _simpleTheme; - Styles[1] = _simpleDataGrid; - break; - case ApplicationTheme.FluentLight: - SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Light); - Styles[0] = _fluentTheme; - Styles[1] = _fluentDataGrid; - break; - case ApplicationTheme.FluentDark: - SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Dark); - Styles[0] = _fluentTheme; - Styles[1] = _fluentDataGrid; - break; - } - - if (themeChanged && ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) - { - MainWindow oldWindow = (desktop.MainWindow as MainWindow)!; - MainWindow newWindow = new MainWindow(oldWindow); - - desktop.MainWindow = newWindow; - DataContext = newWindow.DataContext; - - oldWindow.Hide(); - newWindow.Show(); - oldWindow.Close(); - } + oldWindow.Hide(); + newWindow.Show(); + oldWindow.Close(); } } -} +} \ No newline at end of file diff --git a/src/ApplicationTheme.cs b/src/ApplicationTheme.cs index cfe6db6..831b27b 100644 --- a/src/ApplicationTheme.cs +++ b/src/ApplicationTheme.cs @@ -1,12 +1,9 @@ -using System; +namespace AvaloniaCoreRTDemo; -namespace AvaloniaCoreRTDemo +public enum ApplicationTheme : byte { - public enum ApplicationTheme : byte - { - SimpleLight = 0, - SimpleDark = 1, - FluentLight = 2, - FluentDark = 3, - } -} + SimpleLight = 0, + SimpleDark = 1, + FluentLight = 2, + FluentDark = 3, +} \ No newline at end of file diff --git a/src/AvaloniaCoreRTDemo.csproj b/src/AvaloniaCoreRTDemo.csproj index a3512d3..7adaab3 100644 --- a/src/AvaloniaCoreRTDemo.csproj +++ b/src/AvaloniaCoreRTDemo.csproj @@ -11,7 +11,7 @@ true true true - enable + enable @@ -61,6 +61,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Controls/MainControl.axaml.cs b/src/Controls/MainControl.axaml.cs index b8b0417..bb10f80 100644 --- a/src/Controls/MainControl.axaml.cs +++ b/src/Controls/MainControl.axaml.cs @@ -3,24 +3,23 @@ using Avalonia.Markup.Xaml; using AvaloniaCoreRTDemo.Controls.ViewModels; -namespace AvaloniaCoreRTDemo.Controls +namespace AvaloniaCoreRTDemo.Controls; + +public sealed partial class MainControl : UserControl { - public sealed partial class MainControl : UserControl + public MainControl() { - public MainControl() - { - InitializeComponent(); - } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - DataContext = new MainControlViewModel(); - } - - public void Reload(IMainWindowState model) - { - DataContext = new MainControlViewModel(model); - } + InitializeComponent(); } -} + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + DataContext = new MainControlViewModel(); + } + + public void Reload(IMainWindowState model) + { + DataContext = new MainControlViewModel(model); + } +} \ No newline at end of file diff --git a/src/Controls/ViewModels/MainControlViewModel.cs b/src/Controls/ViewModels/MainControlViewModel.cs index 63a7933..3d6c915 100644 --- a/src/Controls/ViewModels/MainControlViewModel.cs +++ b/src/Controls/ViewModels/MainControlViewModel.cs @@ -1,46 +1,45 @@ using Avalonia.Media.Imaging; using MvvmGen; -namespace AvaloniaCoreRTDemo.Controls.ViewModels +namespace AvaloniaCoreRTDemo.Controls.ViewModels; + +[ViewModel] +internal sealed partial class MainControlViewModel : IMainWindowState { - [ViewModel] - internal sealed partial class MainControlViewModel : IMainWindowState + private IBitmap _dotNetImage; + private IBitmap _avaloniaImage; + + private bool _unloadable = false; + + public IBitmap DotNetImage => _dotNetImage; + public IBitmap AvaloniaImage => _avaloniaImage; + public string? Text { get; set; } + + partial void OnInitialize() { - private IBitmap _dotNetImage; - private IBitmap _avaloniaImage; + _dotNetImage = Utilities.GetImageFromFile("dotnet.png"); + _avaloniaImage = Utilities.GetImageFromFile("avalonia.png"); + } - private bool _unloadable = false; + public MainControlViewModel(IMainWindowState state) : this() + { + _avaloniaImage = state.AvaloniaImage; + _dotNetImage = state.DotNetImage; + Text = state.Text; + state.SetUnloadable(); + } - public IBitmap DotNetImage => _dotNetImage; - public IBitmap AvaloniaImage => _avaloniaImage; - public string? Text { get; set; } - - partial void OnInitialize() + ~MainControlViewModel() + { + if (!_unloadable) { - _dotNetImage = Utilities.GetImageFromFile("dotnet.png"); - _avaloniaImage = Utilities.GetImageFromFile("avalonia.png"); - } - - public MainControlViewModel(IMainWindowState state) : this() - { - _avaloniaImage = state.AvaloniaImage; - _dotNetImage = state.DotNetImage; - Text = state.Text; - state.SetUnloadable(); - } - - ~MainControlViewModel() - { - if (!_unloadable) - { - _dotNetImage.Dispose(); - _avaloniaImage.Dispose(); - } - } - - void IMainWindowState.SetUnloadable() - { - _unloadable = true; + _dotNetImage.Dispose(); + _avaloniaImage.Dispose(); } } -} + + void IMainWindowState.SetUnloadable() + { + _unloadable = true; + } +} \ No newline at end of file diff --git a/src/Interfaces/IMainWindow.cs b/src/Interfaces/IMainWindow.cs index 065ef7d..ec1d934 100644 --- a/src/Interfaces/IMainWindow.cs +++ b/src/Interfaces/IMainWindow.cs @@ -1,15 +1,14 @@ using Avalonia; using Avalonia.Controls; -namespace AvaloniaCoreRTDemo.Interfaces +namespace AvaloniaCoreRTDemo.Interfaces; + +public interface IMainWindow { - public interface IMainWindow - { - IThemeSwitch ThemeSwitch { get; } - IMainWindowState Model { get; } - PixelPoint Position { get; } - Size ClientSize { get; } - Size? FrameSize { get; } - WindowState State { get; } - } -} + IThemeSwitch ThemeSwitch { get; } + IMainWindowState Model { get; } + PixelPoint Position { get; } + Size ClientSize { get; } + Size? FrameSize { get; } + WindowState State { get; } +} \ No newline at end of file diff --git a/src/Interfaces/IMainWindowState.cs b/src/Interfaces/IMainWindowState.cs index af935c6..a077964 100644 --- a/src/Interfaces/IMainWindowState.cs +++ b/src/Interfaces/IMainWindowState.cs @@ -1,15 +1,12 @@ -using System; +using Avalonia.Media.Imaging; -using Avalonia.Media.Imaging; +namespace AvaloniaCoreRTDemo; -namespace AvaloniaCoreRTDemo +public interface IMainWindowState { - public interface IMainWindowState - { - IBitmap DotNetImage { get; } - IBitmap AvaloniaImage { get; } - string? Text { get; } + IBitmap DotNetImage { get; } + IBitmap AvaloniaImage { get; } + string? Text { get; } - void SetUnloadable(); - } -} + void SetUnloadable(); +} \ No newline at end of file diff --git a/src/Interfaces/IThemeSwitch.cs b/src/Interfaces/IThemeSwitch.cs index 45815dc..144de3c 100644 --- a/src/Interfaces/IThemeSwitch.cs +++ b/src/Interfaces/IThemeSwitch.cs @@ -1,8 +1,7 @@ -namespace AvaloniaCoreRTDemo.Interfaces +namespace AvaloniaCoreRTDemo.Interfaces; + +public interface IThemeSwitch { - public interface IThemeSwitch - { - ApplicationTheme Current { get; } - void ChangeTheme(ApplicationTheme theme); - } -} + ApplicationTheme Current { get; } + void ChangeTheme(ApplicationTheme theme); +} \ No newline at end of file diff --git a/src/Program.cs b/src/Program.cs index c689c49..a37ebf6 100644 --- a/src/Program.cs +++ b/src/Program.cs @@ -1,17 +1,16 @@ using Avalonia; -namespace AvaloniaCoreRTDemo -{ - public static class Program - { - // Initialization code. Don't use any Avalonia, third-party APIs or any - // SynchronizationContext-reliant code before AppMain is called: things aren't initialized - // yet and stuff might break. - public static void Main(string[] args) => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); +namespace AvaloniaCoreRTDemo; - // Avalonia configuration, don't remove; also used by visual designer. - public static AppBuilder BuildAvaloniaApp() - => AppBuilder.Configure().UsePlatformDetect() +public static class Program +{ + // Initialization code. Don't use any Avalonia, third-party APIs or any + // SynchronizationContext-reliant code before AppMain is called: things aren't initialized + // yet and stuff might break. + public static void Main(string[] args) => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); + + // Avalonia configuration, don't remove; also used by visual designer. + public static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure().UsePlatformDetect() .LogToTrace(); - } -} +} \ No newline at end of file diff --git a/src/Utilities.cs b/src/Utilities.cs index aea748e..a00da52 100644 --- a/src/Utilities.cs +++ b/src/Utilities.cs @@ -1,49 +1,46 @@ -using System; -using System.IO; -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; using Avalonia; using Avalonia.Controls; using Avalonia.Media.Imaging; using Avalonia.Platform; -namespace AvaloniaCoreRTDemo +namespace AvaloniaCoreRTDemo; + +internal static class Utilities { - internal static class Utilities + public static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + public static readonly bool IsOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); + + public static Bitmap GetImageFromResources(string fileName) { - public static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); - public static readonly bool IsOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); - - public static Bitmap GetImageFromResources(string fileName) - { - var assetLoader = AvaloniaLocator.Current.GetRequiredService(); - using var assetStream = assetLoader.Open(new Uri($"avares://AvaloniaCoreRTDemo/Images/{fileName}")); - return new Bitmap(assetStream); - } - - public static PixelPoint GetWindowPosition(Window window) - { - if (!IsOSX || !window.FrameSize.HasValue) - return window.Position; - else - { - int yOffset = (int)(window.FrameSize.Value.Height - window.ClientSize.Height); - return new(window.Position.X, window.Position.Y + yOffset); - } - } - - public static Bitmap GetImageFromFile(string path) - { - try - { - return new Bitmap(GetImageFullPath(path)); - } - catch (Exception) - { - return GetImageFromResources("broken-link.png"); - } - } - - private static string GetImageFullPath(string fileName) => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName); + var assetLoader = AvaloniaLocator.Current.GetRequiredService(); + using var assetStream = assetLoader.Open(new Uri($"avares://AvaloniaCoreRTDemo/Images/{fileName}")); + return new Bitmap(assetStream); } -} + + public static PixelPoint GetWindowPosition(Window window) + { + if (!IsOSX || !window.FrameSize.HasValue) + return window.Position; + else + { + int yOffset = (int)(window.FrameSize.Value.Height - window.ClientSize.Height); + return new(window.Position.X, window.Position.Y + yOffset); + } + } + + public static Bitmap GetImageFromFile(string path) + { + try + { + return new Bitmap(GetImageFullPath(path)); + } + catch (Exception) + { + return GetImageFromResources("broken-link.png"); + } + } + + private static string GetImageFullPath(string fileName) => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName); +} \ No newline at end of file diff --git a/src/Windows/AboutWindow.axaml.cs b/src/Windows/AboutWindow.axaml.cs index be0891d..2282e6e 100644 --- a/src/Windows/AboutWindow.axaml.cs +++ b/src/Windows/AboutWindow.axaml.cs @@ -1,32 +1,29 @@ -using System; - using Avalonia; using Avalonia.Controls; using Avalonia.Markup.Xaml; using AvaloniaCoreRTDemo.Windows.ViewModels; -namespace AvaloniaCoreRTDemo.Windows +namespace AvaloniaCoreRTDemo.Windows; + +public sealed partial class AboutWindow : Window { - public sealed partial class AboutWindow : Window + private readonly bool _darkTheme; + + public AboutWindow() : this(false) { } + + public AboutWindow(bool darkTheme) { - private readonly bool _darkTheme; - - public AboutWindow() : this(false) { } - - public AboutWindow(bool darkTheme) - { - _darkTheme = darkTheme; - InitializeComponent(); + _darkTheme = darkTheme; + InitializeComponent(); #if DEBUG - this.AttachDevTools(); + this.AttachDevTools(); #endif - } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - DataContext = new AboutViewModel(_darkTheme); - } } -} + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + DataContext = new AboutViewModel(_darkTheme); + } +} \ No newline at end of file diff --git a/src/Windows/MainWindow.axaml.cs b/src/Windows/MainWindow.axaml.cs index 2f02b04..6342873 100644 --- a/src/Windows/MainWindow.axaml.cs +++ b/src/Windows/MainWindow.axaml.cs @@ -6,44 +6,43 @@ using AvaloniaCoreRTDemo.Controls; using AvaloniaCoreRTDemo.Interfaces; using AvaloniaCoreRTDemo.Windows.ViewModels; -namespace AvaloniaCoreRTDemo.Windows +namespace AvaloniaCoreRTDemo.Windows; + +public sealed partial class MainWindow : Window, IMainWindow { - public sealed partial class MainWindow : Window, IMainWindow + private readonly Application? _app = Application.Current; + + private MainControl MainController => this.GetControl("MainControl"); + + public MainWindow() : this(default) { } + + public MainWindow(IMainWindow? window) { - private readonly Application? _app = Application.Current; - - private MainControl MainController => this.GetControl("MainControl"); - - public MainWindow() : this(default) { } - - public MainWindow(IMainWindow? window) - { - InitializeComponent(window); + InitializeComponent(window); #if DEBUG - this.AttachDevTools(); + this.AttachDevTools(); #endif - } + } - IThemeSwitch IMainWindow.ThemeSwitch => (IThemeSwitch)_app!; - IMainWindowState IMainWindow.Model => (IMainWindowState)this.MainController.DataContext!; - PixelPoint IMainWindow.Position => Utilities.GetWindowPosition(this); - Size IMainWindow.ClientSize => ClientSize; - Size? IMainWindow.FrameSize => FrameSize; - WindowState IMainWindow.State => WindowState; + IThemeSwitch IMainWindow.ThemeSwitch => (IThemeSwitch)_app!; + IMainWindowState IMainWindow.Model => (IMainWindowState)this.MainController.DataContext!; + PixelPoint IMainWindow.Position => Utilities.GetWindowPosition(this); + Size IMainWindow.ClientSize => ClientSize; + Size? IMainWindow.FrameSize => FrameSize; + WindowState IMainWindow.State => WindowState; - private void InitializeComponent(IMainWindow? window) + private void InitializeComponent(IMainWindow? window) + { + AvaloniaXamlLoader.Load(this); + DataContext = new MainViewModel(this); + if (window is not null) { - AvaloniaXamlLoader.Load(this); - DataContext = new MainViewModel(this); - if (window is not null) - { - this.MainController.Reload(window.Model); - WindowStartupLocation = WindowStartupLocation.Manual; - WindowState = window.State; - Position = window.Position; - FrameSize = window.FrameSize; - ClientSize = window.ClientSize; - } + this.MainController.Reload(window.Model); + WindowStartupLocation = WindowStartupLocation.Manual; + WindowState = window.State; + Position = window.Position; + FrameSize = window.FrameSize; + ClientSize = window.ClientSize; } } -} +} \ No newline at end of file diff --git a/src/Windows/ViewModels/AboutViewModel.cs b/src/Windows/ViewModels/AboutViewModel.cs index 0f6feb2..425074f 100644 --- a/src/Windows/ViewModels/AboutViewModel.cs +++ b/src/Windows/ViewModels/AboutViewModel.cs @@ -1,62 +1,59 @@ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; using Avalonia.Media.Imaging; using MvvmGen; -namespace AvaloniaCoreRTDemo.Windows.ViewModels +namespace AvaloniaCoreRTDemo.Windows.ViewModels; + +internal record SystemDetail(string Key, string Value); + +[ViewModel] +internal sealed partial class AboutViewModel { - internal record SystemDetail(string Key, string Value); + private readonly IBitmap _computerImage; + private readonly bool _darkTheme; - [ViewModel] - internal sealed partial class AboutViewModel + public IBitmap ComputerImage => _computerImage; + + public IReadOnlyList SystemDetails { get; } = + new[] + { + new SystemDetail("Number of Cores", Environment.ProcessorCount.ToString()), + new SystemDetail("OS", RuntimeInformation.OSDescription), + new SystemDetail("OS Arch", RuntimeInformation.OSArchitecture.ToString()), + new SystemDetail("OS Version", Environment.OSVersion.ToString()), + new SystemDetail("Computer", Environment.MachineName), + new SystemDetail("User", Environment.UserName), + new SystemDetail("System Path", Environment.SystemDirectory), + new SystemDetail("Current Path", Environment.CurrentDirectory), + new SystemDetail("Process Arch", RuntimeInformation.ProcessArchitecture.ToString()), + new SystemDetail("Runtime Name", RuntimeInformation.FrameworkDescription), + new SystemDetail("Runtime Path", RuntimeEnvironment.GetRuntimeDirectory()), + new SystemDetail("Runtime Version", RuntimeEnvironment.GetSystemVersion()), + new SystemDetail("Framework Version", Environment.Version.ToString()), + }; + + private string ComputerImageName { - private readonly IBitmap _computerImage; - private readonly bool _darkTheme; - - public IBitmap ComputerImage => _computerImage; - - public IReadOnlyList SystemDetails { get; } = - new[] - { - new SystemDetail("Number of Cores", Environment.ProcessorCount.ToString()), - new SystemDetail("OS", RuntimeInformation.OSDescription), - new SystemDetail("OS Arch", RuntimeInformation.OSArchitecture.ToString()), - new SystemDetail("OS Version", Environment.OSVersion.ToString()), - new SystemDetail("Computer", Environment.MachineName), - new SystemDetail("User", Environment.UserName), - new SystemDetail("System Path", Environment.SystemDirectory), - new SystemDetail("Current Path", Environment.CurrentDirectory), - new SystemDetail("Process Arch", RuntimeInformation.ProcessArchitecture.ToString()), - new SystemDetail("Runtime Name", RuntimeInformation.FrameworkDescription), - new SystemDetail("Runtime Path", RuntimeEnvironment.GetRuntimeDirectory()), - new SystemDetail("Runtime Version", RuntimeEnvironment.GetSystemVersion()), - new SystemDetail("Framework Version", Environment.Version.ToString()), - }; - - private string ComputerImageName + get { - get - { - if (Utilities.IsWindows) - return !_darkTheme ? "windows.png" : "windows_d.png"; - else if (Utilities.IsOSX) - return !_darkTheme ? "macos.png" : "macos_d.png"; - else - return !_darkTheme ? "linux.png" : "linux_d.png"; - } - } - - public AboutViewModel(bool darkTheme) : this() - { - _darkTheme = darkTheme; - _computerImage = Utilities.GetImageFromResources(ComputerImageName); - } - - ~AboutViewModel() - { - _computerImage.Dispose(); + if (Utilities.IsWindows) + return !_darkTheme ? "windows.png" : "windows_d.png"; + else if (Utilities.IsOSX) + return !_darkTheme ? "macos.png" : "macos_d.png"; + else + return !_darkTheme ? "linux.png" : "linux_d.png"; } } -} + + public AboutViewModel(bool darkTheme) : this() + { + _darkTheme = darkTheme; + _computerImage = Utilities.GetImageFromResources(ComputerImageName); + } + + ~AboutViewModel() + { + _computerImage.Dispose(); + } +} \ No newline at end of file diff --git a/src/Windows/ViewModels/ApplicationModelBase.cs b/src/Windows/ViewModels/ApplicationModelBase.cs index 86297f1..960663e 100644 --- a/src/Windows/ViewModels/ApplicationModelBase.cs +++ b/src/Windows/ViewModels/ApplicationModelBase.cs @@ -1,90 +1,87 @@ -using System; - -using Avalonia.Controls; +using Avalonia.Controls; using AvaloniaCoreRTDemo.Interfaces; using MvvmGen; -namespace AvaloniaCoreRTDemo.Windows.ViewModels +namespace AvaloniaCoreRTDemo.Windows.ViewModels; + +[ViewModel] +internal abstract partial class ApplicationModelBase { - [ViewModel] - internal abstract partial class ApplicationModelBase + private readonly IThemeSwitch _themeSwitch; + + [Property] + private bool _aboutEnabled = true; + + [Property] + private bool _defaultLightEnabled = false; + + [Property] + private bool _defaultDarkEnabled = false; + + [Property] + private bool _fluentLightEnabled = false; + + [Property] + private bool _fluentDarkEnabled = false; + + public ApplicationModelBase(IThemeSwitch themeSwitch) : this() { - private readonly IThemeSwitch _themeSwitch; - - [Property] - private bool _aboutEnabled = true; - - [Property] - private bool _defaultLightEnabled = false; - - [Property] - private bool _defaultDarkEnabled = false; - - [Property] - private bool _fluentLightEnabled = false; - - [Property] - private bool _fluentDarkEnabled = false; - - public ApplicationModelBase(IThemeSwitch themeSwitch) : this() - { - _themeSwitch = themeSwitch; - IntializeTheme(themeSwitch.Current); - } - - [Command] - protected abstract void HelpAbout(); - - [Command] - protected abstract void DefaultLight(); - - [Command] - protected abstract void DefaultDark(); - - [Command] - protected abstract void FluentLight(); - - [Command] - protected abstract void FluentDark(); - - protected async void RunHelpAbout(Window currentWindow) - { - if (AboutEnabled) - try - { - AboutEnabled = false; - await new AboutWindow(IsDarkTheme(_themeSwitch.Current)).ShowDialog(currentWindow); - } - finally - { - AboutEnabled = true; - } - } - - protected void SetTheme(ApplicationTheme theme) - { - IntializeTheme(theme); - _themeSwitch.ChangeTheme(theme); - } - - [Command] - private void FileExit() => Environment.Exit(0); - - private void IntializeTheme(ApplicationTheme theme) - { - DefaultLightEnabled = theme != ApplicationTheme.SimpleLight; - DefaultDarkEnabled = theme != ApplicationTheme.SimpleDark; - FluentLightEnabled = theme != ApplicationTheme.FluentLight; - FluentDarkEnabled = theme != ApplicationTheme.FluentDark; - } - - private static bool IsDarkTheme(ApplicationTheme? theme) => - theme switch - { - ApplicationTheme.SimpleDark => true, - ApplicationTheme.FluentDark => true, - _ => false, - }; + _themeSwitch = themeSwitch; + IntializeTheme(themeSwitch.Current); } -} + + [Command] + protected abstract void HelpAbout(); + + [Command] + protected abstract void DefaultLight(); + + [Command] + protected abstract void DefaultDark(); + + [Command] + protected abstract void FluentLight(); + + [Command] + protected abstract void FluentDark(); + + protected async void RunHelpAbout(Window currentWindow) + { + if (AboutEnabled) + try + { + AboutEnabled = false; + await new AboutWindow(IsDarkTheme(_themeSwitch.Current)).ShowDialog(currentWindow); + } + finally + { + AboutEnabled = true; + } + } + + protected void SetTheme(ApplicationTheme theme) + { + IntializeTheme(theme); + _themeSwitch.ChangeTheme(theme); + } + + [Command] + private void FileExit() => Environment.Exit(0); + + private void IntializeTheme(ApplicationTheme theme) + { + DefaultLightEnabled = theme != ApplicationTheme.SimpleLight; + DefaultDarkEnabled = theme != ApplicationTheme.SimpleDark; + FluentLightEnabled = theme != ApplicationTheme.FluentLight; + FluentDarkEnabled = theme != ApplicationTheme.FluentDark; + } + + private static bool IsDarkTheme(ApplicationTheme? theme) => + theme switch + { + ApplicationTheme.SimpleDark => true, + ApplicationTheme.FluentDark => true, + _ => false, + }; +} \ No newline at end of file diff --git a/src/Windows/ViewModels/MainViewModel.cs b/src/Windows/ViewModels/MainViewModel.cs index aad16f2..9a8f0d0 100644 --- a/src/Windows/ViewModels/MainViewModel.cs +++ b/src/Windows/ViewModels/MainViewModel.cs @@ -1,27 +1,25 @@ using Avalonia.Controls; using AvaloniaCoreRTDemo.Interfaces; -using MvvmGen; -namespace AvaloniaCoreRTDemo.Windows.ViewModels +namespace AvaloniaCoreRTDemo.Windows.ViewModels; + +internal sealed class MainViewModel : ApplicationModelBase where TWindow : Window, IMainWindow { - internal sealed class MainViewModel : ApplicationModelBase where TWindow : Window, IMainWindow + private TWindow _window; + + public MainViewModel(TWindow window) : base(window.ThemeSwitch) { - private TWindow _window; - - public MainViewModel(TWindow window) : base(window.ThemeSwitch) - { - _window = window; - } - - protected override void HelpAbout() => RunHelpAbout(_window); - - protected override void DefaultLight() => SetTheme(ApplicationTheme.SimpleLight); - - protected override void DefaultDark() => SetTheme(ApplicationTheme.SimpleDark); - - protected override void FluentLight() => SetTheme(ApplicationTheme.FluentLight); - - protected override void FluentDark() => SetTheme(ApplicationTheme.FluentDark); + _window = window; } -} + + protected override void HelpAbout() => RunHelpAbout(_window); + + protected override void DefaultLight() => SetTheme(ApplicationTheme.SimpleLight); + + protected override void DefaultDark() => SetTheme(ApplicationTheme.SimpleDark); + + protected override void FluentLight() => SetTheme(ApplicationTheme.FluentLight); + + protected override void FluentDark() => SetTheme(ApplicationTheme.FluentDark); +} \ No newline at end of file