Merge pull request #15 from josephmoresena/master

Sample improvements
This commit is contained in:
Todor Totev 2022-02-20 13:19:47 +02:00 committed by GitHub
commit 440e8db6b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 767 additions and 400 deletions

66
.github/workflows/dotnet.yml vendored Normal file
View File

@ -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

View File

@ -1,24 +1,18 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16 # Visual Studio Version 17
VisualStudioVersion = 16.0.29911.98 VisualStudioVersion = 17.0.31912.275
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AvaloniaCoreRTDemo", "src\AvaloniaCoreRTDemo.csproj", "{41A52A04-F7D8-4981-9546-DB020E54851D}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AvaloniaCoreRTDemo", "src\AvaloniaCoreRTDemo.csproj", "{41A52A04-F7D8-4981-9546-DB020E54851D}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64 Release|x64 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution 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|x64.ActiveCfg = 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}.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|x64.ActiveCfg = Release|x64 {41A52A04-F7D8-4981-9546-DB020E54851D}.Release|x64.ActiveCfg = Release|x64
{41A52A04-F7D8-4981-9546-DB020E54851D}.Release|x64.Build.0 = Release|x64 {41A52A04-F7D8-4981-9546-DB020E54851D}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection

View File

@ -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) 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. 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 in System Preferences, Security & Privacy, General.

View File

@ -1,120 +0,0 @@
<Window
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
WindowState="Normal"
WindowStartupLocation="CenterOwner"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="256"
MinHeight="256" MinWidth="640"
Height="256" Width="640"
MaxHeight="256" MaxWidth="640"
x:Class="AvaloniaCoreRTDemo.AboutWindow"
Title="About"
CanResize="false"
ShowInTaskbar="False">
<Grid
VerticalAlignment="Top" HorizontalAlignment="Left"
ColumnDefinitions="Auto,Auto"
RowDefinitions="Auto">
<Image
Margin="0, 60"
Grid.Row="0"
Grid.Column="0"
Stretch="None"
Source="{Binding ComputerImage}"
VerticalAlignment="Top"
HorizontalAlignment="Left">
</Image>
<ScrollViewer
Margin="0, 10"
Width="500" Height="230"
Grid.Row="0" Grid.Column="1"
VerticalAlignment="Top" HorizontalAlignment="Left"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto">
<Grid
ColumnDefinitions="Auto"
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
<Grid Grid.Row="0" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold"
Text="Number of Cores: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left"
Text="{Binding NCores}"/>
</Grid>
<Grid Grid.Row="1" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold"
Text="OS: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left"
Text="{Binding OS}"/>
</Grid>
<Grid Grid.Row="2" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold"
Text="OS Arch: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left"
Text="{Binding OSArch}"/>
</Grid>
<Grid Grid.Row="3" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold"
Text="OS Version: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left"
Text="{Binding OSVersion}"/>
</Grid>
<Grid Grid.Row="4" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold"
Text="Computer: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left"
Text="{Binding ComputerName}"/>
</Grid>
<Grid Grid.Row="5" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold"
Text="User: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left"
Text="{Binding UserName}"/>
</Grid>
<Grid Grid.Row="6" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold"
Text="System Path: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left"
Text="{Binding SystemPath}"/>
</Grid>
<Grid Grid.Row="7" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold"
Text="Current Path: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left"
Text="{Binding CurrentPath}"/>
</Grid>
<Grid Grid.Row="8" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold"
Text="Process Arch: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left"
Text="{Binding ProcessArch}"/>
</Grid>
<Grid Grid.Row="9" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold"
Text="Runtime Name: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left"
Text="{Binding RuntimeName}"/>
</Grid>
<Grid Grid.Row="10" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold"
Text="Runtime Path: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left"
Text="{Binding RuntimePath}"/>
</Grid>
<Grid Grid.Row="11" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold"
Text="Runtime Version: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left"
Text="{Binding RuntimeVersion}"/>
</Grid>
<Grid Grid.Row="12" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold"
Text="Framework Version: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left"
Text="{Binding FrameworkVersion}"/>
</Grid>
</Grid>
</ScrollViewer>
</Grid>
</Window>

View File

@ -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);
}
}
}

View File

@ -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;
}
}
}

18
src/App.axaml Normal file
View File

@ -0,0 +1,18 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="AvaloniaCoreRTDemo.App">
<NativeMenu.Menu>
<NativeMenu>
<NativeMenuItem Header="About" Gesture="cmd+b" IsEnabled="{Binding AboutEnabled}" Command="{Binding HelpAboutMethod}"/>
</NativeMenu>
</NativeMenu.Menu>
<Application.Styles>
<StyleInclude Source="avares://Avalonia.Themes.Default/Accents/BaseDark.xaml"/>
<StyleInclude Source="avares://Avalonia.Themes.Default/Accents/BaseLight.xaml"/>
<StyleInclude Source="avares://Avalonia.Themes.Default/DefaultTheme.xaml"/>
</Application.Styles>
<Application.Resources>
<FluentTheme x:Key="fluentLight" Mode="Light" />
<FluentTheme x:Key="fluentDark" Mode="Dark" />
</Application.Resources>
</Application>

83
src/App.axaml.cs Normal file
View File

@ -0,0 +1,83 @@
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 = !Utilities.IsOSX ? new MainWindow() : new MainWindowMacOS();
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;
}
}
}
}

View File

@ -1,8 +0,0 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="AvaloniaCoreRTDemo.App">
<Application.Styles>
<StyleInclude Source="avares://Avalonia.Themes.Default/DefaultTheme.xaml"/>
<StyleInclude Source="avares://Avalonia.Themes.Default/Accents/BaseLight.xaml"/>
</Application.Styles>
</Application>

View File

@ -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();
}
}
}

12
src/ApplicationTheme.cs Normal file
View File

@ -0,0 +1,12 @@
using System;
namespace AvaloniaCoreRTDemo
{
public enum ApplicationTheme : Byte
{
DefaultLight = 0,
DefaultDark = 1,
FluentLight = 2,
FluentDark = 3,
}
}

BIN
src/Assets/about.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

Before

Width:  |  Height:  |  Size: 179 KiB

After

Width:  |  Height:  |  Size: 179 KiB

View File

@ -1,61 +1,61 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<!-- if you want to check exceptions, change this to "Exe" and start your app from the console --> <!-- if you want to check exceptions, change this to "Exe" and start your app from the console -->
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<Platforms>AnyCPU;x64</Platforms> <Platforms>x64</Platforms>
<ApplicationIcon>app.ico</ApplicationIcon> <ApplicationIcon>Assets/app.ico</ApplicationIcon>
<InvariantGlobalization>true</InvariantGlobalization>
<!--https://docs.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-options-->
<TrimmerDefaultAction>link</TrimmerDefaultAction>
<IsWindows Condition="$([MSBuild]::IsOSPlatform('Windows'))">true</IsWindows>
<IsLinux Condition="$([MSBuild]::IsOSPlatform('Linux'))">true</IsLinux>
<IsOSX Condition="$([MSBuild]::IsOSPlatform('OSX'))">true</IsOSX>
<DefineConstants Condition="'$(IsOSX)'=='true'">OSX</DefineConstants>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<!-- these can help when debugging weird exceptions especially when reflection is involved. See https://github.com/dotnet/corert/blob/master/Documentation/using-corert/optimizing-corert.md --> <!--Tthese can help when debugging weird exceptions especially when reflection is involved. See https://github.com/dotnet/corert/blob/master/Documentation/using-corert/optimizing-corert.md -->
<!--RootAllApplicationAssemblies: False -> TrimMode:link See https://github.com/dotnet/runtimelab/issues/597 and https://github.com/dotnet/runtimelab/blob/feature/NativeAOT/docs/using-nativeaot/optimizing.md --> <!--RootAllApplicationAssemblies: False -> TrimMode:link See https://github.com/dotnet/runtimelab/issues/597 and https://github.com/dotnet/runtimelab/blob/feature/NativeAOT/docs/using-nativeaot/optimizing.md -->
<TrimMode>link</TrimMode>
<IlcGenerateCompleteTypeMetadata>false</IlcGenerateCompleteTypeMetadata> <IlcGenerateCompleteTypeMetadata>false</IlcGenerateCompleteTypeMetadata>
<IlcGenerateStackTraceData>false</IlcGenerateStackTraceData> <IlcGenerateStackTraceData>false</IlcGenerateStackTraceData>
<IlcDisableUnhandledExceptionExperience>true</IlcDisableUnhandledExceptionExperience> <IlcDisableUnhandledExceptionExperience>true</IlcDisableUnhandledExceptionExperience>
</PropertyGroup> </PropertyGroup>
<ItemGroup Condition="$(RuntimeIdentifier.StartsWith('win'))"> <!-- Instruct NativeAOT to use this native dependency, required to build Avalonia. This library comes from the Windows SDK. -->
<!-- Instruct CoreRT to use this native dependency, required to build Avalonia. This library comes from the Windows SDK. --> <ItemGroup Condition="'$(IsWindows)'=='true'">
<NativeLibrary Include="WindowsApp.lib" /> <NativeLibrary Include="WindowsApp.lib" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Update="**\*.xaml.cs"> <AvaloniaResource Include="Assets/**" />
<DependentUpon>%(Filename)</DependentUpon> <EmbeddedResource Include="Images/**" />
</Compile>
<AvaloniaResource Include="**\*.xaml">
<SubType>Designer</SubType>
</AvaloniaResource>
<AvaloniaResource Include="app.ico" />
<EmbeddedResource Include="linux.png" />
<EmbeddedResource Include="macos.png" />
<EmbeddedResource Include="windows.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="0.10.8" />
<PackageReference Include="Avalonia.Desktop" Version="0.10.8" />
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.8" />
<PackageReference Include="Dotnet.Bundle" Version="*" Condition="$(RuntimeIdentifier.StartsWith('osx'))" />
<PackageReference Include="Microsoft.DotNet.ILCompiler" Version="7.0.0-*" />
</ItemGroup>
<ItemGroup>
<!-- Avalonia relies heavily on reflection. Describe types reflected upon here. -->
<RdXmlFile Include="rd.xml" />
</ItemGroup>
<ItemGroup>
<None Update="avalonia.png" CopyToPublishDirectory="PreserveNewest"> <None Update="avalonia.png" CopyToPublishDirectory="PreserveNewest">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Update="dotnet.png" CopyToPublishDirectory="PreserveNewest"> <None Update="dotnet.png" CopyToPublishDirectory="PreserveNewest">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Update="app.icns" CopyToPublishDirectory="PreserveNewest" Condition="$(RuntimeIdentifier.StartsWith('osx'))"> <None Update="Assets/app.icns" CopyToPublishDirectory="PreserveNewest" Condition="$(RuntimeIdentifier.StartsWith('osx'))">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith('osx'))">
<ItemGroup>
<PackageReference Include="Avalonia" Version="0.10.12" />
<!--Avalonia.Desktop 0.10.8 is used due to an issue on macOS with latest version-->
<PackageReference Include="Avalonia.Desktop" Version="0.10.12" />
<PackageReference Include="Avalonia.Native" Version="0.10.12" />
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.12" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="0.10.12" />
<!--Condition below is needed to generate macOS App only.-->
<PackageReference Include="Dotnet.Bundle" Version="*" Condition="$(RuntimeIdentifier.StartsWith('osx'))" />
</ItemGroup>
<!-- Information for Dotnet.Bundle to Generate macOS app-->
<PropertyGroup Condition="'$(IsOSX)'=='true'">
<CFBundleName>$(AssemblyName)</CFBundleName> <CFBundleName>$(AssemblyName)</CFBundleName>
<CFBundleDisplayName>$(AssemblyName)</CFBundleDisplayName> <CFBundleDisplayName>$(AssemblyName)</CFBundleDisplayName>
<CFBundleIdentifier>com.$(username).$(AssemblyName)</CFBundleIdentifier> <CFBundleIdentifier>com.$(username).$(AssemblyName)</CFBundleIdentifier>
@ -63,18 +63,47 @@
<CFBundlePackageType>APPL</CFBundlePackageType> <CFBundlePackageType>APPL</CFBundlePackageType>
<!--<CFBundleSignature>????</CFBundleSignature>--> <!--<CFBundleSignature>????</CFBundleSignature>-->
<CFBundleExecutable>$(AssemblyName)</CFBundleExecutable> <CFBundleExecutable>$(AssemblyName)</CFBundleExecutable>
<CFBundleIconFile>app.icns</CFBundleIconFile> <CFBundleIconFile>Assets/app.icns</CFBundleIconFile>
<NSPrincipalClass>NSApplication</NSPrincipalClass> <NSPrincipalClass>NSApplication</NSPrincipalClass>
<NSHighResolutionCapable>true</NSHighResolutionCapable> <NSHighResolutionCapable>true</NSHighResolutionCapable>
<CFBundleShortVersionString>1.0</CFBundleShortVersionString> <CFBundleShortVersionString>1.0</CFBundleShortVersionString>
<!-- Optional --> <!-- Optional -->
<NSRequiresAquaSystemAppearance>true</NSRequiresAquaSystemAppearance> <NSRequiresAquaSystemAppearance>true</NSRequiresAquaSystemAppearance>
</PropertyGroup> </PropertyGroup>
<Target Name="ConfigureTrimming" BeforeTargets="PrepareForILLink">
<ItemGroup> <ItemGroup>
<ManagedAssemblyToLink> <PackageReference Include="Microsoft.DotNet.ILCompiler" Version="7.0.0-*" />
<TrimMode>link</TrimMode> <!-- Avalonia relies heavily on reflection. Describe types reflected upon here. -->
</ManagedAssemblyToLink> <RdXmlFile Include="rd.xml" />
</ItemGroup> <RuntimeHostConfigurationOption Include="Switch.System.Reflection.Assembly.SimulatedCallingAssembly" Value="true" />
</Target> </ItemGroup>
<!--App axaml-->
<ItemGroup>
<Compile Update="App.axaml.cs">
<DependentUpon>App.axaml</DependentUpon>
</Compile>
</ItemGroup>
<!--Cross platform xaml-->
<ItemGroup>
<Compile Update="Controls/MainControl.axaml.cs">
<DependentUpon>MainControl.axaml</DependentUpon>
</Compile>
<Compile Update="Windows/AboutWindow.axaml.cs">
<DependentUpon>AboutWindow.axaml</DependentUpon>
</Compile>
</ItemGroup>
<!--No-OSX only xaml-->
<ItemGroup Condition="'$(IsOSX)'!='true'">
<Compile Update="Windows/MainWindow.axaml.cs">
<DependentUpon>MainWindow.axaml</DependentUpon>
</Compile>
</ItemGroup>
<!--OSX only xaml-->
<ItemGroup Condition="'$(IsOSX)'=='true'">
<Compile Update="Windows/MainWindowMacOS.axaml.cs">
<DependentUpon>MainWindowMacOS.axaml</DependentUpon>
</Compile>
</ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,9 @@
<UserControl xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="AvaloniaCoreRTDemo.Controls.MainControl">
<Grid ColumnDefinitions="*,*" RowDefinitions="Auto,Auto,*" Margin="32">
<TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" TextAlignment="Center" Margin="0,6">Welcome to Avalonia UI + NativeAOT!</TextBlock>
<Image Grid.Row="1" Grid.Column="0" Stretch="None" Source="{Binding DotNetImage}"/>
<Image Grid.Row="1" Grid.Column="1" Stretch="None" Source="{Binding AvaloniaImage}"/>
<TextBox Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Watermark="Type here" AcceptsReturn="True" TextWrapping="Wrap"/>
</Grid>
</UserControl>

View File

@ -1,21 +1,21 @@
using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Shapes;
using Avalonia.Markup.Xaml; 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(); InitializeComponent();
this.DataContext = new MainWindowViewModel(this);
} }
private void InitializeComponent() private void InitializeComponent()
{ {
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
this.DataContext = new MainViewModel();
} }
} }
} }

View File

@ -0,0 +1,34 @@
using System;
using System.IO;
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 => this._dotNetImage;
public IBitmap AvaloniaImage => this._avaloniaImage;
public MainViewModel()
{
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();
}
}
}

BIN
src/Images/broken-link.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/Images/linux_d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/Images/macos_d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
src/Images/windows_d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,9 @@
using AvaloniaCoreRTDemo.Interfaces;
namespace AvaloniaCoreRTDemo
{
public interface IMainWindow
{
IThemeSwitch ThemeSwitch { get; }
}
}

View File

@ -0,0 +1,8 @@
namespace AvaloniaCoreRTDemo.Interfaces
{
public interface IThemeSwitch
{
ApplicationTheme Current { get; }
void ChangeTheme(ApplicationTheme theme);
}
}

View File

@ -1,29 +0,0 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaCoreRTDemo.MainWindow"
Width="640" Height="480"
WindowStartupLocation="CenterScreen"
Title="AvaloniaCoreRTDemo"
Icon="avares://AvaloniaCoreRTDemo/app.ico"
MinWidth="400" MinHeight="350">
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
<MenuItem Header="_Exit" Command="{Binding FileExitCommand}"/>
</MenuItem>
<MenuItem Header="_Help">
<MenuItem Header="About" Command="{Binding HelpAboutMethod}"/>
</MenuItem>
</Menu>
<Grid ColumnDefinitions="*,*" RowDefinitions="Auto,Auto,*" Margin="32">
<TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" TextAlignment="Center" Margin="0,6">Welcome to Avalonia UI + CoreRT!</TextBlock>
<Image Grid.Row="1" Grid.Column="0" Stretch="None" Source="{Binding DotNetImage}"></Image>
<Image Grid.Row="1" Grid.Column="1" Stretch="None" Source="{Binding AvaloniaImage}"></Image>
<TextBox Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Watermark="Type here" AcceptsReturn="True" TextWrapping="Wrap"></TextBox>
</Grid>
</DockPanel>
</Window>

View File

@ -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<Unit, Unit> 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;
}
}

View File

@ -2,18 +2,20 @@
namespace AvaloniaCoreRTDemo namespace AvaloniaCoreRTDemo
{ {
class Program public static class Program
{ {
// Initialization code. Don't use any Avalonia, third-party APIs or any // Initialization code. Don't use any Avalonia, third-party APIs or any
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized // SynchronizationContext-reliant code before AppMain is called: things aren't initialized
// yet and stuff might break. // yet and stuff might break.
public static void Main(string[] args) => BuildAvaloniaApp() public static void Main(string[] args) => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
.StartWithClassicDesktopLifetime(args);
// Avalonia configuration, don't remove; also used by visual designer. // Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp() public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>() => AppBuilder.Configure<App>().UsePlatformDetect()
.UsePlatformDetect() .UseAvaloniaNativeOSX()
.LogToTrace(); .LogToTrace();
private static AppBuilder UseAvaloniaNativeOSX(this AppBuilder appBuilder)
=> Utilities.IsOSX ? appBuilder.UseAvaloniaNative() : appBuilder;
} }
} }

39
src/Utilities.cs Normal file
View File

@ -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");
}
}
}
}

View File

@ -0,0 +1,64 @@
<Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="AvaloniaCoreRTDemo.Windows.AboutWindow" d:DesignWidth="640" d:DesignHeight="256"
WindowState="Normal" WindowStartupLocation="CenterOwner" MinHeight="256" MinWidth="640" Height="256" Width="640" MaxHeight="256" MaxWidth="640" Title="About" CanResize="false" ShowInTaskbar="False" Icon="avares://AvaloniaCoreRTDemo/Assets/about.ico">
<Grid VerticalAlignment="Top" HorizontalAlignment="Left" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<Image Margin="0, 60" Grid.Row="0" Grid.Column="0" Stretch="None" Source="{Binding ComputerImage}" VerticalAlignment="Top" HorizontalAlignment="Left">
</Image>
<ScrollViewer Margin="0, 10" Width="500" Height="230" Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto">
<Grid ColumnDefinitions="Auto" RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
<Grid Grid.Row="0" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold" Text="Number of Cores: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" Text="{Binding NCores}"/>
</Grid>
<Grid Grid.Row="1" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold" Text="OS: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" Text="{Binding OS}"/>
</Grid>
<Grid Grid.Row="2" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold" Text="OS Arch: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" Text="{Binding OSArch}"/>
</Grid>
<Grid Grid.Row="3" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold" Text="OS Version: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" Text="{Binding OSVersion}"/>
</Grid>
<Grid Grid.Row="4" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold" Text="Computer: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" Text="{Binding ComputerName}"/>
</Grid>
<Grid Grid.Row="5" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold" Text="User: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" Text="{Binding UserName}"/>
</Grid>
<Grid Grid.Row="6" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold" Text="System Path: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" Text="{Binding SystemPath}"/>
</Grid>
<Grid Grid.Row="7" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold" Text="Current Path: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" Text="{Binding CurrentPath}"/>
</Grid>
<Grid Grid.Row="8" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold" Text="Process Arch: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" Text="{Binding ProcessArch}"/>
</Grid>
<Grid Grid.Row="9" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold" Text="Runtime Name: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" Text="{Binding RuntimeName}"/>
</Grid>
<Grid Grid.Row="10" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold" Text="Runtime Path: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" Text="{Binding RuntimePath}"/>
</Grid>
<Grid Grid.Row="11" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold" Text="Runtime Version: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" Text="{Binding RuntimeVersion}"/>
</Grid>
<Grid Grid.Row="12" Grid.Column="0" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto">
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" FontWeight="Bold" Text="Framework Version: "/>
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" TextAlignment="Left" Text="{Binding FrameworkVersion}"/>
</Grid>
</Grid>
</ScrollViewer>
</Grid>
</Window>

View File

@ -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);
}
}
}

View File

@ -0,0 +1,21 @@
<Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="clr-namespace:AvaloniaCoreRTDemo.Controls" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="AvaloniaCoreRTDemo.Windows.MainWindow"
Width="640" Height="480" WindowStartupLocation="CenterScreen" Title="AvaloniaCoreRTDemo" Icon="avares://AvaloniaCoreRTDemo/Assets/app.ico" MinWidth="400" MinHeight="350">
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
<MenuItem Header="_Exit" Command="{Binding FileExitCommand}"/>
</MenuItem>
<MenuItem Header="_Theme">
<MenuItem Header="Default Light" IsEnabled="{Binding DefaultLightEnabled}" Command="{Binding DefaultLightMethod}"/>
<MenuItem Header="Default Dark" IsEnabled="{Binding DefaultDarkEnabled}" Command="{Binding DefaultDarkMethod}"/>
<MenuItem Header="Fluent Light" IsEnabled="{Binding FluentLightEnabled}" Command="{Binding FluentLightMethod}"/>
<MenuItem Header="Fluent Dark" IsEnabled="{Binding FluentDarkEnabled}" Command="{Binding FluentDarkMethod}"/>
</MenuItem>
<MenuItem Header="_Help">
<MenuItem Header="_About" IsEnabled="{Binding AboutEnabled}" Command="{Binding HelpAboutMethod}"/>
</MenuItem>
</Menu>
<controls:MainControl/>
</DockPanel>
</Window>

View File

@ -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<MainWindow>(this);
}
IThemeSwitch IMainWindow.ThemeSwitch => App.Current as IThemeSwitch;
}
}

View File

@ -0,0 +1,26 @@
<Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="clr-namespace:AvaloniaCoreRTDemo.Controls" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="AvaloniaCoreRTDemo.Windows.MainWindowMacOS"
Width="640" Height="480" WindowStartupLocation="CenterScreen" Title="AvaloniaCoreRTDemo" Icon="avares://AvaloniaCoreRTDemo/Assets/app.ico" MinWidth="400" MinHeight="350">
<controls:MainControl/>
<NativeMenu.Menu>
<NativeMenu>
<NativeMenuItem Header="File">
<NativeMenuItem.Menu>
<NativeMenu>
<NativeMenuItem Header="Exit" Gesture="cmd+e" Command="{Binding FileExitCommand}"/>
</NativeMenu>
</NativeMenuItem.Menu>
</NativeMenuItem>
<NativeMenuItem Header="Theme">
<NativeMenuItem.Menu>
<NativeMenu>
<NativeMenuItem Header="Default Light" IsEnabled="{Binding DefaultLightEnabled}" Command="{Binding DefaultLightMethod}"/>
<NativeMenuItem Header="Default Dark" IsEnabled="{Binding DefaultDarkEnabled}" Command="{Binding DefaultDarkMethod}"/>
<NativeMenuItem Header="Fluent Light" IsEnabled="{Binding FluentLightEnabled}" Command="{Binding FluentLightMethod}"/>
<NativeMenuItem Header="Fluent Dark" IsEnabled="{Binding FluentDarkEnabled}" Command="{Binding FluentDarkMethod}"/>
</NativeMenu>
</NativeMenuItem.Menu>
</NativeMenuItem>
</NativeMenu>
</NativeMenu.Menu>
</Window>

View File

@ -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<MainWindowMacOS>(this);
}
IThemeSwitch IMainWindow.ThemeSwitch => App.Current as IThemeSwitch;
}
}

View File

@ -0,0 +1,54 @@
using System;
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 (Utilities.IsWindows)
return !this._darkTheme ? "windows.png" : "windows_d.png";
else if (Utilities.IsOSX)
return !this._darkTheme ? "macos.png" : "macos_d.png";
else
return !this._darkTheme ? "linux.png" : "linux_d.png";
}
}
public AboutViewModel(Boolean darkTheme)
{
this._darkTheme = darkTheme;
this._computerImage = Utilities.GetImageFromResources(this.ComputerImageName);
}
~AboutViewModel()
{
this._computerImage.Dispose();
}
}
}

View File

@ -0,0 +1,72 @@
using System;
using System.Reactive;
using Avalonia.Controls;
using ReactiveUI;
namespace AvaloniaCoreRTDemo.Windows.ViewModels
{
internal sealed class MainViewModel<TWindow> : 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<Unit, Unit> 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 override 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);
}
}
}

View File

@ -0,0 +1,49 @@
using System;
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;
public abstract void HelpAboutMethod();
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,
};
}
}

View File

@ -1,11 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<packageSources> <packageSources>
<add key="AvaloniaCI" value="https://www.myget.org/F/avalonia-ci/api/v2" /> <add key="dotnet7" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet7/nuget/v3/index.json" />
<add key="dotnet-experimental" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json" />
<add key="dotnet-public" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json" />
<add key="dotnet6" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6/nuget/v3/index.json" />
<add key="dotnet5" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json" />
<add key="nuget" value="https://api.nuget.org/v3/index.json" /> <add key="nuget" value="https://api.nuget.org/v3/index.json" />
</packageSources> </packageSources>
</configuration> </configuration>

View File

@ -15,6 +15,9 @@
</Assembly> </Assembly>
<Assembly Name="SkiaSharp" Dynamic="Required All"></Assembly> <Assembly Name="SkiaSharp" Dynamic="Required All"></Assembly>
<!-- To support Fluent themes trimming the final assembly we need to add this entry -->
<Assembly Name="Avalonia.Themes.Fluent" Dynamic="Required All"></Assembly>
<!-- Not known if and when you need these: <!-- Not known if and when you need these:
<Assembly Name="Avalonia.Controls" Dynamic="Required All"></Assembly> <Assembly Name="Avalonia.Controls" Dynamic="Required All"></Assembly>
<Assembly Name="Avalonia.Base" Dynamic="Required All"></Assembly> <Assembly Name="Avalonia.Base" Dynamic="Required All"></Assembly>

View File

@ -1,2 +1,2 @@
del src\packages.lock.json del src\packages.lock.json
dotnet publish -r win-x64 -c release /p:RestoreLockedMode=true dotnet publish -r win-x64 -c release /p:RestoreLockedMode=true /p:TrimLink=true --self-contained

View File

@ -4,6 +4,10 @@ if [ -d "$dir" ]; then
cd "$dir" cd "$dir"
fi fi
rm -f src/packages.lock.json rm -f src/packages.lock.json
dotnet publish -r osx-x64 -c release /p:RestoreLockedMode=true -t:BundleApp dotnet publish -r osx-x64 -c release /p:RestoreLockedMode=true -t:BundleApp /p:TrimLink=true --self-contained
rm src/bin/Release/net*/osx-x64/publish/*.icns rm -rf src/bin/x64/Release/net6.0/osx-x64/publish/Assets/
strip src/bin/Release/net*/osx-x64/publish/AvaloniaCoreRTDemo.app/Contents/MacOS/AvaloniaCoreRTDemo strip src/bin/x64/Release/net6.0/osx-x64/publish/AvaloniaCoreRTDemo.app/Contents/MacOS/AvaloniaCoreRTDemo
rm -rf src/bin/x64/Release/net6.0/osx-x64/publish/AvaloniaCoreRTDemo.app/Contents/MacOS/Assets/
rm src/bin/x64/Release/net6.0/osx-x64/publish/AvaloniaCoreRTDemo.app/Contents/MacOS/AvaloniaCoreRTDemo.runtimeconfig.json
rm src/bin/x64/Release/net6.0/osx-x64/publish/AvaloniaCoreRTDemo.app/Contents/MacOS/AvaloniaCoreRTDemo.pdb
rm src/bin/x64/Release/net6.0/osx-x64/publish/AvaloniaCoreRTDemo.app/Contents/MacOS/AvaloniaCoreRTDemo.deps.json

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
rm -f src/packages.lock.json rm -f src/packages.lock.json
dotnet publish -r linux-x64 -c release /p:RestoreLockedMode=true dotnet publish -r linux-x64 -c release /p:RestoreLockedMode=true /p:TrimLink=true --self-contained
cd src/bin/Release/net*/linux-x64/publish cd src/bin/x64/Release/net6.0/linux-x64/publish
cp AvaloniaCoreRTDemo AvaloniaCoreRTDemo.bin cp AvaloniaCoreRTDemo AvaloniaCoreRTDemo.bin
strip AvaloniaCoreRTDemo.bin strip AvaloniaCoreRTDemo.bin