diff --git a/.editorconfig b/.editorconfig
index f6bce9cb76..c7a381b730 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -156,6 +156,9 @@ indent_size = 2
[*.{props,targets,config,nuspec}]
indent_size = 2
+[*.json]
+indent_size = 2
+
# Shell scripts
[*.sh]
end_of_line = lf
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000000..80716520d9
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,31 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Desktop (please complete the following information):**
+ - OS: [e.g. Windows, Mac, Linux (State distribution)]
+ - Version [e.g. 0.10.0-rc1 or 0.9.12]
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000000..bbcbbe7d61
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.gitignore b/.gitignore
index b5a46e16f4..7d672c7755 100644
--- a/.gitignore
+++ b/.gitignore
@@ -117,6 +117,7 @@ ClientBin/
*.[Pp]ublish.xml
*.pfx
*.publishsettings
+Events_Avalonia.cs
# RIA/Silverlight projects
Generated_Code/
diff --git a/.gitmodules b/.gitmodules
index 10c780c09f..2d11fdfa9e 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -2,5 +2,5 @@
path = nukebuild/Numerge
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
+ path = src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github
+ url = https://github.com/kekekeks/XamlX.git
diff --git a/.ncrunch/Avalonia.Build.Tasks.v3.ncrunchproject b/.ncrunch/Avalonia.Build.Tasks.v3.ncrunchproject
index 319cd523ce..95a483b433 100644
--- a/.ncrunch/Avalonia.Build.Tasks.v3.ncrunchproject
+++ b/.ncrunch/Avalonia.Build.Tasks.v3.ncrunchproject
@@ -1,5 +1,3 @@
-
- True
-
+
\ No newline at end of file
diff --git a/.ncrunch/Avalonia.Controls.UnitTests.net47.v3.ncrunchproject b/.ncrunch/Avalonia.Controls.UnitTests.net47.v3.ncrunchproject
index e9d39b0c74..f30a20df78 100644
--- a/.ncrunch/Avalonia.Controls.UnitTests.net47.v3.ncrunchproject
+++ b/.ncrunch/Avalonia.Controls.UnitTests.net47.v3.ncrunchproject
@@ -3,5 +3,6 @@
MissingOrIgnoredProjectReference
+ Avalonia.Controls.UnitTests.TimePickerTests
\ No newline at end of file
diff --git a/.ncrunch/Avalonia.MicroCom.v3.ncrunchproject b/.ncrunch/Avalonia.MicroCom.v3.ncrunchproject
new file mode 100644
index 0000000000..319cd523ce
--- /dev/null
+++ b/.ncrunch/Avalonia.MicroCom.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ True
+
+
\ No newline at end of file
diff --git a/.ncrunch/BindingDemo.v3.ncrunchproject b/.ncrunch/BindingDemo.v3.ncrunchproject
new file mode 100644
index 0000000000..319cd523ce
--- /dev/null
+++ b/.ncrunch/BindingDemo.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ True
+
+
\ No newline at end of file
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/.ncrunch/RenderDemo.v3.ncrunchproject b/.ncrunch/RenderDemo.v3.ncrunchproject
new file mode 100644
index 0000000000..319cd523ce
--- /dev/null
+++ b/.ncrunch/RenderDemo.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ True
+
+
\ No newline at end of file
diff --git a/.ncrunch/Sandbox.v3.ncrunchproject b/.ncrunch/Sandbox.v3.ncrunchproject
new file mode 100644
index 0000000000..319cd523ce
--- /dev/null
+++ b/.ncrunch/Sandbox.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ True
+
+
\ No newline at end of file
diff --git a/.ncrunch/VirtualizationDemo.v3.ncrunchproject b/.ncrunch/VirtualizationDemo.v3.ncrunchproject
new file mode 100644
index 0000000000..319cd523ce
--- /dev/null
+++ b/.ncrunch/VirtualizationDemo.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ True
+
+
\ No newline at end of file
diff --git a/Avalonia.sln b/Avalonia.sln
index e40ebae4d6..75f1dd8407 100644
--- a/Avalonia.sln
+++ b/Avalonia.sln
@@ -87,16 +87,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "iOS", "iOS", "{0CB0B92E-6CF
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.iOS", "src\iOS\Avalonia.iOS\Avalonia.iOS.csproj", "{4488AD85-1495-4809-9AA4-DDFE0A48527E}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.iOSTestApplication", "src\iOS\Avalonia.iOSTestApplication\Avalonia.iOSTestApplication.csproj", "{8C923867-8A8F-4F6B-8B80-47D9E8436166}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.LeakTests", "tests\Avalonia.LeakTests\Avalonia.LeakTests.csproj", "{E1AA3DBF-9056-4530-9376-18119A7A3FFE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.UnitTests", "tests\Avalonia.UnitTests\Avalonia.UnitTests.csproj", "{88060192-33D5-4932-B0F9-8BD2763E857D}"
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}"
@@ -125,10 +121,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.NetCore", "s
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1-27F5-4255-9AFC-04ABFD11683A}"
ProjectSection(SolutionItems) = preProject
+ build\AndroidWorkarounds.props = build\AndroidWorkarounds.props
+ build\ApiDiff.props = build\ApiDiff.props
build\Base.props = build\Base.props
build\Binding.props = build\Binding.props
- build\BuildTargets.targets = build\BuildTargets.targets
+ build\CoreLibraries.props = build\CoreLibraries.props
+ build\EmbedXaml.props = build\EmbedXaml.props
build\HarfBuzzSharp.props = build\HarfBuzzSharp.props
+ build\iOSWorkarounds.props = build\iOSWorkarounds.props
build\JetBrains.Annotations.props = build\JetBrains.Annotations.props
build\JetBrains.dotMemoryUnit.props = build\JetBrains.dotMemoryUnit.props
build\Magick.NET-Q16-AnyCPU.props = build\Magick.NET-Q16-AnyCPU.props
@@ -138,17 +138,23 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1
build\NetCore.props = build\NetCore.props
build\NetFX.props = build\NetFX.props
build\ReactiveUI.props = build\ReactiveUI.props
+ build\ReferenceCoreLibraries.props = build\ReferenceCoreLibraries.props
build\Rx.props = build\Rx.props
build\SampleApp.props = build\SampleApp.props
- build\Serilog.props = build\Serilog.props
+ build\SharedVersion.props = build\SharedVersion.props
build\SharpDX.props = build\SharpDX.props
build\SkiaSharp.props = build\SkiaSharp.props
+ build\SourceLink.props = build\SourceLink.props
+ build\System.Drawing.Common.props = build\System.Drawing.Common.props
build\System.Memory.props = build\System.Memory.props
+ build\UnitTests.NetFX.props = build\UnitTests.NetFX.props
build\XUnit.props = build\XUnit.props
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{4D6FAF79-58B4-482F-9122-0668C346364C}"
ProjectSection(SolutionItems) = preProject
+ build\BuildTargets.targets = build\BuildTargets.targets
+ build\LegacyProject.targets = build\LegacyProject.targets
build\UnitTests.NetCore.targets = build\UnitTests.NetCore.targets
EndProjectSection
EndProject
@@ -204,14 +210,35 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Dialogs", "src\Ava
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.FreeDesktop", "src\Avalonia.FreeDesktop\Avalonia.FreeDesktop.csproj", "{4D36CEC8-53F2-40A5-9A37-79AAE356E2DA}"
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("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Headless", "src\Avalonia.Headless\Avalonia.Headless.csproj", "{8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Headless.Vnc", "src\Avalonia.Headless.Vnc\Avalonia.Headless.Vnc.csproj", "{B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Markup.Xaml.Loader", "src\Markup\Avalonia.Markup.Xaml.Loader\Avalonia.Markup.Xaml.Loader.csproj", "{909A8CBD-7D0E-42FD-B841-022AD8925820}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.ReactiveUI.Events", "src\Avalonia.ReactiveUI.Events\Avalonia.ReactiveUI.Events.csproj", "{28F18757-C3E6-4BBE-A37D-11BA2AB9177C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sandbox", "samples\Sandbox\Sandbox.csproj", "{11BE52AF-E2DD-4CF0-B19A-05285ACAF571}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MicroComGenerator", "src\tools\MicroComGenerator\MicroComGenerator.csproj", "{AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.MicroCom", "src\Avalonia.MicroCom\Avalonia.MicroCom.csproj", "{FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiniMvvm", "samples\MiniMvvm\MiniMvvm.csproj", "{BC594FD5-4AF2-409E-A1E6-04123F54D7C5}"
+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 = 4
- 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\RenderHelpers\RenderHelpers.projitems*{7d2d3083-71dd-4cc9-8907-39a0d86fb322}*SharedItemsImports = 4
- tests\Avalonia.RenderTests\Avalonia.RenderTests.projitems*{dabfd304-d6a4-4752-8123-c2ccf7ac7831}*SharedItemsImports = 4
+ src\Shared\RenderHelpers\RenderHelpers.projitems*{3e908f67-5543-4879-a1dc-08eace79b3cd}*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
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -931,26 +958,6 @@ Global
{4488AD85-1495-4809-9AA4-DDFE0A48527E}.Release|iPhone.Build.0 = Release|Any CPU
{4488AD85-1495-4809-9AA4-DDFE0A48527E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4488AD85-1495-4809-9AA4-DDFE0A48527E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.AppStore|iPhone.Build.0 = AppStore|iPhone
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.Debug|Any CPU.ActiveCfg = Debug|iPhone
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.Debug|iPhone.ActiveCfg = Debug|iPhone
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.Debug|iPhone.Build.0 = Debug|iPhone
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.Release|Any CPU.ActiveCfg = Release|iPhone
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.Release|iPhone.ActiveCfg = Release|iPhone
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.Release|iPhone.Build.0 = Release|iPhone
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
- {8C923867-8A8F-4F6B-8B80-47D9E8436166}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{E1AA3DBF-9056-4530-9376-18119A7A3FFE}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{E1AA3DBF-9056-4530-9376-18119A7A3FFE}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{E1AA3DBF-9056-4530-9376-18119A7A3FFE}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@@ -1023,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
@@ -1895,6 +1878,270 @@ Global
{4D36CEC8-53F2-40A5-9A37-79AAE356E2DA}.Release|iPhone.Build.0 = Release|Any CPU
{4D36CEC8-53F2-40A5-9A37-79AAE356E2DA}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4D36CEC8-53F2-40A5-9A37-79AAE356E2DA}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {351337F5-D66F-461B-A957-4EF60BDB4BA6}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {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
+ {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
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|Any CPU.Build.0 = Release|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|iPhone.Build.0 = Release|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {909A8CBD-7D0E-42FD-B841-022AD8925820}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|iPhone.Build.0 = Release|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {28F18757-C3E6-4BBE-A37D-11BA2AB9177C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.AppStore|Any CPU.Build.0 = Release|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.AppStore|iPhone.ActiveCfg = Release|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.AppStore|iPhone.Build.0 = Release|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Release|Any CPU.Build.0 = Release|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Release|iPhone.Build.0 = Release|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Release|iPhone.Build.0 = Release|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Release|iPhone.Build.0 = Release|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {FE2F3E5E-1E34-4972-8DC1-5C2C588E5ECE}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.AppStore|iPhone.Build.0 = Debug|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhone.Build.0 = Release|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1921,7 +2168,6 @@ Global
{7B92AF71-6287-4693-9DCB-BD5B6E927E23} = {7CF9789C-F1D3-4D0E-90E5-F1DF67A2753F}
{FF69B927-C545-49AE-8E16-3D14D621AA12} = {7CF9789C-F1D3-4D0E-90E5-F1DF67A2753F}
{4488AD85-1495-4809-9AA4-DDFE0A48527E} = {0CB0B92E-6CFF-4240-80A5-CCAFE75D91E1}
- {8C923867-8A8F-4F6B-8B80-47D9E8436166} = {0CB0B92E-6CFF-4240-80A5-CCAFE75D91E1}
{E1AA3DBF-9056-4530-9376-18119A7A3FFE} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{88060192-33D5-4932-B0F9-8BD2763E857D} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
@@ -1951,6 +2197,12 @@ Global
{41B02319-965D-4945-8005-C1A3D1224165} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B}
{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}
+ {909A8CBD-7D0E-42FD-B841-022AD8925820} = {8B6A8209-894F-4BA1-B880-965FD453982C}
+ {11BE52AF-E2DD-4CF0-B19A-05285ACAF571} = {9B9E3891-2366-4253-A952-D08BCEB71098}
+ {AEC9031E-06EA-4A9E-9E7F-7D7C719404DD} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
+ {BC594FD5-4AF2-409E-A1E6-04123F54D7C5} = {9B9E3891-2366-4253-A952-D08BCEB71098}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A}
diff --git a/Avalonia.sln.DotSettings b/Avalonia.sln.DotSettings
index 7060f4a62a..25d62b0494 100644
--- a/Avalonia.sln.DotSettings
+++ b/Avalonia.sln.DotSettings
@@ -37,4 +37,5 @@
<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
<Policy Inspect="False" Prefix="T" Suffix="" Style="AaBb" />
<Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" />
+ True
True
\ No newline at end of file
diff --git a/Avalonia.v3.ncrunchsolution b/Avalonia.v3.ncrunchsolution
index a2208a9a91..b97a8e54f5 100644
--- a/Avalonia.v3.ncrunchsolution
+++ b/Avalonia.v3.ncrunchsolution
@@ -3,8 +3,14 @@
tests\TestFiles\**.*
src\Avalonia.Build.Tasks\bin\Debug\netstandard2.0\Avalonia.Build.Tasks.dll
+ src\Avalonia.Build.Tasks\bin\Debug\netstandard2.0\Mono.Cecil.dll
+ src\Avalonia.Build.Tasks\bin\Debug\netstandard2.0\Mono.Cecil.Rocks.dll
+ src\Avalonia.Build.Tasks\bin\Debug\netstandard2.0\Mono.Cecil.Pdb.dll
True
+
+ RunApiCompat = false
+
.ncrunch
True
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index dc57a73f48..fde2931bf9 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -1,76 +1,130 @@
+
# Contributor Covenant Code of Conduct
## Our Pledge
-In the interest of fostering an open and welcoming environment, we as
-contributors and maintainers pledge to making participation in our project and
-our community a harassment-free experience for everyone, regardless of age, body
-size, disability, ethnicity, sex characteristics, gender identity and expression,
-level of experience, education, socio-economic status, nationality, personal
-appearance, race, religion, or sexual identity and orientation.
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
## Our Standards
-Examples of behavior that contributes to creating a positive environment
-include:
+Examples of behavior that contributes to a positive environment for our
+community include:
-* Using welcoming and inclusive language
-* Being respectful of differing viewpoints and experiences
-* Gracefully accepting constructive criticism
-* Focusing on what is best for the community
-* Showing empathy towards other community members
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+ overall community
-Examples of unacceptable behavior by participants include:
+Examples of unacceptable behavior include:
-* The use of sexualized language or imagery and unwelcome sexual attention or
- advances
-* Trolling, insulting/derogatory comments, and personal or political attacks
+* The use of sexualized language or imagery, and sexual attention or
+ advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
-* Publishing others' private information, such as a physical or electronic
- address, without explicit permission
+* Publishing others' private information, such as a physical or email
+ address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
- professional setting
+ professional setting
-## Our Responsibilities
+## Enforcement Responsibilities
-Project maintainers are responsible for clarifying the standards of acceptable
-behavior and are expected to take appropriate and fair corrective action in
-response to any instances of unacceptable behavior.
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
-Project maintainers have the right and responsibility to remove, edit, or
-reject comments, commits, code, wiki edits, issues, and other contributions
-that are not aligned to this Code of Conduct, or to ban temporarily or
-permanently any contributor for other behaviors that they deem inappropriate,
-threatening, offensive, or harmful.
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
## Scope
-This Code of Conduct applies both within project spaces and in public spaces
-when an individual is representing the project or its community. Examples of
-representing a project or community include using an official project e-mail
-address, posting via an official social media account, or acting as an appointed
-representative at an online or offline event. Representation of a project may be
-further defined and clarified by project maintainers.
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported by contacting the project team at steven@avaloniaui.net. All
-complaints will be reviewed and investigated and will result in a response that
-is deemed necessary and appropriate to the circumstances. The project team is
-obligated to maintain confidentiality with regard to the reporter of an incident.
-Further details of specific enforcement policies may be posted separately.
+reported to the community leaders responsible for enforcement at
+steven@avaloniaui.net.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
-Project maintainers who do not follow or enforce the Code of Conduct in good
-faith may face temporary or permanent repercussions as determined by other
-members of the project's leadership.
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
## Attribution
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
-available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
-For answers to common questions about this code of conduct, see
-https://www.contributor-covenant.org/faq
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at
+https://www.contributor-covenant.org/translations.
+
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000000..dcf95ce33c
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,69 @@
+# Contributing to Avalonia
+
+## Before You Start
+
+Drop into our [gitter chat room](https://gitter.im/AvaloniaUI/Avalonia) and let us know what you're thinking of doing. We might be able to give you guidance or let you know if someone else is already working on the feature.
+
+## Style
+
+The codebase uses [.net core](https://github.com/dotnet/runtime/blob/master/docs/coding-guidelines/coding-style.md) coding style.
+
+Try to keep lines of code around 100 characters in length or less, though this is not a hard limit.
+If you're a few characters over then don't worry too much.
+
+**DO NOT USE #REGIONS** full stop.
+
+## Pull requests
+
+A single pull request should be submitted for each change. If you're making more than one change,
+please submit separate pull requests for each change for easy review. Rebase your changes to make
+sense, so a history that looks like:
+
+* Add class A
+* Feature A didn't set Foo when Bar was set
+* Fix spacing
+* Add class B
+* Sort using statements
+
+Should be rebased to read:
+
+* Add class A
+* Add class B
+
+Again, this makes review much easier.
+
+Please try not to submit pull requests that don't add new features (e.g. moving stuff around)
+unless you see something that is obviously wrong or that could be written in a more terse or
+idiomatic style. It takes time to review each pull request - time that I'd prefer to spend writing
+new features!
+
+Prefer terseness to verbosity but don't try to be too clever.
+
+## Tests
+
+There are two types of tests currently in the codebase; unit tests and render tests.
+
+Unit tests should be contained in a class name that mirrors the class being tested with the suffix
+-Tests, e.g.
+
+ Avalonia.Controls.UnitTests.Presenters.TextPresenterTests
+
+Where Avalonia.Controls.UnitTests is the name of the project.
+
+Unit test methods should be named in a sentence style, separated by underscores, that describes in
+English what the test is testing, e.g.
+
+```csharp
+ void Calling_Foo_Should_Increment_Bar()
+```
+
+Render tests should describe what the produced image is:
+
+```csharp
+ void Rectangle_2px_Stroke_Filled()
+```
+
+## Code of Conduct
+
+This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community.
+For more information see the [Contributor Covenant Code of Conduct](https://dotnetfoundation.org/code-of-conduct)
diff --git a/Directory.Build.props b/Directory.Build.props
index 1f26df9bbc..c6610695c4 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,5 +1,8 @@
$(MSBuildThisFileDirectory)build-intermediate/nuget
+ $(MSBuildThisFileDirectory)\src\tools\Avalonia.Designer.HostApp\bin\$(Configuration)\netcoreapp2.0\Avalonia.Designer.HostApp.dll
+
+ false
diff --git a/Documentation/build.md b/Documentation/build.md
new file mode 100644
index 0000000000..5f75290424
--- /dev/null
+++ b/Documentation/build.md
@@ -0,0 +1,75 @@
+# Windows
+
+Avalonia requires at least Visual Studio 2019 and .NET Core SDK 3.1 to build on Windows.
+
+### Clone the Avalonia repository
+
+```
+git clone https://github.com/AvaloniaUI/Avalonia.git
+git submodule update --init
+```
+
+### Open in Visual Studio
+
+Open the `Avalonia.sln` solution in Visual Studio 2019 or newer. The free Visual Studio Community
+edition works fine. Run the `Samples\ControlCatalog.Desktop` project to see the sample application.
+
+# Linux/macOS
+
+It's *not* possible to build the *whole* project on Linux/macOS. You can only build the subset targeting .NET Standard and .NET Core (which is, however, sufficient to get UI working on Linux/macOS). If you want to something that involves changing platform-specific APIs you'll need a Windows machine.
+
+MonoDevelop, Xamarin Studio and Visual Studio for Mac aren't capable of properly opening our solution. You can use Rider (at least 2017.2 EAP) or VSCode instead. They will fail to load most of platform specific projects, but you don't need them to run on .NET Core.
+
+### Install the latest version of .NET Core
+
+Go to https://www.microsoft.com/net/core and follow instructions for your OS. You need SDK (not just "runtime") package.
+
+### Additional requirements for macOS
+
+The build process needs [Xcode](https://developer.apple.com/xcode/) to build the native library. Following the install instructions at the [Xcode](https://developer.apple.com/xcode/) website to properly install.
+
+Linux operating systems ship with their own respective package managers however we will use [Homebrew](https://brew.sh/) to manage packages on macOS. To install follow the instructions [here](https://docs.brew.sh/Installation).
+
+### Install CastXML (pre Nov 2020)
+
+Avalonia requires [CastXML](https://github.com/CastXML/CastXML) for XML processing during the build process. The easiest way to install this is via the operating system's package managers, such as below.
+
+On macOS:
+```
+brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/8a004a91a7fcd3f6620d5b01b6541ff0a640ffba/Formula/castxml.rb
+```
+
+On Debian based Linux (Debian, Ubuntu, Mint, etc):
+```
+sudo apt install castxml
+```
+
+On Red Hat based Linux (Fedora, CentOS, RHEL, etc) using `yum` (`dnf` takes same arguments though):
+```
+sudo yum install castxml
+```
+
+
+### Clone the Avalonia repository
+
+```
+git clone https://github.com/AvaloniaUI/Avalonia.git
+cd Avalonia
+git submodule update --init --recursive
+```
+
+### Build native libraries (macOS only)
+
+On macOS it is necessary to build and manually install the respective native libraries using [Xcode](https://developer.apple.com/xcode/). Execute the build script in the root project with the `CompileNative` task. It will build the headers, build the libraries, and place them in the appropriate place to allow .NET to find them at compilation and run time.
+
+```bash
+./build.sh CompileNative
+```
+
+### Build and Run Avalonia
+
+```
+cd samples/ControlCatalog.NetCore
+dotnet restore
+dotnet run
+```
diff --git a/NOTICE.md b/NOTICE.md
new file mode 100644
index 0000000000..92fd725957
--- /dev/null
+++ b/NOTICE.md
@@ -0,0 +1,305 @@
+# WPF
+
+https://github.com/dotnet/wpf
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+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.
+
+# SharpDX
+
+https://github.com/sharpdx/SharpDX
+
+Copyright (c) 2010-2014 SharpDX - Alexandre Mutel
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+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.
+
+# Silverlight Toolkit
+
+https://github.com/microsoftarchive/SilverlightToolkit
+
+Microsoft Public License (MS-PL)
+
+This license governs use of the accompanying software. If you use the software, you
+accept this license. If you do not accept the license, do not use the software.
+
+1. Definitions
+The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
+same meaning here as under U.S. copyright law.
+A "contribution" is the original software, or any additions or changes to the software.
+A "contributor" is any person that distributes its contribution under this license.
+"Licensed patents" are a contributor's patent claims that read directly on its contribution.
+
+2. Grant of Rights
+(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
+(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
+
+3. Conditions and Limitations
+(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
+(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
+(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
+(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
+(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
+
+# wayland-protocols
+
+https://github.com/wayland-project/wayland-protocols
+
+Copyright 2008-2013 Kristian Hgsberg
+Copyright 2010-2013 Intel Corporation
+Copyright 2013 Rafael Antognolli
+Copyright 2013 Jasper St. Pierre
+Copyright 2014 Jonas dahl
+Copyright 2014 Jason Ekstrand
+Copyright 2014-2015 Collabora, Ltd.
+Copyright 2015 Red Hat Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE 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.
+
+# Metsys.Bson
+
+Copyright (c) 2010, Karl Seguin - http://www.openmymind.net/
+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 the 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 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.
+
+# RichTextKit
+
+https://github.com/toptensoftware/RichTextKit
+
+Copyright 2019 Topten Software. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may
+not use this product except in compliance with the License. You may obtain
+a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations
+under the License.
+
+# Mono
+
+https://github.com/mono/mono
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE 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.
+
+# Collections.Pooled
+
+https://github.com/jtmueller/Collections.Pooled
+
+The MIT License (MIT)
+
+Copyright (c) Joel Mueller
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+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.
+
+# EllipticalArc.java
+
+http://www.spaceroots.org/documents/ellipse/EllipticalArc.java
+http://www.spaceroots.org/documents/ellipse/elliptical-arc.pdf
+
+Copyright (c) 2003-2004, Luc Maisonobe
+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 names of spaceroots.org, spaceroots.com
+ nor the names of their 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.
+
+# WinUI
+
+https://github.com/microsoft/microsoft-ui-xaml
+
+MIT License
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+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/NuGet.Config b/NuGet.Config
index 2a1e0af74d..7a1f28bea7 100644
--- a/NuGet.Config
+++ b/NuGet.Config
@@ -1,7 +1,9 @@
+
+
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 603308ef9a..15392278c9 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -3,18 +3,11 @@ jobs:
pool:
vmImage: 'ubuntu-16.04'
steps:
- - task: CmdLine@2
- displayName: 'Install CastXML'
- inputs:
- script: |
- sudo apt-get update
- sudo apt-get install castxml
-
- task: CmdLine@2
displayName: 'Install Nuke'
inputs:
script: |
- dotnet tool install --global Nuke.GlobalTool --version 0.12.3
+ dotnet tool install --global Nuke.GlobalTool --version 0.24.0
- task: CmdLine@2
displayName: 'Run Nuke'
inputs:
@@ -31,12 +24,15 @@ jobs:
condition: not(canceled())
- job: macOS
+ variables:
+ SolutionDir: '$(Build.SourcesDirectory)'
pool:
- vmImage: 'macOS-10.14'
+ vmImage: 'macOS-10.15'
steps:
- - task: DotNetCoreInstaller@0
+ - task: UseDotNet@2
+ displayName: 'Use .NET Core SDK 3.1.401'
inputs:
- version: '2.1.403'
+ version: 3.1.401
- task: CmdLine@2
displayName: 'Install Mono 5.18'
@@ -45,28 +41,27 @@ jobs:
curl -o ./mono.pkg https://download.mono-project.com/archive/5.18.0/macos-10-universal/MonoFramework-MDK-5.18.0.225.macos10.xamarin.universal.pkg
sudo installer -verbose -pkg ./mono.pkg -target /
+ - task: CmdLine@2
+ displayName: 'Generate avalonia-native'
+ inputs:
+ script: |
+ cd src/tools/MicroComGenerator; dotnet run -i ../../Avalonia.Native/avn.idl --cpp ../../../native/Avalonia.Native/inc/avalonia-native.h
+
- task: Xcode@5
inputs:
actions: 'build'
scheme: ''
- sdk: 'macosx10.14'
+ sdk: 'macosx11.0'
configuration: 'Release'
xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace'
- xcodeVersion: '10' # Options: 8, 9, default, specifyPath
+ xcodeVersion: '12' # Options: 8, 9, default, specifyPath
args: '-derivedDataPath ./'
- - task: CmdLine@2
- displayName: 'Install CastXML'
- inputs:
- script: |
- brew update
- brew install castxml
-
- task: CmdLine@2
displayName: 'Install Nuke'
inputs:
script: |
- dotnet tool install --global Nuke.GlobalTool --version 0.12.3
+ dotnet tool install --global Nuke.GlobalTool --version 0.24.0
- task: CmdLine@2
displayName: 'Run Nuke'
@@ -80,7 +75,7 @@ jobs:
export PATH="$PATH:$HOME/.dotnet/tools"
dotnet --info
printenv
- nuke --target CiAzureOSX --configuration Release
+ nuke --target CiAzureOSX --configuration Release --skip-previewer
- task: PublishTestResults@2
inputs:
@@ -103,12 +98,19 @@ jobs:
- job: Windows
pool:
vmImage: 'windows-2019'
+ variables:
+ SolutionDir: '$(Build.SourcesDirectory)'
steps:
+ - task: UseDotNet@2
+ displayName: 'Use .NET Core SDK 3.1.401'
+ inputs:
+ version: 3.1.401
+
- task: CmdLine@2
displayName: 'Install Nuke'
inputs:
script: |
- dotnet tool install --global Nuke.GlobalTool --version 0.12.3
+ dotnet tool install --global Nuke.GlobalTool --version 0.24.0
- task: CmdLine@2
displayName: 'Run Nuke'
diff --git a/build.ps1 b/build.ps1
index 57e2f80075..985e8abcee 100644
--- a/build.ps1
+++ b/build.ps1
@@ -43,7 +43,7 @@ if (Test-Path $DotNetGlobalFile) {
}
# If dotnet is installed locally, and expected version is not set or installation matches the expected version
-if ((Get-Command "dotnet" -ErrorAction SilentlyContinue) -ne $null -and `
+if ($null -ne (Get-Command "dotnet" -ErrorAction SilentlyContinue) -and `
(!(Test-Path variable:DotNetVersion) -or $(& dotnet --version) -eq $DotNetVersion)) {
$env:DOTNET_EXE = (Get-Command "dotnet").Path
}
@@ -53,7 +53,7 @@ else {
# Download install script
$DotNetInstallFile = "$TempDirectory\dotnet-install.ps1"
- md -force $TempDirectory > $null
+ mkdir -force $TempDirectory > $null
(New-Object System.Net.WebClient).DownloadFile($DotNetInstallUrl, $DotNetInstallFile)
# Install by channel or version
@@ -62,6 +62,8 @@ else {
} else {
ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath }
}
+
+ $env:PATH="$DotNetDirectory;$env:PATH"
}
Write-Output "Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)"
diff --git a/build.sh b/build.sh
index 40b1c225a6..bd162fab9b 100755
--- a/build.sh
+++ b/build.sh
@@ -47,7 +47,7 @@ if [ -f "$DOTNET_GLOBAL_FILE" ]; then
fi
# If dotnet is installed locally, and expected version is not set or installation matches the expected version
-if [[ -x "$(command -v dotnet)" && (-z ${DOTNET_VERSION+x} || $(dotnet --version) == "$DOTNET_VERSION") ]]; then
+if [[ -x "$(command -v dotnet)" && (-z ${DOTNET_VERSION+x} || $(dotnet --version) == "$DOTNET_VERSION") || "$SKIP_DOTNET_DOWNLOAD" == "1" ]]; then
export DOTNET_EXE="$(command -v dotnet)"
else
DOTNET_DIRECTORY="$TEMP_DIRECTORY/dotnet-unix"
@@ -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/ApiDiff.props b/build/ApiDiff.props
new file mode 100644
index 0000000000..da59ad4bf2
--- /dev/null
+++ b/build/ApiDiff.props
@@ -0,0 +1,12 @@
+
+
+ 0.10.0-rc1
+ $(PackageId)
+ Avalonia
+
+
+
+
+
+
+
diff --git a/build/Assets/Icon.png b/build/Assets/Icon.png
new file mode 100644
index 0000000000..41a2a618fb
Binary files /dev/null and b/build/Assets/Icon.png differ
diff --git a/build/CoreLibraries.props b/build/CoreLibraries.props
index 3923bdeeda..fff00041c3 100644
--- a/build/CoreLibraries.props
+++ b/build/CoreLibraries.props
@@ -4,18 +4,18 @@
-
-
+
+
diff --git a/build/EmbedXaml.props b/build/EmbedXaml.props
index 7ce0366dea..0bb8da4f47 100644
--- a/build/EmbedXaml.props
+++ b/build/EmbedXaml.props
@@ -4,8 +4,9 @@
%(Filename)
+
Designer
-
\ No newline at end of file
+
diff --git a/build/HarfBuzzSharp.props b/build/HarfBuzzSharp.props
index f8767c7599..e636461ad9 100644
--- a/build/HarfBuzzSharp.props
+++ b/build/HarfBuzzSharp.props
@@ -1,6 +1,6 @@
-
-
+
+
diff --git a/build/MicroCom.targets b/build/MicroCom.targets
new file mode 100644
index 0000000000..b48e377fd4
--- /dev/null
+++ b/build/MicroCom.targets
@@ -0,0 +1,33 @@
+
+
+
+
+
+ false
+ all
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_AvaloniaPatchComInterop>true
+
+
+
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/NetFX.props b/build/NetFX.props
index ed5cb6dd69..8ffc9ec561 100644
--- a/build/NetFX.props
+++ b/build/NetFX.props
@@ -1,7 +1,7 @@
-
+
diff --git a/build/ReactiveUI.props b/build/ReactiveUI.props
index f827cb9a32..f74ab07e31 100644
--- a/build/ReactiveUI.props
+++ b/build/ReactiveUI.props
@@ -1,5 +1,5 @@
-
+
diff --git a/build/Rx.props b/build/Rx.props
index edff0af160..fde1f80ea1 100644
--- a/build/Rx.props
+++ b/build/Rx.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/SharedVersion.props b/build/SharedVersion.props
index 44d5c239ef..43ec995ed9 100644
--- a/build/SharedVersion.props
+++ b/build/SharedVersion.props
@@ -2,18 +2,25 @@
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
Avalonia
- 0.8.999
- Copyright 2019 © The AvaloniaUI Project
+ 0.10.999
+ Copyright 2020 © The AvaloniaUI Project
https://avaloniaui.net
https://github.com/AvaloniaUI/Avalonia/
true
CS1591
latest
MIT
- https://avatars2.githubusercontent.com/u/14075148?s=200
+ Icon.png
Avalonia is a WPF/UWP-inspired 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 and with experimental support for Android and iOS.
avalonia;avaloniaui;mvvm;rx;reactive extensions;android;ios;mac;forms;wpf;net;netstandard;net461;uwp;xamarin
https://github.com/AvaloniaUI/Avalonia/releases
git
+ $(MSBuildThisFileDirectory)\avalonia.snk
+ true
+ $(DefineConstants);SIGNED_BUILD
+
+
+
+
diff --git a/build/SkiaSharp.props b/build/SkiaSharp.props
index 796bd8e596..f2e7df36cd 100644
--- a/build/SkiaSharp.props
+++ b/build/SkiaSharp.props
@@ -1,6 +1,6 @@
-
-
+
+
diff --git a/build/SourceLink.props b/build/SourceLink.props
index 0c9b6a34f8..e27727c9e8 100644
--- a/build/SourceLink.props
+++ b/build/SourceLink.props
@@ -1,5 +1,5 @@
-
+
-
\ No newline at end of file
+
diff --git a/build/XUnit.props b/build/XUnit.props
index 079565d184..a75e1bac86 100644
--- a/build/XUnit.props
+++ b/build/XUnit.props
@@ -11,4 +11,8 @@
+
+ $(MSBuildThisFileDirectory)\avalonia.snk
+ False
+
diff --git a/build/avalonia.snk b/build/avalonia.snk
new file mode 100644
index 0000000000..10b49deb31
Binary files /dev/null and b/build/avalonia.snk differ
diff --git a/build/iOSWorkarounds.props b/build/iOSWorkarounds.props
deleted file mode 100644
index fe46295770..0000000000
--- a/build/iOSWorkarounds.props
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
- $(MSBuildToolsPath)\..\Roslyn
-
-
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/dirs.proj b/dirs.proj
index 4b3b1183f0..594f2c22d3 100644
--- a/dirs.proj
+++ b/dirs.proj
@@ -6,20 +6,22 @@
-
+
+
-
+
+
diff --git a/global.json b/global.json
index 1e599211d4..b2b2da7c4f 100644
--- a/global.json
+++ b/global.json
@@ -1,7 +1,10 @@
{
+ "sdk": {
+ "version": "3.1.401"
+ },
"msbuild-sdks": {
"Microsoft.Build.Traversal": "1.0.43",
- "MSBuild.Sdk.Extras": "2.0.46",
+ "MSBuild.Sdk.Extras": "2.0.54",
"AggregatePackage.NuGet.Sdk" : "0.1.12"
}
}
diff --git a/licence.md b/licence.md
index d730e936db..d18aef99ad 100644
--- a/licence.md
+++ b/licence.md
@@ -1,6 +1,7 @@
The MIT License (MIT)
-Copyright (c) 2014 Steven Kirk
+Copyright (c) .NET Foundation and Contributors
+All Rights Reserved
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +19,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
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.
\ No newline at end of file
+SOFTWARE.
diff --git a/native/Avalonia.Native/inc/.gitignore b/native/Avalonia.Native/inc/.gitignore
new file mode 100644
index 0000000000..e7aa7fc6a5
--- /dev/null
+++ b/native/Avalonia.Native/inc/.gitignore
@@ -0,0 +1 @@
+avalonia-native.h
diff --git a/native/Avalonia.Native/inc/avalonia-native-guids.h b/native/Avalonia.Native/inc/avalonia-native-guids.h
index 439008fd4b..64fec729a2 100644
--- a/native/Avalonia.Native/inc/avalonia-native-guids.h
+++ b/native/Avalonia.Native/inc/avalonia-native-guids.h
@@ -1,5 +1,2 @@
-// Copyright (c) The Avalonia Project. All rights reserved.
-// Licensed under the MIT license. See licence.md file in the project root for full license information.
-
#define COM_GUIDS_MATERIALIZE
#include "avalonia-native.h"
diff --git a/native/Avalonia.Native/inc/avalonia-native.h b/native/Avalonia.Native/inc/avalonia-native.h
deleted file mode 100644
index f1c7664c3e..0000000000
--- a/native/Avalonia.Native/inc/avalonia-native.h
+++ /dev/null
@@ -1,401 +0,0 @@
-// Copyright (c) The Avalonia Project. All rights reserved.
-// Licensed under the MIT license. See licence.md file in the project root for full license information.
-
-#include "com.h"
-#include "key.h"
-
-#define AVNCOM(name, id) COMINTERFACE(name, 2e2cda0a, 9ae5, 4f1b, 8e, 20, 08, 1a, 04, 27, 9f, id)
-
-struct IAvnWindowEvents;
-struct IAvnWindow;
-struct IAvnPopup;
-struct IAvnMacOptions;
-struct IAvnPlatformThreadingInterface;
-struct IAvnSystemDialogEvents;
-struct IAvnSystemDialogs;
-struct IAvnScreens;
-struct IAvnClipboard;
-struct IAvnCursor;
-struct IAvnCursorFactory;
-struct IAvnGlFeature;
-struct IAvnGlContext;
-struct IAvnGlDisplay;
-struct IAvnGlSurfaceRenderTarget;
-struct IAvnGlSurfaceRenderingSession;
-struct IAvnAppMenu;
-struct IAvnAppMenuItem;
-
-struct AvnSize
-{
- double Width, Height;
-};
-
-struct AvnPixelSize
-{
- int Width, Height;
-};
-
-struct AvnRect
-{
- double X, Y, Width, Height;
-};
-
-struct AvnVector
-{
- double X, Y;
-};
-
-struct AvnPoint
-{
- double X, Y;
-};
-
-struct AvnScreen
-{
- AvnRect Bounds;
- AvnRect WorkingArea;
- float PixelDensity;
- bool Primary;
-};
-
-enum AvnPixelFormat
-{
- kAvnRgb565,
- kAvnRgba8888,
- kAvnBgra8888
-};
-
-struct AvnFramebuffer
-{
- void* Data;
- int Width;
- int Height;
- int Stride;
- AvnVector Dpi;
- AvnPixelFormat PixelFormat;
-};
-
-struct AvnColor
-{
- unsigned char Alpha;
- unsigned char Red;
- unsigned char Green;
- unsigned char Blue;
-};
-
-enum AvnRawMouseEventType
-{
- LeaveWindow,
- LeftButtonDown,
- LeftButtonUp,
- RightButtonDown,
- RightButtonUp,
- MiddleButtonDown,
- MiddleButtonUp,
- Move,
- Wheel,
- NonClientLeftButtonDown
-};
-
-enum AvnRawKeyEventType
-{
- KeyDown,
- KeyUp
-};
-
-enum AvnInputModifiers
-{
- AvnInputModifiersNone = 0,
- Alt = 1,
- Control = 2,
- Shift = 4,
- Windows = 8,
- LeftMouseButton = 16,
- RightMouseButton = 32,
- MiddleMouseButton = 64
-};
-
-enum AvnWindowState
-{
- Normal,
- Minimized,
- Maximized,
-};
-
-enum AvnStandardCursorType
-{
- CursorArrow,
- CursorIbeam,
- CursorWait,
- CursorCross,
- CursorUpArrow,
- CursorSizeWestEast,
- CursorSizeNorthSouth,
- CursorSizeAll,
- CursorNo,
- CursorHand,
- CursorAppStarting,
- CursorHelp,
- CursorTopSide,
- CursorBottomSize,
- CursorLeftSide,
- CursorRightSide,
- CursorTopLeftCorner,
- CursorTopRightCorner,
- CursorBottomLeftCorner,
- CursorBottomRightCorner,
- CursorDragMove,
- CursorDragCopy,
- CursorDragLink,
- CursorNone
-};
-
-enum AvnWindowEdge
-{
- WindowEdgeNorthWest,
- WindowEdgeNorth,
- WindowEdgeNorthEast,
- WindowEdgeWest,
- WindowEdgeEast,
- WindowEdgeSouthWest,
- WindowEdgeSouth,
- WindowEdgeSouthEast
-};
-
-AVNCOM(IAvaloniaNativeFactory, 01) : IUnknown
-{
-public:
- virtual HRESULT Initialize() = 0;
- virtual IAvnMacOptions* GetMacOptions() = 0;
- virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnWindow** ppv) = 0;
- virtual HRESULT CreatePopup (IAvnWindowEvents* cb, IAvnPopup** ppv) = 0;
- virtual HRESULT CreatePlatformThreadingInterface(IAvnPlatformThreadingInterface** ppv) = 0;
- virtual HRESULT CreateSystemDialogs (IAvnSystemDialogs** ppv) = 0;
- virtual HRESULT CreateScreens (IAvnScreens** ppv) = 0;
- virtual HRESULT CreateClipboard(IAvnClipboard** ppv) = 0;
- virtual HRESULT CreateCursorFactory(IAvnCursorFactory** ppv) = 0;
- virtual HRESULT ObtainGlFeature(IAvnGlFeature** ppv) = 0;
- virtual HRESULT ObtainAppMenu(IAvnAppMenu** retOut) = 0;
- virtual HRESULT SetAppMenu(IAvnAppMenu* menu) = 0;
- virtual HRESULT CreateMenu (IAvnAppMenu** ppv) = 0;
- virtual HRESULT CreateMenuItem (IAvnAppMenuItem** ppv) = 0;
- virtual HRESULT CreateMenuItemSeperator (IAvnAppMenuItem** ppv) = 0;
-};
-
-AVNCOM(IAvnString, 17) : IUnknown
-{
- virtual HRESULT Pointer(void**retOut) = 0;
- virtual HRESULT Length(int*ret) = 0;
-};
-
-AVNCOM(IAvnWindowBase, 02) : IUnknown
-{
- virtual HRESULT Show() = 0;
- virtual HRESULT Hide () = 0;
- virtual HRESULT Close() = 0;
- virtual HRESULT Activate () = 0;
- virtual HRESULT GetClientSize(AvnSize*ret) = 0;
- virtual HRESULT GetScaling(double*ret)=0;
- virtual HRESULT SetMinMaxSize(AvnSize minSize, AvnSize maxSize) = 0;
- virtual HRESULT Resize(double width, double height) = 0;
- virtual HRESULT Invalidate (AvnRect rect) = 0;
- virtual HRESULT BeginMoveDrag () = 0;
- virtual HRESULT BeginResizeDrag (AvnWindowEdge edge) = 0;
- virtual HRESULT GetPosition (AvnPoint*ret) = 0;
- virtual HRESULT SetPosition (AvnPoint point) = 0;
- virtual HRESULT PointToClient (AvnPoint point, AvnPoint*ret) = 0;
- virtual HRESULT PointToScreen (AvnPoint point, AvnPoint*ret) = 0;
- virtual HRESULT ThreadSafeSetSwRenderedFrame(AvnFramebuffer* fb, IUnknown* dispose) = 0;
- virtual HRESULT SetTopMost (bool value) = 0;
- virtual HRESULT SetCursor(IAvnCursor* cursor) = 0;
- virtual HRESULT CreateGlRenderTarget(IAvnGlSurfaceRenderTarget** ret) = 0;
- virtual HRESULT GetSoftwareFramebuffer(AvnFramebuffer*ret) = 0;
- virtual HRESULT SetMainMenu(IAvnAppMenu* menu) = 0;
- virtual HRESULT ObtainMainMenu(IAvnAppMenu** retOut) = 0;
- virtual bool TryLock() = 0;
- virtual void Unlock() = 0;
-};
-
-AVNCOM(IAvnPopup, 03) : virtual IAvnWindowBase
-{
-
-};
-
-AVNCOM(IAvnWindow, 04) : virtual IAvnWindowBase
-{
- virtual HRESULT ShowDialog (IAvnWindow* parent) = 0;
- virtual HRESULT SetCanResize(bool value) = 0;
- virtual HRESULT SetHasDecorations(bool value) = 0;
- virtual HRESULT SetTitle (void* utf8Title) = 0;
- virtual HRESULT SetTitleBarColor (AvnColor color) = 0;
- virtual HRESULT SetWindowState(AvnWindowState state) = 0;
- virtual HRESULT GetWindowState(AvnWindowState*ret) = 0;
-};
-
-AVNCOM(IAvnWindowBaseEvents, 05) : IUnknown
-{
- virtual HRESULT Paint() = 0;
- virtual void Closed() = 0;
- virtual void Activated() = 0;
- virtual void Deactivated() = 0;
- virtual void Resized(const AvnSize& size) = 0;
- virtual void PositionChanged (AvnPoint position) = 0;
- virtual void RawMouseEvent (AvnRawMouseEventType type,
- unsigned int timeStamp,
- AvnInputModifiers modifiers,
- AvnPoint point,
- AvnVector delta) = 0;
- virtual bool RawKeyEvent (AvnRawKeyEventType type, unsigned int timeStamp, AvnInputModifiers modifiers, unsigned int key) = 0;
- virtual bool RawTextInputEvent (unsigned int timeStamp, const char* text) = 0;
- virtual void ScalingChanged(double scaling) = 0;
- virtual void RunRenderPriorityJobs() = 0;
-};
-
-
-AVNCOM(IAvnWindowEvents, 06) : IAvnWindowBaseEvents
-{
- /**
- * Closing Event
- * Called when the user presses the OS window close button.
- * return true to allow the close, return false to prevent close.
- */
- virtual bool Closing () = 0;
-
- virtual void WindowStateChanged (AvnWindowState state) = 0;
-};
-
-AVNCOM(IAvnMacOptions, 07) : IUnknown
-{
- virtual HRESULT SetShowInDock(int show) = 0;
- virtual HRESULT SetApplicationTitle (void* utf8string) = 0;
-};
-
-AVNCOM(IAvnActionCallback, 08) : IUnknown
-{
- virtual void Run() = 0;
-};
-
-AVNCOM(IAvnSignaledCallback, 09) : IUnknown
-{
- virtual void Signaled(int priority, bool priorityContainsMeaningfulValue) = 0;
-};
-
-AVNCOM(IAvnLoopCancellation, 0a) : IUnknown
-{
- virtual void Cancel() = 0;
-};
-
-AVNCOM(IAvnPlatformThreadingInterface, 0b) : IUnknown
-{
- virtual bool GetCurrentThreadIsLoopThread() = 0;
- virtual void SetSignaledCallback(IAvnSignaledCallback* cb) = 0;
- virtual IAvnLoopCancellation* CreateLoopCancellation() = 0;
- virtual HRESULT RunLoop(IAvnLoopCancellation* cancel) = 0;
- // Can't pass int* to sharpgentools for some reason
- virtual void Signal(int priority) = 0;
- virtual IUnknown* StartTimer(int priority, int ms, IAvnActionCallback* callback) = 0;
-};
-
-AVNCOM(IAvnSystemDialogEvents, 0c) : IUnknown
-{
- virtual void OnCompleted (int numResults, void* ptrFirstResult) = 0;
-};
-
-AVNCOM(IAvnSystemDialogs, 0d) : IUnknown
-{
- virtual void SelectFolderDialog (IAvnWindow* parentWindowHandle,
- IAvnSystemDialogEvents* events,
- const char* title,
- const char* initialPath) = 0;
-
- virtual void OpenFileDialog (IAvnWindow* parentWindowHandle,
- IAvnSystemDialogEvents* events,
- bool allowMultiple,
- const char* title,
- const char* initialDirectory,
- const char* initialFile,
- const char* filters) = 0;
-
- virtual void SaveFileDialog (IAvnWindow* parentWindowHandle,
- IAvnSystemDialogEvents* events,
- const char* title,
- const char* initialDirectory,
- const char* initialFile,
- const char* filters) = 0;
-};
-
-AVNCOM(IAvnScreens, 0e) : IUnknown
-{
- virtual HRESULT GetScreenCount (int* ret) = 0;
- virtual HRESULT GetScreen (int index, AvnScreen* ret) = 0;
-};
-
-AVNCOM(IAvnClipboard, 0f) : IUnknown
-{
- virtual HRESULT GetText (IAvnString**ppv) = 0;
- virtual HRESULT SetText (void* utf8Text) = 0;
- virtual HRESULT Clear() = 0;
-};
-
-AVNCOM(IAvnCursor, 10) : IUnknown
-{
-};
-
-AVNCOM(IAvnCursorFactory, 11) : IUnknown
-{
- virtual HRESULT GetCursor (AvnStandardCursorType cursorType, IAvnCursor** retOut) = 0;
-};
-
-
-AVNCOM(IAvnGlFeature, 12) : IUnknown
-{
- virtual HRESULT ObtainDisplay(IAvnGlDisplay**retOut) = 0;
- virtual HRESULT ObtainImmediateContext(IAvnGlContext**retOut) = 0;
-};
-
-AVNCOM(IAvnGlDisplay, 13) : IUnknown
-{
- virtual HRESULT GetSampleCount(int* ret) = 0;
- virtual HRESULT GetStencilSize(int* ret) = 0;
- virtual HRESULT ClearContext() = 0;
- virtual void* GetProcAddress(char* proc) = 0;
-};
-
-AVNCOM(IAvnGlContext, 14) : IUnknown
-{
- virtual HRESULT MakeCurrent() = 0;
-};
-
-AVNCOM(IAvnGlSurfaceRenderTarget, 15) : IUnknown
-{
- virtual HRESULT BeginDrawing(IAvnGlSurfaceRenderingSession** ret) = 0;
-};
-
-AVNCOM(IAvnGlSurfaceRenderingSession, 16) : IUnknown
-{
- virtual HRESULT GetPixelSize(AvnPixelSize* ret) = 0;
- virtual HRESULT GetScaling(double* ret) = 0;
-};
-
-AVNCOM(IAvnAppMenu, 17) : IUnknown
-{
- virtual HRESULT AddItem (IAvnAppMenuItem* item) = 0;
- virtual HRESULT RemoveItem (IAvnAppMenuItem* item) = 0;
- virtual HRESULT SetTitle (void* utf8String) = 0;
- virtual HRESULT Clear () = 0;
-};
-
-AVNCOM(IAvnPredicateCallback, 18) : IUnknown
-{
- virtual bool Evaluate() = 0;
-};
-
-AVNCOM(IAvnAppMenuItem, 19) : IUnknown
-{
- virtual HRESULT SetSubMenu (IAvnAppMenu* menu) = 0;
- virtual HRESULT SetTitle (void* utf8String) = 0;
- virtual HRESULT SetGesture (void* utf8String, AvnInputModifiers modifiers) = 0;
- virtual HRESULT SetAction (IAvnPredicateCallback* predicate, IAvnActionCallback* callback) = 0;
-};
-
-extern "C" IAvaloniaNativeFactory* CreateAvaloniaNative();
diff --git a/native/Avalonia.Native/inc/com.h b/native/Avalonia.Native/inc/com.h
index 22fb4a11a3..df251514ef 100644
--- a/native/Avalonia.Native/inc/com.h
+++ b/native/Avalonia.Native/inc/com.h
@@ -1,6 +1,3 @@
-// Copyright (c) The Avalonia Project. All rights reserved.
-// Licensed under the MIT license. See licence.md file in the project root for full license information.
-
#pragma clang diagnostic push
#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection"
#ifndef COM_H_INCLUDED
diff --git a/native/Avalonia.Native/inc/comimpl.h b/native/Avalonia.Native/inc/comimpl.h
index cf1aa4c735..0ff64b7215 100644
--- a/native/Avalonia.Native/inc/comimpl.h
+++ b/native/Avalonia.Native/inc/comimpl.h
@@ -162,6 +162,19 @@ public:
return _obj;
}
+ TInterface* getRetainedReference()
+ {
+ if(_obj == NULL)
+ return NULL;
+ _obj->AddRef();
+ return _obj;
+ }
+
+ TInterface** getPPV()
+ {
+ return &_obj;
+ }
+
operator TInterface*() const
{
return _obj;
diff --git a/native/Avalonia.Native/inc/key.h b/native/Avalonia.Native/inc/key.h
deleted file mode 100644
index cdc9658e29..0000000000
--- a/native/Avalonia.Native/inc/key.h
+++ /dev/null
@@ -1,1023 +0,0 @@
-// Copyright (c) The Avalonia Project. All rights reserved.
-// Licensed under the MIT license. See licence.md file in the project root for full license information.
-
-#ifndef _KEY_H_
-#define _KEY_H_
-
-///
-/// Defines the keys available on a keyboard.
-///
-enum AvnKey
-{
- ///
- /// No key pressed.
- ///
- AvnKeyNone = 0,
-
- ///
- /// The Cancel key.
- ///
- AvnKeyCancel = 1,
-
- ///
- /// The Back key.
- ///
- AvnKeyBack = 2,
-
- ///
- /// The Tab key.
- ///
- AvnKeyTab = 3,
-
- ///
- /// The Linefeed key.
- ///
- AvnKeyLineFeed = 4,
-
- ///
- /// The Clear key.
- ///
- AvnKeyClear = 5,
-
- ///
- /// The Return key.
- ///
- AvnKeyReturn = 6,
-
- ///
- /// The Enter key.
- ///
- AvnKeyEnter = 6,
-
- ///
- /// The Pause key.
- ///
- AvnKeyPause = 7,
-
- ///
- /// The Caps Lock key.
- ///
- AvnKeyCapsLock = 8,
-
- ///
- /// The Caps Lock key.
- ///
- AvnKeyCapital = 8,
-
- ///
- /// The IME Hangul mode key.
- ///
- AvnKeyHangulMode = 9,
-
- ///
- /// The IME Kana mode key.
- ///
- AvnKeyKanaMode = 9,
-
- ///
- /// The IME Junja mode key.
- ///
- AvnKeyJunjaMode = 10,
-
- ///
- /// The IME Final mode key.
- ///
- AvnKeyFinalMode = 11,
-
- ///
- /// The IME Kanji mode key.
- ///
- AvnKeyKanjiMode = 12,
-
- ///
- /// The IME Hanja mode key.
- ///
- HanjaMode = 12,
-
- ///
- /// The Escape key.
- ///
- Escape = 13,
-
- ///
- /// The IME Convert key.
- ///
- ImeConvert = 14,
-
- ///
- /// The IME NonConvert key.
- ///
- ImeNonConvert = 15,
-
- ///
- /// The IME Accept key.
- ///
- ImeAccept = 16,
-
- ///
- /// The IME Mode change key.
- ///
- ImeModeChange = 17,
-
- ///
- /// The space bar.
- ///
- Space = 18,
-
- ///
- /// The Page Up key.
- ///
- PageUp = 19,
-
- ///
- /// The Page Up key.
- ///
- Prior = 19,
-
- ///
- /// The Page Down key.
- ///
- PageDown = 20,
-
- ///
- /// The Page Down key.
- ///
- Next = 20,
-
- ///
- /// The End key.
- ///
- End = 21,
-
- ///
- /// The Home key.
- ///
- Home = 22,
-
- ///
- /// The Left arrow key.
- ///
- Left = 23,
-
- ///
- /// The Up arrow key.
- ///
- Up = 24,
-
- ///
- /// The Right arrow key.
- ///
- Right = 25,
-
- ///
- /// The Down arrow key.
- ///
- Down = 26,
-
- ///
- /// The Select key.
- ///
- Select = 27,
-
- ///
- /// The Print key.
- ///
- Print = 28,
-
- ///
- /// The Execute key.
- ///
- Execute = 29,
-
- ///
- /// The Print Screen key.
- ///
- Snapshot = 30,
-
- ///
- /// The Print Screen key.
- ///
- PrintScreen = 30,
-
- ///
- /// The Insert key.
- ///
- Insert = 31,
-
- ///
- /// The Delete key.
- ///
- Delete = 32,
-
- ///
- /// The Help key.
- ///
- Help = 33,
-
- ///
- /// The 0 key.
- ///
- D0 = 34,
-
- ///
- /// The 1 key.
- ///
- D1 = 35,
-
- ///
- /// The 2 key.
- ///
- D2 = 36,
-
- ///
- /// The 3 key.
- ///
- D3 = 37,
-
- ///
- /// The 4 key.
- ///
- D4 = 38,
-
- ///
- /// The 5 key.
- ///
- D5 = 39,
-
- ///
- /// The 6 key.
- ///
- D6 = 40,
-
- ///
- /// The 7 key.
- ///
- D7 = 41,
-
- ///
- /// The 8 key.
- ///
- D8 = 42,
-
- ///
- /// The 9 key.
- ///
- D9 = 43,
-
- ///
- /// The A key.
- ///
- A = 44,
-
- ///
- /// The B key.
- ///
- B = 45,
-
- ///
- /// The C key.
- ///
- C = 46,
-
- ///
- /// The D key.
- ///
- D = 47,
-
- ///
- /// The E key.
- ///
- E = 48,
-
- ///
- /// The F key.
- ///
- F = 49,
-
- ///
- /// The G key.
- ///
- G = 50,
-
- ///
- /// The H key.
- ///
- H = 51,
-
- ///
- /// The I key.
- ///
- I = 52,
-
- ///
- /// The J key.
- ///
- J = 53,
-
- ///
- /// The K key.
- ///
- AvnKeyK = 54,
-
- ///
- /// The L key.
- ///
- L = 55,
-
- ///
- /// The M key.
- ///
- M = 56,
-
- ///
- /// The N key.
- ///
- N = 57,
-
- ///
- /// The O key.
- ///
- O = 58,
-
- ///
- /// The P key.
- ///
- P = 59,
-
- ///
- /// The Q key.
- ///
- Q = 60,
-
- ///
- /// The R key.
- ///
- R = 61,
-
- ///
- /// The S key.
- ///
- S = 62,
-
- ///
- /// The T key.
- ///
- T = 63,
-
- ///
- /// The U key.
- ///
- U = 64,
-
- ///
- /// The V key.
- ///
- V = 65,
-
- ///
- /// The W key.
- ///
- W = 66,
-
- ///
- /// The X key.
- ///
- X = 67,
-
- ///
- /// The Y key.
- ///
- Y = 68,
-
- ///
- /// The Z key.
- ///
- Z = 69,
-
- ///
- /// The left Windows key.
- ///
- LWin = 70,
-
- ///
- /// The right Windows key.
- ///
- RWin = 71,
-
- ///
- /// The Application key.
- ///
- Apps = 72,
-
- ///
- /// The Sleep key.
- ///
- Sleep = 73,
-
- ///
- /// The 0 key on the numeric keypad.
- ///
- NumPad0 = 74,
-
- ///
- /// The 1 key on the numeric keypad.
- ///
- NumPad1 = 75,
-
- ///
- /// The 2 key on the numeric keypad.
- ///
- NumPad2 = 76,
-
- ///
- /// The 3 key on the numeric keypad.
- ///
- NumPad3 = 77,
-
- ///
- /// The 4 key on the numeric keypad.
- ///
- NumPad4 = 78,
-
- ///
- /// The 5 key on the numeric keypad.
- ///
- NumPad5 = 79,
-
- ///
- /// The 6 key on the numeric keypad.
- ///
- NumPad6 = 80,
-
- ///
- /// The 7 key on the numeric keypad.
- ///
- NumPad7 = 81,
-
- ///
- /// The 8 key on the numeric keypad.
- ///
- NumPad8 = 82,
-
- ///
- /// The 9 key on the numeric keypad.
- ///
- NumPad9 = 83,
-
- ///
- /// The Multiply key.
- ///
- Multiply = 84,
-
- ///
- /// The Add key.
- ///
- Add = 85,
-
- ///
- /// The Separator key.
- ///
- Separator = 86,
-
- ///
- /// The Subtract key.
- ///
- Subtract = 87,
-
- ///
- /// The Decimal key.
- ///
- Decimal = 88,
-
- ///
- /// The Divide key.
- ///
- Divide = 89,
-
- ///
- /// The F1 key.
- ///
- F1 = 90,
-
- ///
- /// The F2 key.
- ///
- F2 = 91,
-
- ///
- /// The F3 key.
- ///
- F3 = 92,
-
- ///
- /// The F4 key.
- ///
- F4 = 93,
-
- ///
- /// The F5 key.
- ///
- F5 = 94,
-
- ///
- /// The F6 key.
- ///
- F6 = 95,
-
- ///
- /// The F7 key.
- ///
- F7 = 96,
-
- ///
- /// The F8 key.
- ///
- F8 = 97,
-
- ///
- /// The F9 key.
- ///
- F9 = 98,
-
- ///
- /// The F10 key.
- ///
- F10 = 99,
-
- ///
- /// The F11 key.
- ///
- F11 = 100,
-
- ///
- /// The F12 key.
- ///
- F12 = 101,
-
- ///
- /// The F13 key.
- ///
- F13 = 102,
-
- ///
- /// The F14 key.
- ///
- F14 = 103,
-
- ///
- /// The F15 key.
- ///
- F15 = 104,
-
- ///
- /// The F16 key.
- ///
- F16 = 105,
-
- ///
- /// The F17 key.
- ///
- F17 = 106,
-
- ///
- /// The F18 key.
- ///
- F18 = 107,
-
- ///
- /// The F19 key.
- ///
- F19 = 108,
-
- ///
- /// The F20 key.
- ///
- F20 = 109,
-
- ///
- /// The F21 key.
- ///
- F21 = 110,
-
- ///
- /// The F22 key.
- ///
- F22 = 111,
-
- ///
- /// The F23 key.
- ///
- F23 = 112,
-
- ///
- /// The F24 key.
- ///
- F24 = 113,
-
- ///
- /// The Numlock key.
- ///
- NumLock = 114,
-
- ///
- /// The Scroll key.
- ///
- Scroll = 115,
-
- ///
- /// The left Shift key.
- ///
- LeftShift = 116,
-
- ///
- /// The right Shift key.
- ///
- RightShift = 117,
-
- ///
- /// The left Ctrl key.
- ///
- LeftCtrl = 118,
-
- ///
- /// The right Ctrl key.
- ///
- RightCtrl = 119,
-
- ///
- /// The left Alt key.
- ///
- LeftAlt = 120,
-
- ///
- /// The right Alt key.
- ///
- RightAlt = 121,
-
- ///
- /// The browser Back key.
- ///
- BrowserBack = 122,
-
- ///
- /// The browser Forward key.
- ///
- BrowserForward = 123,
-
- ///
- /// The browser Refresh key.
- ///
- BrowserRefresh = 124,
-
- ///
- /// The browser Stop key.
- ///
- BrowserStop = 125,
-
- ///
- /// The browser Search key.
- ///
- BrowserSearch = 126,
-
- ///
- /// The browser Favorites key.
- ///
- BrowserFavorites = 127,
-
- ///
- /// The browser Home key.
- ///
- BrowserHome = 128,
-
- ///
- /// The Volume Mute key.
- ///
- VolumeMute = 129,
-
- ///
- /// The Volume Down key.
- ///
- VolumeDown = 130,
-
- ///
- /// The Volume Up key.
- ///
- VolumeUp = 131,
-
- ///
- /// The media Next Track key.
- ///
- MediaNextTrack = 132,
-
- ///
- /// The media Previous Track key.
- ///
- MediaPreviousTrack = 133,
-
- ///
- /// The media Stop key.
- ///
- MediaStop = 134,
-
- ///
- /// The media Play/Pause key.
- ///
- MediaPlayPause = 135,
-
- ///
- /// The Launch Mail key.
- ///
- LaunchMail = 136,
-
- ///
- /// The Select Media key.
- ///
- SelectMedia = 137,
-
- ///
- /// The Launch Application 1 key.
- ///
- LaunchApplication1 = 138,
-
- ///
- /// The Launch Application 2 key.
- ///
- LaunchApplication2 = 139,
-
- ///
- /// The OEM Semicolon key.
- ///
- OemSemicolon = 140,
-
- ///
- /// The OEM 1 key.
- ///
- Oem1 = 140,
-
- ///
- /// The OEM Plus key.
- ///
- OemPlus = 141,
-
- ///
- /// The OEM Comma key.
- ///
- OemComma = 142,
-
- ///
- /// The OEM Minus key.
- ///
- OemMinus = 143,
-
- ///
- /// The OEM Period key.
- ///
- OemPeriod = 144,
-
- ///
- /// The OEM Question Mark key.
- ///
- OemQuestion = 145,
-
- ///
- /// The OEM 2 key.
- ///
- Oem2 = 145,
-
- ///
- /// The OEM Tilde key.
- ///
- OemTilde = 146,
-
- ///
- /// The OEM 3 key.
- ///
- Oem3 = 146,
-
- ///
- /// The ABNT_C1 (Brazilian) key.
- ///
- AbntC1 = 147,
-
- ///
- /// The ABNT_C2 (Brazilian) key.
- ///
- AbntC2 = 148,
-
- ///
- /// The OEM Open Brackets key.
- ///
- OemOpenBrackets = 149,
-
- ///
- /// The OEM 4 key.
- ///
- Oem4 = 149,
-
- ///
- /// The OEM Pipe key.
- ///
- OemPipe = 150,
-
- ///
- /// The OEM 5 key.
- ///
- Oem5 = 150,
-
- ///
- /// The OEM Close Brackets key.
- ///
- OemCloseBrackets = 151,
-
- ///
- /// The OEM 6 key.
- ///
- Oem6 = 151,
-
- ///
- /// The OEM Quotes key.
- ///
- OemQuotes = 152,
-
- ///
- /// The OEM 7 key.
- ///
- Oem7 = 152,
-
- ///
- /// The OEM 8 key.
- ///
- Oem8 = 153,
-
- ///
- /// The OEM Backslash key.
- ///
- OemBackslash = 154,
-
- ///
- /// The OEM 3 key.
- ///
- Oem102 = 154,
-
- ///
- /// A special key masking the real key being processed by an IME.
- ///
- ImeProcessed = 155,
-
- ///
- /// A special key masking the real key being processed as a system key.
- ///
- System = 156,
-
- ///
- /// The OEM ATTN key.
- ///
- OemAttn = 157,
-
- ///
- /// The DBE_ALPHANUMERIC key.
- ///
- DbeAlphanumeric = 157,
-
- ///
- /// The OEM Finish key.
- ///
- OemFinish = 158,
-
- ///
- /// The DBE_KATAKANA key.
- ///
- DbeKatakana = 158,
-
- ///
- /// The DBE_HIRAGANA key.
- ///
- DbeHiragana = 159,
-
- ///
- /// The OEM Copy key.
- ///
- OemCopy = 159,
-
- ///
- /// The DBE_SBCSCHAR key.
- ///
- DbeSbcsChar = 160,
-
- ///
- /// The OEM Auto key.
- ///
- OemAuto = 160,
-
- ///
- /// The DBE_DBCSCHAR key.
- ///
- DbeDbcsChar = 161,
-
- ///
- /// The OEM ENLW key.
- ///
- OemEnlw = 161,
-
- ///
- /// The OEM BackTab key.
- ///
- OemBackTab = 162,
-
- ///
- /// The DBE_ROMAN key.
- ///
- DbeRoman = 162,
-
- ///
- /// The DBE_NOROMAN key.
- ///
- DbeNoRoman = 163,
-
- ///
- /// The ATTN key.
- ///
- Attn = 163,
-
- ///
- /// The CRSEL key.
- ///
- CrSel = 164,
-
- ///
- /// The DBE_ENTERWORDREGISTERMODE key.
- ///
- DbeEnterWordRegisterMode = 164,
-
- ///
- /// The EXSEL key.
- ///
- ExSel = 165,
-
- ///
- /// The DBE_ENTERIMECONFIGMODE key.
- ///
- DbeEnterImeConfigureMode = 165,
-
- ///
- /// The ERASE EOF Key.
- ///
- EraseEof = 166,
-
- ///
- /// The DBE_FLUSHSTRING key.
- ///
- DbeFlushString = 166,
-
- ///
- /// The Play key.
- ///
- Play = 167,
-
- ///
- /// The DBE_CODEINPUT key.
- ///
- DbeCodeInput = 167,
-
- ///
- /// The DBE_NOCODEINPUT key.
- ///
- DbeNoCodeInput = 168,
-
- ///
- /// The Zoom key.
- ///
- Zoom = 168,
-
- ///
- /// Reserved for future use.
- ///
- NoName = 169,
-
- ///
- /// The DBE_DETERMINESTRING key.
- ///
- DbeDetermineString = 169,
-
- ///
- /// The DBE_ENTERDLGCONVERSIONMODE key.
- ///
- DbeEnterDialogConversionMode = 170,
-
- ///
- /// The PA1 key.
- ///
- Pa1 = 170,
-
- ///
- /// The OEM Clear key.
- ///
- OemClear = 171,
-
- ///
- /// The key is used with another key to create a single combined character.
- ///
- DeadCharProcessed = 172,
-};
-
-#endif
diff --git a/native/Avalonia.Native/inc/rendertarget.h b/native/Avalonia.Native/inc/rendertarget.h
new file mode 100644
index 0000000000..2b0338d099
--- /dev/null
+++ b/native/Avalonia.Native/inc/rendertarget.h
@@ -0,0 +1,12 @@
+
+@protocol IRenderTarget
+-(void) setNewLayer: (CALayer*) layer;
+-(HRESULT) setSwFrame: (AvnFramebuffer*) fb;
+-(void) resize: (AvnPixelSize) size withScale: (float) scale;
+-(AvnPixelSize) pixelSize;
+-(IAvnGlSurfaceRenderTarget*) createSurfaceRenderTarget;
+@end
+
+@interface IOSurfaceRenderTarget : NSObject
+-(IOSurfaceRenderTarget*) initWithOpenGlContext: (IAvnGlContext*) context;
+@end
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 c0a49382a7..dba3ee6d31 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
@@ -8,17 +8,24 @@
/* Begin PBXBuildFile section */
1A002B9E232135EE00021753 /* app.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A002B9D232135EE00021753 /* app.mm */; };
+ 1A1852DC23E05814008F0DED /* deadlock.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A1852DB23E05814008F0DED /* deadlock.mm */; };
+ 1A3E5EA823E9E83B00EDE661 /* rendertarget.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A3E5EA723E9E83B00EDE661 /* rendertarget.mm */; };
+ 1A3E5EAA23E9F26C00EDE661 /* IOSurface.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A3E5EA923E9F26C00EDE661 /* IOSurface.framework */; };
+ 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 */; };
+ 1AFD334123E03C4F0042899B /* controlhost.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1AFD334023E03C4F0042899B /* controlhost.mm */; };
37155CE4233C00EB0034DCE9 /* menu.h in Headers */ = {isa = PBXBuildFile; fileRef = 37155CE3233C00EB0034DCE9 /* menu.h */; };
37A517B32159597E00FBA241 /* Screens.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37A517B22159597E00FBA241 /* Screens.mm */; };
37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37C09D8721580FE4006A6758 /* SystemDialogs.mm */; };
37DDA9B0219330F8002E132B /* AvnString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37DDA9AF219330F8002E132B /* AvnString.mm */; };
37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37E2330E21583241000CB7E2 /* KeyTransform.mm */; };
520624B322973F4100C4DCEF /* menu.mm in Sources */ = {isa = PBXBuildFile; fileRef = 520624B222973F4100C4DCEF /* menu.mm */; };
+ 522D5959258159C1006F7F7A /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 522D5958258159C1006F7F7A /* Carbon.framework */; };
5B21A982216530F500CEE36E /* cursor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B21A981216530F500CEE36E /* cursor.mm */; };
5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */; };
AB00E4F72147CA920032A60A /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB00E4F62147CA920032A60A /* main.mm */; };
AB1E522C217613570091CD71 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB1E522B217613570091CD71 /* OpenGL.framework */; };
- AB573DC4217605E400D389A2 /* gl.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB573DC3217605E400D389A2 /* gl.mm */; };
AB661C1E2148230F00291242 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB661C1D2148230F00291242 /* AppKit.framework */; };
AB661C202148286E00291242 /* window.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB661C1F2148286E00291242 /* window.mm */; };
AB8F7D6B21482D7F0057DBA5 /* platformthreading.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB8F7D6A21482D7F0057DBA5 /* platformthreading.mm */; };
@@ -26,6 +33,13 @@
/* Begin PBXFileReference section */
1A002B9D232135EE00021753 /* app.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = app.mm; sourceTree = ""; };
+ 1A1852DB23E05814008F0DED /* deadlock.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = deadlock.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; };
+ 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 = ""; };
+ 1AFD334023E03C4F0042899B /* controlhost.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = controlhost.mm; sourceTree = ""; };
37155CE3233C00EB0034DCE9 /* menu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = menu.h; sourceTree = ""; };
379860FE214DA0C000CD0246 /* KeyTransform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyTransform.h; sourceTree = ""; };
37A4E71A2178846A00EACBCD /* headers */ = {isa = PBXFileReference; lastKnownFileType = folder; name = headers; path = ../../inc; sourceTree = ""; };
@@ -36,12 +50,12 @@
37DDA9B121933371002E132B /* AvnString.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AvnString.h; sourceTree = ""; };
37E2330E21583241000CB7E2 /* KeyTransform.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyTransform.mm; sourceTree = ""; };
520624B222973F4100C4DCEF /* menu.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = menu.mm; sourceTree = ""; };
+ 522D5958258159C1006F7F7A /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
5B21A981216530F500CEE36E /* cursor.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = cursor.mm; sourceTree = ""; };
5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = clipboard.mm; sourceTree = ""; };
5BF943652167AD1D009CAE35 /* cursor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cursor.h; sourceTree = ""; };
AB00E4F62147CA920032A60A /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; };
AB1E522B217613570091CD71 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
- AB573DC3217605E400D389A2 /* gl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = gl.mm; sourceTree = ""; };
AB661C1D2148230F00291242 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
AB661C1F2148286E00291242 /* window.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = window.mm; sourceTree = ""; };
AB661C212148288600291242 /* common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = ""; };
@@ -54,7 +68,10 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 1A3E5EB023E9FE8300EDE661 /* QuartzCore.framework in Frameworks */,
+ 1A3E5EAA23E9F26C00EDE661 /* IOSurface.framework in Frameworks */,
AB1E522C217613570091CD71 /* OpenGL.framework in Frameworks */,
+ 522D5959258159C1006F7F7A /* Carbon.framework in Frameworks */,
AB661C1E2148230F00291242 /* AppKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -65,6 +82,9 @@
AB661C1C2148230E00291242 /* Frameworks */ = {
isa = PBXGroup;
children = (
+ 522D5958258159C1006F7F7A /* Carbon.framework */,
+ 1A3E5EAF23E9FE8300EDE661 /* QuartzCore.framework */,
+ 1A3E5EA923E9F26C00EDE661 /* IOSurface.framework */,
AB1E522B217613570091CD71 /* OpenGL.framework */,
AB661C1D2148230F00291242 /* AppKit.framework */,
);
@@ -74,14 +94,17 @@
AB7A61E62147C814003C5833 = {
isa = PBXGroup;
children = (
+ 1A1852DB23E05814008F0DED /* deadlock.mm */,
1A002B9D232135EE00021753 /* app.mm */,
37DDA9B121933371002E132B /* AvnString.h */,
37DDA9AF219330F8002E132B /* AvnString.mm */,
37A4E71A2178846A00EACBCD /* headers */,
- AB573DC3217605E400D389A2 /* gl.mm */,
+ 1A3E5EAD23E9FB1300EDE661 /* cgl.mm */,
+ 1AFD334023E03C4F0042899B /* controlhost.mm */,
5BF943652167AD1D009CAE35 /* cursor.h */,
5B21A981216530F500CEE36E /* cursor.mm */,
5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */,
+ 1A465D0F246AB61600C5858B /* dnd.mm */,
AB8F7D6A21482D7F0057DBA5 /* platformthreading.mm */,
AB661C212148288600291242 /* common.h */,
379860FE214DA0C000CD0246 /* KeyTransform.h */,
@@ -91,6 +114,7 @@
AB00E4F62147CA920032A60A /* main.mm */,
37155CE3233C00EB0034DCE9 /* menu.h */,
520624B222973F4100C4DCEF /* menu.mm */,
+ 1A3E5EA723E9E83B00EDE661 /* rendertarget.mm */,
37A517B22159597E00FBA241 /* Screens.mm */,
37C09D8721580FE4006A6758 /* SystemDialogs.mm */,
AB7A61F02147C815003C5833 /* Products */,
@@ -177,15 +201,19 @@
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 */,
+ 1A3E5EA823E9E83B00EDE661 /* rendertarget.mm in Sources */,
+ 1A3E5EAE23E9FB1300EDE661 /* cgl.mm in Sources */,
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 */,
- AB573DC4217605E400D389A2 /* gl.mm in Sources */,
AB661C202148286E00291242 /* window.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
diff --git a/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/xcshareddata/xcschemes/Avalonia.Native.OSX.xcscheme b/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/xcshareddata/xcschemes/Avalonia.Native.OSX.xcscheme
index 1a665d3ea5..5d20a135b9 100644
--- a/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/xcshareddata/xcschemes/Avalonia.Native.OSX.xcscheme
+++ b/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/xcshareddata/xcschemes/Avalonia.Native.OSX.xcscheme
@@ -29,8 +29,6 @@
shouldUseLaunchSchemeArgsEnv = "YES">
-
-
-
-
* 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 b62fe8a968..00b748ef63 100644
--- a/native/Avalonia.Native/src/OSX/AvnString.mm
+++ b/native/Avalonia.Native/src/OSX/AvnString.mm
@@ -7,6 +7,7 @@
//
#include "common.h"
+#include
class AvnStringImpl : public virtual ComSingleObject
{
@@ -28,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);
@@ -61,7 +69,60 @@ public:
}
};
+class AvnStringArrayImpl : public virtual ComSingleObject
+{
+private:
+ std::vector> _list;
+public:
+ FORWARD_IUNKNOWN()
+ AvnStringArrayImpl(NSArray* array)
+ {
+ for(int c = 0; c < [array count]; c++)
+ {
+ ComPtr s;
+ *s.getPPV() = new AvnStringImpl([array objectAtIndex:c]);
+ _list.push_back(s);
+ }
+ }
+
+ AvnStringArrayImpl(NSString* string)
+ {
+ ComPtr s;
+ *s.getPPV() = new AvnStringImpl(string);
+ _list.push_back(s);
+ }
+
+ virtual unsigned int GetCount() override
+ {
+ return (unsigned int)_list.size();
+ }
+
+ virtual HRESULT Get(unsigned int index, IAvnString**ppv) override
+ {
+ if(_list.size() <= index)
+ return E_INVALIDARG;
+ *ppv = _list[index].getRetainedReference();
+ return S_OK;
+ }
+};
+
IAvnString* CreateAvnString(NSString* string)
{
return new AvnStringImpl(string);
}
+
+
+IAvnStringArray* CreateAvnStringArray(NSArray * array)
+{
+ return new AvnStringArrayImpl(array);
+}
+
+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/KeyTransform.h b/native/Avalonia.Native/src/OSX/KeyTransform.h
index c4466020c3..2f434570c9 100644
--- a/native/Avalonia.Native/src/OSX/KeyTransform.h
+++ b/native/Avalonia.Native/src/OSX/KeyTransform.h
@@ -1,12 +1,14 @@
-// Copyright (c) The Avalonia Project. All rights reserved.
-// Licensed under the MIT license. See licence.md file in the project root for full license information.
-
#ifndef keytransform_h
#define keytransform_h
#include "common.h"
-#include "key.h"
#include
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 512b35a454..cfa08149cb 100644
--- a/readme.md
+++ b/readme.md
@@ -1,28 +1,26 @@
-
+[](https://gitter.im/AvaloniaUI/Avalonia?utm_campaign=pr-badge&utm_content=badge&utm_medium=badge&utm_source=badge) []( https://aka.ms/dotnet-discord) [](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 WPF/UWP-inspired 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 and with experimental support for Android and iOS.
+
-**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. To see the status of some of our features, please see our [Roadmap here](https://github.com/AvaloniaUI/Avalonia/issues/2239).
+([Xaml Control Gallery](https://github.com/AvaloniaUI/xamlcontrolsgallery))
-| Control catalog | Desktop platforms | Mobile platforms |
-|---|---|---|
-|
|
|
|
+> **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.
-## Getting Started
+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!
-Avalonia [Visual Studio Extension](https://marketplace.visualstudio.com/items?itemName=AvaloniaTeam.AvaloniaforVisualStudio) contains project and control templates that will help you get started. After installing it, open "New Project" dialog in Visual Studio, choose "Avalonia" in "Visual C#" section, select "Avalonia .NET Core Application" and press OK (screenshot). Now you can write code and markup that will work on multiple platforms!
+## 🚀 Getting Started
-For those without Visual Studio, a starter guide for .NET Core CLI can be found [here](http://avaloniaui.net/docs/quickstart/create-new-project#net-core).
+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 starter guide see our [documentation](https://avaloniaui.net/docs/quickstart/create-new-project).
-Avalonia is delivered via NuGet package manager. You can find the packages here: ([stable(ish)](https://www.nuget.org/packages/Avalonia/), [nightly](https://github.com/AvaloniaUI/Avalonia/wiki/Using-nightly-build-feed))
+Avalonia is delivered via NuGet package manager. You can find the packages here: https://www.nuget.org/packages/Avalonia/
Use these commands in the Package Manager console to install Avalonia manually:
```
@@ -30,32 +28,57 @@ Install-Package Avalonia
Install-Package Avalonia.Desktop
```
-## Bleeding Edge Builds
+## Showcase
-or use nightly build feeds as described here:
-https://github.com/AvaloniaUI/Avalonia/wiki/Using-nightly-build-feed
+Examples of UIs built with Avalonia
+
-## Documentation
+([Synfonia](https://github.com/jmacato/Synfonia))
+
+
+([Xaml Control Gallery](https://github.com/AvaloniaUI/xamlcontrolsgallery))
+
+
+([Xaml Control Gallery](https://github.com/AvaloniaUI/xamlcontrolsgallery))
+
+
+([Xaml Control Gallery](https://github.com/AvaloniaUI/xamlcontrolsgallery))
-You can take a look at the [getting started page](http://avaloniaui.net/docs/quickstart/) for an overview of how to get started but probably the best thing to do for now is to already know a little bit about WPF/Silverlight/UWP/XAML and ask questions in our [Gitter room](https://gitter.im/AvaloniaUI/Avalonia).
+## JetBrains Rider
-There's also a high-level [architecture document](http://avaloniaui.net/architecture/project-structure) that is currently a little bit out of date, and I've also started writing blog posts on Avalonia at http://grokys.github.io/.
+[JetBrains Rider](https://www.jetbrains.com/rider/whatsnew/?mkt_tok=eyJpIjoiTURBNU1HSmhNV0kwTUdFMiIsInQiOiJtNnU2VEc1TlNLa1ZRVkROYmdZYVpYREJsaU1qdUhmS3dxSzRHczdYWHl0RVlTNDMwSFwvNUs3VENTNVM0bVcyNFdaRmVYZzVWTTF1N3VrQWNGTkJreEhlam1hMlB4UVVWcHBGM1dNOUxoXC95YnRQdGgyUXl1YmZCM3h3d3BVWWdBIn0%3D#avalonia-support) now has official support for Avalonia.
-Contributions for our docs are always welcome!
+Code completion, inspections and refactorings are supported out of the box, for XAML previewer add `https://plugins.jetbrains.com/plugins/dev/14839` to plugin repositories and install [AvaloniaRider](https://github.com/ForNeVeR/AvaloniaRider) plugin.
+
+## Bleeding Edge Builds
+
+We also have a [nightly build](https://github.com/AvaloniaUI/Avalonia/wiki/Using-nightly-build-feed) which tracks the current state of master. Although these packages are less stable than the release on NuGet.org, you'll get all the latest features and bugfixes right away and many of our users actually prefer this feed!
+
+## Documentation
+
+Documentation can be found on our website at https://avaloniaui.net/docs/. We also have a [tutorial](https://avaloniaui.net/docs/tutorial/) over there for newcomers.
## Building and Using
-See the [build instructions here](http://avaloniaui.net/contributing/build).
+See the [build instructions here](Documentation/build.md).
## Contributing
-Please read the [contribution guidelines](http://avaloniaui.net/contributing/contributing) before submitting a pull request.
+Please read the [contribution guidelines](CONTRIBUTING.md) before submitting a pull request.
-### Contributors
+## Code of Conduct
-This project exists thanks to all the people who contribute. [[Contribute](http://avaloniaui.net/contributing/contributing)].
-
+This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community.
+For more information see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).
+
+## Licence
+Avalonia is licenced under the [MIT licence](licence.md).
+
+## Contributors
+
+This project exists thanks to all the people who contribute. [[Contribute](https://avaloniaui.net/contributing)].
+
### Backers
@@ -63,7 +86,6 @@ Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com
-
### Sponsors
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/Avalonia#sponsor)]
@@ -78,3 +100,7 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
+
+## .NET Foundation
+
+This project is supported by the [.NET Foundation](https://dotnetfoundation.org).
diff --git a/samples/BindingDemo/App.xaml.cs b/samples/BindingDemo/App.xaml.cs
index f2f44cd502..8a5364c70b 100644
--- a/samples/BindingDemo/App.xaml.cs
+++ b/samples/BindingDemo/App.xaml.cs
@@ -1,10 +1,6 @@
-using System;
using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Logging.Serilog;
+using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
-using Avalonia.ReactiveUI;
-using Serilog;
namespace BindingDemo
{
@@ -15,13 +11,19 @@ namespace BindingDemo
AvaloniaXamlLoader.Load(this);
}
- private static void Main()
+ public override void OnFrameworkInitializationCompleted()
{
- AppBuilder.Configure()
- .UsePlatformDetect()
- .UseReactiveUI()
- .LogToDebug()
- .Start();
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ desktop.MainWindow = new MainWindow();
+ base.OnFrameworkInitializationCompleted();
}
+
+ public static int Main(string[] args)
+ => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
+
+ public static AppBuilder BuildAvaloniaApp()
+ => AppBuilder.Configure()
+ .UsePlatformDetect()
+ .LogToTrace();
}
}
diff --git a/samples/BindingDemo/BindingDemo.csproj b/samples/BindingDemo/BindingDemo.csproj
index 3005fdbc51..d898b737a9 100644
--- a/samples/BindingDemo/BindingDemo.csproj
+++ b/samples/BindingDemo/BindingDemo.csproj
@@ -1,17 +1,16 @@
Exe
- netcoreapp2.0;net461
+ netcoreapp3.1
+
-
+
-
-
diff --git a/samples/BindingDemo/MainWindow.xaml b/samples/BindingDemo/MainWindow.xaml
index b57a9a0a9e..b583503327 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">
+
+
+
diff --git a/samples/ControlCatalog/App.xaml.cs b/samples/ControlCatalog/App.xaml.cs
index 958729e2e8..020fb2fff3 100644
--- a/samples/ControlCatalog/App.xaml.cs
+++ b/samples/ControlCatalog/App.xaml.cs
@@ -1,15 +1,88 @@
using System;
using Avalonia;
-using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
+using Avalonia.Markup.Xaml.Styling;
+using Avalonia.Styling;
namespace ControlCatalog
{
public class App : Application
{
+ private static readonly StyleInclude DataGridFluent = new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
+ {
+ Source = new Uri("avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml")
+ };
+
+ private static readonly StyleInclude DataGridDefault = new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
+ {
+ Source = new Uri("avares://Avalonia.Controls.DataGrid/Themes/Default.xaml")
+ };
+
+ public static Styles FluentDark = new Styles
+ {
+ new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
+ {
+ Source = new Uri("avares://Avalonia.Themes.Fluent/FluentDark.xaml")
+ },
+ DataGridFluent
+ };
+
+ public static Styles FluentLight = new Styles
+ {
+ new StyleInclude(new Uri("avares://ControlCatalog/Styles"))
+ {
+ Source = new Uri("avares://Avalonia.Themes.Fluent/FluentLight.xaml")
+ },
+ DataGridFluent
+ };
+
+ public static Styles DefaultLight = new Styles
+ {
+ new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog"))
+ {
+ Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/Base.xaml")
+ },
+ new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog"))
+ {
+ Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/BaseLight.xaml")
+ },
+ new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog"))
+ {
+ Source = new Uri("avares://Avalonia.Themes.Default/Accents/BaseLight.xaml")
+ },
+ new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog"))
+ {
+ Source = new Uri("avares://Avalonia.Themes.Default/DefaultTheme.xaml")
+ },
+ DataGridDefault
+ };
+
+ public static Styles DefaultDark = new Styles
+ {
+ new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog"))
+ {
+ Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/Base.xaml")
+ },
+ new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog"))
+ {
+ Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/BaseDark.xaml")
+ },
+ new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog"))
+ {
+ Source = new Uri("avares://Avalonia.Themes.Default/Accents/BaseDark.xaml")
+ },
+ new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog"))
+ {
+ Source = new Uri("avares://Avalonia.Themes.Default/DefaultTheme.xaml")
+ },
+ DataGridDefault
+ };
+
public override void Initialize()
{
+ Styles.Insert(0, FluentLight);
+
AvaloniaXamlLoader.Load(this);
}
@@ -19,7 +92,7 @@ namespace ControlCatalog
desktopLifetime.MainWindow = new MainWindow();
else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewLifetime)
singleViewLifetime.MainView = new MainView();
-
+
base.OnFrameworkInitializationCompleted();
}
}
diff --git a/samples/ControlCatalog/ControlCatalog.csproj b/samples/ControlCatalog/ControlCatalog.csproj
index 4c2769bcc4..1aa926a2a6 100644
--- a/samples/ControlCatalog/ControlCatalog.csproj
+++ b/samples/ControlCatalog/ControlCatalog.csproj
@@ -1,6 +1,7 @@
- netstandard2.0
+ netstandard2.0
+ true
@@ -17,14 +18,15 @@
+
-
+
+
-
diff --git a/samples/ControlCatalog/DecoratedWindow.xaml b/samples/ControlCatalog/DecoratedWindow.xaml
index 8e4c97b7f0..5251a2fa55 100644
--- a/samples/ControlCatalog/DecoratedWindow.xaml
+++ b/samples/ControlCatalog/DecoratedWindow.xaml
@@ -6,25 +6,21 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml
index 874560a294..f001425964 100644
--- a/samples/ControlCatalog/MainView.xaml
+++ b/samples/ControlCatalog/MainView.xaml
@@ -1,10 +1,7 @@
+ x:Class="ControlCatalog.MainView">
+
@@ -29,35 +27,70 @@
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
-
+
+
+
+
+
-
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
-
- Light
- Dark
-
+
+
+ No Decorations
+ Border Only
+ Full Decorations
+
+
+ Fluent - Light
+ Fluent - Dark
+ Simple - Light
+ Simple - Dark
+
+
+ None
+ Transparent
+ Blur
+ AcrylicBlur
+
+
+
diff --git a/samples/ControlCatalog/MainView.xaml.cs b/samples/ControlCatalog/MainView.xaml.cs
index acb9bc5bc6..c84f2f06b6 100644
--- a/samples/ControlCatalog/MainView.xaml.cs
+++ b/samples/ControlCatalog/MainView.xaml.cs
@@ -32,30 +32,40 @@ 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.FluentLight;
break;
case 1:
- Styles[0] = dark;
+ Application.Current.Styles[0] = App.FluentDark;
+ break;
+ case 2:
+ Application.Current.Styles[0] = App.DefaultLight;
+ break;
+ case 3:
+ Application.Current.Styles[0] = App.DefaultDark;
break;
}
+ };
+
+ var decorations = this.Find("Decorations");
+ decorations.SelectionChanged += (sender, e) =>
+ {
+ if (VisualRoot is Window window)
+ window.SystemDecorations = (SystemDecorations)decorations.SelectedIndex;
};
- Styles.Add(light);
+ }
+
+ protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
+ {
+ base.OnAttachedToVisualTree(e);
+ var decorations = this.Find("Decorations");
+ if (VisualRoot is Window window)
+ decorations.SelectedIndex = (int)window.SystemDecorations;
}
}
}
diff --git a/samples/ControlCatalog/MainWindow.xaml b/samples/ControlCatalog/MainWindow.xaml
index 248f94082d..6a70bb082f 100644
--- a/samples/ControlCatalog/MainWindow.xaml
+++ b/samples/ControlCatalog/MainWindow.xaml
@@ -7,50 +7,76 @@
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">
-
+ ExtendClientAreaToDecorationsHint="{Binding ExtendClientAreaEnabled}"
+ ExtendClientAreaChromeHints="{Binding ChromeHints}"
+ ExtendClientAreaTitleBarHeightHint="{Binding TitleBarHeight}"
+ TransparencyLevelHint="{Binding TransparencyLevel}"
+ x:Name="MainWindow"
+ x:Class="ControlCatalog.MainWindow" WindowState="{Binding WindowState, Mode=TwoWay}">
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/MainWindow.xaml.cs b/samples/ControlCatalog/MainWindow.xaml.cs
index 38cbde9d92..723351ae57 100644
--- a/samples/ControlCatalog/MainWindow.xaml.cs
+++ b/samples/ControlCatalog/MainWindow.xaml.cs
@@ -1,13 +1,11 @@
+using System;
+using System.Runtime.InteropServices;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Notifications;
-using Avalonia.Controls.Primitives;
+using Avalonia.Input;
using Avalonia.Markup.Xaml;
-using Avalonia.Threading;
using ControlCatalog.ViewModels;
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
namespace ControlCatalog
{
@@ -31,10 +29,17 @@ namespace ControlCatalog
DataContext = new MainWindowViewModel(_notificationArea);
_recentMenu = ((NativeMenu.GetMenu(this).Items[0] as NativeMenuItem).Menu.Items[2] as NativeMenuItem).Menu;
+
var mainMenu = this.FindControl
+
+
+
-
+
-
-
-
-
-
-
-
+
diff --git a/samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml.cs b/samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml.cs
index decd849adc..9e898c4536 100644
--- a/samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml.cs
+++ b/samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml.cs
@@ -5,22 +5,32 @@ using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Layout;
using Avalonia.Markup.Xaml;
+using Avalonia.VisualTree;
using ControlCatalog.ViewModels;
namespace ControlCatalog.Pages
{
public class ItemsRepeaterPage : UserControl
{
+ private readonly ItemsRepeaterPageViewModel _viewModel;
private ItemsRepeater _repeater;
private ScrollViewer _scroller;
+ private Button _scrollToLast;
+ private Button _scrollToRandom;
+ private Random _random = new Random(0);
public ItemsRepeaterPage()
{
this.InitializeComponent();
_repeater = this.FindControl("repeater");
_scroller = this.FindControl("scroller");
+ _scrollToLast = this.FindControl
diff --git a/samples/ControlCatalog/Pages/MenuPage.xaml.cs b/samples/ControlCatalog/Pages/MenuPage.xaml.cs
index 46dbe3dcad..5999510b6c 100644
--- a/samples/ControlCatalog/Pages/MenuPage.xaml.cs
+++ b/samples/ControlCatalog/Pages/MenuPage.xaml.cs
@@ -6,7 +6,6 @@ using System.Windows.Input;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using ControlCatalog.ViewModels;
-using ReactiveUI;
namespace ControlCatalog.Pages
{
diff --git a/samples/ControlCatalog/Pages/NumericUpDownPage.xaml b/samples/ControlCatalog/Pages/NumericUpDownPage.xaml
index e605a92da0..d75622f1fb 100644
--- a/samples/ControlCatalog/Pages/NumericUpDownPage.xaml
+++ b/samples/ControlCatalog/Pages/NumericUpDownPage.xaml
@@ -1,5 +1,6 @@
Numeric up-down control
@@ -50,22 +51,22 @@
Text:
-
+
Minimum:
+ CultureInfo="{Binding #upDown.CultureInfo}" VerticalAlignment="Center" Margin="2" HorizontalAlignment="Center"/>
Maximum:
+ CultureInfo="{Binding #upDown.CultureInfo}" VerticalAlignment="Center" Margin="2" HorizontalAlignment="Center"/>
Increment:
+ Margin="2" HorizontalAlignment="Center"/>
Value:
+ Margin="2" HorizontalAlignment="Center"/>
@@ -73,8 +74,17 @@
Usage of NumericUpDown:
+
+ NumericUpDown with Validation Errors:
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/NumericUpDownPage.xaml.cs b/samples/ControlCatalog/Pages/NumericUpDownPage.xaml.cs
index 92da64d87e..31749edf08 100644
--- a/samples/ControlCatalog/Pages/NumericUpDownPage.xaml.cs
+++ b/samples/ControlCatalog/Pages/NumericUpDownPage.xaml.cs
@@ -6,7 +6,7 @@ using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Markup.Xaml;
-using ReactiveUI;
+using MiniMvvm;
namespace ControlCatalog.Pages
{
@@ -26,7 +26,7 @@ namespace ControlCatalog.Pages
}
- public class NumbersPageViewModel : ReactiveObject
+ public class NumbersPageViewModel : ViewModelBase
{
private IList _formats;
private FormatObject _selectedFormat;
diff --git a/samples/ControlCatalog/Pages/OpenGlPage.xaml b/samples/ControlCatalog/Pages/OpenGlPage.xaml
new file mode 100644
index 0000000000..0eb09004ba
--- /dev/null
+++ b/samples/ControlCatalog/Pages/OpenGlPage.xaml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+ Yaw
+
+ Pitch
+
+ Roll
+
+
+ D
+ I
+ S
+ C
+ O
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/OpenGlPage.xaml.cs b/samples/ControlCatalog/Pages/OpenGlPage.xaml.cs
new file mode 100644
index 0000000000..cb79bf219a
--- /dev/null
+++ b/samples/ControlCatalog/Pages/OpenGlPage.xaml.cs
@@ -0,0 +1,402 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Numerics;
+using System.Runtime.InteropServices;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.OpenGL;
+using Avalonia.OpenGL.Controls;
+using Avalonia.Platform.Interop;
+using Avalonia.Threading;
+using static Avalonia.OpenGL.GlConsts;
+// ReSharper disable StringLiteralTypo
+
+namespace ControlCatalog.Pages
+{
+ public class OpenGlPage : UserControl
+ {
+
+ }
+
+ public class OpenGlPageControl : OpenGlControlBase
+ {
+ private float _yaw;
+
+ public static readonly DirectProperty YawProperty =
+ AvaloniaProperty.RegisterDirect("Yaw", o => o.Yaw, (o, v) => o.Yaw = v);
+
+ public float Yaw
+ {
+ get => _yaw;
+ set => SetAndRaise(YawProperty, ref _yaw, value);
+ }
+
+ private float _pitch;
+
+ public static readonly DirectProperty PitchProperty =
+ AvaloniaProperty.RegisterDirect("Pitch", o => o.Pitch, (o, v) => o.Pitch = v);
+
+ public float Pitch
+ {
+ get => _pitch;
+ set => SetAndRaise(PitchProperty, ref _pitch, value);
+ }
+
+
+ private float _roll;
+
+ public static readonly DirectProperty RollProperty =
+ AvaloniaProperty.RegisterDirect("Roll", o => o.Roll, (o, v) => o.Roll = v);
+
+ public float Roll
+ {
+ get => _roll;
+ set => SetAndRaise(RollProperty, ref _roll, value);
+ }
+
+
+ private float _disco;
+
+ public static readonly DirectProperty DiscoProperty =
+ AvaloniaProperty.RegisterDirect("Disco", o => o.Disco, (o, v) => o.Disco = v);
+
+ public float Disco
+ {
+ get => _disco;
+ set => SetAndRaise(DiscoProperty, ref _disco, value);
+ }
+
+ private string _info;
+
+ public static readonly DirectProperty InfoProperty =
+ AvaloniaProperty.RegisterDirect("Info", o => o.Info, (o, v) => o.Info = v);
+
+ public string Info
+ {
+ get => _info;
+ private set => SetAndRaise(InfoProperty, ref _info, value);
+ }
+
+ static OpenGlPageControl()
+ {
+ AffectsRender(YawProperty, PitchProperty, RollProperty, DiscoProperty);
+ }
+
+ private int _vertexShader;
+ private int _fragmentShader;
+ private int _shaderProgram;
+ private int _vertexBufferObject;
+ private int _indexBufferObject;
+ private int _vertexArrayObject;
+ private GlExtrasInterface _glExt;
+
+ private string GetShader(bool fragment, string shader)
+ {
+ var version = (GlVersion.Type == GlProfileType.OpenGL ?
+ RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? 150 : 120 :
+ 100);
+ var data = "#version " + version + "\n";
+ if (GlVersion.Type == GlProfileType.OpenGLES)
+ data += "precision mediump float;\n";
+ if (version >= 150)
+ {
+ shader = shader.Replace("attribute", "in");
+ if (fragment)
+ shader = shader
+ .Replace("varying", "in")
+ .Replace("//DECLAREGLFRAG", "out vec4 outFragColor;")
+ .Replace("gl_FragColor", "outFragColor");
+ else
+ shader = shader.Replace("varying", "out");
+ }
+
+ data += shader;
+
+ return data;
+ }
+
+
+ private string VertexShaderSource => GetShader(false, @"
+ attribute vec3 aPos;
+ attribute vec3 aNormal;
+ uniform mat4 uModel;
+ uniform mat4 uProjection;
+ uniform mat4 uView;
+
+ varying vec3 FragPos;
+ varying vec3 VecPos;
+ varying vec3 Normal;
+ uniform float uTime;
+ uniform float uDisco;
+ void main()
+ {
+ float discoScale = sin(uTime * 10.0) / 10.0;
+ float distortionX = 1.0 + uDisco * cos(uTime * 20.0) / 10.0;
+
+ float scale = 1.0 + uDisco * discoScale;
+
+ vec3 scaledPos = aPos;
+ scaledPos.x = scaledPos.x * distortionX;
+
+ scaledPos *= scale;
+ gl_Position = uProjection * uView * uModel * vec4(scaledPos, 1.0);
+ FragPos = vec3(uModel * vec4(aPos, 1.0));
+ VecPos = aPos;
+ Normal = normalize(vec3(uModel * vec4(aNormal, 1.0)));
+ }
+");
+
+ private string FragmentShaderSource => GetShader(true, @"
+ varying vec3 FragPos;
+ varying vec3 VecPos;
+ varying vec3 Normal;
+ uniform float uMaxY;
+ uniform float uMinY;
+ uniform float uTime;
+ uniform float uDisco;
+ //DECLAREGLFRAG
+
+ void main()
+ {
+ float y = (VecPos.y - uMinY) / (uMaxY - uMinY);
+ float c = cos(atan(VecPos.x, VecPos.z) * 20.0 + uTime * 40.0 + y * 50.0);
+ float s = sin(-atan(VecPos.z, VecPos.x) * 20.0 - uTime * 20.0 - y * 30.0);
+
+ vec3 discoColor = vec3(
+ 0.5 + abs(0.5 - y) * cos(uTime * 10.0),
+ 0.25 + (smoothstep(0.3, 0.8, y) * (0.5 - c / 4.0)),
+ 0.25 + abs((smoothstep(0.1, 0.4, y) * (0.5 - s / 4.0))));
+
+ vec3 objectColor = vec3((1.0 - y), 0.40 + y / 4.0, y * 0.75 + 0.25);
+ objectColor = objectColor * (1.0 - uDisco) + discoColor * uDisco;
+
+ float ambientStrength = 0.3;
+ vec3 lightColor = vec3(1.0, 1.0, 1.0);
+ vec3 lightPos = vec3(uMaxY * 2.0, uMaxY * 2.0, uMaxY * 2.0);
+ vec3 ambient = ambientStrength * lightColor;
+
+
+ vec3 norm = normalize(Normal);
+ vec3 lightDir = normalize(lightPos - FragPos);
+
+ float diff = max(dot(norm, lightDir), 0.0);
+ vec3 diffuse = diff * lightColor;
+
+ vec3 result = (ambient + diffuse) * objectColor;
+ gl_FragColor = vec4(result, 1.0);
+
+ }
+");
+
+ [StructLayout(LayoutKind.Sequential, Pack = 4)]
+ private struct Vertex
+ {
+ public Vector3 Position;
+ public Vector3 Normal;
+ }
+
+ private readonly Vertex[] _points;
+ private readonly ushort[] _indices;
+ private readonly float _minY;
+ private readonly float _maxY;
+
+
+ public OpenGlPageControl()
+ {
+ var name = typeof(OpenGlPage).Assembly.GetManifestResourceNames().First(x => x.Contains("teapot.bin"));
+ using (var sr = new BinaryReader(typeof(OpenGlPage).Assembly.GetManifestResourceStream(name)))
+ {
+ var buf = new byte[sr.ReadInt32()];
+ sr.Read(buf, 0, buf.Length);
+ var points = new float[buf.Length / 4];
+ Buffer.BlockCopy(buf, 0, points, 0, buf.Length);
+ buf = new byte[sr.ReadInt32()];
+ sr.Read(buf, 0, buf.Length);
+ _indices = new ushort[buf.Length / 2];
+ Buffer.BlockCopy(buf, 0, _indices, 0, buf.Length);
+ _points = new Vertex[points.Length / 3];
+ for (var primitive = 0; primitive < points.Length / 3; primitive++)
+ {
+ var srci = primitive * 3;
+ _points[primitive] = new Vertex
+ {
+ Position = new Vector3(points[srci], points[srci + 1], points[srci + 2])
+ };
+ }
+
+ for (int i = 0; i < _indices.Length; i += 3)
+ {
+ Vector3 a = _points[_indices[i]].Position;
+ Vector3 b = _points[_indices[i + 1]].Position;
+ Vector3 c = _points[_indices[i + 2]].Position;
+ var normal = Vector3.Normalize(Vector3.Cross(c - b, a - b));
+
+ _points[_indices[i]].Normal += normal;
+ _points[_indices[i + 1]].Normal += normal;
+ _points[_indices[i + 2]].Normal += normal;
+ }
+
+ for (int i = 0; i < _points.Length; i++)
+ {
+ _points[i].Normal = Vector3.Normalize(_points[i].Normal);
+ _maxY = Math.Max(_maxY, _points[i].Position.Y);
+ _minY = Math.Min(_minY, _points[i].Position.Y);
+ }
+ }
+
+ }
+
+ private void CheckError(GlInterface gl)
+ {
+ int err;
+ while ((err = gl.GetError()) != GL_NO_ERROR)
+ Console.WriteLine(err);
+ }
+
+ protected unsafe override void OnOpenGlInit(GlInterface GL, int fb)
+ {
+ CheckError(GL);
+ _glExt = new GlExtrasInterface(GL);
+
+ Info = $"Renderer: {GL.GetString(GL_RENDERER)} Version: {GL.GetString(GL_VERSION)}";
+
+ // Load the source of the vertex shader and compile it.
+ _vertexShader = GL.CreateShader(GL_VERTEX_SHADER);
+ Console.WriteLine(GL.CompileShaderAndGetError(_vertexShader, VertexShaderSource));
+
+ // Load the source of the fragment shader and compile it.
+ _fragmentShader = GL.CreateShader(GL_FRAGMENT_SHADER);
+ Console.WriteLine(GL.CompileShaderAndGetError(_fragmentShader, FragmentShaderSource));
+
+ // Create the shader program, attach the vertex and fragment shaders and link the program.
+ _shaderProgram = GL.CreateProgram();
+ GL.AttachShader(_shaderProgram, _vertexShader);
+ GL.AttachShader(_shaderProgram, _fragmentShader);
+ const int positionLocation = 0;
+ const int normalLocation = 1;
+ GL.BindAttribLocationString(_shaderProgram, positionLocation, "aPos");
+ GL.BindAttribLocationString(_shaderProgram, normalLocation, "aNormal");
+ Console.WriteLine(GL.LinkProgramAndGetError(_shaderProgram));
+ CheckError(GL);
+
+ // Create the vertex buffer object (VBO) for the vertex data.
+ _vertexBufferObject = GL.GenBuffer();
+ // Bind the VBO and copy the vertex data into it.
+ GL.BindBuffer(GL_ARRAY_BUFFER, _vertexBufferObject);
+ CheckError(GL);
+ var vertexSize = Marshal.SizeOf();
+ fixed (void* pdata = _points)
+ GL.BufferData(GL_ARRAY_BUFFER, new IntPtr(_points.Length * vertexSize),
+ new IntPtr(pdata), GL_STATIC_DRAW);
+
+ _indexBufferObject = GL.GenBuffer();
+ GL.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferObject);
+ CheckError(GL);
+ fixed (void* pdata = _indices)
+ GL.BufferData(GL_ELEMENT_ARRAY_BUFFER, new IntPtr(_indices.Length * sizeof(ushort)), new IntPtr(pdata),
+ GL_STATIC_DRAW);
+ CheckError(GL);
+ _vertexArrayObject = _glExt.GenVertexArray();
+ _glExt.BindVertexArray(_vertexArrayObject);
+ CheckError(GL);
+ GL.VertexAttribPointer(positionLocation, 3, GL_FLOAT,
+ 0, vertexSize, IntPtr.Zero);
+ GL.VertexAttribPointer(normalLocation, 3, GL_FLOAT,
+ 0, vertexSize, new IntPtr(12));
+ GL.EnableVertexAttribArray(positionLocation);
+ GL.EnableVertexAttribArray(normalLocation);
+ CheckError(GL);
+
+ }
+
+ protected override void OnOpenGlDeinit(GlInterface GL, int fb)
+ {
+ // Unbind everything
+ GL.BindBuffer(GL_ARRAY_BUFFER, 0);
+ GL.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ _glExt.BindVertexArray(0);
+ GL.UseProgram(0);
+
+ // Delete all resources.
+ GL.DeleteBuffers(2, new[] { _vertexBufferObject, _indexBufferObject });
+ _glExt.DeleteVertexArrays(1, new[] { _vertexArrayObject });
+ GL.DeleteProgram(_shaderProgram);
+ GL.DeleteShader(_fragmentShader);
+ GL.DeleteShader(_vertexShader);
+ }
+
+ static Stopwatch St = Stopwatch.StartNew();
+ protected override unsafe void OnOpenGlRender(GlInterface gl, int fb)
+ {
+ gl.ClearColor(0, 0, 0, 0);
+ gl.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ gl.Enable(GL_DEPTH_TEST);
+ gl.Viewport(0, 0, (int)Bounds.Width, (int)Bounds.Height);
+ var GL = gl;
+
+ GL.BindBuffer(GL_ARRAY_BUFFER, _vertexBufferObject);
+ GL.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferObject);
+ _glExt.BindVertexArray(_vertexArrayObject);
+ GL.UseProgram(_shaderProgram);
+ CheckError(GL);
+ var projection =
+ Matrix4x4.CreatePerspectiveFieldOfView((float)(Math.PI / 4), (float)(Bounds.Width / Bounds.Height),
+ 0.01f, 1000);
+
+
+ var view = Matrix4x4.CreateLookAt(new Vector3(25, 25, 25), new Vector3(), new Vector3(0, -1, 0));
+ var model = Matrix4x4.CreateFromYawPitchRoll(_yaw, _pitch, _roll);
+ var modelLoc = GL.GetUniformLocationString(_shaderProgram, "uModel");
+ var viewLoc = GL.GetUniformLocationString(_shaderProgram, "uView");
+ var projectionLoc = GL.GetUniformLocationString(_shaderProgram, "uProjection");
+ var maxYLoc = GL.GetUniformLocationString(_shaderProgram, "uMaxY");
+ var minYLoc = GL.GetUniformLocationString(_shaderProgram, "uMinY");
+ var timeLoc = GL.GetUniformLocationString(_shaderProgram, "uTime");
+ var discoLoc = GL.GetUniformLocationString(_shaderProgram, "uDisco");
+ GL.UniformMatrix4fv(modelLoc, 1, false, &model);
+ GL.UniformMatrix4fv(viewLoc, 1, false, &view);
+ GL.UniformMatrix4fv(projectionLoc, 1, false, &projection);
+ GL.Uniform1f(maxYLoc, _maxY);
+ GL.Uniform1f(minYLoc, _minY);
+ GL.Uniform1f(timeLoc, (float)St.Elapsed.TotalSeconds);
+ GL.Uniform1f(discoLoc, _disco);
+ CheckError(GL);
+ GL.DrawElements(GL_TRIANGLES, _indices.Length, GL_UNSIGNED_SHORT, IntPtr.Zero);
+
+ CheckError(GL);
+ if (_disco > 0.01)
+ Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background);
+ }
+
+ class GlExtrasInterface : GlInterfaceBase
+ {
+ public GlExtrasInterface(GlInterface gl) : base(gl.GetProcAddress, gl.ContextInfo)
+ {
+ }
+
+ public delegate void GlDeleteVertexArrays(int count, int[] buffers);
+ [GlMinVersionEntryPoint("glDeleteVertexArrays", 3,0)]
+ [GlExtensionEntryPoint("glDeleteVertexArraysOES", "GL_OES_vertex_array_object")]
+ public GlDeleteVertexArrays DeleteVertexArrays { get; }
+
+ public delegate void GlBindVertexArray(int array);
+ [GlMinVersionEntryPoint("glBindVertexArray", 3,0)]
+ [GlExtensionEntryPoint("glBindVertexArrayOES", "GL_OES_vertex_array_object")]
+ public GlBindVertexArray BindVertexArray { get; }
+ public delegate void GlGenVertexArrays(int n, int[] rv);
+
+ [GlMinVersionEntryPoint("glGenVertexArrays",3,0)]
+ [GlExtensionEntryPoint("glGenVertexArraysOES", "GL_OES_vertex_array_object")]
+ public GlGenVertexArrays GenVertexArrays { get; }
+
+ public int GenVertexArray()
+ {
+ var rv = new int[1];
+ GenVertexArrays(1, rv);
+ return rv[0];
+ }
+ }
+ }
+}
diff --git a/samples/ControlCatalog/Pages/ProgressBarPage.xaml b/samples/ControlCatalog/Pages/ProgressBarPage.xaml
index 39bbf391bb..2ec0b48c76 100644
--- a/samples/ControlCatalog/Pages/ProgressBarPage.xaml
+++ b/samples/ControlCatalog/Pages/ProgressBarPage.xaml
@@ -1,25 +1,19 @@
-
+
ProgressBar
A progress bar control
-
-
+
+
+
-
-
+
-
-
+
-
-
+
+
diff --git a/samples/ControlCatalog/Pages/RelativePanelPage.axaml b/samples/ControlCatalog/Pages/RelativePanelPage.axaml
new file mode 100644
index 0000000000..4dcdcc195f
--- /dev/null
+++ b/samples/ControlCatalog/Pages/RelativePanelPage.axaml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/RelativePanelPage.axaml.cs b/samples/ControlCatalog/Pages/RelativePanelPage.axaml.cs
new file mode 100644
index 0000000000..11d0a5152e
--- /dev/null
+++ b/samples/ControlCatalog/Pages/RelativePanelPage.axaml.cs
@@ -0,0 +1,19 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace ControlCatalog.Pages
+{
+ public class RelativePanelPage : UserControl
+ {
+ public RelativePanelPage()
+ {
+ this.InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}
diff --git a/samples/ControlCatalog/Pages/ScreenPage.cs b/samples/ControlCatalog/Pages/ScreenPage.cs
index d775eb9635..c39f414b44 100644
--- a/samples/ControlCatalog/Pages/ScreenPage.cs
+++ b/samples/ControlCatalog/Pages/ScreenPage.cs
@@ -29,7 +29,8 @@ namespace ControlCatalog.Pages
var screens = w.Screens.All;
var scaling = ((IRenderRoot)w).RenderScaling;
- Pen p = new Pen(Brushes.Black);
+ var drawBrush = Brushes.Green;
+ Pen p = new Pen(drawBrush);
if (screens != null)
foreach (Screen screen in screens)
{
@@ -53,19 +54,19 @@ namespace ControlCatalog.Pages
};
text.Text = $"Bounds: {screen.Bounds.Width}:{screen.Bounds.Height}";
- context.DrawText(Brushes.Black, boundsRect.Position.WithY(boundsRect.Size.Height), text);
+ context.DrawText(drawBrush, boundsRect.Position.WithY(boundsRect.Size.Height), text);
text.Text = $"WorkArea: {screen.WorkingArea.Width}:{screen.WorkingArea.Height}";
- context.DrawText(Brushes.Black, boundsRect.Position.WithY(boundsRect.Size.Height + 20), text);
+ context.DrawText(drawBrush, boundsRect.Position.WithY(boundsRect.Size.Height + 20), text);
text.Text = $"Scaling: {screen.PixelDensity * 100}%";
- context.DrawText(Brushes.Black, boundsRect.Position.WithY(boundsRect.Size.Height + 40), text);
+ context.DrawText(drawBrush, boundsRect.Position.WithY(boundsRect.Size.Height + 40), text);
text.Text = $"Primary: {screen.Primary}";
- context.DrawText(Brushes.Black, boundsRect.Position.WithY(boundsRect.Size.Height + 60), text);
+ context.DrawText(drawBrush, boundsRect.Position.WithY(boundsRect.Size.Height + 60), text);
text.Text = $"Current: {screen.Equals(w.Screens.ScreenFromBounds(new PixelRect(w.Position, PixelSize.FromSize(w.Bounds.Size, scaling))))}";
- context.DrawText(Brushes.Black, boundsRect.Position.WithY(boundsRect.Size.Height + 80), text);
+ context.DrawText(drawBrush, boundsRect.Position.WithY(boundsRect.Size.Height + 80), text);
}
context.DrawRectangle(p, new Rect(w.Position.X / 10f + Math.Abs(_leftMost), w.Position.Y / 10, w.Bounds.Width / 10, w.Bounds.Height / 10));
diff --git a/samples/ControlCatalog/Pages/ScrollViewerPage.xaml b/samples/ControlCatalog/Pages/ScrollViewerPage.xaml
new file mode 100644
index 0000000000..bbefcab9ca
--- /dev/null
+++ b/samples/ControlCatalog/Pages/ScrollViewerPage.xaml
@@ -0,0 +1,35 @@
+
+
+ ScrollViewer
+ Allows for horizontal and vertical content scrolling.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/ScrollViewerPage.xaml.cs b/samples/ControlCatalog/Pages/ScrollViewerPage.xaml.cs
new file mode 100644
index 0000000000..dcd7a88a56
--- /dev/null
+++ b/samples/ControlCatalog/Pages/ScrollViewerPage.xaml.cs
@@ -0,0 +1,65 @@
+using System.Collections.Generic;
+using Avalonia.Controls;
+using Avalonia.Controls.Primitives;
+using Avalonia.Markup.Xaml;
+using MiniMvvm;
+
+namespace ControlCatalog.Pages
+{
+ public class ScrollViewerPageViewModel : ViewModelBase
+ {
+ private bool _allowAutoHide;
+ private ScrollBarVisibility _horizontalScrollVisibility;
+ private ScrollBarVisibility _verticalScrollVisibility;
+
+ public ScrollViewerPageViewModel()
+ {
+ AvailableVisibility = new List
+ {
+ ScrollBarVisibility.Auto,
+ ScrollBarVisibility.Visible,
+ ScrollBarVisibility.Hidden,
+ ScrollBarVisibility.Disabled,
+ };
+
+ HorizontalScrollVisibility = ScrollBarVisibility.Auto;
+ VerticalScrollVisibility = ScrollBarVisibility.Auto;
+ AllowAutoHide = true;
+ }
+
+ public bool AllowAutoHide
+ {
+ get => _allowAutoHide;
+ set => this.RaiseAndSetIfChanged(ref _allowAutoHide, value);
+ }
+
+ public ScrollBarVisibility HorizontalScrollVisibility
+ {
+ get => _horizontalScrollVisibility;
+ set => this.RaiseAndSetIfChanged(ref _horizontalScrollVisibility, value);
+ }
+
+ public ScrollBarVisibility VerticalScrollVisibility
+ {
+ get => _verticalScrollVisibility;
+ set => this.RaiseAndSetIfChanged(ref _verticalScrollVisibility, value);
+ }
+
+ public List AvailableVisibility { get; }
+ }
+
+ public class ScrollViewerPage : UserControl
+ {
+ public ScrollViewerPage()
+ {
+ InitializeComponent();
+
+ DataContext = new ScrollViewerPageViewModel();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}
diff --git a/samples/ControlCatalog/Pages/SliderPage.xaml b/samples/ControlCatalog/Pages/SliderPage.xaml
index 58f7b881fe..b3f32ed421 100644
--- a/samples/ControlCatalog/Pages/SliderPage.xaml
+++ b/samples/ControlCatalog/Pages/SliderPage.xaml
@@ -1,20 +1,43 @@
Slider
A control that lets the user select from a range of values by moving a Thumb control along a Track.
-
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/SplitViewPage.xaml b/samples/ControlCatalog/Pages/SplitViewPage.xaml
new file mode 100644
index 0000000000..6902b27715
--- /dev/null
+++ b/samples/ControlCatalog/Pages/SplitViewPage.xaml
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Inline
+ CompactInline
+ Overlay
+ CompactOverlay
+
+
+
+
+ SystemControlBackgroundChromeMediumLowBrush
+ Red
+ Blue
+ Green
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/SplitViewPage.xaml.cs b/samples/ControlCatalog/Pages/SplitViewPage.xaml.cs
new file mode 100644
index 0000000000..cbf217c94a
--- /dev/null
+++ b/samples/ControlCatalog/Pages/SplitViewPage.xaml.cs
@@ -0,0 +1,21 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using ControlCatalog.ViewModels;
+
+namespace ControlCatalog.Pages
+{
+ public class SplitViewPage : UserControl
+ {
+ public SplitViewPage()
+ {
+ this.InitializeComponent();
+ DataContext = new SplitViewPageViewModel();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}
diff --git a/samples/ControlCatalog/Pages/TabControlPage.xaml.cs b/samples/ControlCatalog/Pages/TabControlPage.xaml.cs
index a38a3ab4cb..f49b13091b 100644
--- a/samples/ControlCatalog/Pages/TabControlPage.xaml.cs
+++ b/samples/ControlCatalog/Pages/TabControlPage.xaml.cs
@@ -6,7 +6,7 @@ using Avalonia.Markup.Xaml;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
-using ReactiveUI;
+using MiniMvvm;
namespace ControlCatalog.Pages
{
@@ -56,7 +56,7 @@ namespace ControlCatalog.Pages
return new Bitmap(assets.Open(new Uri(uri)));
}
- private class PageViewModel : ReactiveObject
+ private class PageViewModel : ViewModelBase
{
private Dock _tabPlacement;
diff --git a/samples/ControlCatalog/Pages/TextBlockPage.xaml b/samples/ControlCatalog/Pages/TextBlockPage.xaml
new file mode 100644
index 0000000000..d4f72f161a
--- /dev/null
+++ b/samples/ControlCatalog/Pages/TextBlockPage.xaml
@@ -0,0 +1,125 @@
+
+
+ TextBlock
+ A control that can display text
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/TextBlockPage.xaml.cs b/samples/ControlCatalog/Pages/TextBlockPage.xaml.cs
new file mode 100644
index 0000000000..49fecbe7c5
--- /dev/null
+++ b/samples/ControlCatalog/Pages/TextBlockPage.xaml.cs
@@ -0,0 +1,18 @@
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace ControlCatalog.Pages
+{
+ public class TextBlockPage : UserControl
+ {
+ public TextBlockPage()
+ {
+ this.InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}
diff --git a/samples/ControlCatalog/Pages/TextBoxPage.xaml b/samples/ControlCatalog/Pages/TextBoxPage.xaml
index 64118a00b4..4958174f40 100644
--- a/samples/ControlCatalog/Pages/TextBoxPage.xaml
+++ b/samples/ControlCatalog/Pages/TextBoxPage.xaml
@@ -1,9 +1,10 @@
+ x:Class="ControlCatalog.Pages.TextBoxPage"
+ xmlns:sys="clr-namespace:System;assembly=netstandard">
- TextBox
- A control into which the user can input text
+
+
-
+
+
+
+
+
+
+
@@ -37,22 +45,24 @@
Text="Multiline TextBox with TextWrapping.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est." />
+
+
-
- resm fonts
-
-
-
-
-
-
-
- res fonts
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/ToggleSwitchPage.xaml b/samples/ControlCatalog/Pages/ToggleSwitchPage.xaml
new file mode 100644
index 0000000000..161ee2ee16
--- /dev/null
+++ b/samples/ControlCatalog/Pages/ToggleSwitchPage.xaml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/ToggleSwitchPage.xaml.cs b/samples/ControlCatalog/Pages/ToggleSwitchPage.xaml.cs
new file mode 100644
index 0000000000..66f7d14c7f
--- /dev/null
+++ b/samples/ControlCatalog/Pages/ToggleSwitchPage.xaml.cs
@@ -0,0 +1,19 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace ControlCatalog.Pages
+{
+ public class ToggleSwitchPage : UserControl
+ {
+ public ToggleSwitchPage()
+ {
+ this.InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}
diff --git a/samples/ControlCatalog/Pages/ToolTipPage.xaml b/samples/ControlCatalog/Pages/ToolTipPage.xaml
index cbe1e3059c..ec073d48a9 100644
--- a/samples/ControlCatalog/Pages/ToolTipPage.xaml
+++ b/samples/ControlCatalog/Pages/ToolTipPage.xaml
@@ -12,13 +12,13 @@
HorizontalAlignment="Center">
Hover Here
-
diff --git a/samples/ControlCatalog/Pages/TreeViewPage.xaml b/samples/ControlCatalog/Pages/TreeViewPage.xaml
index 3a81e2ed02..6d99132680 100644
--- a/samples/ControlCatalog/Pages/TreeViewPage.xaml
+++ b/samples/ControlCatalog/Pages/TreeViewPage.xaml
@@ -19,8 +19,8 @@
Add
-
Remove
+ Select Random
Single
diff --git a/samples/ControlCatalog/Pages/TreeViewPage.xaml.cs b/samples/ControlCatalog/Pages/TreeViewPage.xaml.cs
index 1f35f05f1d..3fb990459f 100644
--- a/samples/ControlCatalog/Pages/TreeViewPage.xaml.cs
+++ b/samples/ControlCatalog/Pages/TreeViewPage.xaml.cs
@@ -1,9 +1,6 @@
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Reactive;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
-using ReactiveUI;
+using ControlCatalog.ViewModels;
namespace ControlCatalog.Pages
{
@@ -12,104 +9,12 @@ namespace ControlCatalog.Pages
public TreeViewPage()
{
InitializeComponent();
- DataContext = new PageViewModel();
+ DataContext = new TreeViewPageViewModel();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
-
- private class PageViewModel : ReactiveObject
- {
- private SelectionMode _selectionMode;
-
- public PageViewModel()
- {
- Node root = new Node();
- Items = root.Children;
- SelectedItems = new ObservableCollection();
-
- AddItemCommand = ReactiveCommand.Create(() =>
- {
- Node parentItem = SelectedItems.Count > 0 ? SelectedItems[0] : root;
- parentItem.AddNewItem();
- });
-
- RemoveItemCommand = ReactiveCommand.Create(() =>
- {
- while (SelectedItems.Count > 0)
- {
- Node lastItem = SelectedItems[0];
- RecursiveRemove(Items, lastItem);
- SelectedItems.Remove(lastItem);
- }
-
- bool RecursiveRemove(ObservableCollection items, Node selectedItem)
- {
- if (items.Remove(selectedItem))
- {
- return true;
- }
-
- foreach (Node item in items)
- {
- if (item.AreChildrenInitialized && RecursiveRemove(item.Children, selectedItem))
- {
- return true;
- }
- }
-
- return false;
- }
- });
- }
-
- public ObservableCollection Items { get; }
-
- public ObservableCollection SelectedItems { get; }
-
- public ReactiveCommand AddItemCommand { get; }
-
- public ReactiveCommand RemoveItemCommand { get; }
-
- public SelectionMode SelectionMode
- {
- get => _selectionMode;
- set
- {
- SelectedItems.Clear();
- this.RaiseAndSetIfChanged(ref _selectionMode, value);
- }
- }
- }
-
- private class Node
- {
- private int _counter;
- private ObservableCollection _children;
-
- public string Header { get; private set; }
-
- public bool AreChildrenInitialized => _children != null;
-
- public ObservableCollection Children
- {
- get
- {
- if (_children == null)
- {
- _children = new ObservableCollection(Enumerable.Range(1, 10).Select(i => CreateNewNode()));
- }
- return _children;
- }
- }
-
- public void AddNewItem() => Children.Add(CreateNewNode());
-
- public override string ToString() => Header;
-
- private Node CreateNewNode() => new Node {Header = $"Item {_counter++}"};
- }
}
}
diff --git a/samples/ControlCatalog/Pages/WindowCustomizationsPage.xaml b/samples/ControlCatalog/Pages/WindowCustomizationsPage.xaml
new file mode 100644
index 0000000000..b90f43c3b6
--- /dev/null
+++ b/samples/ControlCatalog/Pages/WindowCustomizationsPage.xaml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+ None
+ Transparent
+ Blur
+ AcrylicBlur
+
+
+
diff --git a/samples/ControlCatalog/Pages/WindowCustomizationsPage.xaml.cs b/samples/ControlCatalog/Pages/WindowCustomizationsPage.xaml.cs
new file mode 100644
index 0000000000..d8d4f3f371
--- /dev/null
+++ b/samples/ControlCatalog/Pages/WindowCustomizationsPage.xaml.cs
@@ -0,0 +1,19 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace ControlCatalog.Pages
+{
+ public class WindowCustomizationsPage : UserControl
+ {
+ public WindowCustomizationsPage()
+ {
+ this.InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}
diff --git a/samples/ControlCatalog/Pages/teapot.bin b/samples/ControlCatalog/Pages/teapot.bin
new file mode 100644
index 0000000000..589eeb912d
Binary files /dev/null and b/samples/ControlCatalog/Pages/teapot.bin differ
diff --git a/samples/ControlCatalog/SideBar.xaml b/samples/ControlCatalog/SideBar.xaml
index 26d25a6266..7c911e91e9 100644
--- a/samples/ControlCatalog/SideBar.xaml
+++ b/samples/ControlCatalog/SideBar.xaml
@@ -12,7 +12,7 @@
+
diff --git a/samples/ControlCatalog/ViewModels/ContextMenuPageViewModel.cs b/samples/ControlCatalog/ViewModels/ContextMenuPageViewModel.cs
index 5c2f74d2d5..3f5d0cd93c 100644
--- a/samples/ControlCatalog/ViewModels/ContextMenuPageViewModel.cs
+++ b/samples/ControlCatalog/ViewModels/ContextMenuPageViewModel.cs
@@ -3,7 +3,7 @@ using System.Reactive;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.VisualTree;
-using ReactiveUI;
+using MiniMvvm;
namespace ControlCatalog.ViewModels
{
@@ -12,9 +12,9 @@ namespace ControlCatalog.ViewModels
public Control View { get; set; }
public ContextMenuPageViewModel()
{
- OpenCommand = ReactiveCommand.CreateFromTask(Open);
- SaveCommand = ReactiveCommand.Create(Save);
- OpenRecentCommand = ReactiveCommand.Create(OpenRecent);
+ OpenCommand = MiniCommand.CreateFromTask(Open);
+ SaveCommand = MiniCommand.Create(Save);
+ OpenRecentCommand = MiniCommand.Create(OpenRecent);
MenuItems = new[]
{
@@ -44,9 +44,9 @@ namespace ControlCatalog.ViewModels
}
public IReadOnlyList MenuItems { get; set; }
- public ReactiveCommand OpenCommand { get; }
- public ReactiveCommand SaveCommand { get; }
- public ReactiveCommand OpenRecentCommand { get; }
+ public MiniCommand OpenCommand { get; }
+ public MiniCommand SaveCommand { get; }
+ public MiniCommand OpenRecentCommand { get; }
public async Task Open()
{
diff --git a/samples/ControlCatalog/ViewModels/ItemsRepeaterPageViewModel.cs b/samples/ControlCatalog/ViewModels/ItemsRepeaterPageViewModel.cs
index bc2ce80714..ee1fa6ae77 100644
--- a/samples/ControlCatalog/ViewModels/ItemsRepeaterPageViewModel.cs
+++ b/samples/ControlCatalog/ViewModels/ItemsRepeaterPageViewModel.cs
@@ -1,31 +1,34 @@
using System;
using System.Collections.ObjectModel;
using System.Linq;
-using ReactiveUI;
+using Avalonia.Media;
+using MiniMvvm;
namespace ControlCatalog.ViewModels
{
- public class ItemsRepeaterPageViewModel : ReactiveObject
+ public class ItemsRepeaterPageViewModel : ViewModelBase
{
- private int newItemIndex = 1;
+ private int _newItemIndex = 1;
+ private int _newGenerationIndex = 0;
+ private ObservableCollection- _items;
public ItemsRepeaterPageViewModel()
{
- Items = new ObservableCollection
- (
- Enumerable.Range(1, 100000).Select(i => new Item
- {
- Text = $"Item {i.ToString()}",
- }));
+ Items = CreateItems();
}
- public ObservableCollection
- Items { get; }
+ public ObservableCollection
- Items
+ {
+ get => _items;
+ set => this.RaiseAndSetIfChanged(ref _items, value);
+ }
public Item SelectedItem { get; set; }
public void AddItem()
{
var index = SelectedItem != null ? Items.IndexOf(SelectedItem) : -1;
- Items.Insert(index + 1, new Item { Text = $"New Item {newItemIndex++}" });
+ Items.Insert(index + 1, new Item(index + 1) { Text = $"New Item {_newItemIndex++}" });
}
public void RandomizeHeights()
@@ -38,10 +41,30 @@ namespace ControlCatalog.ViewModels
}
}
- public class Item : ReactiveObject
+ public void ResetItems()
+ {
+ Items = CreateItems();
+ }
+
+ private ObservableCollection
- CreateItems()
+ {
+ var suffix = _newGenerationIndex == 0 ? string.Empty : $"[{_newGenerationIndex.ToString()}]";
+
+ _newGenerationIndex++;
+
+ return new ObservableCollection
- (
+ Enumerable.Range(1, 100000).Select(i => new Item(i)
+ {
+ Text = $"Item {i.ToString()} {suffix}"
+ }));
+ }
+
+ public class Item : ViewModelBase
{
private double _height = double.NaN;
+ public Item(int index) => Index = index;
+ public int Index { get; }
public string Text { get; set; }
public double Height
diff --git a/samples/ControlCatalog/ViewModels/ListBoxPageViewModel.cs b/samples/ControlCatalog/ViewModels/ListBoxPageViewModel.cs
new file mode 100644
index 0000000000..7f2d6e9572
--- /dev/null
+++ b/samples/ControlCatalog/ViewModels/ListBoxPageViewModel.cs
@@ -0,0 +1,94 @@
+using System;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Reactive;
+using Avalonia.Controls;
+using Avalonia.Controls.Selection;
+using MiniMvvm;
+
+namespace ControlCatalog.ViewModels
+{
+ public class ListBoxPageViewModel : ViewModelBase
+ {
+ private bool _multiple;
+ private bool _toggle;
+ private bool _alwaysSelected;
+ private bool _autoScrollToSelectedItem = true;
+ private int _counter;
+ private IObservable _selectionMode;
+
+ public ListBoxPageViewModel()
+ {
+ Items = new ObservableCollection(Enumerable.Range(1, 10000).Select(i => GenerateItem()));
+
+ Selection = new SelectionModel();
+ Selection.Select(1);
+
+ _selectionMode = this.WhenAnyValue(
+ x => x.Multiple,
+ x => x.Toggle,
+ x => x.AlwaysSelected,
+ (m, t, a) =>
+ (m ? Avalonia.Controls.SelectionMode.Multiple : 0) |
+ (t ? Avalonia.Controls.SelectionMode.Toggle : 0) |
+ (a ? Avalonia.Controls.SelectionMode.AlwaysSelected : 0));
+
+ AddItemCommand = MiniCommand.Create(() => Items.Add(GenerateItem()));
+
+ RemoveItemCommand = MiniCommand.Create(() =>
+ {
+ var items = Selection.SelectedItems.ToList();
+
+ foreach (var item in items)
+ {
+ Items.Remove(item);
+ }
+ });
+
+ SelectRandomItemCommand = MiniCommand.Create(() =>
+ {
+ var random = new Random();
+
+ using (Selection.BatchUpdate())
+ {
+ Selection.Clear();
+ Selection.Select(random.Next(Items.Count - 1));
+ }
+ });
+ }
+
+ public ObservableCollection Items { get; }
+ public SelectionModel Selection { get; }
+ public IObservable SelectionMode => _selectionMode;
+
+ public bool Multiple
+ {
+ get => _multiple;
+ set => this.RaiseAndSetIfChanged(ref _multiple, value);
+ }
+
+ public bool Toggle
+ {
+ get => _toggle;
+ set => this.RaiseAndSetIfChanged(ref _toggle, value);
+ }
+
+ public bool AlwaysSelected
+ {
+ get => _alwaysSelected;
+ set => this.RaiseAndSetIfChanged(ref _alwaysSelected, value);
+ }
+
+ public bool AutoScrollToSelectedItem
+ {
+ get => _autoScrollToSelectedItem;
+ set => this.RaiseAndSetIfChanged(ref _autoScrollToSelectedItem, value);
+ }
+
+ public MiniCommand AddItemCommand { get; }
+ public MiniCommand RemoveItemCommand { get; }
+ public MiniCommand SelectRandomItemCommand { get; }
+
+ private string GenerateItem() => $"Item {_counter++.ToString()}";
+ }
+}
diff --git a/samples/ControlCatalog/ViewModels/MainWindowViewModel.cs b/samples/ControlCatalog/ViewModels/MainWindowViewModel.cs
index 89e7653618..4b3cfa9c9d 100644
--- a/samples/ControlCatalog/ViewModels/MainWindowViewModel.cs
+++ b/samples/ControlCatalog/ViewModels/MainWindowViewModel.cs
@@ -1,35 +1,48 @@
using System.Reactive;
+using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls.Notifications;
using Avalonia.Dialogs;
-using ReactiveUI;
+using Avalonia.Platform;
+using System;
+using MiniMvvm;
namespace ControlCatalog.ViewModels
{
- class MainWindowViewModel : ReactiveObject
+ class MainWindowViewModel : ViewModelBase
{
private IManagedNotificationManager _notificationManager;
+ private bool _isMenuItemChecked = true;
+ private WindowState _windowState;
+ private WindowState[] _windowStates;
+ private int _transparencyLevel;
+ private ExtendClientAreaChromeHints _chromeHints;
+ private bool _extendClientAreaEnabled;
+ private bool _systemTitleBarEnabled;
+ private bool _preferSystemChromeEnabled;
+ private double _titleBarHeight;
+
public MainWindowViewModel(IManagedNotificationManager notificationManager)
{
_notificationManager = notificationManager;
- ShowCustomManagedNotificationCommand = ReactiveCommand.Create(() =>
+ ShowCustomManagedNotificationCommand = MiniCommand.Create(() =>
{
NotificationManager.Show(new NotificationViewModel(NotificationManager) { Title = "Hey There!", Message = "Did you know that Avalonia now supports Custom In-Window Notifications?" });
});
- ShowManagedNotificationCommand = ReactiveCommand.Create(() =>
+ ShowManagedNotificationCommand = MiniCommand.Create(() =>
{
NotificationManager.Show(new Avalonia.Controls.Notifications.Notification("Welcome", "Avalonia now supports Notifications.", NotificationType.Information));
});
- ShowNativeNotificationCommand = ReactiveCommand.Create(() =>
+ ShowNativeNotificationCommand = MiniCommand.Create(() =>
{
NotificationManager.Show(new Avalonia.Controls.Notifications.Notification("Error", "Native Notifications are not quite ready. Coming soon.", NotificationType.Error));
});
- AboutCommand = ReactiveCommand.CreateFromTask(async () =>
+ AboutCommand = MiniCommand.CreateFromTask(async () =>
{
var dialog = new AboutAvaloniaDialog();
@@ -38,10 +51,94 @@ namespace ControlCatalog.ViewModels
await dialog.ShowDialog(mainWindow);
});
- ExitCommand = ReactiveCommand.Create(() =>
+ ExitCommand = MiniCommand.Create(() =>
{
(App.Current.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime).Shutdown();
});
+
+ ToggleMenuItemCheckedCommand = MiniCommand.Create(() =>
+ {
+ IsMenuItemChecked = !IsMenuItemChecked;
+ });
+
+ WindowState = WindowState.Normal;
+
+ WindowStates = new WindowState[]
+ {
+ WindowState.Minimized,
+ WindowState.Normal,
+ WindowState.Maximized,
+ WindowState.FullScreen,
+ };
+
+ this.WhenAnyValue(x => x.SystemTitleBarEnabled, x=>x.PreferSystemChromeEnabled)
+ .Subscribe(x =>
+ {
+ var hints = ExtendClientAreaChromeHints.NoChrome | ExtendClientAreaChromeHints.OSXThickTitleBar;
+
+ if(x.Item1)
+ {
+ hints |= ExtendClientAreaChromeHints.SystemChrome;
+ }
+
+ if(x.Item2)
+ {
+ hints |= ExtendClientAreaChromeHints.PreferSystemChrome;
+ }
+
+ ChromeHints = hints;
+ });
+
+ SystemTitleBarEnabled = true;
+ TitleBarHeight = -1;
+ }
+
+ public int TransparencyLevel
+ {
+ get { return _transparencyLevel; }
+ set { this.RaiseAndSetIfChanged(ref _transparencyLevel, value); }
+ }
+
+ public ExtendClientAreaChromeHints ChromeHints
+ {
+ get { return _chromeHints; }
+ set { this.RaiseAndSetIfChanged(ref _chromeHints, value); }
+ }
+
+ public bool ExtendClientAreaEnabled
+ {
+ get { return _extendClientAreaEnabled; }
+ set { this.RaiseAndSetIfChanged(ref _extendClientAreaEnabled, value); }
+ }
+
+ public bool SystemTitleBarEnabled
+ {
+ get { return _systemTitleBarEnabled; }
+ set { this.RaiseAndSetIfChanged(ref _systemTitleBarEnabled, value); }
+ }
+
+ public bool PreferSystemChromeEnabled
+ {
+ get { return _preferSystemChromeEnabled; }
+ set { this.RaiseAndSetIfChanged(ref _preferSystemChromeEnabled, value); }
+ }
+
+ public double TitleBarHeight
+ {
+ get { return _titleBarHeight; }
+ set { this.RaiseAndSetIfChanged(ref _titleBarHeight, value); }
+ }
+
+ public WindowState WindowState
+ {
+ get { return _windowState; }
+ set { this.RaiseAndSetIfChanged(ref _windowState, value); }
+ }
+
+ public WindowState[] WindowStates
+ {
+ get { return _windowStates; }
+ set { this.RaiseAndSetIfChanged(ref _windowStates, value); }
}
public IManagedNotificationManager NotificationManager
@@ -50,14 +147,22 @@ namespace ControlCatalog.ViewModels
set { this.RaiseAndSetIfChanged(ref _notificationManager, value); }
}
- public ReactiveCommand ShowCustomManagedNotificationCommand { get; }
+ public bool IsMenuItemChecked
+ {
+ get { return _isMenuItemChecked; }
+ set { this.RaiseAndSetIfChanged(ref _isMenuItemChecked, value); }
+ }
+
+ public MiniCommand ShowCustomManagedNotificationCommand { get; }
+
+ public MiniCommand ShowManagedNotificationCommand { get; }
- public ReactiveCommand ShowManagedNotificationCommand { get; }
+ public MiniCommand ShowNativeNotificationCommand { get; }
- public ReactiveCommand ShowNativeNotificationCommand { get; }
+ public MiniCommand AboutCommand { get; }
- public ReactiveCommand AboutCommand { get; }
+ public MiniCommand ExitCommand { get; }
- public ReactiveCommand ExitCommand { get; }
+ public MiniCommand ToggleMenuItemCheckedCommand { get; }
}
}
diff --git a/samples/ControlCatalog/ViewModels/MenuPageViewModel.cs b/samples/ControlCatalog/ViewModels/MenuPageViewModel.cs
index dc9c4a8f49..ecbd59c5d7 100644
--- a/samples/ControlCatalog/ViewModels/MenuPageViewModel.cs
+++ b/samples/ControlCatalog/ViewModels/MenuPageViewModel.cs
@@ -4,7 +4,7 @@ using System.Reactive.Linq;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.VisualTree;
-using ReactiveUI;
+using MiniMvvm;
namespace ControlCatalog.ViewModels
{
@@ -13,10 +13,27 @@ namespace ControlCatalog.ViewModels
public Control View { get; set; }
public MenuPageViewModel()
{
- OpenCommand = ReactiveCommand.CreateFromTask(Open);
- SaveCommand = ReactiveCommand.Create(Save, Observable.Return(false));
- OpenRecentCommand = ReactiveCommand.Create(OpenRecent);
+ OpenCommand = MiniCommand.CreateFromTask(Open);
+ SaveCommand = MiniCommand.Create(Save);
+ OpenRecentCommand = MiniCommand.Create(OpenRecent);
+ var recentItems = new[]
+ {
+ new MenuItemViewModel
+ {
+ Header = "File1.txt",
+ Command = OpenRecentCommand,
+ CommandParameter = @"c:\foo\File1.txt"
+ },
+ new MenuItemViewModel
+ {
+ Header = "File2.txt",
+ Command = OpenRecentCommand,
+ CommandParameter = @"c:\foo\File2.txt"
+ },
+ };
+
+ RecentItems = recentItems;
MenuItems = new[]
{
new MenuItemViewModel
@@ -24,27 +41,13 @@ namespace ControlCatalog.ViewModels
Header = "_File",
Items = new[]
{
- new MenuItemViewModel { Header = "_Open...", Command = OpenCommand },
+ new MenuItemViewModel { Header = "O_pen...", Command = OpenCommand },
new MenuItemViewModel { Header = "Save", Command = SaveCommand },
new MenuItemViewModel { Header = "-" },
new MenuItemViewModel
{
Header = "Recent",
- Items = new[]
- {
- new MenuItemViewModel
- {
- Header = "File1.txt",
- Command = OpenRecentCommand,
- CommandParameter = @"c:\foo\File1.txt"
- },
- new MenuItemViewModel
- {
- Header = "File2.txt",
- Command = OpenRecentCommand,
- CommandParameter = @"c:\foo\File2.txt"
- },
- }
+ Items = recentItems
},
}
},
@@ -61,9 +64,10 @@ namespace ControlCatalog.ViewModels
}
public IReadOnlyList MenuItems { get; set; }
- public ReactiveCommand OpenCommand { get; }
- public ReactiveCommand SaveCommand { get; }
- public ReactiveCommand OpenRecentCommand { get; }
+ public IReadOnlyList RecentItems { get; set; }
+ public MiniCommand OpenCommand { get; }
+ public MiniCommand SaveCommand { get; }
+ public MiniCommand OpenRecentCommand { get; }
public async Task Open()
{
diff --git a/samples/ControlCatalog/ViewModels/NotificationViewModel.cs b/samples/ControlCatalog/ViewModels/NotificationViewModel.cs
index 8724ba344b..2052481015 100644
--- a/samples/ControlCatalog/ViewModels/NotificationViewModel.cs
+++ b/samples/ControlCatalog/ViewModels/NotificationViewModel.cs
@@ -1,6 +1,6 @@
using System.Reactive;
using Avalonia.Controls.Notifications;
-using ReactiveUI;
+using MiniMvvm;
namespace ControlCatalog.ViewModels
{
@@ -8,12 +8,12 @@ namespace ControlCatalog.ViewModels
{
public NotificationViewModel(INotificationManager manager)
{
- YesCommand = ReactiveCommand.Create(() =>
+ YesCommand = MiniCommand.Create(() =>
{
manager.Show(new Avalonia.Controls.Notifications.Notification("Avalonia Notifications", "Start adding notifications to your app today."));
});
- NoCommand = ReactiveCommand.Create(() =>
+ NoCommand = MiniCommand.Create(() =>
{
manager.Show(new Avalonia.Controls.Notifications.Notification("Avalonia Notifications", "Start adding notifications to your app today. To find out more visit..."));
});
@@ -22,9 +22,9 @@ namespace ControlCatalog.ViewModels
public string Title { get; set; }
public string Message { get; set; }
- public ReactiveCommand YesCommand { get; }
+ public MiniCommand YesCommand { get; }
- public ReactiveCommand NoCommand { get; }
+ public MiniCommand NoCommand { get; }
}
}
diff --git a/samples/ControlCatalog/ViewModels/SplitViewPageViewModel.cs b/samples/ControlCatalog/ViewModels/SplitViewPageViewModel.cs
new file mode 100644
index 0000000000..9e6932bb76
--- /dev/null
+++ b/samples/ControlCatalog/ViewModels/SplitViewPageViewModel.cs
@@ -0,0 +1,46 @@
+using System;
+using Avalonia.Controls;
+using MiniMvvm;
+
+namespace ControlCatalog.ViewModels
+{
+ public class SplitViewPageViewModel : ViewModelBase
+ {
+ private bool _isLeft = true;
+ private int _displayMode = 3; //CompactOverlay
+
+ public bool IsLeft
+ {
+ get => _isLeft;
+ set
+ {
+ this.RaiseAndSetIfChanged(ref _isLeft, value);
+ this.RaisePropertyChanged(nameof(PanePlacement));
+ }
+ }
+
+ public int DisplayMode
+ {
+ get => _displayMode;
+ set
+ {
+ this.RaiseAndSetIfChanged(ref _displayMode, value);
+ this.RaisePropertyChanged(nameof(CurrentDisplayMode));
+ }
+ }
+
+ public SplitViewPanePlacement PanePlacement => _isLeft ? SplitViewPanePlacement.Left : SplitViewPanePlacement.Right;
+
+ public SplitViewDisplayMode CurrentDisplayMode
+ {
+ get
+ {
+ if (Enum.IsDefined(typeof(SplitViewDisplayMode), _displayMode))
+ {
+ return (SplitViewDisplayMode)_displayMode;
+ }
+ return SplitViewDisplayMode.CompactOverlay;
+ }
+ }
+ }
+}
diff --git a/samples/ControlCatalog/ViewModels/TreeViewPageViewModel.cs b/samples/ControlCatalog/ViewModels/TreeViewPageViewModel.cs
new file mode 100644
index 0000000000..c03379330f
--- /dev/null
+++ b/samples/ControlCatalog/ViewModels/TreeViewPageViewModel.cs
@@ -0,0 +1,124 @@
+using System;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Reactive;
+using Avalonia.Controls;
+using MiniMvvm;
+
+namespace ControlCatalog.ViewModels
+{
+ public class TreeViewPageViewModel : ViewModelBase
+ {
+ private readonly Node _root;
+ private SelectionMode _selectionMode;
+
+ public TreeViewPageViewModel()
+ {
+ _root = new Node();
+
+ Items = _root.Children;
+ SelectedItems = new ObservableCollection();
+
+ AddItemCommand = MiniCommand.Create(AddItem);
+ RemoveItemCommand = MiniCommand.Create(RemoveItem);
+ SelectRandomItemCommand = MiniCommand.Create(SelectRandomItem);
+ }
+
+ public ObservableCollection Items { get; }
+ public ObservableCollection SelectedItems { get; }
+ public MiniCommand AddItemCommand { get; }
+ public MiniCommand RemoveItemCommand { get; }
+ public MiniCommand SelectRandomItemCommand { get; }
+
+ public SelectionMode SelectionMode
+ {
+ get => _selectionMode;
+ set
+ {
+ SelectedItems.Clear();
+ this.RaiseAndSetIfChanged(ref _selectionMode, value);
+ }
+ }
+
+ private void AddItem()
+ {
+ var parentItem = SelectedItems.Count > 0 ? (Node)SelectedItems[0] : _root;
+ parentItem.AddItem();
+ }
+
+ private void RemoveItem()
+ {
+ while (SelectedItems.Count > 0)
+ {
+ Node lastItem = (Node)SelectedItems[0];
+ RecursiveRemove(Items, lastItem);
+ SelectedItems.RemoveAt(0);
+ }
+
+ bool RecursiveRemove(ObservableCollection items, Node selectedItem)
+ {
+ if (items.Remove(selectedItem))
+ {
+ return true;
+ }
+
+ foreach (Node item in items)
+ {
+ if (item.AreChildrenInitialized && RecursiveRemove(item.Children, selectedItem))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+
+ private void SelectRandomItem()
+ {
+ var random = new Random();
+ var depth = random.Next(4);
+ var indexes = Enumerable.Range(0, depth).Select(x => random.Next(10));
+ var node = _root;
+
+ foreach (var i in indexes)
+ {
+ node = node.Children[i];
+ }
+
+ SelectedItems.Clear();
+ SelectedItems.Add(node);
+ }
+
+ public class Node
+ {
+ private ObservableCollection _children;
+ private int _childIndex = 10;
+
+ public Node()
+ {
+ Header = "Item";
+ }
+
+ public Node(Node parent, int index)
+ {
+ Parent = parent;
+ Header = parent.Header + ' ' + index;
+ }
+
+ public Node Parent { get; }
+ public string Header { get; }
+ public bool AreChildrenInitialized => _children != null;
+ public ObservableCollection Children => _children ??= CreateChildren();
+ public void AddItem() => Children.Add(new Node(this, _childIndex++));
+ public void RemoveItem(Node child) => Children.Remove(child);
+ public override string ToString() => Header;
+
+ private ObservableCollection CreateChildren()
+ {
+ return new ObservableCollection(
+ Enumerable.Range(0, 10).Select(i => new Node(this, i)));
+ }
+ }
+ }
+}
diff --git a/samples/Directory.Build.props b/samples/Directory.Build.props
index b9075b957b..8fc91aca14 100644
--- a/samples/Directory.Build.props
+++ b/samples/Directory.Build.props
@@ -1,6 +1,7 @@
false
+ $(MSBuildThisFileDirectory)..\src\tools\Avalonia.Designer.HostApp\bin\Debug\netcoreapp2.0\Avalonia.Designer.HostApp.dll
diff --git a/samples/MiniMvvm/MiniCommand.cs b/samples/MiniMvvm/MiniCommand.cs
new file mode 100644
index 0000000000..c6a9273c20
--- /dev/null
+++ b/samples/MiniMvvm/MiniCommand.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Threading.Tasks;
+using System.Windows.Input;
+
+namespace MiniMvvm
+{
+ public sealed class MiniCommand : MiniCommand, ICommand
+ {
+ private readonly Action _cb;
+ private bool _busy;
+ private Func _acb;
+
+ public MiniCommand(Action cb)
+ {
+ _cb = cb;
+ }
+
+ public MiniCommand(Func cb)
+ {
+ _acb = cb;
+ }
+
+ private bool Busy
+ {
+ get => _busy;
+ set
+ {
+ _busy = value;
+ CanExecuteChanged?.Invoke(this, EventArgs.Empty);
+ }
+ }
+
+
+ public override event EventHandler CanExecuteChanged;
+ public override bool CanExecute(object parameter) => !_busy;
+
+ public override async void Execute(object parameter)
+ {
+ if(Busy)
+ return;
+ try
+ {
+ Busy = true;
+ if (_cb != null)
+ _cb((T)parameter);
+ else
+ await _acb((T)parameter);
+ }
+ finally
+ {
+ Busy = false;
+ }
+ }
+ }
+
+ public abstract class MiniCommand : ICommand
+ {
+ public static MiniCommand Create(Action cb) => new MiniCommand
\ No newline at end of file
+
diff --git a/samples/RenderDemo/Pages/GlyphRunPage.xaml b/samples/RenderDemo/Pages/GlyphRunPage.xaml
new file mode 100644
index 0000000000..c2914e8847
--- /dev/null
+++ b/samples/RenderDemo/Pages/GlyphRunPage.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs b/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs
new file mode 100644
index 0000000000..857358f6b2
--- /dev/null
+++ b/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs
@@ -0,0 +1,80 @@
+using System;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using Avalonia.Media;
+using Avalonia.Threading;
+
+namespace RenderDemo.Pages
+{
+ public class GlyphRunPage : UserControl
+ {
+ private Image _imageControl;
+ private GlyphTypeface _glyphTypeface = Typeface.Default.GlyphTypeface;
+ private readonly Random _rand = new Random();
+ private ushort[] _glyphIndices = new ushort[1];
+ private float _fontSize = 20;
+ private int _direction = 10;
+
+ public GlyphRunPage()
+ {
+ this.InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+
+ _imageControl = this.FindControl("imageControl");
+ _imageControl.Source = new DrawingImage();
+
+ DispatcherTimer.Run(() =>
+ {
+ UpdateGlyphRun();
+
+ return true;
+ }, TimeSpan.FromSeconds(1));
+ }
+
+ private void UpdateGlyphRun()
+ {
+ var c = (uint)_rand.Next(65, 90);
+
+ if (_fontSize + _direction > 200)
+ {
+ _direction = -10;
+ }
+
+ if (_fontSize + _direction < 20)
+ {
+ _direction = 10;
+ }
+
+ _fontSize += _direction;
+
+ _glyphIndices[0] = _glyphTypeface.GetGlyph(c);
+
+ var scale = (double)_fontSize / _glyphTypeface.DesignEmHeight;
+
+ var drawingGroup = new DrawingGroup();
+
+ var glyphRunDrawing = new GlyphRunDrawing
+ {
+ Foreground = Brushes.Black,
+ GlyphRun = new GlyphRun(_glyphTypeface, _fontSize, _glyphIndices),
+ };
+
+ drawingGroup.Children.Add(glyphRunDrawing);
+
+ var geometryDrawing = new GeometryDrawing
+ {
+ Pen = new Pen(Brushes.Black),
+ Geometry = new RectangleGeometry { Rect = new Rect(glyphRunDrawing.GlyphRun.Size) }
+ };
+
+ drawingGroup.Children.Add(geometryDrawing);
+
+ (_imageControl.Source as DrawingImage).Drawing = drawingGroup;
+ }
+ }
+}
diff --git a/samples/RenderDemo/Pages/LineBoundsPage.xaml b/samples/RenderDemo/Pages/LineBoundsPage.xaml
new file mode 100644
index 0000000000..07d658630a
--- /dev/null
+++ b/samples/RenderDemo/Pages/LineBoundsPage.xaml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/samples/RenderDemo/Pages/LineBoundsPage.xaml.cs b/samples/RenderDemo/Pages/LineBoundsPage.xaml.cs
new file mode 100644
index 0000000000..28ddedd4bc
--- /dev/null
+++ b/samples/RenderDemo/Pages/LineBoundsPage.xaml.cs
@@ -0,0 +1,19 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace RenderDemo.Pages
+{
+ public class LineBoundsPage : UserControl
+ {
+ public LineBoundsPage()
+ {
+ this.InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}
diff --git a/samples/RenderDemo/Pages/RenderTargetBitmapPage.cs b/samples/RenderDemo/Pages/RenderTargetBitmapPage.cs
index 3eb2276c48..f263786ab7 100644
--- a/samples/RenderDemo/Pages/RenderTargetBitmapPage.cs
+++ b/samples/RenderDemo/Pages/RenderTargetBitmapPage.cs
@@ -39,7 +39,7 @@ namespace RenderDemo.Pages
ctx.FillRectangle(Brushes.Fuchsia, new Rect(50, 50, 100, 100));
}
- context.DrawImage(_bitmap, 1,
+ context.DrawImage(_bitmap,
new Rect(0, 0, 200, 200),
new Rect(0, 0, 200, 200));
Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background);
diff --git a/samples/RenderDemo/Pages/TransitionsPage.xaml b/samples/RenderDemo/Pages/TransitionsPage.xaml
new file mode 100644
index 0000000000..d6da293ff3
--- /dev/null
+++ b/samples/RenderDemo/Pages/TransitionsPage.xaml
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hover to activate Transform Keyframe Animations.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/RenderDemo/Pages/TransitionsPage.xaml.cs b/samples/RenderDemo/Pages/TransitionsPage.xaml.cs
new file mode 100644
index 0000000000..5f446c9e99
--- /dev/null
+++ b/samples/RenderDemo/Pages/TransitionsPage.xaml.cs
@@ -0,0 +1,37 @@
+using Avalonia.Animation;
+using Avalonia.Controls;
+using Avalonia.Interactivity;
+using Avalonia.Markup.Xaml;
+using RenderDemo.ViewModels;
+
+namespace RenderDemo.Pages
+{
+ public class TransitionsPage : UserControl
+ {
+ public TransitionsPage()
+ {
+ InitializeComponent();
+ this.DataContext = new AnimationsPageViewModel();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+
+ private void ToggleClock(object sender, RoutedEventArgs args)
+ {
+ var button = sender as Button;
+ var clock = button.Clock;
+
+ if (clock.PlayState == PlayState.Run)
+ {
+ clock.PlayState = PlayState.Pause;
+ }
+ else if (clock.PlayState == PlayState.Pause)
+ {
+ clock.PlayState = PlayState.Run;
+ }
+ }
+ }
+}
diff --git a/samples/RenderDemo/Pages/WriteableBitmapPage.cs b/samples/RenderDemo/Pages/WriteableBitmapPage.cs
new file mode 100644
index 0000000000..850e398a93
--- /dev/null
+++ b/samples/RenderDemo/Pages/WriteableBitmapPage.cs
@@ -0,0 +1,92 @@
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.LogicalTree;
+using Avalonia.Media;
+using Avalonia.Media.Imaging;
+using Avalonia.Media.Immutable;
+using Avalonia.Platform;
+using Avalonia.Threading;
+
+namespace RenderDemo.Pages
+{
+ public class WriteableBitmapPage : Control
+ {
+ private WriteableBitmap _unpremulBitmap;
+ private WriteableBitmap _premulBitmap;
+ private readonly Stopwatch _st = Stopwatch.StartNew();
+
+ protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
+ {
+ _unpremulBitmap = new WriteableBitmap(new PixelSize(256, 256), new Vector(96, 96), PixelFormat.Bgra8888, AlphaFormat.Unpremul);
+ _premulBitmap = new WriteableBitmap(new PixelSize(256, 256), new Vector(96, 96), PixelFormat.Bgra8888, AlphaFormat.Premul);
+
+ base.OnAttachedToLogicalTree(e);
+ }
+
+ protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
+ {
+ base.OnDetachedFromLogicalTree(e);
+
+ _unpremulBitmap?.Dispose();
+ _unpremulBitmap = null;
+
+ _premulBitmap?.Dispose();
+ _unpremulBitmap = null;
+ }
+
+ public override void Render(DrawingContext context)
+ {
+ void FillPixels(WriteableBitmap bitmap, byte fillAlpha, bool premul)
+ {
+ using (var fb = bitmap.Lock())
+ {
+ var data = new int[fb.Size.Width * fb.Size.Height];
+
+ for (int y = 0; y < fb.Size.Height; y++)
+ {
+ for (int x = 0; x < fb.Size.Width; x++)
+ {
+ var color = new Color(fillAlpha, 0, 255, 0);
+
+ if (premul)
+ {
+ byte r = (byte) (color.R * color.A / 255);
+ byte g = (byte) (color.G * color.A / 255);
+ byte b = (byte) (color.B * color.A / 255);
+
+ color = new Color(fillAlpha, r, g, b);
+ }
+
+ data[y * fb.Size.Width + x] = (int) color.ToUint32();
+ }
+ }
+
+ Marshal.Copy(data, 0, fb.Address, fb.Size.Width * fb.Size.Height);
+ }
+ }
+
+ base.Render(context);
+
+ byte alpha = (byte)((_st.ElapsedMilliseconds / 10) % 256);
+
+ FillPixels(_unpremulBitmap, alpha, false);
+ FillPixels(_premulBitmap, alpha, true);
+
+ context.FillRectangle(Brushes.Red, new Rect(0, 0, 256 * 3, 256));
+
+ context.DrawImage(_unpremulBitmap,
+ new Rect(0, 0, 256, 256),
+ new Rect(0, 0, 256, 256));
+
+ context.DrawImage(_premulBitmap,
+ new Rect(0, 0, 256, 256),
+ new Rect(256, 0, 256, 256));
+
+ context.FillRectangle(new ImmutableSolidColorBrush(Colors.Lime, alpha / 255d), new Rect(512, 0, 256, 256));
+
+ Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background);
+ }
+ }
+}
diff --git a/samples/RenderDemo/RenderDemo.csproj b/samples/RenderDemo/RenderDemo.csproj
index bbd8666456..bba1d23e0a 100644
--- a/samples/RenderDemo/RenderDemo.csproj
+++ b/samples/RenderDemo/RenderDemo.csproj
@@ -1,17 +1,21 @@
Exe
- netcoreapp2.0;net461
+ netcoreapp3.1
+
+
+
+
+
+
-
-
diff --git a/samples/RenderDemo/SideBar.xaml b/samples/RenderDemo/SideBar.xaml
index d6bde0b146..fd23067f61 100644
--- a/samples/RenderDemo/SideBar.xaml
+++ b/samples/RenderDemo/SideBar.xaml
@@ -1,65 +1,68 @@
-
+
-
-
-
-
-
+
+
+
+
+
+
diff --git a/samples/RenderDemo/ViewModels/MainWindowViewModel.cs b/samples/RenderDemo/ViewModels/MainWindowViewModel.cs
index d2d789a687..19917c20df 100644
--- a/samples/RenderDemo/ViewModels/MainWindowViewModel.cs
+++ b/samples/RenderDemo/ViewModels/MainWindowViewModel.cs
@@ -1,33 +1,68 @@
-using System;
-using System.Reactive;
-using ReactiveUI;
+using System.Reactive;
+using System.Threading.Tasks;
+using MiniMvvm;
namespace RenderDemo.ViewModels
{
- public class MainWindowViewModel : ReactiveObject
+ public class MainWindowViewModel : ViewModelBase
{
private bool drawDirtyRects = false;
private bool drawFps = true;
+ private double width = 800;
+ private double height = 600;
public MainWindowViewModel()
{
- ToggleDrawDirtyRects = ReactiveCommand.Create(() => DrawDirtyRects = !DrawDirtyRects);
- ToggleDrawFps = ReactiveCommand.Create(() => DrawFps = !DrawFps);
+ ToggleDrawDirtyRects = MiniCommand.Create(() => DrawDirtyRects = !DrawDirtyRects);
+ ToggleDrawFps = MiniCommand.Create(() => DrawFps = !DrawFps);
+ ResizeWindow = MiniCommand.CreateFromTask(ResizeWindowAsync);
}
public bool DrawDirtyRects
{
- get { return drawDirtyRects; }
- set { this.RaiseAndSetIfChanged(ref drawDirtyRects, value); }
+ get => drawDirtyRects;
+ set => this.RaiseAndSetIfChanged(ref drawDirtyRects, value);
}
public bool DrawFps
{
- get { return drawFps; }
- set { this.RaiseAndSetIfChanged(ref drawFps, value); }
+ get => drawFps;
+ set => this.RaiseAndSetIfChanged(ref drawFps, value);
}
- public ReactiveCommand ToggleDrawDirtyRects { get; }
- public ReactiveCommand ToggleDrawFps { get; }
+ public double Width
+ {
+ get => width;
+ set => this.RaiseAndSetIfChanged(ref width, value);
+ }
+
+ public double Height
+ {
+ get => height;
+ set => this.RaiseAndSetIfChanged(ref height, value);
+ }
+
+ public MiniCommand ToggleDrawDirtyRects { get; }
+ public MiniCommand ToggleDrawFps { get; }
+ public MiniCommand ResizeWindow { get; }
+
+ private async Task ResizeWindowAsync()
+ {
+ for (int i = 0; i < 30; i++)
+ {
+ Width += 10;
+ Height += 5;
+ await Task.Delay(10);
+ }
+
+ await Task.Delay(10);
+
+ for (int i = 0; i < 30; i++)
+ {
+ Width -= 10;
+ Height -= 5;
+ await Task.Delay(10);
+ }
+ }
}
}
diff --git a/samples/Sandbox/App.axaml b/samples/Sandbox/App.axaml
new file mode 100644
index 0000000000..f601f9f78f
--- /dev/null
+++ b/samples/Sandbox/App.axaml
@@ -0,0 +1,8 @@
+
+
+
+
+
diff --git a/samples/Sandbox/App.axaml.cs b/samples/Sandbox/App.axaml.cs
new file mode 100644
index 0000000000..7eb8345784
--- /dev/null
+++ b/samples/Sandbox/App.axaml.cs
@@ -0,0 +1,22 @@
+using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Markup.Xaml;
+
+namespace Sandbox
+{
+ public class App : Application
+ {
+ public override void Initialize()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+
+ public override void OnFrameworkInitializationCompleted()
+ {
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktopLifetime)
+ {
+ desktopLifetime.MainWindow = new MainWindow();
+ }
+ }
+ }
+}
diff --git a/samples/Sandbox/MainWindow.axaml b/samples/Sandbox/MainWindow.axaml
new file mode 100644
index 0000000000..6929f192c7
--- /dev/null
+++ b/samples/Sandbox/MainWindow.axaml
@@ -0,0 +1,4 @@
+
+
diff --git a/samples/Sandbox/MainWindow.axaml.cs b/samples/Sandbox/MainWindow.axaml.cs
new file mode 100644
index 0000000000..3d54036d29
--- /dev/null
+++ b/samples/Sandbox/MainWindow.axaml.cs
@@ -0,0 +1,21 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using Avalonia.Win32.WinRT.Composition;
+
+namespace Sandbox
+{
+ public class MainWindow : Window
+ {
+ public MainWindow()
+ {
+ this.InitializeComponent();
+ this.AttachDevTools();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}
diff --git a/samples/Sandbox/Program.cs b/samples/Sandbox/Program.cs
new file mode 100644
index 0000000000..1e74105196
--- /dev/null
+++ b/samples/Sandbox/Program.cs
@@ -0,0 +1,15 @@
+using Avalonia;
+
+namespace Sandbox
+{
+ public class Program
+ {
+ static void Main(string[] args)
+ {
+ AppBuilder.Configure()
+ .UsePlatformDetect()
+ .LogToTrace()
+ .StartWithClassicDesktopLifetime(args);
+ }
+ }
+}
diff --git a/samples/Sandbox/Sandbox.csproj b/samples/Sandbox/Sandbox.csproj
new file mode 100644
index 0000000000..0c19440a1e
--- /dev/null
+++ b/samples/Sandbox/Sandbox.csproj
@@ -0,0 +1,17 @@
+
+
+
+ WinExe
+ netcoreapp3.1
+ true
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/VirtualizationDemo/App.xaml.cs b/samples/VirtualizationDemo/App.xaml.cs
index b220807443..81b80c1f40 100644
--- a/samples/VirtualizationDemo/App.xaml.cs
+++ b/samples/VirtualizationDemo/App.xaml.cs
@@ -1,7 +1,5 @@
-// Copyright (c) The Avalonia Project. All rights reserved.
-// Licensed under the MIT license. See licence.md file in the project root for full license information.
-
using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
namespace VirtualizationDemo
@@ -12,5 +10,12 @@ namespace VirtualizationDemo
{
AvaloniaXamlLoader.Load(this);
}
+
+ public override void OnFrameworkInitializationCompleted()
+ {
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ desktop.MainWindow = new MainWindow();
+ base.OnFrameworkInitializationCompleted();
+ }
}
}
diff --git a/samples/VirtualizationDemo/MainWindow.xaml b/samples/VirtualizationDemo/MainWindow.xaml
index 12137cd03d..4bd657bf93 100644
--- a/samples/VirtualizationDemo/MainWindow.xaml
+++ b/samples/VirtualizationDemo/MainWindow.xaml
@@ -45,7 +45,7 @@
()
- .UsePlatformDetect()
- .UseReactiveUI()
- .LogToDebug()
- .Start();
- }
+ public static AppBuilder BuildAvaloniaApp()
+ => AppBuilder.Configure()
+ .UsePlatformDetect()
+ .LogToTrace();
+
+ public static int Main(string[] args)
+ => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
}
}
diff --git a/samples/VirtualizationDemo/ViewModels/ItemViewModel.cs b/samples/VirtualizationDemo/ViewModels/ItemViewModel.cs
index 4401a2dfeb..9ba505ffe5 100644
--- a/samples/VirtualizationDemo/ViewModels/ItemViewModel.cs
+++ b/samples/VirtualizationDemo/ViewModels/ItemViewModel.cs
@@ -1,12 +1,9 @@
-// Copyright (c) The Avalonia Project. All rights reserved.
-// Licensed under the MIT license. See licence.md file in the project root for full license information.
-
-using System;
-using ReactiveUI;
+using System;
+using MiniMvvm;
namespace VirtualizationDemo.ViewModels
{
- internal class ItemViewModel : ReactiveObject
+ internal class ItemViewModel : ViewModelBase
{
private string _prefix;
private int _index;
diff --git a/samples/VirtualizationDemo/ViewModels/MainWindowViewModel.cs b/samples/VirtualizationDemo/ViewModels/MainWindowViewModel.cs
index 649c64ab1d..514df691ae 100644
--- a/samples/VirtualizationDemo/ViewModels/MainWindowViewModel.cs
+++ b/samples/VirtualizationDemo/ViewModels/MainWindowViewModel.cs
@@ -1,19 +1,17 @@
-// Copyright (c) The Avalonia Project. All rights reserved.
-// Licensed under the MIT license. See licence.md file in the project root for full license information.
-
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
-using ReactiveUI;
using Avalonia.Layout;
+using Avalonia.Controls.Selection;
+using MiniMvvm;
namespace VirtualizationDemo.ViewModels
{
- internal class MainWindowViewModel : ReactiveObject
+ internal class MainWindowViewModel : ViewModelBase
{
private int _itemCount = 200;
private string _newItemString = "New Item";
@@ -28,15 +26,15 @@ namespace VirtualizationDemo.ViewModels
public MainWindowViewModel()
{
this.WhenAnyValue(x => x.ItemCount).Subscribe(ResizeItems);
- RecreateCommand = ReactiveCommand.Create(() => Recreate());
+ RecreateCommand = MiniCommand.Create(() => Recreate());
- AddItemCommand = ReactiveCommand.Create(() => AddItem());
+ AddItemCommand = MiniCommand.Create(() => AddItem());
- RemoveItemCommand = ReactiveCommand.Create(() => Remove());
+ RemoveItemCommand = MiniCommand.Create(() => Remove());
- SelectFirstCommand = ReactiveCommand.Create(() => SelectItem(0));
+ SelectFirstCommand = MiniCommand.Create(() => SelectItem(0));
- SelectLastCommand = ReactiveCommand.Create(() => SelectItem(Items.Count - 1));
+ SelectLastCommand = MiniCommand.Create(() => SelectItem(Items.Count - 1));
}
public string NewItemString
@@ -51,8 +49,7 @@ namespace VirtualizationDemo.ViewModels
set { this.RaiseAndSetIfChanged(ref _itemCount, value); }
}
- public AvaloniaList SelectedItems { get; }
- = new AvaloniaList();
+ public SelectionModel Selection { get; } = new SelectionModel();
public AvaloniaList Items
{
@@ -93,11 +90,11 @@ namespace VirtualizationDemo.ViewModels
public IEnumerable VirtualizationModes =>
Enum.GetValues(typeof(ItemVirtualizationMode)).Cast();
- public ReactiveCommand AddItemCommand { get; private set; }
- public ReactiveCommand RecreateCommand { get; private set; }
- public ReactiveCommand RemoveItemCommand { get; private set; }
- public ReactiveCommand SelectFirstCommand { get; private set; }
- public ReactiveCommand SelectLastCommand { get; private set; }
+ public MiniCommand AddItemCommand { get; private set; }
+ public MiniCommand RecreateCommand { get; private set; }
+ public MiniCommand RemoveItemCommand { get; private set; }
+ public MiniCommand SelectFirstCommand { get; private set; }
+ public MiniCommand SelectLastCommand { get; private set; }
public void RandomizeSize()
{
@@ -141,9 +138,9 @@ namespace VirtualizationDemo.ViewModels
{
var index = Items.Count;
- if (SelectedItems.Count > 0)
+ if (Selection.SelectedItems.Count > 0)
{
- index = Items.IndexOf(SelectedItems[0]);
+ index = Selection.SelectedIndex;
}
Items.Insert(index, new ItemViewModel(_newItemIndex++, NewItemString));
@@ -151,9 +148,9 @@ namespace VirtualizationDemo.ViewModels
private void Remove()
{
- if (SelectedItems.Count > 0)
+ if (Selection.SelectedItems.Count > 0)
{
- Items.RemoveAll(SelectedItems);
+ Items.RemoveAll(Selection.SelectedItems.ToList());
}
}
@@ -167,8 +164,7 @@ namespace VirtualizationDemo.ViewModels
private void SelectItem(int index)
{
- SelectedItems.Clear();
- SelectedItems.Add(Items[index]);
+ Selection.SelectedIndex = index;
}
}
}
diff --git a/samples/VirtualizationDemo/VirtualizationDemo.csproj b/samples/VirtualizationDemo/VirtualizationDemo.csproj
index 3005fdbc51..d898b737a9 100644
--- a/samples/VirtualizationDemo/VirtualizationDemo.csproj
+++ b/samples/VirtualizationDemo/VirtualizationDemo.csproj
@@ -1,17 +1,16 @@
Exe
- netcoreapp2.0;net461
+ netcoreapp3.1
+
-
+
-
-
diff --git a/samples/interop/Direct3DInteropSample/App.paml.cs b/samples/interop/Direct3DInteropSample/App.paml.cs
index 1b6d5fd39c..29365decfe 100644
--- a/samples/interop/Direct3DInteropSample/App.paml.cs
+++ b/samples/interop/Direct3DInteropSample/App.paml.cs
@@ -1,4 +1,5 @@
using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
namespace Direct3DInteropSample
@@ -9,5 +10,12 @@ namespace Direct3DInteropSample
{
AvaloniaXamlLoader.Load(this);
}
+
+ public override void OnFrameworkInitializationCompleted()
+ {
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ desktop.MainWindow = new MainWindow();
+ base.OnFrameworkInitializationCompleted();
+ }
}
}
diff --git a/samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj b/samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj
index 3e318278c1..cd9963a2e5 100644
--- a/samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj
+++ b/samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj
@@ -22,11 +22,10 @@
-
+
-
diff --git a/samples/interop/Direct3DInteropSample/MainWindow.cs b/samples/interop/Direct3DInteropSample/MainWindow.cs
index 1ac4b44a74..6cc3cb9116 100644
--- a/samples/interop/Direct3DInteropSample/MainWindow.cs
+++ b/samples/interop/Direct3DInteropSample/MainWindow.cs
@@ -1,7 +1,4 @@
-// Copyright (c) The Avalonia Project. All rights reserved.
-// Licensed under the MIT license. See licence.md file in the project root for full license information.
-
-using System;
+using System;
using Avalonia;
using Avalonia.Controls;
diff --git a/samples/interop/Direct3DInteropSample/MainWindowViewModel.cs b/samples/interop/Direct3DInteropSample/MainWindowViewModel.cs
index d39a21cd07..21679a99c5 100644
--- a/samples/interop/Direct3DInteropSample/MainWindowViewModel.cs
+++ b/samples/interop/Direct3DInteropSample/MainWindowViewModel.cs
@@ -3,11 +3,11 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-using ReactiveUI;
+using MiniMvvm;
namespace Direct3DInteropSample
{
- public class MainWindowViewModel : ReactiveObject
+ public class MainWindowViewModel : ViewModelBase
{
private double _rotationX;
diff --git a/samples/interop/Direct3DInteropSample/Program.cs b/samples/interop/Direct3DInteropSample/Program.cs
index 21302fa68a..bf8e76d7e4 100644
--- a/samples/interop/Direct3DInteropSample/Program.cs
+++ b/samples/interop/Direct3DInteropSample/Program.cs
@@ -1,19 +1,16 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Avalonia;
+using Avalonia;
namespace Direct3DInteropSample
{
class Program
{
- static void Main(string[] args)
- {
- AppBuilder.Configure()
- .With(new Win32PlatformOptions {UseDeferredRendering = false})
- .UseWin32().UseDirect2D1().Start();
- }
+ public static AppBuilder BuildAvaloniaApp()
+ => AppBuilder.Configure()
+ .With(new Win32PlatformOptions { UseDeferredRendering = false })
+ .UseWin32()
+ .UseDirect2D1();
+
+ public static int Main(string[] args)
+ => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
}
}
diff --git a/samples/interop/NativeEmbedSample/App.xaml b/samples/interop/NativeEmbedSample/App.xaml
new file mode 100644
index 0000000000..e35ade4087
--- /dev/null
+++ b/samples/interop/NativeEmbedSample/App.xaml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/samples/interop/NativeEmbedSample/App.xaml.cs b/samples/interop/NativeEmbedSample/App.xaml.cs
new file mode 100644
index 0000000000..cb17cfc35d
--- /dev/null
+++ b/samples/interop/NativeEmbedSample/App.xaml.cs
@@ -0,0 +1,22 @@
+using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Markup.Xaml;
+
+namespace NativeEmbedSample
+{
+ public class App : Application
+ {
+ public override void Initialize()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+
+ public override void OnFrameworkInitializationCompleted()
+ {
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktopLifetime)
+ desktopLifetime.MainWindow = new MainWindow();
+
+ base.OnFrameworkInitializationCompleted();
+ }
+ }
+}
diff --git a/samples/interop/NativeEmbedSample/EmbedSample.cs b/samples/interop/NativeEmbedSample/EmbedSample.cs
new file mode 100644
index 0000000000..ab9df11e19
--- /dev/null
+++ b/samples/interop/NativeEmbedSample/EmbedSample.cs
@@ -0,0 +1,121 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+using Avalonia.Controls;
+using Avalonia.Platform;
+using Avalonia.Threading;
+using MonoMac.AppKit;
+using MonoMac.Foundation;
+using MonoMac.WebKit;
+using Encoding = SharpDX.Text.Encoding;
+
+namespace NativeEmbedSample
+{
+ public class EmbedSample : NativeControlHost
+ {
+ public bool IsSecond { get; set; }
+ private Process _mplayer;
+
+ IPlatformHandle CreateLinux(IPlatformHandle parent)
+ {
+ if (IsSecond)
+ {
+ var chooser = GtkHelper.CreateGtkFileChooser(parent.Handle);
+ if (chooser != null)
+ return chooser;
+ }
+
+ var control = base.CreateNativeControlCore(parent);
+ var nodes = Path.GetFullPath(Path.Combine(typeof(EmbedSample).Assembly.GetModules()[0].FullyQualifiedName,
+ "..",
+ "nodes.mp4"));
+ _mplayer = Process.Start(new ProcessStartInfo("mplayer",
+ $"-vo x11 -zoom -loop 0 -wid {control.Handle.ToInt64()} \"{nodes}\"")
+ {
+ UseShellExecute = false,
+
+ });
+ return control;
+ }
+
+ void DestroyLinux(IPlatformHandle handle)
+ {
+ _mplayer?.Kill();
+ _mplayer = null;
+ base.DestroyNativeControlCore(handle);
+ }
+
+ private const string RichText =
+ @"{\rtf1\ansi\ansicpg1251\deff0\nouicompat\deflang1049{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
+{\colortbl ;\red255\green0\blue0;\red0\green77\blue187;\red0\green176\blue80;\red155\green0\blue211;\red247\green150\blue70;\red75\green172\blue198;}
+{\*\generator Riched20 6.3.9600}\viewkind4\uc1
+\pard\sa200\sl276\slmult1\f0\fs22\lang9 I \i am\i0 a \cf1\b Rich Text \cf0\b0\fs24 control\cf2\fs28 !\cf3\fs32 !\cf4\fs36 !\cf1\fs40 !\cf5\fs44 !\cf6\fs48 !\cf0\fs44\par
+}";
+
+ IPlatformHandle CreateWin32(IPlatformHandle parent)
+ {
+ WinApi.LoadLibrary("Msftedit.dll");
+ var handle = WinApi.CreateWindowEx(0, "RICHEDIT50W",
+ @"Rich Edit",
+ 0x800000 | 0x10000000 | 0x40000000 | 0x800000 | 0x10000 | 0x0004, 0, 0, 1, 1, parent.Handle,
+ IntPtr.Zero, WinApi.GetModuleHandle(null), IntPtr.Zero);
+ var st = new WinApi.SETTEXTEX { Codepage = 65001, Flags = 0x00000008 };
+ var text = RichText.Replace("", IsSecond ? "\\qr " : "");
+ var bytes = Encoding.UTF8.GetBytes(text);
+ WinApi.SendMessage(handle, 0x0400 + 97, ref st, bytes);
+ return new PlatformHandle(handle, "HWND");
+
+ }
+
+ void DestroyWin32(IPlatformHandle handle)
+ {
+ WinApi.DestroyWindow(handle.Handle);
+ }
+
+ IPlatformHandle CreateOSX(IPlatformHandle parent)
+ {
+ // Note: We are using MonoMac for example purposes
+ // It shouldn't be used in production apps
+ MacHelper.EnsureInitialized();
+
+ var webView = new WebView();
+ Dispatcher.UIThread.Post(() =>
+ {
+ webView.MainFrame.LoadRequest(new NSUrlRequest(new NSUrl(
+ IsSecond ? "https://bing.com": "https://google.com/")));
+ });
+ return new MacOSViewHandle(webView);
+
+ }
+
+ void DestroyOSX(IPlatformHandle handle)
+ {
+ ((MacOSViewHandle)handle).Dispose();
+ }
+
+ protected override IPlatformHandle CreateNativeControlCore(IPlatformHandle parent)
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ return CreateLinux(parent);
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ return CreateWin32(parent);
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ return CreateOSX(parent);
+ return base.CreateNativeControlCore(parent);
+ }
+
+ protected override void DestroyNativeControlCore(IPlatformHandle control)
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ DestroyLinux(control);
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ DestroyWin32(control);
+ else if(RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ DestroyOSX(control);
+ else
+ base.DestroyNativeControlCore(control);
+ }
+ }
+}
diff --git a/samples/interop/NativeEmbedSample/GtkHelper.cs b/samples/interop/NativeEmbedSample/GtkHelper.cs
new file mode 100644
index 0000000000..e389a51ef5
--- /dev/null
+++ b/samples/interop/NativeEmbedSample/GtkHelper.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Threading.Tasks;
+using Avalonia.Controls.Platform;
+using Avalonia.Platform;
+using Avalonia.Platform.Interop;
+using Avalonia.X11.NativeDialogs;
+using static Avalonia.X11.NativeDialogs.Gtk;
+using static Avalonia.X11.NativeDialogs.Glib;
+namespace NativeEmbedSample
+{
+ public class GtkHelper
+ {
+ private static Task s_gtkTask;
+ class FileChooser : INativeControlHostDestroyableControlHandle
+ {
+ private readonly IntPtr _widget;
+
+ public FileChooser(IntPtr widget, IntPtr xid)
+ {
+ _widget = widget;
+ Handle = xid;
+ }
+
+ public IntPtr Handle { get; }
+ public string HandleDescriptor => "XID";
+ public void Destroy()
+ {
+ RunOnGlibThread(() =>
+ {
+ gtk_widget_destroy(_widget);
+ return 0;
+ }).Wait();
+ }
+ }
+
+
+
+ public static IPlatformHandle CreateGtkFileChooser(IntPtr parentXid)
+ {
+ if (s_gtkTask == null)
+ s_gtkTask = StartGtk();
+ if (!s_gtkTask.Result)
+ return null;
+ return RunOnGlibThread(() =>
+ {
+ using (var title = new Utf8Buffer("Embedded"))
+ {
+ var widget = gtk_file_chooser_dialog_new(title, IntPtr.Zero, GtkFileChooserAction.SelectFolder,
+ IntPtr.Zero);
+ gtk_widget_realize(widget);
+ var xid = gdk_x11_window_get_xid(gtk_widget_get_window(widget));
+ gtk_window_present(widget);
+ return new FileChooser(widget, xid);
+ }
+ }).Result;
+ }
+ }
+}
diff --git a/samples/interop/NativeEmbedSample/MacHelper.cs b/samples/interop/NativeEmbedSample/MacHelper.cs
new file mode 100644
index 0000000000..74a06a0a0c
--- /dev/null
+++ b/samples/interop/NativeEmbedSample/MacHelper.cs
@@ -0,0 +1,39 @@
+using System;
+using Avalonia.Platform;
+using MonoMac.AppKit;
+
+namespace NativeEmbedSample
+{
+ public class MacHelper
+ {
+ private static bool _isInitialized;
+
+ public static void EnsureInitialized()
+ {
+ if (_isInitialized)
+ return;
+ _isInitialized = true;
+ NSApplication.Init();
+ }
+ }
+
+ class MacOSViewHandle : IPlatformHandle, IDisposable
+ {
+ private NSView _view;
+
+ public MacOSViewHandle(NSView view)
+ {
+ _view = view;
+ }
+
+ public IntPtr Handle => _view?.Handle ?? IntPtr.Zero;
+ public string HandleDescriptor => "NSView";
+
+ public void Dispose()
+ {
+ _view.Dispose();
+ _view = null;
+ }
+ }
+
+}
diff --git a/samples/interop/NativeEmbedSample/MainWindow.xaml b/samples/interop/NativeEmbedSample/MainWindow.xaml
new file mode 100644
index 0000000000..f2161a1bea
--- /dev/null
+++ b/samples/interop/NativeEmbedSample/MainWindow.xaml
@@ -0,0 +1,52 @@
+
+
+
+
+ Show popup (delay)
+ Show popup
+
+
+
+ Text
+
+
+ Tooltip
+
+
+
+
+
+
+
+
+ Visible
+
+
+
+
+
+
+
+ Visible
+
+
+
+
+
+
diff --git a/samples/interop/NativeEmbedSample/MainWindow.xaml.cs b/samples/interop/NativeEmbedSample/MainWindow.xaml.cs
new file mode 100644
index 0000000000..4324aa2762
--- /dev/null
+++ b/samples/interop/NativeEmbedSample/MainWindow.xaml.cs
@@ -0,0 +1,36 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Interactivity;
+using Avalonia.Markup.Xaml;
+
+namespace NativeEmbedSample
+{
+ public class MainWindow : Window
+ {
+ public MainWindow()
+ {
+ AvaloniaXamlLoader.Load(this);
+ this.AttachDevTools();
+ }
+
+ public async void ShowPopupDelay(object sender, RoutedEventArgs args)
+ {
+ await Task.Delay(3000);
+ ShowPopup(sender, args);
+ }
+
+ public void ShowPopup(object sender, RoutedEventArgs args)
+ {
+
+ new ContextMenu()
+ {
+ Items = new List