diff --git a/.gitmodules b/.gitmodules
index 10c780c09f..9dbc50ef61 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -3,4 +3,4 @@
url = https://github.com/kekekeks/Numerge.git
[submodule "src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github"]
path = src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github
- url = https://github.com/kekekeks/XamlIl.git
+ url = https://github.com/kekekeks/XamlX.git
diff --git a/.ncrunch/NativeEmbedSample.v3.ncrunchproject b/.ncrunch/NativeEmbedSample.v3.ncrunchproject
new file mode 100644
index 0000000000..319cd523ce
--- /dev/null
+++ b/.ncrunch/NativeEmbedSample.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ True
+
+
\ No newline at end of file
diff --git a/Avalonia.sln b/Avalonia.sln
index 38f8e5f720..4ab647a25e 100644
--- a/Avalonia.sln
+++ b/Avalonia.sln
@@ -95,8 +95,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.UnitTests", "tests
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Benchmarks", "tests\Avalonia.Benchmarks\Avalonia.Benchmarks.csproj", "{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Logging.Serilog", "src\Avalonia.Logging.Serilog\Avalonia.Logging.Serilog.csproj", "{B61B66A3-B82D-4875-8001-89D3394FE0C9}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.DesignerSupport", "src\Avalonia.DesignerSupport\Avalonia.DesignerSupport.csproj", "{799A7BB5-3C2C-48B6-85A7-406A12C420DA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog", "samples\ControlCatalog\ControlCatalog.csproj", "{D0A739B9-3C68-4BA6-A328-41606954B6BD}"
@@ -140,7 +138,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1
build\ReactiveUI.props = build\ReactiveUI.props
build\Rx.props = build\Rx.props
build\SampleApp.props = build\SampleApp.props
- build\Serilog.props = build\Serilog.props
build\SharpDX.props = build\SharpDX.props
build\SkiaSharp.props = build\SkiaSharp.props
build\System.Memory.props = build\System.Memory.props
@@ -206,12 +203,20 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.FreeDesktop", "src
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Controls.DataGrid.UnitTests", "tests\Avalonia.Controls.DataGrid.UnitTests\Avalonia.Controls.DataGrid.UnitTests.csproj", "{351337F5-D66F-461B-A957-4EF60BDB4BA6}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NativeEmbedSample", "samples\interop\NativeEmbedSample\NativeEmbedSample.csproj", "{3C84E04B-36CF-4D0D-B965-C26DD649D1F3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Themes.Fluent", "src\Avalonia.Themes.Fluent\Avalonia.Themes.Fluent.csproj", "{C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Headless", "src\Avalonia.Headless\Avalonia.Headless.csproj", "{8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Headless.Vnc", "src\Avalonia.Headless.Vnc\Avalonia.Headless.Vnc.csproj", "{B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}"
+EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Shared\RenderHelpers\RenderHelpers.projitems*{3c4c0cb4-0c0f-4450-a37b-148c84ff905f}*SharedItemsImports = 13
src\Shared\RenderHelpers\RenderHelpers.projitems*{3e908f67-5543-4879-a1dc-08eace79b3cd}*SharedItemsImports = 5
- src\Shared\PlatformSupport\PlatformSupport.projitems*{4488ad85-1495-4809-9aa4-ddfe0a48527e}*SharedItemsImports = 4
- src\Shared\PlatformSupport\PlatformSupport.projitems*{7b92af71-6287-4693-9dcb-bd5b6e927e23}*SharedItemsImports = 4
+ src\Shared\PlatformSupport\PlatformSupport.projitems*{4488ad85-1495-4809-9aa4-ddfe0a48527e}*SharedItemsImports = 5
+ src\Shared\PlatformSupport\PlatformSupport.projitems*{7b92af71-6287-4693-9dcb-bd5b6e927e23}*SharedItemsImports = 5
src\Shared\RenderHelpers\RenderHelpers.projitems*{7d2d3083-71dd-4cc9-8907-39a0d86fb322}*SharedItemsImports = 5
src\Shared\PlatformSupport\PlatformSupport.projitems*{88060192-33d5-4932-b0f9-8bd2763e857d}*SharedItemsImports = 5
src\Shared\PlatformSupport\PlatformSupport.projitems*{e4d9629c-f168-4224-3f51-a5e482ffbc42}*SharedItemsImports = 13
@@ -1025,30 +1030,6 @@ Global
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Release|iPhone.Build.0 = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.AppStore|Any CPU.Build.0 = Release|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.AppStore|iPhone.ActiveCfg = Release|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.AppStore|iPhone.Build.0 = Release|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.Debug|iPhone.Build.0 = Debug|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.Release|Any CPU.Build.0 = Release|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.Release|iPhone.ActiveCfg = Release|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.Release|iPhone.Build.0 = Release|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {B61B66A3-B82D-4875-8001-89D3394FE0C9}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{799A7BB5-3C2C-48B6-85A7-406A12C420DA}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{799A7BB5-3C2C-48B6-85A7-406A12C420DA}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{799A7BB5-3C2C-48B6-85A7-406A12C420DA}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@@ -1849,6 +1830,54 @@ Global
{3278F3A9-9509-4A3F-A15B-BDC8B5BFF632}.Release|iPhone.Build.0 = Release|Any CPU
{3278F3A9-9509-4A3F-A15B-BDC8B5BFF632}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{3278F3A9-9509-4A3F-A15B-BDC8B5BFF632}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.Release|iPhone.Build.0 = Release|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.Release|iPhone.Build.0 = Release|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{4D55985A-1EE2-4F25-AD39-6EA8BC04F8FB}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{4D55985A-1EE2-4F25-AD39-6EA8BC04F8FB}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{4D55985A-1EE2-4F25-AD39-6EA8BC04F8FB}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
@@ -1921,6 +1950,54 @@ Global
{351337F5-D66F-461B-A957-4EF60BDB4BA6}.Release|iPhone.Build.0 = Release|Any CPU
{351337F5-D66F-461B-A957-4EF60BDB4BA6}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{351337F5-D66F-461B-A957-4EF60BDB4BA6}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.Release|iPhone.Build.0 = Release|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Release|iPhone.Build.0 = Release|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {C42D2FC1-A531-4ED4-84B9-89AEC7C962FC}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1978,6 +2055,7 @@ Global
{D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{351337F5-D66F-461B-A957-4EF60BDB4BA6} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
+ {3C84E04B-36CF-4D0D-B965-C26DD649D1F3} = {A0CC0258-D18C-4AB3-854F-7101680FC3F9}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A}
diff --git a/NOTICE.md b/NOTICE.md
index 0e1d792e84..92fd725957 100644
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -271,3 +271,35 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
+
+# Chromium
+
+https://github.com/chromium/chromium
+
+// Copyright 2015 The Chromium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/build.sh b/build.sh
index 40b1c225a6..a40e00f815 100755
--- a/build.sh
+++ b/build.sh
@@ -67,6 +67,8 @@ else
fi
fi
+export PATH=$DOTNET_DIRECTORY:$PATH
+
echo "Microsoft (R) .NET Core SDK version $("$DOTNET_EXE" --version)"
"$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" -- ${BUILD_ARGUMENTS[@]}
diff --git a/build/CoreLibraries.props b/build/CoreLibraries.props
index d61268173d..d17eec0135 100644
--- a/build/CoreLibraries.props
+++ b/build/CoreLibraries.props
@@ -7,10 +7,10 @@
-
+
diff --git a/build/Moq.props b/build/Moq.props
index 7de9b6b6ba..9e2fd1db5d 100644
--- a/build/Moq.props
+++ b/build/Moq.props
@@ -1,5 +1,5 @@
-
+
diff --git a/build/Serilog.props b/build/Serilog.props
deleted file mode 100644
index a814cf998d..0000000000
--- a/build/Serilog.props
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/build/readme.md b/build/readme.md
index 387afb3425..e147556b1c 100644
--- a/build/readme.md
+++ b/build/readme.md
@@ -9,8 +9,6 @@
-
-
@@ -22,4 +20,4 @@
```XML
-```
\ No newline at end of file
+```
diff --git a/native/Avalonia.Native/inc/avalonia-native.h b/native/Avalonia.Native/inc/avalonia-native.h
index b86c679397..9ff6130e5f 100644
--- a/native/Avalonia.Native/inc/avalonia-native.h
+++ b/native/Avalonia.Native/inc/avalonia-native.h
@@ -26,7 +26,8 @@ struct IAvnStringArray;
struct IAvnDndResultCallback;
struct IAvnGCHandleDeallocatorCallback;
struct IAvnMenuEvents;
-
+struct IAvnNativeControlHost;
+struct IAvnNativeControlHostTopLevelAttachment;
enum SystemDecorations {
SystemDecorationsNone = 0,
SystemDecorationsBorderOnly = 1,
@@ -204,6 +205,15 @@ enum AvnMenuItemToggleType
Radio
};
+enum AvnExtendClientAreaChromeHints
+{
+ AvnNoChrome = 0,
+ AvnSystemChrome = 0x01,
+ AvnPreferSystemChrome = 0x02,
+ AvnOSXThickTitleBar = 0x08,
+ AvnDefaultChrome = AvnSystemChrome,
+};
+
AVNCOM(IAvaloniaNativeFactory, 01) : IUnknown
{
public:
@@ -256,6 +266,7 @@ AVNCOM(IAvnWindowBase, 02) : IUnknown
virtual HRESULT ObtainNSWindowHandleRetained(void** retOut) = 0;
virtual HRESULT ObtainNSViewHandle(void** retOut) = 0;
virtual HRESULT ObtainNSViewHandleRetained(void** retOut) = 0;
+ virtual HRESULT CreateNativeControlHost(IAvnNativeControlHost** retOut) = 0;
virtual HRESULT BeginDragAndDropOperation(AvnDragDropEffects effects, AvnPoint point,
IAvnClipboard* clipboard, IAvnDndResultCallback* cb, void* sourceHandle) = 0;
virtual HRESULT SetBlurEnabled (bool enable) = 0;
@@ -276,6 +287,11 @@ AVNCOM(IAvnWindow, 04) : virtual IAvnWindowBase
virtual HRESULT SetTitleBarColor (AvnColor color) = 0;
virtual HRESULT SetWindowState(AvnWindowState state) = 0;
virtual HRESULT GetWindowState(AvnWindowState*ret) = 0;
+ virtual HRESULT TakeFocusFromChildren() = 0;
+ virtual HRESULT SetExtendClientArea (bool enable) = 0;
+ virtual HRESULT SetExtendClientAreaHints (AvnExtendClientAreaChromeHints hints) = 0;
+ virtual HRESULT GetExtendTitleBarHeight (double*ret) = 0;
+ virtual HRESULT SetExtendTitleBarHeight (double value) = 0;
};
AVNCOM(IAvnWindowBaseEvents, 05) : IUnknown
@@ -295,6 +311,7 @@ AVNCOM(IAvnWindowBaseEvents, 05) : IUnknown
virtual bool RawTextInputEvent (unsigned int timeStamp, const char* text) = 0;
virtual void ScalingChanged(double scaling) = 0;
virtual void RunRenderPriorityJobs() = 0;
+ virtual void LostFocus() = 0;
virtual AvnDragDropEffects DragEvent(AvnDragEventType type, AvnPoint position,
AvnInputModifiers modifiers, AvnDragDropEffects effects,
IAvnClipboard* clipboard, void* dataObjectHandle) = 0;
@@ -387,6 +404,9 @@ AVNCOM(IAvnClipboard, 0f) : IUnknown
virtual HRESULT SetText (char* type, void* utf8Text) = 0;
virtual HRESULT ObtainFormats(IAvnStringArray**ppv) = 0;
virtual HRESULT GetStrings(char* type, IAvnStringArray**ppv) = 0;
+ virtual HRESULT SetBytes(char* type, void* utf8Text, int len) = 0;
+ virtual HRESULT GetBytes(char* type, IAvnString**ppv) = 0;
+
virtual HRESULT Clear() = 0;
};
@@ -475,4 +495,22 @@ AVNCOM(IAvnGCHandleDeallocatorCallback, 22) : IUnknown
virtual void FreeGCHandle(void* handle) = 0;
};
+AVNCOM(IAvnNativeControlHost, 20) : IUnknown
+{
+ virtual HRESULT CreateDefaultChild(void* parent, void** retOut) = 0;
+ virtual IAvnNativeControlHostTopLevelAttachment* CreateAttachment() = 0;
+ virtual void DestroyDefaultChild(void* child) = 0;
+};
+
+AVNCOM(IAvnNativeControlHostTopLevelAttachment, 21) : IUnknown
+{
+ virtual void* GetParentHandle() = 0;
+ virtual HRESULT InitializeWithChildHandle(void* child) = 0;
+ virtual HRESULT AttachTo(IAvnNativeControlHost* host) = 0;
+ virtual void ShowInBounds(float x, float y, float width, float height) = 0;
+ virtual void HideWithSize(float width, float height) = 0;
+ virtual void ReleaseChild() = 0;
+};
+
+
extern "C" IAvaloniaNativeFactory* CreateAvaloniaNative();
diff --git a/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj b/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj
index ea28780c81..d5cad4d1ca 100644
--- a/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj
+++ b/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj
@@ -10,6 +10,8 @@
1A002B9E232135EE00021753 /* app.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A002B9D232135EE00021753 /* app.mm */; };
1A3E5EA823E9E83B00EDE661 /* rendertarget.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A3E5EA723E9E83B00EDE661 /* rendertarget.mm */; };
1A3E5EAA23E9F26C00EDE661 /* IOSurface.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A3E5EA923E9F26C00EDE661 /* IOSurface.framework */; };
+ 1A1852DC23E05814008F0DED /* deadlock.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A1852DB23E05814008F0DED /* deadlock.mm */; };
+ 1AFD334123E03C4F0042899B /* controlhost.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1AFD334023E03C4F0042899B /* controlhost.mm */; };
1A3E5EAE23E9FB1300EDE661 /* cgl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A3E5EAD23E9FB1300EDE661 /* cgl.mm */; };
1A3E5EB023E9FE8300EDE661 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A3E5EAF23E9FE8300EDE661 /* QuartzCore.framework */; };
1A465D10246AB61600C5858B /* dnd.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A465D0F246AB61600C5858B /* dnd.mm */; };
@@ -32,6 +34,8 @@
1A002B9D232135EE00021753 /* app.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = app.mm; sourceTree = ""; };
1A3E5EA723E9E83B00EDE661 /* rendertarget.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = rendertarget.mm; sourceTree = ""; };
1A3E5EA923E9F26C00EDE661 /* IOSurface.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOSurface.framework; path = System/Library/Frameworks/IOSurface.framework; sourceTree = SDKROOT; };
+ 1A1852DB23E05814008F0DED /* deadlock.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = deadlock.mm; sourceTree = ""; };
+ 1AFD334023E03C4F0042899B /* controlhost.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = controlhost.mm; sourceTree = ""; };
1A3E5EAD23E9FB1300EDE661 /* cgl.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = cgl.mm; sourceTree = ""; };
1A3E5EAF23E9FE8300EDE661 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
1A465D0F246AB61600C5858B /* dnd.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = dnd.mm; sourceTree = ""; };
@@ -86,11 +90,13 @@
AB7A61E62147C814003C5833 = {
isa = PBXGroup;
children = (
+ 1A1852DB23E05814008F0DED /* deadlock.mm */,
1A002B9D232135EE00021753 /* app.mm */,
37DDA9B121933371002E132B /* AvnString.h */,
37DDA9AF219330F8002E132B /* AvnString.mm */,
37A4E71A2178846A00EACBCD /* headers */,
1A3E5EAD23E9FB1300EDE661 /* cgl.mm */,
+ 1AFD334023E03C4F0042899B /* controlhost.mm */,
5BF943652167AD1D009CAE35 /* cursor.h */,
5B21A981216530F500CEE36E /* cursor.mm */,
5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */,
@@ -191,6 +197,7 @@
files = (
1A002B9E232135EE00021753 /* app.mm in Sources */,
5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */,
+ 1A1852DC23E05814008F0DED /* deadlock.mm in Sources */,
5B21A982216530F500CEE36E /* cursor.mm in Sources */,
37DDA9B0219330F8002E132B /* AvnString.mm in Sources */,
AB8F7D6B21482D7F0057DBA5 /* platformthreading.mm in Sources */,
@@ -199,6 +206,7 @@
37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */,
520624B322973F4100C4DCEF /* menu.mm in Sources */,
37A517B32159597E00FBA241 /* Screens.mm in Sources */,
+ 1AFD334123E03C4F0042899B /* controlhost.mm in Sources */,
1A465D10246AB61600C5858B /* dnd.mm in Sources */,
AB00E4F72147CA920032A60A /* main.mm in Sources */,
37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */,
diff --git a/native/Avalonia.Native/src/OSX/AvnString.h b/native/Avalonia.Native/src/OSX/AvnString.h
index 88bc4e6963..5d299374e5 100644
--- a/native/Avalonia.Native/src/OSX/AvnString.h
+++ b/native/Avalonia.Native/src/OSX/AvnString.h
@@ -12,4 +12,5 @@
extern IAvnString* CreateAvnString(NSString* string);
extern IAvnStringArray* CreateAvnStringArray(NSArray* array);
extern IAvnStringArray* CreateAvnStringArray(NSString* string);
+extern IAvnString* CreateByteArray(void* data, int len);
#endif /* AvnString_h */
diff --git a/native/Avalonia.Native/src/OSX/AvnString.mm b/native/Avalonia.Native/src/OSX/AvnString.mm
index 6445a9fef1..00b748ef63 100644
--- a/native/Avalonia.Native/src/OSX/AvnString.mm
+++ b/native/Avalonia.Native/src/OSX/AvnString.mm
@@ -29,6 +29,13 @@ public:
memcpy((void*)_cstring, (void*)cstring, _length);
}
+ AvnStringImpl(void*ptr, int len)
+ {
+ _length = len;
+ _cstring = (const char*)malloc(_length);
+ memcpy((void*)_cstring, ptr, len);
+ }
+
virtual ~AvnStringImpl()
{
free((void*)_cstring);
@@ -114,3 +121,8 @@ IAvnStringArray* CreateAvnStringArray(NSString* string)
{
return new AvnStringArrayImpl(string);
}
+
+IAvnString* CreateByteArray(void* data, int len)
+{
+ return new AvnStringImpl(data, len);
+}
diff --git a/native/Avalonia.Native/src/OSX/app.mm b/native/Avalonia.Native/src/OSX/app.mm
index 1e74a70e66..814b91cb62 100644
--- a/native/Avalonia.Native/src/OSX/app.mm
+++ b/native/Avalonia.Native/src/OSX/app.mm
@@ -29,9 +29,43 @@ NSApplicationActivationPolicy AvnDesiredActivationPolicy = NSApplicationActivati
@end
+@interface AvnApplication : NSApplication
+
+
+@end
+
+@implementation AvnApplication
+{
+ BOOL _isHandlingSendEvent;
+}
+
+- (void)sendEvent:(NSEvent *)event
+{
+ bool oldHandling = _isHandlingSendEvent;
+ _isHandlingSendEvent = true;
+ @try {
+ [super sendEvent: event];
+ } @finally {
+ _isHandlingSendEvent = oldHandling;
+ }
+}
+
+// This is needed for certain embedded controls
+- (BOOL) isHandlingSendEvent
+{
+ return _isHandlingSendEvent;
+}
+
+- (void)setHandlingSendEvent:(BOOL)handlingSendEvent
+{
+ _isHandlingSendEvent = handlingSendEvent;
+}
+
+@end
+
extern void InitializeAvnApp()
{
- NSApplication* app = [NSApplication sharedApplication];
+ NSApplication* app = [AvnApplication sharedApplication];
id delegate = [AvnAppDelegate new];
[app setDelegate:delegate];
}
diff --git a/native/Avalonia.Native/src/OSX/clipboard.mm b/native/Avalonia.Native/src/OSX/clipboard.mm
index 18d60d3853..116a08670e 100644
--- a/native/Avalonia.Native/src/OSX/clipboard.mm
+++ b/native/Avalonia.Native/src/OSX/clipboard.mm
@@ -82,6 +82,40 @@ public:
return S_OK;
}
+
+ virtual HRESULT SetBytes(char* type, void* bytes, int len) override
+ {
+ auto typeString = [NSString stringWithUTF8String:(const char*)type];
+ auto data = [NSData dataWithBytes:bytes length:len];
+ if(_item == nil)
+ [_pb setData:data forType:typeString];
+ else
+ [_item setData:data forType:typeString];
+ return S_OK;
+ }
+
+ virtual HRESULT GetBytes(char* type, IAvnString**ppv) override
+ {
+ *ppv = nil;
+ auto typeString = [NSString stringWithUTF8String:(const char*)type];
+ NSData*data;
+ @try
+ {
+ if(_item)
+ data = [_item dataForType:typeString];
+ else
+ data = [_pb dataForType:typeString];
+ if(data == nil)
+ return E_FAIL;
+ }
+ @catch(NSException* e)
+ {
+ return E_FAIL;
+ }
+ *ppv = CreateByteArray((void*)data.bytes, (int)data.length);
+ return S_OK;
+ }
+
virtual HRESULT Clear() override
{
diff --git a/native/Avalonia.Native/src/OSX/common.h b/native/Avalonia.Native/src/OSX/common.h
index df6a7be91c..871bca086d 100644
--- a/native/Avalonia.Native/src/OSX/common.h
+++ b/native/Avalonia.Native/src/OSX/common.h
@@ -24,6 +24,7 @@ extern IAvnGlDisplay* GetGlDisplay();
extern IAvnMenu* CreateAppMenu(IAvnMenuEvents* events);
extern IAvnMenuItem* CreateAppMenuItem();
extern IAvnMenuItem* CreateAppMenuItemSeperator();
+extern IAvnNativeControlHost* CreateNativeControlHost(NSView* parent);
extern void SetAppMenu (NSString* appName, IAvnMenu* appMenu);
extern IAvnMenu* GetAppMenu ();
extern NSMenuItem* GetAppMenuItem ();
@@ -54,4 +55,12 @@ template inline T* objc_cast(id from) {
- (void) action;
@end
+class AvnInsidePotentialDeadlock
+{
+public:
+ static bool IsInside();
+ AvnInsidePotentialDeadlock();
+ ~AvnInsidePotentialDeadlock();
+};
+
#endif
diff --git a/native/Avalonia.Native/src/OSX/controlhost.mm b/native/Avalonia.Native/src/OSX/controlhost.mm
new file mode 100644
index 0000000000..5ee2344ac7
--- /dev/null
+++ b/native/Avalonia.Native/src/OSX/controlhost.mm
@@ -0,0 +1,160 @@
+#include "common.h"
+
+
+IAvnNativeControlHostTopLevelAttachment* CreateAttachment();
+
+class AvnNativeControlHost :
+ public ComSingleObject
+{
+public:
+ FORWARD_IUNKNOWN();
+ NSView* View;
+ AvnNativeControlHost(NSView* view)
+ {
+ View = view;
+ }
+
+ virtual HRESULT CreateDefaultChild(void* parent, void** retOut) override
+ {
+ NSView* view = [NSView new];
+ [view setWantsLayer: true];
+
+ *retOut = (__bridge_retained void*)view;
+ return S_OK;
+ };
+
+ virtual IAvnNativeControlHostTopLevelAttachment* CreateAttachment() override
+ {
+ return ::CreateAttachment();
+ };
+
+ virtual void DestroyDefaultChild(void* child) override
+ {
+ // ARC will release the object for us
+ (__bridge_transfer NSView*) child;
+ }
+};
+
+class AvnNativeControlHostTopLevelAttachment :
+public ComSingleObject
+{
+ NSView* _holder;
+ NSView* _child;
+public:
+ FORWARD_IUNKNOWN();
+
+ AvnNativeControlHostTopLevelAttachment()
+ {
+ _holder = [NSView new];
+ [_holder setWantsLayer:true];
+ }
+
+ virtual ~AvnNativeControlHostTopLevelAttachment()
+ {
+ if(_child != nil && [_child superview] == _holder)
+ {
+ [_child removeFromSuperview];
+ }
+
+ if([_holder superview] != nil)
+ {
+ [_holder removeFromSuperview];
+ }
+ }
+
+ virtual void* GetParentHandle() override
+ {
+ return (__bridge void*)_holder;
+ };
+
+ virtual HRESULT InitializeWithChildHandle(void* child) override
+ {
+ if(_child != nil)
+ return E_FAIL;
+ _child = (__bridge NSView*)child;
+ if(_child == nil)
+ return E_FAIL;
+ [_holder addSubview:_child];
+ [_child setHidden: false];
+ return S_OK;
+ };
+
+ virtual HRESULT AttachTo(IAvnNativeControlHost* host) override
+ {
+ if(host == nil)
+ {
+ [_holder removeFromSuperview];
+ [_holder setHidden: true];
+ }
+ else
+ {
+ AvnNativeControlHost* chost = dynamic_cast(host);
+ if(chost == nil || chost->View == nil)
+ return E_FAIL;
+ [_holder setHidden:true];
+ [chost->View addSubview:_holder];
+ }
+ return S_OK;
+ };
+
+ virtual void ShowInBounds(float x, float y, float width, float height) override
+ {
+ if(_child == nil)
+ return;
+ if(AvnInsidePotentialDeadlock::IsInside())
+ {
+ IAvnNativeControlHostTopLevelAttachment* slf = this;
+ slf->AddRef();
+ dispatch_async(dispatch_get_main_queue(), ^{
+ slf->ShowInBounds(x, y, width, height);
+ slf->Release();
+ });
+ return;
+ }
+
+ NSRect childFrame = {0, 0, width, height};
+ NSRect holderFrame = {x, y, width, height};
+
+ [_child setFrame: childFrame];
+ [_holder setFrame: holderFrame];
+ [_holder setHidden: false];
+ if([_holder superview] != nil)
+ [[_holder superview] setNeedsDisplay:true];
+ }
+
+ virtual void HideWithSize(float width, float height) override
+ {
+ if(_child == nil)
+ return;
+ if(AvnInsidePotentialDeadlock::IsInside())
+ {
+ IAvnNativeControlHostTopLevelAttachment* slf = this;
+ slf->AddRef();
+ dispatch_async(dispatch_get_main_queue(), ^{
+ slf->HideWithSize(width, height);
+ slf->Release();
+ });
+ return;
+ }
+
+ NSRect frame = {0, 0, width, height};
+ [_holder setHidden: true];
+ [_child setFrame: frame];
+ }
+
+ virtual void ReleaseChild() override
+ {
+ [_child removeFromSuperview];
+ _child = nil;
+ }
+};
+
+IAvnNativeControlHostTopLevelAttachment* CreateAttachment()
+{
+ return new AvnNativeControlHostTopLevelAttachment();
+}
+
+extern IAvnNativeControlHost* CreateNativeControlHost(NSView* parent)
+{
+ return new AvnNativeControlHost(parent);
+}
diff --git a/native/Avalonia.Native/src/OSX/deadlock.mm b/native/Avalonia.Native/src/OSX/deadlock.mm
new file mode 100644
index 0000000000..cb1767c90f
--- /dev/null
+++ b/native/Avalonia.Native/src/OSX/deadlock.mm
@@ -0,0 +1,17 @@
+#include "common.h"
+
+static int Counter = 0;
+AvnInsidePotentialDeadlock::AvnInsidePotentialDeadlock()
+{
+ Counter++;
+}
+
+AvnInsidePotentialDeadlock::~AvnInsidePotentialDeadlock()
+{
+ Counter--;
+}
+
+bool AvnInsidePotentialDeadlock::IsInside()
+{
+ return Counter!=0;
+}
diff --git a/native/Avalonia.Native/src/OSX/window.h b/native/Avalonia.Native/src/OSX/window.h
index bdf3007a28..b1f64bca88 100644
--- a/native/Avalonia.Native/src/OSX/window.h
+++ b/native/Avalonia.Native/src/OSX/window.h
@@ -3,9 +3,6 @@
class WindowBaseImpl;
-@interface AutoFitContentVisualEffectView : NSVisualEffectView
-@end
-
@interface AvnView : NSView
-(AvnView* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent;
-(NSEvent* _Nonnull) lastMouseDownEvent;
@@ -15,6 +12,14 @@ class WindowBaseImpl;
-(AvnPixelSize) getPixelSize;
@end
+@interface AutoFitContentView : NSView
+-(AutoFitContentView* _Nonnull) initWithContent: (NSView* _Nonnull) content;
+-(void) ShowTitleBar: (bool) show;
+-(void) SetTitleBarHeightHint: (double) height;
+-(void) SetContent: (NSView* _Nonnull) content;
+-(void) ShowBlur: (bool) show;
+@end
+
@interface AvnWindow : NSWindow
+(void) closeAll;
-(AvnWindow* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent;
@@ -27,6 +32,8 @@ class WindowBaseImpl;
-(void) showWindowMenuWithAppMenu;
-(void) applyMenu:(NSMenu* _Nullable)menu;
-(double) getScaling;
+-(double) getExtendedTitleBarHeight;
+-(void) setIsExtended:(bool)value;
@end
struct INSWindowHolder
diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm
index abfae3cf1e..872269bb26 100644
--- a/native/Avalonia.Native/src/OSX/window.mm
+++ b/native/Avalonia.Native/src/OSX/window.mm
@@ -6,8 +6,6 @@
#include
#include "rendertarget.h"
-
-
class WindowBaseImpl : public virtual ComSingleObject, public INSWindowHolder
{
private:
@@ -20,7 +18,7 @@ public:
View = NULL;
Window = NULL;
}
- NSVisualEffectView* VisualEffect;
+ AutoFitContentView* StandardContainer;
AvnView* View;
AvnWindow* Window;
ComPtr BaseEvents;
@@ -39,6 +37,7 @@ public:
_glContext = gl;
renderTarget = [[IOSurfaceRenderTarget alloc] initWithOpenGlContext: gl];
View = [[AvnView alloc] initWithParent:this];
+ StandardContainer = [[AutoFitContentView new] initWithContent:View];
Window = [[AvnWindow alloc] initWithParent:this];
@@ -49,12 +48,8 @@ public:
[Window setStyleMask:NSWindowStyleMaskBorderless];
[Window setBackingType:NSBackingStoreBuffered];
- VisualEffect = [AutoFitContentVisualEffectView new];
- [VisualEffect setBlendingMode:NSVisualEffectBlendingModeBehindWindow];
- [VisualEffect setMaterial:NSVisualEffectMaterialLight];
- [VisualEffect setAutoresizesSubviews:true];
-
- [Window setContentView: View];
+ [Window setOpaque:false];
+ [Window setContentView: StandardContainer];
}
virtual HRESULT ObtainNSWindowHandle(void** ret) override
@@ -116,10 +111,15 @@ public:
{
SetPosition(lastPositionSet);
UpdateStyle();
-
- [Window makeKeyAndOrderFront:Window];
- [NSApp activateIgnoringOtherApps:YES];
-
+ if(ShouldTakeFocusOnShow())
+ {
+ [Window makeKeyAndOrderFront:Window];
+ [NSApp activateIgnoringOtherApps:YES];
+ }
+ else
+ {
+ [Window orderFront: Window];
+ }
[Window setTitle:_lastTitle];
_shown = true;
@@ -128,6 +128,11 @@ public:
}
}
+ virtual bool ShouldTakeFocusOnShow()
+ {
+ return true;
+ }
+
virtual HRESULT Hide () override
{
@autoreleasepool
@@ -390,14 +395,17 @@ public:
return *ppv == nil ? E_FAIL : S_OK;
}
+ virtual HRESULT CreateNativeControlHost(IAvnNativeControlHost** retOut) override
+ {
+ if(View == NULL)
+ return E_FAIL;
+ *retOut = ::CreateNativeControlHost(View);
+ return S_OK;
+ }
+
virtual HRESULT SetBlurEnabled (bool enable) override
{
- [Window setContentView: enable ? VisualEffect : View];
-
- if(enable)
- {
- [VisualEffect addSubview:View];
- }
+ [StandardContainer ShowBlur:enable];
return S_OK;
}
@@ -474,6 +482,8 @@ private:
bool _inSetWindowState;
NSRect _preZoomSize;
bool _transitioningWindowState;
+ bool _isClientAreaExtended;
+ AvnExtendClientAreaChromeHints _extendClientHints;
FORWARD_IUNKNOWN()
BEGIN_INTERFACE_MAP()
@@ -487,6 +497,8 @@ private:
ComPtr WindowEvents;
WindowImpl(IAvnWindowEvents* events, IAvnGlContext* gl) : WindowBaseImpl(events, gl)
{
+ _isClientAreaExtended = false;
+ _extendClientHints = AvnDefaultChrome;
_fullScreenActive = false;
_canResize = true;
_decorations = SystemDecorationsFull;
@@ -505,8 +517,20 @@ private:
if ([subview isKindOfClass:NSClassFromString(@"NSTitlebarContainerView")]) {
NSView *titlebarView = [subview subviews][0];
for (id button in titlebarView.subviews) {
- if ([button isKindOfClass:[NSButton class]]) {
- [button setHidden: (_decorations != SystemDecorationsFull)];
+ if ([button isKindOfClass:[NSButton class]])
+ {
+ if(_isClientAreaExtended)
+ {
+ auto wantsChrome = (_extendClientHints & AvnSystemChrome) || (_extendClientHints & AvnPreferSystemChrome);
+
+ [button setHidden: !wantsChrome];
+ }
+ else
+ {
+ [button setHidden: (_decorations != SystemDecorationsFull)];
+ }
+
+ [button setWantsLayer:true];
}
}
}
@@ -582,6 +606,35 @@ private:
if(_lastWindowState != state)
{
+ if(_isClientAreaExtended)
+ {
+ if(_lastWindowState == FullScreen)
+ {
+ // we exited fs.
+ if(_extendClientHints & AvnOSXThickTitleBar)
+ {
+ Window.toolbar = [NSToolbar new];
+ Window.toolbar.showsBaselineSeparator = false;
+ }
+
+ [Window setTitlebarAppearsTransparent:true];
+
+ [StandardContainer setFrameSize: StandardContainer.frame.size];
+ }
+ else if(state == FullScreen)
+ {
+ // we entered fs.
+ if(_extendClientHints & AvnOSXThickTitleBar)
+ {
+ Window.toolbar = nullptr;
+ }
+
+ [Window setTitlebarAppearsTransparent:false];
+
+ [StandardContainer setFrameSize: StandardContainer.frame.size];
+ }
+ }
+
_lastWindowState = state;
WindowEvents->WindowStateChanged(state);
}
@@ -638,8 +691,6 @@ private:
return S_OK;
}
- auto currentFrame = [Window frame];
-
UpdateStyle();
HideOrShowTrafficLights();
@@ -766,6 +817,90 @@ private:
}
}
+ virtual HRESULT TakeFocusFromChildren () override
+ {
+ if(Window == nil)
+ return S_OK;
+ if([Window isKeyWindow])
+ [Window makeFirstResponder: View];
+
+ return S_OK;
+ }
+
+ virtual HRESULT SetExtendClientArea (bool enable) override
+ {
+ _isClientAreaExtended = enable;
+
+ if(enable)
+ {
+ Window.titleVisibility = NSWindowTitleHidden;
+
+ [Window setTitlebarAppearsTransparent:true];
+
+ auto wantsTitleBar = (_extendClientHints & AvnSystemChrome) || (_extendClientHints & AvnPreferSystemChrome);
+
+ if (wantsTitleBar)
+ {
+ [StandardContainer ShowTitleBar:true];
+ }
+ else
+ {
+ [StandardContainer ShowTitleBar:false];
+ }
+
+ if(_extendClientHints & AvnOSXThickTitleBar)
+ {
+ Window.toolbar = [NSToolbar new];
+ Window.toolbar.showsBaselineSeparator = false;
+ }
+ else
+ {
+ Window.toolbar = nullptr;
+ }
+ }
+ else
+ {
+ Window.titleVisibility = NSWindowTitleVisible;
+ Window.toolbar = nullptr;
+ [Window setTitlebarAppearsTransparent:false];
+ View.layer.zPosition = 0;
+ }
+
+ [Window setIsExtended:enable];
+
+ HideOrShowTrafficLights();
+
+ UpdateStyle();
+
+ return S_OK;
+ }
+
+ virtual HRESULT SetExtendClientAreaHints (AvnExtendClientAreaChromeHints hints) override
+ {
+ _extendClientHints = hints;
+
+ SetExtendClientArea(_isClientAreaExtended);
+ return S_OK;
+ }
+
+ virtual HRESULT GetExtendTitleBarHeight (double*ret) override
+ {
+ if(ret == nullptr)
+ {
+ return E_POINTER;
+ }
+
+ *ret = [Window getExtendedTitleBarHeight];
+
+ return S_OK;
+ }
+
+ virtual HRESULT SetExtendTitleBarHeight (double value) override
+ {
+ [StandardContainer SetTitleBarHeightHint:value];
+ return S_OK;
+ }
+
void EnterFullScreenMode ()
{
_fullScreenActive = true;
@@ -775,8 +910,9 @@ private:
[Window setTitlebarAppearsTransparent:NO];
[Window setTitle:_lastTitle];
- [Window setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskResizable];
-
+ Window.styleMask = Window.styleMask | NSWindowStyleMaskTitled | NSWindowStyleMaskResizable;
+ Window.styleMask = Window.styleMask & ~NSWindowStyleMaskFullSizeContentView;
+
[Window toggleFullScreen:nullptr];
}
@@ -924,19 +1060,120 @@ protected:
{
s |= NSWindowStyleMaskMiniaturizable;
}
+
+ if(_isClientAreaExtended)
+ {
+ s |= NSWindowStyleMaskFullSizeContentView | NSWindowStyleMaskTexturedBackground;
+ }
return s;
}
};
NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEventTrackingRunLoopMode, NSModalPanelRunLoopMode, NSRunLoopCommonModes, NSConnectionReplyMode, nil];
-@implementation AutoFitContentVisualEffectView
+@implementation AutoFitContentView
+{
+ NSVisualEffectView* _titleBarMaterial;
+ NSBox* _titleBarUnderline;
+ NSView* _content;
+ NSVisualEffectView* _blurBehind;
+ double _titleBarHeightHint;
+ bool _settingSize;
+}
+
+-(AutoFitContentView* _Nonnull) initWithContent:(NSView *)content
+{
+ _titleBarHeightHint = -1;
+ _content = content;
+ _settingSize = false;
+
+ [self setAutoresizesSubviews:true];
+ [self setWantsLayer:true];
+
+ _titleBarMaterial = [NSVisualEffectView new];
+ [_titleBarMaterial setBlendingMode:NSVisualEffectBlendingModeWithinWindow];
+ [_titleBarMaterial setMaterial:NSVisualEffectMaterialTitlebar];
+ [_titleBarMaterial setWantsLayer:true];
+ _titleBarMaterial.hidden = true;
+
+ _titleBarUnderline = [NSBox new];
+ _titleBarUnderline.boxType = NSBoxSeparator;
+ _titleBarUnderline.fillColor = [NSColor underPageBackgroundColor];
+ _titleBarUnderline.hidden = true;
+
+ [self addSubview:_titleBarMaterial];
+ [self addSubview:_titleBarUnderline];
+
+ _blurBehind = [NSVisualEffectView new];
+ [_blurBehind setBlendingMode:NSVisualEffectBlendingModeBehindWindow];
+ [_blurBehind setMaterial:NSVisualEffectMaterialLight];
+ [_blurBehind setWantsLayer:true];
+ _blurBehind.hidden = true;
+
+ [self addSubview:_blurBehind];
+ [self addSubview:_content];
+
+ [self setWantsLayer:true];
+ return self;
+}
+
+-(void) ShowBlur:(bool)show
+{
+ _blurBehind.hidden = !show;
+}
+
+-(void) ShowTitleBar: (bool) show
+{
+ _titleBarMaterial.hidden = !show;
+ _titleBarUnderline.hidden = !show;
+}
+
+-(void) SetTitleBarHeightHint: (double) height
+{
+ _titleBarHeightHint = height;
+
+ [self setFrameSize:self.frame.size];
+}
+
-(void)setFrameSize:(NSSize)newSize
{
- [super setFrameSize:newSize];
- if([[self subviews] count] == 0)
+ if(_settingSize)
+ {
return;
- [[self subviews][0] setFrameSize: newSize];
+ }
+
+ _settingSize = true;
+ [super setFrameSize:newSize];
+
+ [_blurBehind setFrameSize:newSize];
+ [_content setFrameSize:newSize];
+
+ auto window = objc_cast([self window]);
+
+ // TODO get actual titlebar size
+
+ double height = _titleBarHeightHint == -1 ? [window getExtendedTitleBarHeight] : _titleBarHeightHint;
+
+ NSRect tbar;
+ tbar.origin.x = 0;
+ tbar.origin.y = newSize.height - height;
+ tbar.size.width = newSize.width;
+ tbar.size.height = height;
+
+ [_titleBarMaterial setFrame:tbar];
+ tbar.size.height = height < 1 ? 0 : 1;
+ [_titleBarUnderline setFrame:tbar];
+ _settingSize = false;
+}
+
+-(void) SetContent: (NSView* _Nonnull) content
+{
+ if(content != nullptr)
+ {
+ [content removeFromSuperview];
+ [self addSubview:content];
+ _content = content;
+ }
}
@end
@@ -1060,9 +1297,9 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
_parent->BaseEvents->Resized(AvnSize{newSize.width, newSize.height});
}
-
- (void)updateLayer
{
+ AvnInsidePotentialDeadlock deadlock;
if (_parent == nullptr)
{
return;
@@ -1107,7 +1344,11 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
_lastPixelSize.Width = (int)fsize.width;
_lastPixelSize.Height = (int)fsize.height;
[self updateRenderTarget];
- _parent->BaseEvents->ScalingChanged([_parent->Window backingScaleFactor]);
+
+ if(_parent != nullptr)
+ {
+ _parent->BaseEvents->ScalingChanged([_parent->Window backingScaleFactor]);
+ }
[super viewDidChangeBackingProperties];
}
@@ -1138,7 +1379,6 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
return;
}
- [self becomeFirstResponder];
auto localPoint = [self convertPoint:[event locationInWindow] toView:self];
auto avnPoint = [self toAvnPoint:localPoint];
auto point = [self translateLocalPoint:avnPoint];
@@ -1165,11 +1405,31 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
auto timestamp = [event timestamp] * 1000;
auto modifiers = [self getModifiers:[event modifierFlags]];
- [self becomeFirstResponder];
- _parent->BaseEvents->RawMouseEvent(type, timestamp, modifiers, point, delta);
+ if(type != AvnRawMouseEventType::Move ||
+ (
+ [self window] != nil &&
+ (
+ [[self window] firstResponder] == nil
+ || ![[[self window] firstResponder] isKindOfClass: [NSView class]]
+ )
+ )
+ )
+ [self becomeFirstResponder];
+
+ if(_parent != nullptr)
+ {
+ _parent->BaseEvents->RawMouseEvent(type, timestamp, modifiers, point, delta);
+ }
+
[super mouseMoved:event];
}
+- (BOOL) resignFirstResponder
+{
+ _parent->BaseEvents->LostFocus();
+ return YES;
+}
+
- (void)mouseMoved:(NSEvent *)event
{
[self mouseEvent:event withType:Move];
@@ -1290,7 +1550,10 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
auto timestamp = [event timestamp] * 1000;
auto modifiers = [self getModifiers:[event modifierFlags]];
- _lastKeyHandled = _parent->BaseEvents->RawKeyEvent(type, timestamp, modifiers, key);
+ if(_parent != nullptr)
+ {
+ _lastKeyHandled = _parent->BaseEvents->RawKeyEvent(type, timestamp, modifiers, key);
+ }
}
- (BOOL)performKeyEquivalent:(NSEvent *)event
@@ -1381,7 +1644,10 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
{
if(!_lastKeyHandled)
{
- _lastKeyHandled = _parent->BaseEvents->RawTextInputEvent(0, [string UTF8String]);
+ if(_parent != nullptr)
+ {
+ _lastKeyHandled = _parent->BaseEvents->RawTextInputEvent(0, [string UTF8String]);
+ }
}
}
@@ -1467,15 +1733,43 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
bool _canBecomeKeyAndMain;
bool _closed;
bool _isEnabled;
+ bool _isExtended;
AvnMenu* _menu;
double _lastScaling;
}
+-(void) setIsExtended:(bool)value;
+{
+ _isExtended = value;
+}
+
-(double) getScaling
{
return _lastScaling;
}
+-(double) getExtendedTitleBarHeight
+{
+ if(_isExtended)
+ {
+ for (id subview in self.contentView.superview.subviews)
+ {
+ if ([subview isKindOfClass:NSClassFromString(@"NSTitlebarContainerView")])
+ {
+ NSView *titlebarView = [subview subviews][0];
+
+ return (double)titlebarView.frame.size.height;
+ }
+ }
+
+ return -1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+(void)closeAll
{
NSArray* windows = [NSArray arrayWithArray:[NSApp windows]];
@@ -1594,6 +1888,7 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
[self setOpaque:NO];
[self setBackgroundColor: [NSColor clearColor]];
[self invalidateShadow];
+ _isExtended = false;
return self;
}
@@ -1677,7 +1972,11 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
{
[self showWindowMenuWithAppMenu];
- _parent->BaseEvents->Activated();
+ if(_parent != nullptr)
+ {
+ _parent->BaseEvents->Activated();
+ }
+
[super becomeKeyWindow];
}
}
@@ -1794,8 +2093,12 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
- (void)windowDidMove:(NSNotification *)notification
{
AvnPoint position;
- _parent->GetPosition(&position);
- _parent->BaseEvents->PositionChanged(position);
+
+ if(_parent != nullptr)
+ {
+ _parent->GetPosition(&position);
+ _parent->BaseEvents->PositionChanged(position);
+ }
}
@end
@@ -1813,7 +2116,6 @@ private:
WindowEvents = events;
[Window setLevel:NSPopUpMenuWindowLevel];
}
-
protected:
virtual NSWindowStyleMask GetStyle() override
{
@@ -1831,6 +2133,11 @@ protected:
return S_OK;
}
}
+public:
+ virtual bool ShouldTakeFocusOnShow() override
+ {
+ return false;
+ }
};
extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events, IAvnGlContext* gl)
diff --git a/nukebuild/Build.cs b/nukebuild/Build.cs
index 5460dc7720..fe877dc49c 100644
--- a/nukebuild/Build.cs
+++ b/nukebuild/Build.cs
@@ -101,7 +101,7 @@ partial class Build : NukeBuild
.SetProjectFile(projectFile)
// This is required for VS2019 image on Azure Pipelines
.When(Parameters.IsRunningOnWindows &&
- Parameters.IsRunningOnAzure, c => c
+ Parameters.IsRunningOnAzure, _ => _
.AddProperty("JavaSdkDirectory", GetVariable("JAVA_HOME_8_X64")))
.AddProperty("PackageVersion", Parameters.Version)
.AddProperty("iOSRoslynPathHackRequired", true)
@@ -176,7 +176,7 @@ partial class Build : NukeBuild
.SetFramework(fw)
.EnableNoBuild()
.EnableNoRestore()
- .When(Parameters.PublishTestResults, c => c
+ .When(Parameters.PublishTestResults, _ => _
.SetLogger("trx")
.SetResultsDirectory(Parameters.TestResultsRoot)));
}
@@ -268,6 +268,8 @@ partial class Build : NukeBuild
.DependsOn(CreateIntermediateNugetPackages)
.Executes(() =>
{
+ BuildTasksPatcher.PatchBuildTasksInPackage(Parameters.NugetIntermediateRoot / "Avalonia.Build.Tasks." +
+ Parameters.Version + ".nupkg");
var config = Numerge.MergeConfiguration.LoadFile(RootDirectory / "nukebuild" / "numerge.config");
EnsureCleanDirectory(Parameters.NugetRoot);
if(!Numerge.NugetPackageMerger.Merge(Parameters.NugetIntermediateRoot, Parameters.NugetRoot, config,
diff --git a/nukebuild/BuildTasksPatcher.cs b/nukebuild/BuildTasksPatcher.cs
new file mode 100644
index 0000000000..44f01da669
--- /dev/null
+++ b/nukebuild/BuildTasksPatcher.cs
@@ -0,0 +1,76 @@
+using System;
+using System.IO;
+using System.IO.Compression;
+using System.Linq;
+using ILRepacking;
+using Mono.Cecil;
+
+public class BuildTasksPatcher
+{
+ public static void PatchBuildTasksInPackage(string packagePath)
+ {
+ using (var archive = new ZipArchive(File.Open(packagePath, FileMode.Open, FileAccess.ReadWrite),
+ ZipArchiveMode.Update))
+ {
+
+ foreach (var entry in archive.Entries.ToList())
+ {
+ if (entry.Name == "Avalonia.Build.Tasks.dll")
+ {
+ var temp = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".dll");
+ var output = temp + ".output";
+ var patched = new MemoryStream();
+ try
+ {
+ entry.ExtractToFile(temp, true);
+ var repack = new ILRepacking.ILRepack(new RepackOptions()
+ {
+ Internalize = true,
+ InputAssemblies = new[]
+ {
+ temp, typeof(Mono.Cecil.AssemblyDefinition).Assembly.GetModules()[0]
+ .FullyQualifiedName
+ },
+ SearchDirectories = new string[0],
+ OutputFile = output
+ });
+ repack.Repack();
+
+
+ // 'hurr-durr assembly with the same name is already loaded' prevention
+ using (var asm = AssemblyDefinition.ReadAssembly(output,
+ new ReaderParameters { ReadWrite = true, InMemory = true, }))
+ {
+ asm.Name = new AssemblyNameDefinition(
+ "Avalonia.Build.Tasks."
+ + Guid.NewGuid().ToString().Replace("-", ""),
+ new Version(0, 0, 0));
+ asm.Write(patched);
+ patched.Position = 0;
+ }
+ }
+ finally
+ {
+ try
+ {
+ if (File.Exists(temp))
+ File.Delete(temp);
+ if (File.Exists(output))
+ File.Delete(output);
+ }
+ catch
+ {
+ //ignore
+ }
+ }
+
+ var fn = entry.FullName;
+ entry.Delete();
+ var newEntry = archive.CreateEntry(fn, CompressionLevel.Optimal);
+ using (var s = newEntry.Open())
+ patched.CopyTo(s);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/nukebuild/Numerge b/nukebuild/Numerge
index 4464343aef..aef10ae67d 160000
--- a/nukebuild/Numerge
+++ b/nukebuild/Numerge
@@ -1 +1 @@
-Subproject commit 4464343aef5c8ab7a42fcb20a483a6058199f8b8
+Subproject commit aef10ae67dc55c95f49b52a505a0be33bfa297a5
diff --git a/nukebuild/_build.csproj b/nukebuild/_build.csproj
index 584c36d033..4c64d4ff93 100644
--- a/nukebuild/_build.csproj
+++ b/nukebuild/_build.csproj
@@ -14,6 +14,9 @@
+
+
+
diff --git a/packages/Avalonia/Avalonia.csproj b/packages/Avalonia/Avalonia.csproj
index 2c5a09bee7..cd3ce9adcd 100644
--- a/packages/Avalonia/Avalonia.csproj
+++ b/packages/Avalonia/Avalonia.csproj
@@ -41,6 +41,10 @@
true
build\
+
+ true
+ build\
+
diff --git a/packages/Avalonia/AvaloniaBuildTasks.props b/packages/Avalonia/AvaloniaBuildTasks.props
index 30bafa37ee..deea3aa391 100644
--- a/packages/Avalonia/AvaloniaBuildTasks.props
+++ b/packages/Avalonia/AvaloniaBuildTasks.props
@@ -1,3 +1,11 @@
-
+
+
+
+
+
+
+
+
+
diff --git a/packages/Avalonia/AvaloniaBuildTasks.targets b/packages/Avalonia/AvaloniaBuildTasks.targets
index 537495fcad..84a62bb5c0 100644
--- a/packages/Avalonia/AvaloniaBuildTasks.targets
+++ b/packages/Avalonia/AvaloniaBuildTasks.targets
@@ -4,6 +4,20 @@
<_AvaloniaUseExternalMSBuild Condition="'$(_AvaloniaForceInternalMSBuild)' == 'true'">false
low
+
+
+
+
+ %(Filename)
+ Code
+
+
+ %(Filename)
+ Code
+
+
+
+
+ DependsOnTargets="$(BuildAvaloniaResourcesDependsOn)">
+
+
+
+
diff --git a/packages/Avalonia/AvaloniaItemSchema.xaml b/packages/Avalonia/AvaloniaItemSchema.xaml
new file mode 100644
index 0000000000..a51ea3c0be
--- /dev/null
+++ b/packages/Avalonia/AvaloniaItemSchema.xaml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/readme.md b/readme.md
index 8ae3f1ad66..6a04c7e31e 100644
--- a/readme.md
+++ b/readme.md
@@ -1,24 +1,20 @@
-
+[](https://gitter.im/AvaloniaUI/Avalonia?utm_campaign=pr-badge&utm_content=badge&utm_medium=badge&utm_source=badge) [](https://dev.azure.com/AvaloniaUI/AvaloniaUI/_build/latest?definitionId=4) [](#backers) [](#sponsors) 
+
+[](https://www.nuget.org/packages/Avalonia) [](https://www.nuget.org/packages/Avalonia) [](https://www.myget.org/gallery/avalonia-ci) 
-# Avalonia
+
-| Gitter Chat | Build Status (Win, Linux, OSX) | Open Collective | NuGet | MyGet |
-|---|---|---|---|---|
-| [](https://gitter.im/AvaloniaUI/Avalonia?utm_campaign=pr-badge&utm_content=badge&utm_medium=badge&utm_source=badge) | [](https://dev.azure.com/AvaloniaUI/AvaloniaUI/_build/latest?definitionId=4) | [](#backers) [](#sponsors) | [](https://www.nuget.org/packages/Avalonia) | [](https://www.myget.org/gallery/avalonia-ci) |
+## 📖 About AvaloniaUI
-## About
+Avalonia is a cross-platform XAML-based UI framework providing a flexible styling system and supporting a wide range of Operating Systems such as Windows via .NET Framework and .NET Core, Linux via Xorg, macOS. Avalonia is ready for **General-Purpose Desktop App Development**. However, there may be some bugs and breaking changes as we continue along into this project's development.
-**Avalonia** is a cross-platform XAML-based UI framework providing a flexible styling system and supporting a wide range of Operating Systems such as Windows (.NET Framework, .NET Core), Linux (via Xorg), macOS.
+
-**Avalonia** is ready for **General-Purpose Desktop App Development**. However, there may be some bugs and breaking changes as we continue along into this project's development.
+> **Note:** The UI theme you see in the picture above is still work-in-progress and will be available in the upcoming Avalonia 0.10.0 release. However, you can connect to our nightly build feed and install latest pre-release versions of Avalonia NuGet packages, if you are willing to help out with the development and testing. See [Using nightly build feed](https://github.com/AvaloniaUI/Avalonia/wiki/Using-nightly-build-feed) for more info.
-To see the status of some of our features, please see our [Roadmap here](https://github.com/AvaloniaUI/Avalonia/issues/2239).
+To see the status of some of our features, please see our [Roadmap](https://github.com/AvaloniaUI/Avalonia/issues/2239). You can also see what [breaking changes](https://github.com/AvaloniaUI/Avalonia/issues/3538) we have planned and what our [past breaking changes](https://github.com/AvaloniaUI/Avalonia/wiki/Breaking-Changes) have been. [Awesome Avalonia](https://github.com/AvaloniaCommunity/awesome-avalonia) is community-curated list of awesome Avalonia UI tools, libraries, projects and resources. Go and see what people are building with Avalonia!
-You can also see what [breaking changes](https://github.com/AvaloniaUI/Avalonia/issues/3538) we have planned and what our [past breaking changes](https://github.com/AvaloniaUI/Avalonia/wiki/Breaking-Changes) have been.
-
-[Awesome Avalonia](https://github.com/AvaloniaCommunity/awesome-avalonia) is community-curated list of awesome Avalonia UI tools, libraries, projects and resources. Go and see what people are building with Avalonia!
-
-## Getting Started
+## 🚀 Getting Started
The Avalonia [Visual Studio Extension](https://marketplace.visualstudio.com/items?itemName=AvaloniaTeam.AvaloniaforVisualStudio) contains project and control templates that will help you get started, or you can use the .NET Core CLI. For a starer guide see our [documentation](http://avaloniaui.net/docs/quickstart/create-new-project).
@@ -30,6 +26,17 @@ Install-Package Avalonia
Install-Package Avalonia.Desktop
```
+## Showcase
+
+Examples of UIs built with Avalonia
+
+
+
+
+
+
+
+
## JetBrains Rider
If you need to develop Avalonia app with JetBrains Rider, go and *vote* on [this issue](https://youtrack.jetbrains.com/issue/RIDER-39247) in their tracker. JetBrains won't do things without their users telling them that they want the feature, so only **YOU** can make it happen.
@@ -61,7 +68,7 @@ Avalonia is licenced under the [MIT licence](licence.md).
## Contributors
-This project exists thanks to all the people who contribute. [[Contribute](http://avaloniaui.net/contributing/contributing)].
+This project exists thanks to all the people who contribute. [[Contribute](http://avaloniaui.net/contributing)].
### Backers
diff --git a/samples/BindingDemo/App.xaml.cs b/samples/BindingDemo/App.xaml.cs
index f2f44cd502..13875aeb21 100644
--- a/samples/BindingDemo/App.xaml.cs
+++ b/samples/BindingDemo/App.xaml.cs
@@ -1,10 +1,8 @@
using System;
using Avalonia;
using Avalonia.Controls;
-using Avalonia.Logging.Serilog;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
-using Serilog;
namespace BindingDemo
{
diff --git a/samples/BindingDemo/BindingDemo.csproj b/samples/BindingDemo/BindingDemo.csproj
index ce33f42143..817023fd71 100644
--- a/samples/BindingDemo/BindingDemo.csproj
+++ b/samples/BindingDemo/BindingDemo.csproj
@@ -10,7 +10,6 @@
-
diff --git a/samples/BindingDemo/MainWindow.xaml b/samples/BindingDemo/MainWindow.xaml
index 26a62ebca6..14c371efef 100644
--- a/samples/BindingDemo/MainWindow.xaml
+++ b/samples/BindingDemo/MainWindow.xaml
@@ -5,7 +5,8 @@
xmlns:local="clr-namespace:BindingDemo"
Title="AvaloniaUI Bindings Test"
Width="800"
- Height="600">
+ Height="600"
+ x:DataType="vm:MainWindowViewModel">
+
@@ -29,7 +30,11 @@
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
-
+
+
+
+
+
+
+
+
+
@@ -67,10 +76,12 @@
Full Decorations
- Light
- Dark
+ Fluent - Dark
+ Fluent - Light
+ Simple - Light
+ Simple - Dark
-
+
None
Transparent
Blur
diff --git a/samples/ControlCatalog/MainView.xaml.cs b/samples/ControlCatalog/MainView.xaml.cs
index 8c4818fb07..b0c205246e 100644
--- a/samples/ControlCatalog/MainView.xaml.cs
+++ b/samples/ControlCatalog/MainView.xaml.cs
@@ -32,30 +32,25 @@ namespace ControlCatalog
}
- var light = new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog"))
- {
- Source = new Uri("resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default")
- };
- var dark = new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog"))
- {
- Source = new Uri("resm:Avalonia.Themes.Default.Accents.BaseDark.xaml?assembly=Avalonia.Themes.Default")
- };
-
-
var themes = this.Find("Themes");
themes.SelectionChanged += (sender, e) =>
{
switch (themes.SelectedIndex)
{
case 0:
- Styles[0] = light;
+ Application.Current.Styles[0] = App.FluentDark;
break;
case 1:
- Styles[0] = dark;
+ Application.Current.Styles[0] = App.FluentLight;
+ break;
+ case 2:
+ Application.Current.Styles[0] = App.DefaultLight;
+ break;
+ case 3:
+ Application.Current.Styles[0] = App.DefaultDark;
break;
}
- };
- Styles.Add(light);
+ };
var decorations = this.Find("Decorations");
decorations.SelectionChanged += (sender, e) =>
@@ -63,13 +58,6 @@ namespace ControlCatalog
if (VisualRoot is Window window)
window.SystemDecorations = (SystemDecorations)decorations.SelectedIndex;
};
-
- var transparencyLevels = this.Find("TransparencyLevels");
- transparencyLevels.SelectionChanged += (sender, e) =>
- {
- if (VisualRoot is Window window)
- window.TransparencyLevelHint = (WindowTransparencyLevel)transparencyLevels.SelectedIndex;
- };
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
diff --git a/samples/ControlCatalog/MainWindow.xaml b/samples/ControlCatalog/MainWindow.xaml
index a0bb956425..97bd88f5e4 100644
--- a/samples/ControlCatalog/MainWindow.xaml
+++ b/samples/ControlCatalog/MainWindow.xaml
@@ -7,7 +7,12 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:ControlCatalog.ViewModels"
xmlns:v="clr-namespace:ControlCatalog.Views"
- x:Class="ControlCatalog.MainWindow" WindowState="{Binding WindowState, Mode=TwoWay}" Background="Transparent">
+ ExtendClientAreaToDecorationsHint="{Binding ExtendClientAreaEnabled}"
+ ExtendClientAreaChromeHints="{Binding ChromeHints}"
+ ExtendClientAreaTitleBarHeightHint="{Binding TitleBarHeight}"
+ TransparencyLevelHint="{Binding TransparencyLevel}"
+ x:Name="MainWindow"
+ x:Class="ControlCatalog.MainWindow" WindowState="{Binding WindowState, Mode=TwoWay}">
@@ -56,20 +61,30 @@
-
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Models/Person.cs b/samples/ControlCatalog/Models/Person.cs
index 4248cb8056..a0abcfe8f4 100644
--- a/samples/ControlCatalog/Models/Person.cs
+++ b/samples/ControlCatalog/Models/Person.cs
@@ -21,12 +21,12 @@ namespace ControlCatalog.Models
get => _firstName;
set
{
+ _firstName = value;
if (string.IsNullOrWhiteSpace(value))
SetError(nameof(FirstName), "First Name Required");
else
SetError(nameof(FirstName), null);
- _firstName = value;
OnPropertyChanged(nameof(FirstName));
}
@@ -37,12 +37,12 @@ namespace ControlCatalog.Models
get => _lastName;
set
{
+ _lastName = value;
if (string.IsNullOrWhiteSpace(value))
SetError(nameof(LastName), "Last Name Required");
else
SetError(nameof(LastName), null);
- _lastName = value;
OnPropertyChanged(nameof(LastName));
}
}
@@ -95,4 +95,4 @@ namespace ControlCatalog.Models
return null;
}
}
-}
\ No newline at end of file
+}
diff --git a/samples/ControlCatalog/Pages/AcrylicPage.xaml b/samples/ControlCatalog/Pages/AcrylicPage.xaml
new file mode 100644
index 0000000000..96cfcc5288
--- /dev/null
+++ b/samples/ControlCatalog/Pages/AcrylicPage.xaml
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/AcrylicPage.xaml.cs b/samples/ControlCatalog/Pages/AcrylicPage.xaml.cs
new file mode 100644
index 0000000000..44e7c4b92b
--- /dev/null
+++ b/samples/ControlCatalog/Pages/AcrylicPage.xaml.cs
@@ -0,0 +1,19 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace ControlCatalog.Pages
+{
+ public class AcrylicPage : UserControl
+ {
+ public AcrylicPage()
+ {
+ this.InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}
diff --git a/samples/ControlCatalog/Pages/BorderPage.xaml b/samples/ControlCatalog/Pages/BorderPage.xaml
index c30056d5e5..bfd14cc627 100644
--- a/samples/ControlCatalog/Pages/BorderPage.xaml
+++ b/samples/ControlCatalog/Pages/BorderPage.xaml
@@ -9,26 +9,33 @@
Margin="0,16,0,0"
HorizontalAlignment="Center"
Spacing="16">
-
+
Border
-
Border and Background
-
Rounded Corners
-
Rounded Corners
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/ButtonPage.xaml b/samples/ControlCatalog/Pages/ButtonPage.xaml
index 39d89590c2..a4427c70c5 100644
--- a/samples/ControlCatalog/Pages/ButtonPage.xaml
+++ b/samples/ControlCatalog/Pages/ButtonPage.xaml
@@ -9,10 +9,10 @@
Margin="0,16,0,0"
HorizontalAlignment="Center"
Spacing="16">
-
-
+
+
-
+
-
+
+
+
+
+
-
-
-
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/ButtonPage.xaml.cs b/samples/ControlCatalog/Pages/ButtonPage.xaml.cs
index 1d0c228a0e..5e555c8c91 100644
--- a/samples/ControlCatalog/Pages/ButtonPage.xaml.cs
+++ b/samples/ControlCatalog/Pages/ButtonPage.xaml.cs
@@ -5,5 +5,25 @@ namespace ControlCatalog.Pages
{
public class ButtonPage : UserControl
{
+ private int repeatButtonClickCount = 0;
+
+ public ButtonPage()
+ {
+ InitializeComponent();
+
+ this.FindControl("RepeatButton").Click += OnRepeatButtonClick;
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+
+ public void OnRepeatButtonClick(object sender, object args)
+ {
+ repeatButtonClickCount++;
+ var textBlock = this.FindControl("RepeatButtonTextBlock");
+ textBlock.Text = $"Repeat Button: {repeatButtonClickCount}";
+ }
}
}
diff --git a/samples/ControlCatalog/Pages/DatePickerPage.xaml b/samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml
similarity index 75%
rename from samples/ControlCatalog/Pages/DatePickerPage.xaml
rename to samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml
index 30d5a7506f..107472105a 100644
--- a/samples/ControlCatalog/Pages/DatePickerPage.xaml
+++ b/samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml
@@ -1,8 +1,8 @@
+ x:Class="ControlCatalog.Pages.CalendarDatePickerPage">
- DatePicker
+ CalendarDatePicker
A control for selecting dates with a calendar drop-down
-
-
-
-
-
-
-
+
diff --git a/samples/ControlCatalog/Pages/DatePickerPage.xaml.cs b/samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml.cs
similarity index 57%
rename from samples/ControlCatalog/Pages/DatePickerPage.xaml.cs
rename to samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml.cs
index ef01887c9e..95bdeb363a 100644
--- a/samples/ControlCatalog/Pages/DatePickerPage.xaml.cs
+++ b/samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml.cs
@@ -4,17 +4,17 @@ using System;
namespace ControlCatalog.Pages
{
- public class DatePickerPage : UserControl
+ public class CalendarDatePickerPage : UserControl
{
- public DatePickerPage()
+ public CalendarDatePickerPage()
{
InitializeComponent();
- var dp1 = this.FindControl("DatePicker1");
- var dp2 = this.FindControl("DatePicker2");
- var dp3 = this.FindControl("DatePicker3");
- var dp4 = this.FindControl("DatePicker4");
- var dp5 = this.FindControl("DatePicker5");
+ var dp1 = this.FindControl("DatePicker1");
+ var dp2 = this.FindControl("DatePicker2");
+ var dp3 = this.FindControl("DatePicker3");
+ var dp4 = this.FindControl("DatePicker4");
+ var dp5 = this.FindControl("DatePicker5");
dp1.SelectedDate = DateTime.Today;
dp2.SelectedDate = DateTime.Today.AddDays(10);
diff --git a/samples/ControlCatalog/Pages/ComboBoxPage.xaml b/samples/ControlCatalog/Pages/ComboBoxPage.xaml
index bbfbd4b4cd..369f703718 100644
--- a/samples/ControlCatalog/Pages/ComboBoxPage.xaml
+++ b/samples/ControlCatalog/Pages/ComboBoxPage.xaml
@@ -6,7 +6,7 @@
A drop-down list.
-
+
Inline Items
Inline Item 2
Inline Item 3
@@ -16,7 +16,7 @@
-
+
Control Items
diff --git a/samples/ControlCatalog/Pages/ContextMenuPage.xaml b/samples/ControlCatalog/Pages/ContextMenuPage.xaml
index 8f147638b5..8ccd8e97f7 100644
--- a/samples/ControlCatalog/Pages/ContextMenuPage.xaml
+++ b/samples/ControlCatalog/Pages/ContextMenuPage.xaml
@@ -9,7 +9,7 @@
Margin="0,16,0,0"
HorizontalAlignment="Center"
Spacing="16">
-
@@ -34,7 +34,7 @@
-
diff --git a/samples/ControlCatalog/Pages/DateTimePickerPage.xaml b/samples/ControlCatalog/Pages/DateTimePickerPage.xaml
new file mode 100644
index 0000000000..af6b6e8605
--- /dev/null
+++ b/samples/ControlCatalog/Pages/DateTimePickerPage.xaml
@@ -0,0 +1,123 @@
+
+
+ DatePicker and TimePicker
+
+
+
+
+ A simple DatePicker with a header
+
+
+
+
+
+
+
+
+ <DatePicker Header="Pick a date" />
+
+
+
+
+
+
+ A DatePicker with day formatted and year hidden.
+
+
+
+
+
+
+
+
+ <DatePicker DayFormat="d (ddd)" YearVisible="False" />
+
+
+
+
+
+
+
+
+ A simple TimePicker.
+
+
+
+
+
+
+
+
+ <TimePicker />
+
+
+
+
+
+
+ A TimePicker with a header and minute increments specified.
+
+
+
+
+
+
+
+
+ <TimePicker Header="Arrival time" MinuteIncrement="15" />
+
+
+
+
+
+
+ A TimePicker using a 12-hour clock.
+
+
+
+
+
+
+
+
+ <TimePicker ClockIdentifier="12HourClock" Header="12 hour clock" />
+
+
+
+
+
+
+ A TimePicker using a 24-hour clock.
+
+
+
+
+
+
+
+
+ <TimePicker ClockIdentifier="24HourClock" Header="24 hour clock" />
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/DateTimePickerPage.xaml.cs b/samples/ControlCatalog/Pages/DateTimePickerPage.xaml.cs
new file mode 100644
index 0000000000..6c7ae3437e
--- /dev/null
+++ b/samples/ControlCatalog/Pages/DateTimePickerPage.xaml.cs
@@ -0,0 +1,30 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace ControlCatalog.Pages
+{
+ public class DateTimePickerPage : UserControl
+ {
+ public DateTimePickerPage()
+ {
+ this.InitializeComponent();
+ this.FindControl("DatePickerDesc").Text = "Use a DatePicker to let users set a date in your app, " +
+ "for example to schedule an appointment. The DatePicker displays three controls for month, day, and year. " +
+ "These controls are easy to use with touch or mouse, and they can be styled and configured in several different ways. " +
+ "Order of month, day, and year is dynamically set based on user date settings";
+
+ this.FindControl("TimePickerDesc").Text = "Use a TimePicker to let users set a time in your app, for example " +
+ "to set a reminder. The TimePicker displays three controls for hour, minute, and AM / PM(if necessary).These controls " +
+ "are easy to use with touch or mouse, and they can be styled and configured in several different ways. " +
+ "12 - hour or 24 - hour clock and visiblility of AM / PM is dynamically set based on user time settings, or can be overridden.";
+
+
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}
diff --git a/samples/ControlCatalog/Pages/DialogsPage.xaml b/samples/ControlCatalog/Pages/DialogsPage.xaml
index 0834e829d8..a0e82663bf 100644
--- a/samples/ControlCatalog/Pages/DialogsPage.xaml
+++ b/samples/ControlCatalog/Pages/DialogsPage.xaml
@@ -11,5 +11,7 @@
+
+
diff --git a/samples/ControlCatalog/Pages/DialogsPage.xaml.cs b/samples/ControlCatalog/Pages/DialogsPage.xaml.cs
index dcb94a89e7..cf6c771e34 100644
--- a/samples/ControlCatalog/Pages/DialogsPage.xaml.cs
+++ b/samples/ControlCatalog/Pages/DialogsPage.xaml.cs
@@ -93,6 +93,21 @@ namespace ControlCatalog.Pages
window.ShowInTaskbar = false;
window.ShowDialog(GetWindow());
};
+ this.FindControl