diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
new file mode 100644
index 0000000..e569ecc
--- /dev/null
+++ b/.github/workflows/dotnet.yml
@@ -0,0 +1,66 @@
+name: NativeAOT Build
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ build-on-linux:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Setup NativeAOT pre-requisites
+ run: sudo apt-get install clang zlib1g-dev libkrb5-dev --assume-yes
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: 6.0.x
+ - name: Publish
+ run: |
+ sudo chmod +x ./test.sh
+ ./test.sh
+ - uses: actions/upload-artifact@v2
+ with:
+ name: Linux-Artifact
+ path: |
+ ./src/bin/x64/Release/net6.0/linux-x64/publish/*.bin
+ ./src/bin/x64/Release/net6.0/linux-x64/publish/*.so
+ ./src/bin/x64/Release/net6.0/linux-x64/publish/*.png
+ build-on-windows:
+ runs-on: windows-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: 6.0.x
+ - name: Publish
+ run: ./test.cmd
+ - uses: actions/upload-artifact@v2
+ with:
+ name: Windows-Artifact
+ path: |
+ .\src\bin\x64\Release\net6.0\win-x64\publish\*.exe
+ .\src\bin\x64\Release\net6.0\win-x64\publish\*.dll
+ .\src\bin\x64\Release\net6.0\win-x64\publish\*.png
+ build-on-macos:
+ runs-on: macos-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: 6.0.x
+ - name: Publish
+ run: |
+ sudo chmod +x ./test.command
+ ./test.command
+ cd ./src/bin/x64/Release/net6.0/osx-x64/publish
+ zip -r -0 macOS-Artifact.zip *.app
+ mv *.zip ../../../../../../../.
+ - uses: actions/upload-artifact@v2
+ with:
+ name: macOS-Artifact
+ path: macOS-Artifact.zip
diff --git a/AvaloniaCoreRTDemo.sln b/AvaloniaCoreRTDemo.sln
index e12cf41..24fd18d 100644
--- a/AvaloniaCoreRTDemo.sln
+++ b/AvaloniaCoreRTDemo.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29911.98
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31912.275
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AvaloniaCoreRTDemo", "src\AvaloniaCoreRTDemo.csproj", "{41A52A04-F7D8-4981-9546-DB020E54851D}"
EndProject
@@ -13,12 +13,12 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {41A52A04-F7D8-4981-9546-DB020E54851D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {41A52A04-F7D8-4981-9546-DB020E54851D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {41A52A04-F7D8-4981-9546-DB020E54851D}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {41A52A04-F7D8-4981-9546-DB020E54851D}.Debug|Any CPU.Build.0 = Debug|x64
{41A52A04-F7D8-4981-9546-DB020E54851D}.Debug|x64.ActiveCfg = Debug|x64
{41A52A04-F7D8-4981-9546-DB020E54851D}.Debug|x64.Build.0 = Debug|x64
- {41A52A04-F7D8-4981-9546-DB020E54851D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {41A52A04-F7D8-4981-9546-DB020E54851D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {41A52A04-F7D8-4981-9546-DB020E54851D}.Release|Any CPU.ActiveCfg = Release|x64
+ {41A52A04-F7D8-4981-9546-DB020E54851D}.Release|Any CPU.Build.0 = Release|x64
{41A52A04-F7D8-4981-9546-DB020E54851D}.Release|x64.ActiveCfg = Release|x64
{41A52A04-F7D8-4981-9546-DB020E54851D}.Release|x64.Build.0 = Release|x64
EndGlobalSection
diff --git a/src/AboutWindow.xaml b/src/AboutWindow.xaml
deleted file mode 100644
index 14a606e..0000000
--- a/src/AboutWindow.xaml
+++ /dev/null
@@ -1,120 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/AboutWindow.xaml.cs b/src/AboutWindow.xaml.cs
deleted file mode 100644
index e749cf2..0000000
--- a/src/AboutWindow.xaml.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Markup.Xaml;
-
-namespace AvaloniaCoreRTDemo
-{
- public class AboutWindow : Window
- {
- public AboutWindow()
- {
- this.InitializeComponent();
- this.DataContext = new AboutWindowViewModel();
- }
-
- private void InitializeComponent()
- {
- AvaloniaXamlLoader.Load(this);
- }
- }
-}
diff --git a/src/AboutWindowViewModel.cs b/src/AboutWindowViewModel.cs
deleted file mode 100644
index 424a18d..0000000
--- a/src/AboutWindowViewModel.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-using System;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using Avalonia.Media.Imaging;
-using ReactiveUI;
-
-namespace AvaloniaCoreRTDemo
-{
- public class AboutWindowViewModel : ReactiveObject
- {
- private readonly IBitmap computerImage;
-
- public IBitmap ComputerImage => computerImage;
- public String NCores => Environment.ProcessorCount.ToString();
- public String OS => RuntimeInformation.OSDescription;
- public String OSArch => RuntimeInformation.OSArchitecture.ToString();
- public String OSVersion => Environment.OSVersion.ToString();
- public String ComputerName => Environment.MachineName;
- public String UserName => Environment.UserName;
- public String SystemPath => Environment.SystemDirectory;
- public String CurrentPath => Environment.CurrentDirectory;
- public String ProcessArch => RuntimeInformation.ProcessArchitecture.ToString();
- public String RuntimeName => RuntimeInformation.FrameworkDescription;
- public String RuntimePath => RuntimeEnvironment.GetRuntimeDirectory();
- public String RuntimeVersion => RuntimeEnvironment.GetSystemVersion();
- public String FrameworkVersion => Environment.Version.ToString();
-
- private String ComputerImageName
- {
- get
- {
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- return "windows.png";
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
- return "macos.png";
- else
- return "linux.png";
- }
- }
-
- public AboutWindowViewModel()
- {
- this.computerImage = GetImageFromResources(this.ComputerImageName);
- }
-
- ~AboutWindowViewModel()
- {
- 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 a = asm.GetManifestResourceStream(resourceName))
- return new Bitmap(a);
- else
- return null;
- }
- }
-}
diff --git a/src/App.axaml b/src/App.axaml
new file mode 100644
index 0000000..e058919
--- /dev/null
+++ b/src/App.axaml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/App.axaml.cs b/src/App.axaml.cs
new file mode 100644
index 0000000..42529d0
--- /dev/null
+++ b/src/App.axaml.cs
@@ -0,0 +1,87 @@
+using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Markup.Xaml;
+using Avalonia.Styling;
+using Avalonia.Themes.Fluent;
+
+using AvaloniaCoreRTDemo.Interfaces;
+using AvaloniaCoreRTDemo.Windows;
+
+namespace AvaloniaCoreRTDemo
+{
+ public sealed class App : Application, IThemeSwitch
+ {
+ private IStyle _baseLight;
+ private IStyle _baseDark;
+
+ private IStyle _fluentLight;
+ private IStyle _fluentDark;
+
+ private ApplicationTheme _currentTheme;
+
+ public override void Initialize()
+ {
+ AvaloniaXamlLoader.Load(this);
+ this.Name = "AvaloniaCoreRTDemo";
+ }
+
+ public override void OnFrameworkInitializationCompleted()
+ {
+ this.InitializeThemes();
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ {
+ desktop.MainWindow =
+#if !OSX
+ new MainWindow();
+#else
+ new MainWindowMacOS();
+#endif
+ this.DataContext = desktop.MainWindow.DataContext;
+ }
+ base.OnFrameworkInitializationCompleted();
+ }
+
+ private void InitializeThemes()
+ {
+ this._baseDark = this.Styles[0];
+ this._baseLight = this.Styles[1];
+
+ this.Styles.Remove(this._baseDark);
+
+ this._fluentLight = (FluentTheme)this.Resources["fluentLight"]!;
+ this._fluentDark = (FluentTheme)this.Resources["fluentDark"]!;
+
+ this._currentTheme = ApplicationTheme.DefaultLight;
+ }
+
+ ApplicationTheme IThemeSwitch.Current => this._currentTheme;
+
+ void IThemeSwitch.ChangeTheme(ApplicationTheme theme)
+ {
+ this._currentTheme = theme;
+ switch (theme)
+ {
+ case ApplicationTheme.DefaultLight:
+ this.Styles[0] = this._baseLight;
+ this.Styles.Remove(this._baseDark);
+ break;
+ case ApplicationTheme.DefaultDark:
+ this.Styles[0] = this._baseDark;
+ this.Styles.Remove(this._baseLight);
+ break;
+ case ApplicationTheme.FluentLight:
+ this.Styles[0] = this._fluentLight;
+ this.Styles.Remove(this._fluentDark);
+ if (!this.Styles.Contains(this._baseLight))
+ this.Styles.Add(this._baseLight);
+ break;
+ case ApplicationTheme.FluentDark:
+ this.Styles[0] = this._fluentDark;
+ this.Styles.Remove(this._baseLight);
+ if (!this.Styles.Contains(this._baseDark))
+ this.Styles.Add(this._baseDark);
+ break;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/App.xaml b/src/App.xaml
deleted file mode 100644
index 6029ed9..0000000
--- a/src/App.xaml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
diff --git a/src/App.xaml.cs b/src/App.xaml.cs
deleted file mode 100644
index 2610577..0000000
--- a/src/App.xaml.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using Avalonia;
-using Avalonia.Controls.ApplicationLifetimes;
-using Avalonia.Markup.Xaml;
-
-namespace AvaloniaCoreRTDemo
-{
- public class App : Application
- {
- public override void Initialize()
- {
- AvaloniaXamlLoader.Load(this);
- }
-
- public override void OnFrameworkInitializationCompleted()
- {
- if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
- {
- desktop.MainWindow = new MainWindow();
- }
-
- base.OnFrameworkInitializationCompleted();
- }
- }
-}
\ No newline at end of file
diff --git a/src/ApplicationTheme.cs b/src/ApplicationTheme.cs
new file mode 100644
index 0000000..2323998
--- /dev/null
+++ b/src/ApplicationTheme.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace AvaloniaCoreRTDemo
+{
+ public enum ApplicationTheme : Byte
+ {
+ DefaultLight = 0,
+ DefaultDark = 1,
+ FluentLight = 2,
+ FluentDark = 3,
+ }
+}
diff --git a/src/Assets/about.ico b/src/Assets/about.ico
new file mode 100644
index 0000000..b8d8f38
Binary files /dev/null and b/src/Assets/about.ico differ
diff --git a/src/app.icns b/src/Assets/app.icns
similarity index 100%
rename from src/app.icns
rename to src/Assets/app.icns
diff --git a/src/app.ico b/src/Assets/app.ico
similarity index 100%
rename from src/app.ico
rename to src/Assets/app.ico
diff --git a/src/AvaloniaCoreRTDemo.csproj b/src/AvaloniaCoreRTDemo.csproj
index a4682c4..26a4b5f 100644
--- a/src/AvaloniaCoreRTDemo.csproj
+++ b/src/AvaloniaCoreRTDemo.csproj
@@ -1,61 +1,61 @@
-
+
+
-
+
WinExe
- net5.0
- AnyCPU;x64
- app.ico
+ net6.0
+ x64
+ Assets/app.ico
+ true
+
+ link
+ true
+ true
+ true
+ OSX
-
+
- link
false
false
true
-
-
-
+
+
+
-
- %(Filename)
-
-
- Designer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
PreserveNewest
PreserveNewest
-
-
+
+
PreserveNewest
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
$(AssemblyName)
$(AssemblyName)
com.$(username).$(AssemblyName)
@@ -63,18 +63,51 @@
APPL
$(AssemblyName)
- app.icns
+ Assets/app.icns
NSApplication
true
1.0
true
-
-
-
-
- link
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+ App.axaml
+
+
+
+
+
+
+ MainControl.axaml
+
+
+ AboutWindow.axaml
+
+
+
+
+
+ MainWindow.axaml
+
+
+
+
+
+
+
+ MainWindowMacOS.axaml
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Controls/MainControl.axaml b/src/Controls/MainControl.axaml
new file mode 100644
index 0000000..cdf5d75
--- /dev/null
+++ b/src/Controls/MainControl.axaml
@@ -0,0 +1,9 @@
+
+
+ Welcome to Avalonia UI + NativeAOT!
+
+
+
+
+
diff --git a/src/MainWindow.xaml.cs b/src/Controls/MainControl.axaml.cs
similarity index 50%
rename from src/MainWindow.xaml.cs
rename to src/Controls/MainControl.axaml.cs
index d170c3e..59d7185 100644
--- a/src/MainWindow.xaml.cs
+++ b/src/Controls/MainControl.axaml.cs
@@ -1,21 +1,21 @@
-using Avalonia;
using Avalonia.Controls;
-using Avalonia.Controls.Shapes;
using Avalonia.Markup.Xaml;
-namespace AvaloniaCoreRTDemo
+using AvaloniaCoreRTDemo.Controls.ViewModels;
+
+namespace AvaloniaCoreRTDemo.Controls
{
- public class MainWindow : Window
+ public sealed partial class MainControl : UserControl
{
- public MainWindow()
+ public MainControl()
{
InitializeComponent();
- this.DataContext = new MainWindowViewModel(this);
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
+ this.DataContext = new MainViewModel();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Controls/ViewModels/MainViewModel.cs b/src/Controls/ViewModels/MainViewModel.cs
new file mode 100644
index 0000000..ee69584
--- /dev/null
+++ b/src/Controls/ViewModels/MainViewModel.cs
@@ -0,0 +1,34 @@
+using System;
+using System.IO;
+using System.Runtime.CompilerServices;
+
+using Avalonia.Media.Imaging;
+
+using ReactiveUI;
+
+namespace AvaloniaCoreRTDemo.Controls.ViewModels
+{
+ internal sealed class MainViewModel : ReactiveObject
+ {
+ 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 AvaloniaImage
+ {
+ get { return _avaloniaImage; }
+ set { this.RaiseAndSetIfChanged(ref Unsafe.AsRef(this._avaloniaImage), value); }
+ }
+
+ public MainViewModel()
+ {
+ this._dotNetImage = new Bitmap(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dotnet.png"));
+ this._avaloniaImage = new Bitmap(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "avalonia.png"));
+ }
+ }
+}
diff --git a/src/linux.png b/src/Images/linux.png
similarity index 100%
rename from src/linux.png
rename to src/Images/linux.png
diff --git a/src/Images/linux_d.png b/src/Images/linux_d.png
new file mode 100644
index 0000000..1ab908b
Binary files /dev/null and b/src/Images/linux_d.png differ
diff --git a/src/macos.png b/src/Images/macos.png
similarity index 100%
rename from src/macos.png
rename to src/Images/macos.png
diff --git a/src/Images/macos_d.png b/src/Images/macos_d.png
new file mode 100644
index 0000000..3166c5d
Binary files /dev/null and b/src/Images/macos_d.png differ
diff --git a/src/windows.png b/src/Images/windows.png
similarity index 100%
rename from src/windows.png
rename to src/Images/windows.png
diff --git a/src/Images/windows_d.png b/src/Images/windows_d.png
new file mode 100644
index 0000000..a9890c9
Binary files /dev/null and b/src/Images/windows_d.png differ
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 @@
+
+
+