Iuiuv3gZ~eN|J9y@V>zQSzQ_pL?yZ16)KDqn{Czle@@)KJQmmQjWAYQ$&
zvv-gFOf}D)y*s77ueQDP;^~HwlhqUA8fD-6?43slq?X~f<4-@T0;eBG4<~Ww%#!wH
zaM~1hwV_w+8t_U7jhGq|w`t7e+bl_rY+B3?J5Vyvrtap~(wj{>ky$tO9-ok9Pk5DzLOTebkzzVS{
zaCN2(vw^ay@NuM)f=Y>D27stB8rt%mHgQcdlEIi~`;^pRvto4s_J`TFbvA+N{{@RN
BtNs80
literal 0
HcmV?d00001
diff --git a/src/Interfaces/IMainWindow.cs b/src/Interfaces/IMainWindow.cs
new file mode 100644
index 0000000..2f8b2a8
--- /dev/null
+++ b/src/Interfaces/IMainWindow.cs
@@ -0,0 +1,9 @@
+using AvaloniaCoreRTDemo.Interfaces;
+
+namespace AvaloniaCoreRTDemo
+{
+ public interface IMainWindow
+ {
+ IThemeSwitch ThemeSwitch { get; }
+ }
+}
diff --git a/src/Interfaces/IThemeSwitch.cs b/src/Interfaces/IThemeSwitch.cs
new file mode 100644
index 0000000..45815dc
--- /dev/null
+++ b/src/Interfaces/IThemeSwitch.cs
@@ -0,0 +1,8 @@
+namespace AvaloniaCoreRTDemo.Interfaces
+{
+ public interface IThemeSwitch
+ {
+ ApplicationTheme Current { get; }
+ void ChangeTheme(ApplicationTheme theme);
+ }
+}
diff --git a/src/MainWindow.xaml b/src/MainWindow.xaml
deleted file mode 100644
index 915b90a..0000000
--- a/src/MainWindow.xaml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
- Welcome to Avalonia UI + CoreRT!
-
-
-
-
-
-
-
diff --git a/src/MainWindowViewModel.cs b/src/MainWindowViewModel.cs
deleted file mode 100644
index fad3eb4..0000000
--- a/src/MainWindowViewModel.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using Avalonia.Media.Imaging;
-using ReactiveUI;
-using System;
-using System.Reactive;
-using Path = System.IO.Path;
-
-namespace AvaloniaCoreRTDemo
-{
- public class MainWindowViewModel: ReactiveObject
- {
- public MainWindowViewModel(MainWindow window)
- {
- _window = window;
-
- DotNetImage = new Bitmap(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dotnet.png"));
- AvaloniaImage = new Bitmap(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "avalonia.png"));
-
- FileExitCommand = ReactiveCommand.Create(RunFileExit);
- }
-
- public IBitmap DotNetImage
- {
- get { return dotNetImage; }
- set { this.RaiseAndSetIfChanged(ref this.dotNetImage, value); }
- }
-
- public IBitmap AvaloniaImage
- {
- get { return avaloniaImage; }
- set { this.RaiseAndSetIfChanged(ref this.avaloniaImage, value); }
- }
-
- public ReactiveCommand FileExitCommand { get; }
- public void HelpAboutMethod() => RunHelpAbout();
-
- void RunFileExit()
- {
- Environment.Exit(0);
- }
-
- void RunHelpAbout()
- {
- new AboutWindow().ShowDialog(_window);
- }
-
- private IBitmap dotNetImage;
- private IBitmap avaloniaImage;
- private readonly MainWindow _window;
- }
-}
\ No newline at end of file
diff --git a/src/Program.cs b/src/Program.cs
index a90b6af..0bde694 100644
--- a/src/Program.cs
+++ b/src/Program.cs
@@ -1,4 +1,5 @@
-using Avalonia;
+
+using Avalonia;
namespace AvaloniaCoreRTDemo
{
@@ -7,13 +8,14 @@ namespace AvaloniaCoreRTDemo
// 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);
+ 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();
+ => AppBuilder.Configure().UsePlatformDetect()
+#if OSX
+ .UseAvaloniaNative()
+#endif
+ .LogToTrace();
}
}
diff --git a/src/Windows/AboutWindow.axaml b/src/Windows/AboutWindow.axaml
new file mode 100644
index 0000000..8ef32d8
--- /dev/null
+++ b/src/Windows/AboutWindow.axaml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Windows/AboutWindow.axaml.cs b/src/Windows/AboutWindow.axaml.cs
new file mode 100644
index 0000000..4b9ca92
--- /dev/null
+++ b/src/Windows/AboutWindow.axaml.cs
@@ -0,0 +1,28 @@
+using System;
+
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+using AvaloniaCoreRTDemo.Windows.ViewModels;
+
+namespace AvaloniaCoreRTDemo.Windows
+{
+ public sealed partial class AboutWindow : Window
+ {
+ public AboutWindow()
+ {
+ this.InitializeComponent();
+ }
+
+ public AboutWindow(Boolean darkTheme)
+ {
+ this.InitializeComponent(darkTheme);
+ }
+
+ private void InitializeComponent(Boolean darkTheme = default)
+ {
+ AvaloniaXamlLoader.Load(this);
+ this.DataContext = new AboutViewModel(darkTheme);
+ }
+ }
+}
diff --git a/src/Windows/MainWindow.axaml b/src/Windows/MainWindow.axaml
new file mode 100644
index 0000000..f912199
--- /dev/null
+++ b/src/Windows/MainWindow.axaml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
diff --git a/src/Windows/MainWindow.axaml.cs b/src/Windows/MainWindow.axaml.cs
new file mode 100644
index 0000000..a846014
--- /dev/null
+++ b/src/Windows/MainWindow.axaml.cs
@@ -0,0 +1,28 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+using AvaloniaCoreRTDemo.Interfaces;
+using AvaloniaCoreRTDemo.Windows.ViewModels;
+
+namespace AvaloniaCoreRTDemo.Windows
+{
+ public sealed partial class MainWindow : Window, IMainWindow
+ {
+ public MainWindow()
+ {
+ InitializeComponent();
+#if DEBUG
+ this.AttachDevTools();
+#endif
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ this.DataContext = new MainViewModel(this);
+ }
+
+ IThemeSwitch IMainWindow.ThemeSwitch => App.Current as IThemeSwitch;
+ }
+}
diff --git a/src/Windows/MainWindowMacOS.axaml b/src/Windows/MainWindowMacOS.axaml
new file mode 100644
index 0000000..4ea0793
--- /dev/null
+++ b/src/Windows/MainWindowMacOS.axaml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Windows/MainWindowMacOS.axaml.cs b/src/Windows/MainWindowMacOS.axaml.cs
new file mode 100644
index 0000000..9c25bcc
--- /dev/null
+++ b/src/Windows/MainWindowMacOS.axaml.cs
@@ -0,0 +1,28 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+using AvaloniaCoreRTDemo.Interfaces;
+using AvaloniaCoreRTDemo.Windows.ViewModels;
+
+namespace AvaloniaCoreRTDemo.Windows
+{
+ public partial class MainWindowMacOS : Window, IMainWindow
+ {
+ public MainWindowMacOS()
+ {
+ InitializeComponent();
+#if DEBUG
+ this.AttachDevTools();
+#endif
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ this.DataContext = new MainViewModel(this);
+ }
+
+ IThemeSwitch IMainWindow.ThemeSwitch => App.Current as IThemeSwitch;
+ }
+}
diff --git a/src/Windows/ViewModels/AboutViewModel.cs b/src/Windows/ViewModels/AboutViewModel.cs
new file mode 100644
index 0000000..ee4b0a9
--- /dev/null
+++ b/src/Windows/ViewModels/AboutViewModel.cs
@@ -0,0 +1,68 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+using Avalonia.Media.Imaging;
+
+using ReactiveUI;
+
+namespace AvaloniaCoreRTDemo.Windows.ViewModels
+{
+ internal sealed class AboutViewModel : ReactiveObject
+ {
+ private readonly IBitmap _computerImage;
+ private readonly Boolean _darkTheme;
+
+ public IBitmap ComputerImage => _computerImage;
+ public static String NCores => Environment.ProcessorCount.ToString();
+ public static String OS => RuntimeInformation.OSDescription;
+ public static String OSArch => RuntimeInformation.OSArchitecture.ToString();
+ public static String OSVersion => Environment.OSVersion.ToString();
+ public static String ComputerName => Environment.MachineName;
+ public static String UserName => Environment.UserName;
+ public static String SystemPath => Environment.SystemDirectory;
+ public static String CurrentPath => Environment.CurrentDirectory;
+ public static String ProcessArch => RuntimeInformation.ProcessArchitecture.ToString();
+ public static String RuntimeName => RuntimeInformation.FrameworkDescription;
+ public static String RuntimePath => RuntimeEnvironment.GetRuntimeDirectory();
+ public static String RuntimeVersion => RuntimeEnvironment.GetSystemVersion();
+ public static String FrameworkVersion => Environment.Version.ToString();
+
+ private String ComputerImageName
+ {
+ get
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ return !_darkTheme ? "windows.png" : "windows_d.png";
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ return !_darkTheme ? "macos.png" : "macos_d.png";
+ else
+ return !_darkTheme ? "linux.png" : "linux_d.png";
+ }
+ }
+
+ public AboutViewModel(Boolean darkTheme)
+ {
+ this._darkTheme = darkTheme;
+ this._computerImage = GetImageFromResources(this.ComputerImageName);
+ }
+
+ ~AboutViewModel()
+ {
+ this._computerImage.Dispose();
+ }
+
+ private static Bitmap GetImageFromResources(String fileName)
+ {
+ Assembly asm = Assembly.GetExecutingAssembly();
+ String resourceName = asm.GetManifestResourceNames().FirstOrDefault(str => str.EndsWith(fileName));
+ if (resourceName != null)
+ using (Stream bitmapStream = asm.GetManifestResourceStream(resourceName))
+ return new Bitmap(bitmapStream);
+ else
+ return default;
+ }
+ }
+}
diff --git a/src/Windows/ViewModels/MainViewModel.cs b/src/Windows/ViewModels/MainViewModel.cs
new file mode 100644
index 0000000..1a72964
--- /dev/null
+++ b/src/Windows/ViewModels/MainViewModel.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Reactive;
+
+using Avalonia.Controls;
+
+using ReactiveUI;
+
+namespace AvaloniaCoreRTDemo.Windows.ViewModels
+{
+ internal sealed class MainViewModel : MainViewModelBase
+ where TWindow : Window, IMainWindow
+ {
+ private readonly TWindow _window;
+
+ private Boolean _defaultLightEnable = true;
+ private Boolean _defaultDarkEnable = true;
+ private Boolean _fluentLightEnable = true;
+ private Boolean _fluentDarkEnable = true;
+
+ public Boolean DefaultLightEnabled
+ {
+ get => this._defaultLightEnable;
+ set => this.RaiseAndSetIfChanged(ref this._defaultLightEnable, value);
+ }
+
+ public Boolean DefaultDarkEnabled
+ {
+ get => this._defaultDarkEnable;
+ set => this.RaiseAndSetIfChanged(ref this._defaultDarkEnable, value);
+ }
+
+ public Boolean FluentLightEnabled
+ {
+ get => this._fluentLightEnable;
+ set => this.RaiseAndSetIfChanged(ref this._fluentLightEnable, value);
+ }
+
+ public Boolean FluentDarkEnabled
+ {
+ get => this._fluentDarkEnable;
+ set => this.RaiseAndSetIfChanged(ref this._fluentDarkEnable, value);
+ }
+
+ public ReactiveCommand FileExitCommand { get; }
+
+ public MainViewModel(TWindow window)
+ : base(window.ThemeSwitch)
+ {
+ this._window = window;
+ this.FileExitCommand = ReactiveCommand.Create(RunFileExit);
+ this.ChangeTheme(window.ThemeSwitch.Current);
+ }
+
+ public void DefaultLightMethod() => this.ChangeTheme(ApplicationTheme.DefaultLight);
+ public void DefaultDarkMethod() => this.ChangeTheme(ApplicationTheme.DefaultDark);
+ public void FluentLightMethod() => this.ChangeTheme(ApplicationTheme.FluentLight);
+ public void FluentDarkMethod() => this.ChangeTheme(ApplicationTheme.FluentDark);
+ public void HelpAboutMethod() => base.RunHelpAbout(this._window);
+
+ private void RunFileExit()
+ => Environment.Exit(0);
+
+ private void ChangeTheme(ApplicationTheme theme)
+ {
+ this.DefaultLightEnabled = theme != ApplicationTheme.DefaultLight && theme != ApplicationTheme.FluentLight;
+ this.DefaultDarkEnabled = theme != ApplicationTheme.DefaultDark && theme != ApplicationTheme.FluentDark;
+ this.FluentLightEnabled = theme != ApplicationTheme.FluentLight;
+ this.FluentDarkEnabled = theme != ApplicationTheme.FluentDark;
+ this._window.ThemeSwitch?.ChangeTheme(theme);
+ }
+ }
+}
diff --git a/src/Windows/ViewModels/MainViewModelBase.cs b/src/Windows/ViewModels/MainViewModelBase.cs
new file mode 100644
index 0000000..9c9f2c6
--- /dev/null
+++ b/src/Windows/ViewModels/MainViewModelBase.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Avalonia.Controls;
+
+using AvaloniaCoreRTDemo.Interfaces;
+
+using ReactiveUI;
+
+namespace AvaloniaCoreRTDemo.Windows.ViewModels
+{
+ internal abstract class MainViewModelBase : ReactiveObject
+ {
+ private readonly IThemeSwitch _themeSwitch;
+ private Boolean _aboutEnable = true;
+
+ public Boolean AboutEnabled
+ {
+ get => this._aboutEnable;
+ set => this.RaiseAndSetIfChanged(ref this._aboutEnable, value);
+ }
+
+ public MainViewModelBase(IThemeSwitch window)
+ => this._themeSwitch = window;
+
+ protected async void RunHelpAbout(Window currentWindow)
+ {
+ if (this.AboutEnabled)
+ try
+ {
+ this.AboutEnabled = false;
+ await new AboutWindow(IsDarkTheme(this._themeSwitch.Current)).ShowDialog(currentWindow);
+ }
+ finally
+ {
+ this.AboutEnabled = true;
+ }
+ }
+
+ private static Boolean IsDarkTheme(ApplicationTheme? theme)
+ => theme switch
+ {
+ ApplicationTheme.DefaultDark => true,
+ ApplicationTheme.FluentDark => true,
+ _ => false,
+ };
+ }
+}
diff --git a/src/nuget.config b/src/nuget.config
index 8afae99..1dfbeae 100644
--- a/src/nuget.config
+++ b/src/nuget.config
@@ -1,11 +1,7 @@
-
-
-
-
-
+
diff --git a/src/rd.xml b/src/rd.xml
index fa7ccfe..8e5aae8 100644
--- a/src/rd.xml
+++ b/src/rd.xml
@@ -9,6 +9,9 @@
+
+
+
-
+
+
MainWindowMacOS.axaml
From 3073afd6c7f4f08cf3f4a5f02dd2ee3ab4f1763e Mon Sep 17 00:00:00 2001
From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com>
Date: Sun, 12 Dec 2021 00:24:32 -0500
Subject: [PATCH 3/8] Artifacts information
---
README.md | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/README.md b/README.md
index 4a6491d..12aff36 100644
--- a/README.md
+++ b/README.md
@@ -37,3 +37,9 @@ Feel free to use this sample as a base for your projects.
When developing, keep in mind that Avalonia uses Reflection extensively. NativeAOT, being an AOT compiler, needs your help to get reflection right. Refer to `rd.xml` file in the solution. In it, you describe all assemblies and types which your app would potentially reflect over. For more information, see [Reflection in AOT mode](https://github.com/dotnet/runtimelab/blob/feature/NativeAOT/docs/using-nativeaot/reflection-in-aot-mode.md)
This project is configured to help you debug issues with publishing. Before publishing, check the CSPROJ file and modify the various Ilc* properties according to [Optimizing programs targeting Native AOT](https://github.com/dotnet/runtimelab/blob/feature/NativeAOT/docs/using-nativeaot/optimizing.md) document.
+
+## Artifact test
+
+For any change in this repo we will build the artifact for Windows-x64, Linux-x64 and macOS-x64.
+You can download them from workflows run results.
+For run the artifact on macOS make sure to allow the application inSystem Preferences, Security & Privacy, General.
From eab730c1f2f63be033be935851c7ea82021f3812 Mon Sep 17 00:00:00 2001
From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com>
Date: Mon, 13 Dec 2021 16:17:55 -0500
Subject: [PATCH 4/8] Sample improves
* No remove axaml files for makes the sample simpler.
* Creation of utilities class.
* Avoid using ref Bitmap on MainViewModel.
* Avoid application crashing when dotnet.png or avalonia.png are missing. Using an replace embeded image instead.
* Conditionally invoke of UseAvaloniaNative at runtime.
---
src/App.axaml.cs | 8 +---
src/AvaloniaCoreRTDemo.csproj | 4 --
src/Controls/ViewModels/MainViewModel.cs | 26 ++++++-------
src/Images/broken-link.png | Bin 0 -> 15464 bytes
src/Program.cs | 12 +++---
src/Utilities.cs | 39 ++++++++++++++++++++
src/Windows/ViewModels/AboutViewModel.cs | 26 +++----------
src/Windows/ViewModels/MainViewModel.cs | 2 +-
src/Windows/ViewModels/MainViewModelBase.cs | 6 +--
9 files changed, 69 insertions(+), 54 deletions(-)
create mode 100644 src/Images/broken-link.png
create mode 100644 src/Utilities.cs
diff --git a/src/App.axaml.cs b/src/App.axaml.cs
index 42529d0..e05cb41 100644
--- a/src/App.axaml.cs
+++ b/src/App.axaml.cs
@@ -1,3 +1,4 @@
+
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
@@ -30,12 +31,7 @@ namespace AvaloniaCoreRTDemo
this.InitializeThemes();
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
- desktop.MainWindow =
-#if !OSX
- new MainWindow();
-#else
- new MainWindowMacOS();
-#endif
+ desktop.MainWindow = !Utilities.IsOSX ? new MainWindow() : new MainWindowMacOS();
this.DataContext = desktop.MainWindow.DataContext;
}
base.OnFrameworkInitializationCompleted();
diff --git a/src/AvaloniaCoreRTDemo.csproj b/src/AvaloniaCoreRTDemo.csproj
index 73edcee..7e20a93 100644
--- a/src/AvaloniaCoreRTDemo.csproj
+++ b/src/AvaloniaCoreRTDemo.csproj
@@ -99,15 +99,11 @@
MainWindow.axaml
-
-
MainWindowMacOS.axaml
-
-
\ No newline at end of file
diff --git a/src/Controls/ViewModels/MainViewModel.cs b/src/Controls/ViewModels/MainViewModel.cs
index ee69584..29fc9f4 100644
--- a/src/Controls/ViewModels/MainViewModel.cs
+++ b/src/Controls/ViewModels/MainViewModel.cs
@@ -1,6 +1,5 @@
using System;
using System.IO;
-using System.Runtime.CompilerServices;
using Avalonia.Media.Imaging;
@@ -13,22 +12,23 @@ namespace AvaloniaCoreRTDemo.Controls.ViewModels
private readonly IBitmap _dotNetImage;
private readonly IBitmap _avaloniaImage;
- public IBitmap DotNetImage
- {
- get { return _dotNetImage; }
- set { this.RaiseAndSetIfChanged(ref Unsafe.AsRef(this._dotNetImage), value); }
- }
+ public IBitmap DotNetImage => this._dotNetImage;
- public IBitmap AvaloniaImage
- {
- get { return _avaloniaImage; }
- set { this.RaiseAndSetIfChanged(ref Unsafe.AsRef(this._avaloniaImage), value); }
- }
+ public IBitmap AvaloniaImage => this._avaloniaImage;
public MainViewModel()
{
- this._dotNetImage = new Bitmap(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dotnet.png"));
- this._avaloniaImage = new Bitmap(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "avalonia.png"));
+ this._dotNetImage = Utilities.GetImageFromFile(GetImageFullPath("dotnet.png"));
+ this._avaloniaImage = Utilities.GetImageFromFile(GetImageFullPath("avalonia.png"));
+ }
+
+ private static String GetImageFullPath(String fileName)
+ => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
+
+ ~MainViewModel()
+ {
+ this._dotNetImage.Dispose();
+ this._avaloniaImage.Dispose();
}
}
}
diff --git a/src/Images/broken-link.png b/src/Images/broken-link.png
new file mode 100644
index 0000000000000000000000000000000000000000..585ee1c69da73bde6f11a4b633229295b562fe7e
GIT binary patch
literal 15464
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
eT35vr1^ypBP2?iy5Uwr&0000 AppBuilder.Configure().UsePlatformDetect()
-#if OSX
- .UseAvaloniaNative()
-#endif
+ .UseAvaloniaNativeOSX()
.LogToTrace();
+
+ private static AppBuilder UseAvaloniaNativeOSX(this AppBuilder appBuilder)
+ => Utilities.IsOSX ? appBuilder.UseAvaloniaNative() : appBuilder;
}
}
diff --git a/src/Utilities.cs b/src/Utilities.cs
new file mode 100644
index 0000000..4296e91
--- /dev/null
+++ b/src/Utilities.cs
@@ -0,0 +1,39 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+using Avalonia.Media.Imaging;
+
+namespace AvaloniaCoreRTDemo
+{
+ internal static class Utilities
+ {
+ public static readonly Boolean IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
+ public static readonly Boolean IsOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
+
+ public static Bitmap GetImageFromResources(String fileName)
+ {
+ Assembly asm = Assembly.GetExecutingAssembly();
+ String resourceName = asm.GetManifestResourceNames().FirstOrDefault(str => str.EndsWith(fileName));
+ if (resourceName != null)
+ using (Stream bitmapStream = asm.GetManifestResourceStream(resourceName))
+ return new Bitmap(bitmapStream);
+ else
+ return default;
+ }
+
+ public static Bitmap GetImageFromFile(String path)
+ {
+ try
+ {
+ return new Bitmap(path);
+ }
+ catch (Exception)
+ {
+ return GetImageFromResources("broken-link.png");
+ }
+ }
+ }
+}
diff --git a/src/Windows/ViewModels/AboutViewModel.cs b/src/Windows/ViewModels/AboutViewModel.cs
index ee4b0a9..b09161e 100644
--- a/src/Windows/ViewModels/AboutViewModel.cs
+++ b/src/Windows/ViewModels/AboutViewModel.cs
@@ -1,7 +1,4 @@
using System;
-using System.IO;
-using System.Linq;
-using System.Reflection;
using System.Runtime.InteropServices;
using Avalonia.Media.Imaging;
@@ -34,35 +31,24 @@ namespace AvaloniaCoreRTDemo.Windows.ViewModels
{
get
{
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- return !_darkTheme ? "windows.png" : "windows_d.png";
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
- return !_darkTheme ? "macos.png" : "macos_d.png";
+ if (Utilities.IsWindows)
+ return !this._darkTheme ? "windows.png" : "windows_d.png";
+ else if (Utilities.IsOSX)
+ return !this._darkTheme ? "macos.png" : "macos_d.png";
else
- return !_darkTheme ? "linux.png" : "linux_d.png";
+ return !this._darkTheme ? "linux.png" : "linux_d.png";
}
}
public AboutViewModel(Boolean darkTheme)
{
this._darkTheme = darkTheme;
- this._computerImage = GetImageFromResources(this.ComputerImageName);
+ this._computerImage = Utilities.GetImageFromResources(this.ComputerImageName);
}
~AboutViewModel()
{
this._computerImage.Dispose();
}
-
- private static Bitmap GetImageFromResources(String fileName)
- {
- Assembly asm = Assembly.GetExecutingAssembly();
- String resourceName = asm.GetManifestResourceNames().FirstOrDefault(str => str.EndsWith(fileName));
- if (resourceName != null)
- using (Stream bitmapStream = asm.GetManifestResourceStream(resourceName))
- return new Bitmap(bitmapStream);
- else
- return default;
- }
}
}
diff --git a/src/Windows/ViewModels/MainViewModel.cs b/src/Windows/ViewModels/MainViewModel.cs
index 1a72964..a0acc74 100644
--- a/src/Windows/ViewModels/MainViewModel.cs
+++ b/src/Windows/ViewModels/MainViewModel.cs
@@ -55,7 +55,7 @@ namespace AvaloniaCoreRTDemo.Windows.ViewModels
public void DefaultDarkMethod() => this.ChangeTheme(ApplicationTheme.DefaultDark);
public void FluentLightMethod() => this.ChangeTheme(ApplicationTheme.FluentLight);
public void FluentDarkMethod() => this.ChangeTheme(ApplicationTheme.FluentDark);
- public void HelpAboutMethod() => base.RunHelpAbout(this._window);
+ public override void HelpAboutMethod() => base.RunHelpAbout(this._window);
private void RunFileExit()
=> Environment.Exit(0);
diff --git a/src/Windows/ViewModels/MainViewModelBase.cs b/src/Windows/ViewModels/MainViewModelBase.cs
index 9c9f2c6..c7faffd 100644
--- a/src/Windows/ViewModels/MainViewModelBase.cs
+++ b/src/Windows/ViewModels/MainViewModelBase.cs
@@ -1,8 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Avalonia.Controls;
@@ -26,6 +22,8 @@ namespace AvaloniaCoreRTDemo.Windows.ViewModels
public MainViewModelBase(IThemeSwitch window)
=> this._themeSwitch = window;
+ public abstract void HelpAboutMethod();
+
protected async void RunHelpAbout(Window currentWindow)
{
if (this.AboutEnabled)
From 6789fbaec7021a682d6a179c24283172d330bc29 Mon Sep 17 00:00:00 2001
From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com>
Date: Wed, 22 Dec 2021 17:08:44 -0500
Subject: [PATCH 5/8] Avalonia UI 0.10.10 -> 0.10.11
---
src/AvaloniaCoreRTDemo.csproj | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/AvaloniaCoreRTDemo.csproj b/src/AvaloniaCoreRTDemo.csproj
index 7e20a93..38802a6 100644
--- a/src/AvaloniaCoreRTDemo.csproj
+++ b/src/AvaloniaCoreRTDemo.csproj
@@ -43,11 +43,11 @@
-
+
-
-
-
+
+
+
@@ -106,4 +106,4 @@
MainWindowMacOS.axaml
-
\ No newline at end of file
+
From 8e38c08db3aad838d9f7d6643b752723a56d8a18 Mon Sep 17 00:00:00 2001
From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com>
Date: Sun, 13 Feb 2022 18:35:14 -0500
Subject: [PATCH 6/8] Avalonia 0.10.12
---
src/AvaloniaCoreRTDemo.csproj | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/AvaloniaCoreRTDemo.csproj b/src/AvaloniaCoreRTDemo.csproj
index 38802a6..837215a 100644
--- a/src/AvaloniaCoreRTDemo.csproj
+++ b/src/AvaloniaCoreRTDemo.csproj
@@ -43,13 +43,13 @@
-
+
-
-
-
+
+
+
-
+
From bfec7e3ad2f0c3bdb404ab9f1a835693fcef8d13 Mon Sep 17 00:00:00 2001
From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com>
Date: Tue, 15 Feb 2022 14:13:06 -0500
Subject: [PATCH 7/8] Update nuget.config
---
src/nuget.config | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/nuget.config b/src/nuget.config
index 1dfbeae..73b40f7 100644
--- a/src/nuget.config
+++ b/src/nuget.config
@@ -1,7 +1,7 @@
-
+
From 4aacf93202903ac38173ddf6b06c7a03ab98dadd Mon Sep 17 00:00:00 2001
From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com>
Date: Tue, 15 Feb 2022 14:32:10 -0500
Subject: [PATCH 8/8] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 12aff36..c0ed692 100644
--- a/README.md
+++ b/README.md
@@ -42,4 +42,4 @@ This project is configured to help you debug issues with publishing. Before publ
For any change in this repo we will build the artifact for Windows-x64, Linux-x64 and macOS-x64.
You can download them from workflows run results.
-For run the artifact on macOS make sure to allow the application inSystem Preferences, Security & Privacy, General.
+For run the artifact on macOS make sure to allow the application in System Preferences, Security & Privacy, General.