Browse Source

Merge branch 'master' into features/Issue_11334

pull/11575/head
workgroupengineering 3 years ago
committed by GitHub
parent
commit
139b1822e3
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      .ncrunch/MobileSandbox.Browser.v3.ncrunchproject
  2. 5
      .ncrunch/WindowsInteropTest.net461.v3.ncrunchproject
  3. 5
      .ncrunch/WindowsInteropTest.net6.0-windows.v3.ncrunchproject
  4. 28
      .nuke/build.schema.json
  5. 1
      Avalonia.Desktop.slnf
  6. 41
      Avalonia.sln
  7. 31
      Documentation/build.md
  8. 64
      api/Avalonia.Controls.ColorPicker.nupkg.xml
  9. 418
      api/Avalonia.Themes.Fluent.nupkg.xml
  10. 406
      api/Avalonia.Themes.Simple.nupkg.xml
  11. 10
      api/Avalonia.nupkg.xml
  12. 1
      build/CoreLibraries.props
  13. 1
      build/ExternalConsumers.props
  14. 8
      build/SourceLink.props
  15. 6
      dirs.proj
  16. 1
      native/Avalonia.Native/inc/com.h
  17. 19
      native/Avalonia.Native/inc/comimpl.h
  18. 11
      native/Avalonia.Native/inc/noarc.h
  19. 16
      native/Avalonia.Native/inc/rendertarget.h
  20. 20
      native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj
  21. 5
      native/Avalonia.Native/src/OSX/AvnView.h
  22. 46
      native/Avalonia.Native/src/OSX/AvnView.mm
  23. 6
      native/Avalonia.Native/src/OSX/PopupImpl.mm
  24. 13
      native/Avalonia.Native/src/OSX/WindowBaseImpl.h
  25. 66
      native/Avalonia.Native/src/OSX/WindowBaseImpl.mm
  26. 2
      native/Avalonia.Native/src/OSX/WindowImpl.h
  27. 2
      native/Avalonia.Native/src/OSX/WindowImpl.mm
  28. 18
      native/Avalonia.Native/src/OSX/app.mm
  29. 11
      native/Avalonia.Native/src/OSX/automation.mm
  30. 32
      native/Avalonia.Native/src/OSX/common.h
  31. 44
      native/Avalonia.Native/src/OSX/main.mm
  32. 161
      native/Avalonia.Native/src/OSX/metal.mm
  33. 11
      native/Avalonia.Native/src/OSX/noarc.mm
  34. 245
      native/Avalonia.Native/src/OSX/rendertarget.mm
  35. 154
      nukebuild/ApiDiffValidation.cs
  36. 24
      nukebuild/Build.cs
  37. 22
      nukebuild/BuildParameters.cs
  38. 2
      nukebuild/Numerge
  39. 109
      nukebuild/RefAssemblyGenerator.cs
  40. 4
      nukebuild/Shims.cs
  41. 20
      nukebuild/_build.csproj
  42. 2
      packages/Avalonia/Avalonia.csproj
  43. 1
      packages/Avalonia/Avalonia.targets
  44. 26
      packages/Avalonia/AvaloniaBuildTasks.targets
  45. 26
      packages/Avalonia/AvaloniaPrivateApis.targets
  46. 6
      readme.md
  47. 5
      samples/AppWithoutLifetime/MainWindow.axaml.cs
  48. 6
      samples/AppWithoutLifetime/Sub.axaml.cs
  49. 9
      samples/ControlCatalog.Android/ControlCatalog.Android.csproj
  50. 12
      samples/ControlCatalog.Android/MainActivity.cs
  51. 66
      samples/ControlCatalog.Android/Resources/drawable-night-v31/avalonia_anim.xml
  52. 71
      samples/ControlCatalog.Android/Resources/drawable-v31/avalonia_anim.xml
  53. 21
      samples/ControlCatalog.Android/Resources/values-v31/styles.xml
  54. 11
      samples/ControlCatalog.Android/Resources/values/styles.xml
  55. 35
      samples/ControlCatalog.Android/SplashActivity.cs
  56. 7
      samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj
  57. 11
      samples/ControlCatalog.Desktop/Program.cs
  58. 2
      samples/ControlCatalog.NetCore/NativeControls/Win/WinApi.cs
  59. 25
      samples/ControlCatalog.NetCore/Program.cs
  60. 3
      samples/ControlCatalog/App.xaml
  61. 4
      samples/ControlCatalog/App.xaml.cs
  62. 31
      samples/ControlCatalog/Models/GDPdLengthConverter.cs
  63. 5
      samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml
  64. 10
      samples/ControlCatalog/Pages/CompositionPage.axaml.cs
  65. 25
      samples/ControlCatalog/Pages/DataGridPage.xaml
  66. 16
      samples/ControlCatalog/Pages/GesturePage.cs
  67. 12
      samples/ControlCatalog/ViewModels/ListBoxPageViewModel.cs
  68. 4
      samples/GpuInterop/DrawingSurfaceDemoBase.cs
  69. 8
      samples/MobileSandbox.Android/MainActivity.cs
  70. 10
      samples/MobileSandbox.Android/MobileSandbox.Android.csproj
  71. 66
      samples/MobileSandbox.Android/Resources/drawable-night-v31/avalonia_anim.xml
  72. 71
      samples/MobileSandbox.Android/Resources/drawable-v31/avalonia_anim.xml
  73. 4
      samples/MobileSandbox.Android/Resources/values-night/colors.xml
  74. 16
      samples/MobileSandbox.Android/Resources/values-v31/styles.xml
  75. 7
      samples/MobileSandbox.Android/Resources/values/styles.xml
  76. 17
      samples/MobileSandbox.Android/SplashActivity.cs
  77. 5
      samples/MobileSandbox.Browser/Logo.svg
  78. 43
      samples/MobileSandbox.Browser/MobileSandbox.Browser.csproj
  79. 19
      samples/MobileSandbox.Browser/Program.cs
  80. 12
      samples/MobileSandbox.Browser/Properties/launchSettings.json
  81. 7
      samples/MobileSandbox.Browser/Roots.xml
  82. 56
      samples/MobileSandbox.Browser/app.css
  83. BIN
      samples/MobileSandbox.Browser/favicon.ico
  84. 31
      samples/MobileSandbox.Browser/index.html
  85. 16
      samples/MobileSandbox.Browser/main.js
  86. 11
      samples/MobileSandbox.Browser/runtimeconfig.template.json
  87. 5
      samples/RenderDemo/Pages/CustomStringAnimator.cs
  88. 4
      samples/SafeAreaDemo.Android/MainActivity.cs
  89. 66
      samples/SafeAreaDemo.Android/Resources/drawable-night-v31/avalonia_anim.xml
  90. 71
      samples/SafeAreaDemo.Android/Resources/drawable-v31/avalonia_anim.xml
  91. 4
      samples/SafeAreaDemo.Android/Resources/values-night/colors.xml
  92. 16
      samples/SafeAreaDemo.Android/Resources/values-v31/styles.xml
  93. 7
      samples/SafeAreaDemo.Android/Resources/values/styles.xml
  94. 13
      samples/SafeAreaDemo.Android/SafeAreaDemo.Android.csproj
  95. 30
      samples/SafeAreaDemo.Android/SplashActivity.cs
  96. 6
      samples/SafeAreaDemo/Views/MainView.xaml.cs
  97. 4
      samples/interop/WindowsInteropTest/EmbedToWinFormsDemo.Designer.cs
  98. 23
      samples/interop/WindowsInteropTest/EmbedToWinFormsDemo.cs
  99. 33
      samples/interop/WindowsInteropTest/EmbedToWpfDemo.xaml
  100. 52
      samples/interop/WindowsInteropTest/EmbedToWpfDemo.xaml.cs

5
.ncrunch/MobileSandbox.Browser.v3.ncrunchproject

@ -0,0 +1,5 @@
<ProjectConfiguration>
<Settings>
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
</Settings>
</ProjectConfiguration>

5
.ncrunch/WindowsInteropTest.net461.v3.ncrunchproject

@ -0,0 +1,5 @@
<ProjectConfiguration>
<Settings>
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
</Settings>
</ProjectConfiguration>

5
.ncrunch/WindowsInteropTest.net6.0-windows.v3.ncrunchproject

@ -0,0 +1,5 @@
<ProjectConfiguration>
<Settings>
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
</Settings>
</ProjectConfiguration>

28
.nuke/build.schema.json

@ -6,17 +6,18 @@
"build": { "build": {
"type": "object", "type": "object",
"properties": { "properties": {
"Configuration": { "api-baseline": {
"type": "string", "type": "string"
"description": "configuration" },
"configuration": {
"type": "string"
}, },
"Continue": { "Continue": {
"type": "boolean", "type": "boolean",
"description": "Indicates to continue a previously failed build attempt" "description": "Indicates to continue a previously failed build attempt"
}, },
"ForceNugetVersion": { "force-nuget-version": {
"type": "string", "type": "string"
"description": "force-nuget-version"
}, },
"Help": { "Help": {
"type": "boolean", "type": "boolean",
@ -89,17 +90,16 @@
"RunRenderTests", "RunRenderTests",
"RunTests", "RunTests",
"RunToolsTests", "RunToolsTests",
"ValidateApiDiff",
"ZipFiles" "ZipFiles"
] ]
} }
}, },
"SkipPreviewer": { "skip-previewer": {
"type": "boolean", "type": "boolean"
"description": "skip-previewer"
}, },
"SkipTests": { "skip-tests": {
"type": "boolean", "type": "boolean"
"description": "skip-tests"
}, },
"Target": { "Target": {
"type": "array", "type": "array",
@ -124,10 +124,14 @@
"RunRenderTests", "RunRenderTests",
"RunTests", "RunTests",
"RunToolsTests", "RunToolsTests",
"ValidateApiDiff",
"ZipFiles" "ZipFiles"
] ]
} }
}, },
"update-api-suppression": {
"type": "boolean"
},
"Verbosity": { "Verbosity": {
"type": "string", "type": "string",
"description": "Logging verbosity during build execution. Default is 'Normal'", "description": "Logging verbosity during build execution. Default is 'Normal'",

1
Avalonia.Desktop.slnf

@ -24,6 +24,7 @@
"src\\Avalonia.Dialogs\\Avalonia.Dialogs.csproj", "src\\Avalonia.Dialogs\\Avalonia.Dialogs.csproj",
"src\\Avalonia.Fonts.Inter\\Avalonia.Fonts.Inter.csproj", "src\\Avalonia.Fonts.Inter\\Avalonia.Fonts.Inter.csproj",
"src\\Avalonia.FreeDesktop\\Avalonia.FreeDesktop.csproj", "src\\Avalonia.FreeDesktop\\Avalonia.FreeDesktop.csproj",
"src\\Avalonia.Metal\\Avalonia.Metal.csproj",
"src\\Avalonia.MicroCom\\Avalonia.MicroCom.csproj", "src\\Avalonia.MicroCom\\Avalonia.MicroCom.csproj",
"src\\Avalonia.Native\\Avalonia.Native.csproj", "src\\Avalonia.Native\\Avalonia.Native.csproj",
"src\\Avalonia.OpenGL\\Avalonia.OpenGL.csproj", "src\\Avalonia.OpenGL\\Avalonia.OpenGL.csproj",

41
Avalonia.sln

@ -135,7 +135,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Linux", "Linux", "{86C53C40
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.LinuxFramebuffer", "src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj", "{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.LinuxFramebuffer", "src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj", "{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Win32.Interop", "src\Windows\Avalonia.Win32.Interop\Avalonia.Win32.Interop.csproj", "{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Win32.Interoperability", "src\Windows\Avalonia.Win32.Interoperability\Avalonia.Win32.Interoperability.csproj", "{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia.RenderTests", "tests\Avalonia.Skia.RenderTests\Avalonia.Skia.RenderTests.csproj", "{E1582370-37B3-403C-917F-8209551B1634}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia.RenderTests", "tests\Avalonia.Skia.RenderTests\Avalonia.Skia.RenderTests.csproj", "{E1582370-37B3-403C-917F-8209551B1634}"
EndProject EndProject
@ -251,6 +251,7 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Generators.Sandbox", "samples\Generators.Sandbox\Generators.Sandbox.csproj", "{A82AD1BC-EBE6-4FC3-A13B-D52A50297533}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Generators.Sandbox", "samples\Generators.Sandbox\Generators.Sandbox.csproj", "{A82AD1BC-EBE6-4FC3-A13B-D52A50297533}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppWithoutLifetime", "samples\AppWithoutLifetime\AppWithoutLifetime.csproj", "{F8928267-688E-4A51-989C-612A72446D33}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppWithoutLifetime", "samples\AppWithoutLifetime\AppWithoutLifetime.csproj", "{F8928267-688E-4A51-989C-612A72446D33}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SafeAreaDemo", "samples\SafeAreaDemo\SafeAreaDemo.csproj", "{6B60A970-D5D2-49C2-8BAB-F9C7973B74B6}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SafeAreaDemo", "samples\SafeAreaDemo\SafeAreaDemo.csproj", "{6B60A970-D5D2-49C2-8BAB-F9C7973B74B6}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SafeAreaDemo.Android", "samples\SafeAreaDemo.Android\SafeAreaDemo.Android.csproj", "{22E3BC08-EAF7-4889-BDC4-B4D3046C4E2D}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SafeAreaDemo.Android", "samples\SafeAreaDemo.Android\SafeAreaDemo.Android.csproj", "{22E3BC08-EAF7-4889-BDC4-B4D3046C4E2D}"
@ -263,13 +264,17 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Headless", "Headless", "{FF
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Headless.XUnit", "src\Headless\Avalonia.Headless.XUnit\Avalonia.Headless.XUnit.csproj", "{F47F8316-4D4B-4026-8EF3-16B2CFDA8119}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Headless.XUnit", "src\Headless\Avalonia.Headless.XUnit\Avalonia.Headless.XUnit.csproj", "{F47F8316-4D4B-4026-8EF3-16B2CFDA8119}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Headless.NUnit", "src\Headless\Avalonia.Headless.NUnit\Avalonia.Headless.NUnit.csproj", "{ED976634-B118-43F8-8B26-0279C7A7044F}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Headless.NUnit", "src\Headless\Avalonia.Headless.NUnit\Avalonia.Headless.NUnit.csproj", "{ED976634-B118-43F8-8B26-0279C7A7044F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Generators.Tests", "tests\Avalonia.Generators.Tests\Avalonia.Generators.Tests.csproj", "{4B8EBBEB-A1AD-49EC-8B69-B93ED15BFA64}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Headless.NUnit.UnitTests", "tests\Avalonia.Headless.NUnit.UnitTests\Avalonia.Headless.NUnit.UnitTests.csproj", "{2999D79E-3C20-4A90-B651-CA7E0AC92D35}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Generators.Tests", "tests\Avalonia.Generators.Tests\Avalonia.Generators.Tests.csproj", "{4B8EBBEB-A1AD-49EC-8B69-B93ED15BFA64}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Headless.XUnit.UnitTests", "tests\Avalonia.Headless.XUnit.UnitTests\Avalonia.Headless.XUnit.UnitTests.csproj", "{F83FC908-A4E3-40DE-B4CF-A4BA1E92CDB3}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Headless.NUnit.UnitTests", "tests\Avalonia.Headless.NUnit.UnitTests\Avalonia.Headless.NUnit.UnitTests.csproj", "{2999D79E-3C20-4A90-B651-CA7E0AC92D35}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MobileSandbox.Browser", "samples\MobileSandbox.Browser\MobileSandbox.Browser.csproj", "{43FCC14E-EEBE-44B3-BCBC-F1C537EECBF8}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Headless.XUnit.UnitTests", "tests\Avalonia.Headless.XUnit.UnitTests\Avalonia.Headless.XUnit.UnitTests.csproj", "{F83FC908-A4E3-40DE-B4CF-A4BA1E92CDB3}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Metal", "src\Avalonia.Metal\Avalonia.Metal.csproj", "{60B4ED1F-ECFA-453B-8A70-1788261C8355}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -606,10 +611,6 @@ Global
{13F1135D-BA1A-435C-9C5B-A368D1D63DE4}.Debug|Any CPU.Build.0 = Debug|Any CPU {13F1135D-BA1A-435C-9C5B-A368D1D63DE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{13F1135D-BA1A-435C-9C5B-A368D1D63DE4}.Release|Any CPU.ActiveCfg = Release|Any CPU {13F1135D-BA1A-435C-9C5B-A368D1D63DE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{13F1135D-BA1A-435C-9C5B-A368D1D63DE4}.Release|Any CPU.Build.0 = Release|Any CPU {13F1135D-BA1A-435C-9C5B-A368D1D63DE4}.Release|Any CPU.Build.0 = Release|Any CPU
{F47F8316-4D4B-4026-8EF3-16B2CFDA8119}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F47F8316-4D4B-4026-8EF3-16B2CFDA8119}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F47F8316-4D4B-4026-8EF3-16B2CFDA8119}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F47F8316-4D4B-4026-8EF3-16B2CFDA8119}.Release|Any CPU.Build.0 = Release|Any CPU
{A82AD1BC-EBE6-4FC3-A13B-D52A50297533}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A82AD1BC-EBE6-4FC3-A13B-D52A50297533}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A82AD1BC-EBE6-4FC3-A13B-D52A50297533}.Debug|Any CPU.Build.0 = Debug|Any CPU {A82AD1BC-EBE6-4FC3-A13B-D52A50297533}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A82AD1BC-EBE6-4FC3-A13B-D52A50297533}.Release|Any CPU.ActiveCfg = Release|Any CPU {A82AD1BC-EBE6-4FC3-A13B-D52A50297533}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -638,14 +639,14 @@ Global
{FC956F9A-4C3A-4A1A-ACDD-BB54DCB661DD}.Release|Any CPU.ActiveCfg = Release|Any CPU {FC956F9A-4C3A-4A1A-ACDD-BB54DCB661DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FC956F9A-4C3A-4A1A-ACDD-BB54DCB661DD}.Release|Any CPU.Build.0 = Release|Any CPU {FC956F9A-4C3A-4A1A-ACDD-BB54DCB661DD}.Release|Any CPU.Build.0 = Release|Any CPU
{FC956F9A-4C3A-4A1A-ACDD-BB54DCB661DD}.Release|Any CPU.Deploy.0 = Release|Any CPU {FC956F9A-4C3A-4A1A-ACDD-BB54DCB661DD}.Release|Any CPU.Deploy.0 = Release|Any CPU
{ED976634-B118-43F8-8B26-0279C7A7044F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ED976634-B118-43F8-8B26-0279C7A7044F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ED976634-B118-43F8-8B26-0279C7A7044F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ED976634-B118-43F8-8B26-0279C7A7044F}.Release|Any CPU.Build.0 = Release|Any CPU
{F47F8316-4D4B-4026-8EF3-16B2CFDA8119}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F47F8316-4D4B-4026-8EF3-16B2CFDA8119}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F47F8316-4D4B-4026-8EF3-16B2CFDA8119}.Debug|Any CPU.Build.0 = Debug|Any CPU {F47F8316-4D4B-4026-8EF3-16B2CFDA8119}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F47F8316-4D4B-4026-8EF3-16B2CFDA8119}.Release|Any CPU.ActiveCfg = Release|Any CPU {F47F8316-4D4B-4026-8EF3-16B2CFDA8119}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F47F8316-4D4B-4026-8EF3-16B2CFDA8119}.Release|Any CPU.Build.0 = Release|Any CPU {F47F8316-4D4B-4026-8EF3-16B2CFDA8119}.Release|Any CPU.Build.0 = Release|Any CPU
{ED976634-B118-43F8-8B26-0279C7A7044F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ED976634-B118-43F8-8B26-0279C7A7044F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ED976634-B118-43F8-8B26-0279C7A7044F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ED976634-B118-43F8-8B26-0279C7A7044F}.Release|Any CPU.Build.0 = Release|Any CPU
{4B8EBBEB-A1AD-49EC-8B69-B93ED15BFA64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4B8EBBEB-A1AD-49EC-8B69-B93ED15BFA64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4B8EBBEB-A1AD-49EC-8B69-B93ED15BFA64}.Debug|Any CPU.Build.0 = Debug|Any CPU {4B8EBBEB-A1AD-49EC-8B69-B93ED15BFA64}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4B8EBBEB-A1AD-49EC-8B69-B93ED15BFA64}.Release|Any CPU.ActiveCfg = Release|Any CPU {4B8EBBEB-A1AD-49EC-8B69-B93ED15BFA64}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -658,6 +659,14 @@ Global
{F83FC908-A4E3-40DE-B4CF-A4BA1E92CDB3}.Debug|Any CPU.Build.0 = Debug|Any CPU {F83FC908-A4E3-40DE-B4CF-A4BA1E92CDB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F83FC908-A4E3-40DE-B4CF-A4BA1E92CDB3}.Release|Any CPU.ActiveCfg = Release|Any CPU {F83FC908-A4E3-40DE-B4CF-A4BA1E92CDB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F83FC908-A4E3-40DE-B4CF-A4BA1E92CDB3}.Release|Any CPU.Build.0 = Release|Any CPU {F83FC908-A4E3-40DE-B4CF-A4BA1E92CDB3}.Release|Any CPU.Build.0 = Release|Any CPU
{43FCC14E-EEBE-44B3-BCBC-F1C537EECBF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{43FCC14E-EEBE-44B3-BCBC-F1C537EECBF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{43FCC14E-EEBE-44B3-BCBC-F1C537EECBF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{43FCC14E-EEBE-44B3-BCBC-F1C537EECBF8}.Release|Any CPU.Build.0 = Release|Any CPU
{60B4ED1F-ECFA-453B-8A70-1788261C8355}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{60B4ED1F-ECFA-453B-8A70-1788261C8355}.Debug|Any CPU.Build.0 = Debug|Any CPU
{60B4ED1F-ECFA-453B-8A70-1788261C8355}.Release|Any CPU.ActiveCfg = Release|Any CPU
{60B4ED1F-ECFA-453B-8A70-1788261C8355}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -727,9 +736,6 @@ Global
{C810060E-3809-4B74-A125-F11533AF9C1B} = {9B9E3891-2366-4253-A952-D08BCEB71098} {C810060E-3809-4B74-A125-F11533AF9C1B} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{C692FE73-43DB-49CE-87FC-F03ED61F25C9} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637} {C692FE73-43DB-49CE-87FC-F03ED61F25C9} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
{F4E36AA8-814E-4704-BC07-291F70F45193} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {F4E36AA8-814E-4704-BC07-291F70F45193} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{8C89950F-F5D9-47FC-8066-CBC1EC3DF8FC} = {FF237916-7150-496B-89ED-6CA3292896E7}
{B859AE7C-F34F-4A9E-88AE-E0E7229FDE1E} = {FF237916-7150-496B-89ED-6CA3292896E7}
{F47F8316-4D4B-4026-8EF3-16B2CFDA8119} = {FF237916-7150-496B-89ED-6CA3292896E7}
{DDA28789-C21A-4654-86CE-D01E81F095C5} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637} {DDA28789-C21A-4654-86CE-D01E81F095C5} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
{A82AD1BC-EBE6-4FC3-A13B-D52A50297533} = {9B9E3891-2366-4253-A952-D08BCEB71098} {A82AD1BC-EBE6-4FC3-A13B-D52A50297533} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{F8928267-688E-4A51-989C-612A72446D33} = {9B9E3891-2366-4253-A952-D08BCEB71098} {F8928267-688E-4A51-989C-612A72446D33} = {9B9E3891-2366-4253-A952-D08BCEB71098}
@ -737,11 +743,12 @@ Global
{22E3BC08-EAF7-4889-BDC4-B4D3046C4E2D} = {9B9E3891-2366-4253-A952-D08BCEB71098} {22E3BC08-EAF7-4889-BDC4-B4D3046C4E2D} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{4CDAD037-34A2-4CCF-A03A-C6C7B988A572} = {9B9E3891-2366-4253-A952-D08BCEB71098} {4CDAD037-34A2-4CCF-A03A-C6C7B988A572} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{FC956F9A-4C3A-4A1A-ACDD-BB54DCB661DD} = {9B9E3891-2366-4253-A952-D08BCEB71098} {FC956F9A-4C3A-4A1A-ACDD-BB54DCB661DD} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{ED976634-B118-43F8-8B26-0279C7A7044F} = {FF237916-7150-496B-89ED-6CA3292896E7}
{F47F8316-4D4B-4026-8EF3-16B2CFDA8119} = {FF237916-7150-496B-89ED-6CA3292896E7} {F47F8316-4D4B-4026-8EF3-16B2CFDA8119} = {FF237916-7150-496B-89ED-6CA3292896E7}
{ED976634-B118-43F8-8B26-0279C7A7044F} = {FF237916-7150-496B-89ED-6CA3292896E7}
{4B8EBBEB-A1AD-49EC-8B69-B93ED15BFA64} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {4B8EBBEB-A1AD-49EC-8B69-B93ED15BFA64} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{2999D79E-3C20-4A90-B651-CA7E0AC92D35} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {2999D79E-3C20-4A90-B651-CA7E0AC92D35} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{F83FC908-A4E3-40DE-B4CF-A4BA1E92CDB3} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {F83FC908-A4E3-40DE-B4CF-A4BA1E92CDB3} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{43FCC14E-EEBE-44B3-BCBC-F1C537EECBF8} = {9B9E3891-2366-4253-A952-D08BCEB71098}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A} SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A}

31
Documentation/build.md

@ -14,6 +14,18 @@ git submodule update --init
Go to https://dotnet.microsoft.com/download/visual-studio-sdks and install the latest version of the .NET Core SDK compatible with Avalonia UI. Make sure to download the SDK (not just the "runtime") package. The version compatible is indicated within the [global.json](https://github.com/AvaloniaUI/Avalonia/blob/master/global.json) file. Note that Avalonia UI does not always use the latest version and is hardcoded to use the last version known to be compatible (SDK releases may break the builds from time-to-time). Go to https://dotnet.microsoft.com/download/visual-studio-sdks and install the latest version of the .NET Core SDK compatible with Avalonia UI. Make sure to download the SDK (not just the "runtime") package. The version compatible is indicated within the [global.json](https://github.com/AvaloniaUI/Avalonia/blob/master/global.json) file. Note that Avalonia UI does not always use the latest version and is hardcoded to use the last version known to be compatible (SDK releases may break the builds from time-to-time).
### Installing necessary .NET Workloads
.NET SDK requires developers to install workloads for each platform they are targeting.
Since Avalonia targets pretty much every supported .NET platform, you need to install these workloads as well.
Running it from the command line:
```
dotnet workload install android ios wasm-tools wasm-experimental
```
macOS workloads are not required to build Avalonia.
Note: on Unix OS you need to run this command from sudo.
## Build and Run Avalonia ## Build and Run Avalonia
``` ```
@ -43,6 +55,25 @@ Build and run `ControlCatalog.NetCore` project to see the sample application.
>CSC : error CS0006: Metadata file 'C:\...\Avalonia\packages\Avalonia\bin\Debug\netcoreapp2.0\Avalonia.dll' could not be found >CSC : error CS0006: Metadata file 'C:\...\Avalonia\packages\Avalonia\bin\Debug\netcoreapp2.0\Avalonia.dll' could not be found
``` ```
To correct this, right click on the `Avalonia.DesktopRuntime` project then press `Build` to build the project manually. Afterwards the solution should build normally and the ControlCatalog can be run. To correct this, right click on the `Avalonia.DesktopRuntime` project then press `Build` to build the project manually. Afterwards the solution should build normally and the ControlCatalog can be run.
* **Error MSB4062 GenerateAvaloniaResourcesTask**
Same as previous one, you need to manually build `Avalonia.Build.Tasks` project at least once.
Alternatively, you can build the solution once with Nuke.
## Building packages with Nuke
Install Nuke
`dotnet tool install --global Nuke.GlobalTool --version 6.2.1`
Build project:
`nuke --target Compile --configuration Release`
And run tests:
`nuke --target RunTests --configuration Release`
Or if you need to create nuget packages as well (it will compile and run tests automatically):
`nuke --target Package --configuration Release`
# Linux/macOS # Linux/macOS

64
api/Avalonia.Controls.ColorPicker.nupkg.xml

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Fluent/ColorPicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Fluent/ColorPreviewer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Fluent/ColorSlider.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Fluent/ColorSpectrum.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Fluent/ColorView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Simple/ColorPicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Simple/ColorPreviewer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Simple/ColorSlider.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Simple/ColorSpectrum.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Simple/ColorView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
</Suppressions>

418
api/Avalonia.Themes.Fluent.nupkg.xml

@ -0,0 +1,418 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Accents/BaseResources.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Accents/FluentControlResources.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/AdornerLayer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/AutoCompleteBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Button.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ButtonSpinner.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Calendar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarDatePicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarDayButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CaptionButtons.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Carousel.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CheckBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ComboBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ComboBoxItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ContentControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ContextMenu.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DataValidationErrors.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DatePicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DateTimePickerShared.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DropDownButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/EmbeddableControlRoot.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Expander.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/FlyoutPresenter.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/GridSplitter.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ItemsControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Label.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ListBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ListBoxItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ManagedFileChooser.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Menu.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/MenuFlyoutPresenter.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/MenuItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/MenuScrollViewer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/NativeMenuBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/NotificationCard.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/NumericUpDown.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/OverlayPopupHost.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/PathIcon.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/PopupRoot.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ProgressBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RadioButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RefreshContainer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RefreshVisualizer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RepeatButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ScrollBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ScrollViewer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SelectableTextBlock.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Separator.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Slider.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SplitButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SplitView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabStrip.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabStripItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TextBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ThemeVariantScope.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TimePicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TitleBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ToggleButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ToggleSwitch.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ToolTip.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TransitioningContentControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TreeView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TreeViewItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Window.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/WindowNotificationManager.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
</Suppressions>

406
api/Avalonia.Themes.Simple.nupkg.xml

@ -0,0 +1,406 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Accents/Base.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/AdornerLayer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/AutoCompleteBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Button.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ButtonSpinner.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Calendar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarDatePicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarDayButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CaptionButtons.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Carousel.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CheckBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ComboBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ComboBoxItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ContentControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ContextMenu.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DataValidationErrors.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DatePicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DateTimePickerShared.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DropDownButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/EmbeddableControlRoot.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Expander.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/FlyoutPresenter.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/GridSplitter.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ItemsControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Label.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ListBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ListBoxItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ManagedFileChooser.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Menu.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/MenuFlyoutPresenter.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/MenuItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/NativeMenuBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/NotificationCard.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/NumericUpDown.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/OverlayPopupHost.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/PathIcon.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/PopupRoot.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ProgressBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RadioButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RefreshContainer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RefreshVisualizer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RepeatButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ScrollBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ScrollViewer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SelectableTextBlock.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Separator.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Slider.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SplitButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SplitView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabStrip.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabStripItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TextBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ThemeVariantScope.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TimePicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TitleBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ToggleButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ToggleSwitch.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ToolTip.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TransitioningContentControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TreeView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TreeViewItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Window.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/WindowNotificationManager.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
</Suppressions>

10
api/Avalonia.nupkg.xml

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>P:Avalonia.Rendering.Composition.ICompositionGpuImportedObject.ImportCompleted</Target>
<Left>baseline/netstandard2.0/Avalonia.Base.dll</Left>
<Right>target/netstandard2.0/Avalonia.Base.dll</Right>
</Suppression>
</Suppressions>

1
build/CoreLibraries.props

@ -4,6 +4,7 @@
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Controls/Avalonia.Controls.csproj" /> <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Controls/Avalonia.Controls.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj" /> <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.OpenGL/Avalonia.OpenGL.csproj" /> <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.OpenGL/Avalonia.OpenGL.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Metal/Avalonia.Metal.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Dialogs/Avalonia.Dialogs.csproj" /> <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Avalonia.Dialogs/Avalonia.Dialogs.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Markup/Avalonia.Markup/Avalonia.Markup.csproj" /> <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Markup/Avalonia.Markup/Avalonia.Markup.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj" /> <ProjectReference Include="$(MSBuildThisFileDirectory)/../src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj" />

1
build/ExternalConsumers.props

@ -1,6 +1,7 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup> <ItemGroup>
<InternalsVisibleTo Include="AvaloniaUI.Xpf.WinApiShim, PublicKey=0024000004800000940000000602000000240000525341310004000001000100a7f4b8b7db0bfb8d74992dc94ecafae031019197ff4263d87ac0a5835fab101c973ccab6fa6e7d90e8f987374f7c6de18dd0b5cd7d6c41e574a8bc66b64836b7c7e707e1aa393d27e33a08f372c1c9965be81658937c85698f4a1c0f73be68a61ffce06d49d1366bf18464c20a29859ccf105fc2d5e35c7ae68919eab668bf8e" /> <InternalsVisibleTo Include="AvaloniaUI.Xpf.WinApiShim, PublicKey=0024000004800000940000000602000000240000525341310004000001000100a7f4b8b7db0bfb8d74992dc94ecafae031019197ff4263d87ac0a5835fab101c973ccab6fa6e7d90e8f987374f7c6de18dd0b5cd7d6c41e574a8bc66b64836b7c7e707e1aa393d27e33a08f372c1c9965be81658937c85698f4a1c0f73be68a61ffce06d49d1366bf18464c20a29859ccf105fc2d5e35c7ae68919eab668bf8e" />
<InternalsVisibleTo Include="AvaloniaUI.Xpf.WpfAbstractions, PublicKey=0024000004800000940000000602000000240000525341310004000001000100a7f4b8b7db0bfb8d74992dc94ecafae031019197ff4263d87ac0a5835fab101c973ccab6fa6e7d90e8f987374f7c6de18dd0b5cd7d6c41e574a8bc66b64836b7c7e707e1aa393d27e33a08f372c1c9965be81658937c85698f4a1c0f73be68a61ffce06d49d1366bf18464c20a29859ccf105fc2d5e35c7ae68919eab668bf8e" />
<InternalsVisibleTo Include="System.Windows.Forms, PublicKey=00000000000000000400000000000000" /> <InternalsVisibleTo Include="System.Windows.Forms, PublicKey=00000000000000000400000000000000" />
<InternalsVisibleTo Include="System.Windows.Forms.Primitives, PublicKey=00000000000000000400000000000000" /> <InternalsVisibleTo Include="System.Windows.Forms.Primitives, PublicKey=00000000000000000400000000000000" />
<InternalsVisibleTo Include="PresentationFramework-SystemData, PublicKey=00000000000000000400000000000000" /> <InternalsVisibleTo Include="PresentationFramework-SystemData, PublicKey=00000000000000000400000000000000" />

8
build/SourceLink.props

@ -1,9 +1,9 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<PublishRepositoryUrl>true</PublishRepositoryUrl> <PublishRepositoryUrl>true</PublishRepositoryUrl>
<IncludeSymbols>false</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<EmbedUntrackedSources>true</EmbedUntrackedSources> <EmbedUntrackedSources>true</EmbedUntrackedSources>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(TF_BUILD)' == 'true'"> <PropertyGroup Condition="'$(TF_BUILD)' == 'true'">
@ -14,10 +14,6 @@
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild> <ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<DebugType Condition="$(ContinuousIntegrationBuild) == 'true'">embedded</DebugType>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All"/> <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All"/>
</ItemGroup> </ItemGroup>

6
dirs.proj

@ -14,11 +14,11 @@
<ProjectReference Remove="samples/*.Android/*.csproj" /> <ProjectReference Remove="samples/*.Android/*.csproj" />
<ProjectReference Remove="samples/*.Browser/*.csproj" /> <ProjectReference Remove="samples/*.Browser/*.csproj" />
<ProjectReference Remove="samples/*.Blazor/*.csproj" /> <ProjectReference Remove="samples/*.Blazor/*.csproj" />
<ProjectReference Remove="samples/ControlCatalog.Desktop/*.*proj" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="!$([MSBuild]::IsOsPlatform('Windows')) OR '$(MSBuildRuntimeType)' != 'Full'"> <ItemGroup Condition="!$([MSBuild]::IsOsPlatform('Windows'))">
<ProjectReference Remove="src/Windows/Avalonia.Win32.Interop/Avalonia.Win32.Interop.csproj" /> <ProjectReference Remove="src/Windows/Avalonia.Win32.Interoperability/Avalonia.Win32.Interoperability.csproj" />
<ProjectReference Remove="samples/interop/**/*.*proj" /> <ProjectReference Remove="samples/interop/**/*.*proj" />
<ProjectReference Remove="samples/ControlCatalog.Desktop/*.*proj" />
</ItemGroup> </ItemGroup>
<!-- Build android and iOS projects only on Windows, where we have installed android workload --> <!-- Build android and iOS projects only on Windows, where we have installed android workload -->

1
native/Avalonia.Native/inc/com.h

@ -28,6 +28,7 @@ typedef DWORD ULONG;
#define E_UNEXPECTED 0x8000FFFFL #define E_UNEXPECTED 0x8000FFFFL
#define E_HANDLE 0x80070006L #define E_HANDLE 0x80070006L
#define E_INVALIDARG 0x80070057L #define E_INVALIDARG 0x80070057L
#define COR_E_INVALIDOPERATION 0x80131509L
struct IUnknown struct IUnknown
{ {

19
native/Avalonia.Native/inc/comimpl.h

@ -43,6 +43,18 @@ public:
_obj->AddRef(); _obj->AddRef();
} }
} }
ComPtr(TInterface* pObj, bool ownsHandle)
{
_obj = 0;
if (pObj)
{
_obj = pObj;
if(!ownsHandle)
_obj->AddRef();
}
}
ComPtr(const ComPtr& ptr) ComPtr(const ComPtr& ptr)
{ {
@ -92,6 +104,13 @@ public:
{ {
return &_obj; return &_obj;
} }
void setNoAddRef(TInterface* value)
{
if(_obj != nullptr)
_obj->Release();
_obj = value;
}
operator TInterface*() const operator TInterface*() const
{ {

11
native/Avalonia.Native/inc/noarc.h

@ -0,0 +1,11 @@
#import <AppKit/AppKit.h>
class CppAutoreleasePool
{
void* _pool;
public:
CppAutoreleasePool();
~CppAutoreleasePool();
};
#define START_ARP_CALL CppAutoreleasePool __autoreleasePool

16
native/Avalonia.Native/inc/rendertarget.h

@ -5,13 +5,21 @@
#include "avalonia-native.h" #include "avalonia-native.h"
@protocol IRenderTarget @protocol IRenderTarget
-(void) setNewLayer: (CALayer*) layer;
-(HRESULT) setSwFrame: (AvnFramebuffer*) fb;
-(void) resize: (AvnPixelSize) size withScale: (float) scale; -(void) resize: (AvnPixelSize) size withScale: (float) scale;
-(AvnPixelSize) pixelSize; -(CALayer*) layer;
-(IAvnGlSurfaceRenderTarget*) createSurfaceRenderTarget;
@end @end
@interface IOSurfaceRenderTarget : NSObject<IRenderTarget> @interface IOSurfaceRenderTarget : NSObject<IRenderTarget>
-(IOSurfaceRenderTarget*) initWithOpenGlContext: (IAvnGlContext*) context; -(IOSurfaceRenderTarget*) initWithOpenGlContext: (IAvnGlContext*) context;
-(IAvnGlSurfaceRenderTarget*) createSurfaceRenderTarget;
-(IAvnSoftwareRenderTarget*) createSoftwareRenderTarget;
-(HRESULT) setSwFrame: (AvnFramebuffer*) fb;
-(void)consumeSurfaces;
@end @end
@interface MetalRenderTarget : NSObject<IRenderTarget>
-(MetalRenderTarget*) initWithDevice: (IAvnMetalDevice*) device;
-(void) getRenderTarget: (IAvnMetalRenderTarget**) ppv;
@end

20
native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj

@ -43,6 +43,11 @@
523484CA26EA688F00EA0C2C /* trayicon.mm in Sources */ = {isa = PBXBuildFile; fileRef = 523484C926EA688F00EA0C2C /* trayicon.mm */; }; 523484CA26EA688F00EA0C2C /* trayicon.mm in Sources */ = {isa = PBXBuildFile; fileRef = 523484C926EA688F00EA0C2C /* trayicon.mm */; };
5B21A982216530F500CEE36E /* cursor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B21A981216530F500CEE36E /* cursor.mm */; }; 5B21A982216530F500CEE36E /* cursor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B21A981216530F500CEE36E /* cursor.mm */; };
5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */; }; 5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */; };
64B1EA48E308E574685AFB07 /* metal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 64B1EBEECBE13D8616D7C934 /* metal.mm */; };
64B1ECA861163C0EFF0E502B /* noarc.h in Headers */ = {isa = PBXBuildFile; fileRef = 64B1E26F2B1B9C577BF52F06 /* noarc.h */; };
64B1ED7C5433AC3B815FFCC5 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 64B1E23CAFE5FEC7AD981B1B /* Metal.framework */; };
64B1EE5DD4D882D587CE76CE /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 64B1E677F7791226F783ACE4 /* CoreGraphics.framework */; };
64B1EF3C757B71526FFAF436 /* noarc.mm in Sources */ = {isa = PBXBuildFile; fileRef = 64B1E4FA7D9D6E5F47AA8606 /* noarc.mm */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
855EDC9F28C6546F00807998 /* PlatformBehaviorInhibition.mm in Sources */ = {isa = PBXBuildFile; fileRef = 855EDC9E28C6546F00807998 /* PlatformBehaviorInhibition.mm */; }; 855EDC9F28C6546F00807998 /* PlatformBehaviorInhibition.mm in Sources */ = {isa = PBXBuildFile; fileRef = 855EDC9E28C6546F00807998 /* PlatformBehaviorInhibition.mm */; };
8D2F3512292F6AAE007FCF54 /* AvnTextInputMethodDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8D2F3511292F6AAE007FCF54 /* AvnTextInputMethodDelegate.h */; }; 8D2F3512292F6AAE007FCF54 /* AvnTextInputMethodDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8D2F3511292F6AAE007FCF54 /* AvnTextInputMethodDelegate.h */; };
8D300D65292D0A6800320C49 /* AvnTextInputMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = 8D300D64292D0A6800320C49 /* AvnTextInputMethod.h */; }; 8D300D65292D0A6800320C49 /* AvnTextInputMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = 8D300D64292D0A6800320C49 /* AvnTextInputMethod.h */; };
@ -99,6 +104,11 @@
5B21A981216530F500CEE36E /* cursor.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = cursor.mm; sourceTree = "<group>"; }; 5B21A981216530F500CEE36E /* cursor.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = cursor.mm; sourceTree = "<group>"; };
5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = clipboard.mm; sourceTree = "<group>"; }; 5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = clipboard.mm; sourceTree = "<group>"; };
5BF943652167AD1D009CAE35 /* cursor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cursor.h; sourceTree = "<group>"; }; 5BF943652167AD1D009CAE35 /* cursor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cursor.h; sourceTree = "<group>"; };
64B1E23CAFE5FEC7AD981B1B /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; };
64B1E26F2B1B9C577BF52F06 /* noarc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = noarc.h; path = ../../inc/noarc.h; sourceTree = "<group>"; };
64B1E4FA7D9D6E5F47AA8606 /* noarc.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = noarc.mm; sourceTree = "<group>"; };
64B1E677F7791226F783ACE4 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
64B1EBEECBE13D8616D7C934 /* metal.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = metal.mm; sourceTree = "<group>"; };
855EDC9E28C6546F00807998 /* PlatformBehaviorInhibition.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PlatformBehaviorInhibition.mm; sourceTree = "<group>"; }; 855EDC9E28C6546F00807998 /* PlatformBehaviorInhibition.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PlatformBehaviorInhibition.mm; sourceTree = "<group>"; };
8D2F3511292F6AAE007FCF54 /* AvnTextInputMethodDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AvnTextInputMethodDelegate.h; sourceTree = "<group>"; }; 8D2F3511292F6AAE007FCF54 /* AvnTextInputMethodDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AvnTextInputMethodDelegate.h; sourceTree = "<group>"; };
8D300D64292D0A6800320C49 /* AvnTextInputMethod.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AvnTextInputMethod.h; sourceTree = "<group>"; }; 8D300D64292D0A6800320C49 /* AvnTextInputMethod.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AvnTextInputMethod.h; sourceTree = "<group>"; };
@ -126,6 +136,8 @@
AB1E522C217613570091CD71 /* OpenGL.framework in Frameworks */, AB1E522C217613570091CD71 /* OpenGL.framework in Frameworks */,
522D5959258159C1006F7F7A /* Carbon.framework in Frameworks */, 522D5959258159C1006F7F7A /* Carbon.framework in Frameworks */,
AB661C1E2148230F00291242 /* AppKit.framework in Frameworks */, AB661C1E2148230F00291242 /* AppKit.framework in Frameworks */,
64B1ED7C5433AC3B815FFCC5 /* Metal.framework in Frameworks */,
64B1EE5DD4D882D587CE76CE /* CoreGraphics.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -141,6 +153,8 @@
1A3E5EA923E9F26C00EDE661 /* IOSurface.framework */, 1A3E5EA923E9F26C00EDE661 /* IOSurface.framework */,
AB1E522B217613570091CD71 /* OpenGL.framework */, AB1E522B217613570091CD71 /* OpenGL.framework */,
AB661C1D2148230F00291242 /* AppKit.framework */, AB661C1D2148230F00291242 /* AppKit.framework */,
64B1E23CAFE5FEC7AD981B1B /* Metal.framework */,
64B1E677F7791226F783ACE4 /* CoreGraphics.framework */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
@ -198,6 +212,9 @@
18391DB45C7D892E61BF388C /* WindowInterfaces.h */, 18391DB45C7D892E61BF388C /* WindowInterfaces.h */,
18391BB698579F40F1783F31 /* PopupImpl.mm */, 18391BB698579F40F1783F31 /* PopupImpl.mm */,
183910513F396141938832B5 /* PopupImpl.h */, 183910513F396141938832B5 /* PopupImpl.h */,
64B1EBEECBE13D8616D7C934 /* metal.mm */,
64B1E4FA7D9D6E5F47AA8606 /* noarc.mm */,
64B1E26F2B1B9C577BF52F06 /* noarc.h */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -230,6 +247,7 @@
18391F1E2411C79405A9943A /* WindowProtocol.h in Headers */, 18391F1E2411C79405A9943A /* WindowProtocol.h in Headers */,
183914E50CF6D2EFC1667F7C /* WindowInterfaces.h in Headers */, 183914E50CF6D2EFC1667F7C /* WindowInterfaces.h in Headers */,
18391AC65ADD7DDD33FBE737 /* PopupImpl.h in Headers */, 18391AC65ADD7DDD33FBE737 /* PopupImpl.h in Headers */,
64B1ECA861163C0EFF0E502B /* noarc.h in Headers */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -319,6 +337,8 @@
18391AC16726CBC45856233B /* AvnWindow.mm in Sources */, 18391AC16726CBC45856233B /* AvnWindow.mm in Sources */,
18391D8CD1756DC858DC1A09 /* PopupImpl.mm in Sources */, 18391D8CD1756DC858DC1A09 /* PopupImpl.mm in Sources */,
EDF8CDCD2964CB01001EE34F /* PlatformSettings.mm in Sources */, EDF8CDCD2964CB01001EE34F /* PlatformSettings.mm in Sources */,
64B1EA48E308E574685AFB07 /* metal.mm in Sources */,
64B1EF3C757B71526FFAF436 /* noarc.mm in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

5
native/Avalonia.Native/src/OSX/AvnView.h

@ -11,15 +11,16 @@
#include "KeyTransform.h" #include "KeyTransform.h"
@class AvnAccessibilityElement; @class AvnAccessibilityElement;
@protocol IRenderTarget;
@interface AvnView : NSView<NSTextInputClient, NSDraggingDestination, AvnTextInputMethodDelegate> @interface AvnView : NSView<NSTextInputClient, NSDraggingDestination, AvnTextInputMethodDelegate, CALayerDelegate>
-(AvnView* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent; -(AvnView* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent;
-(NSEvent* _Nonnull) lastMouseDownEvent; -(NSEvent* _Nonnull) lastMouseDownEvent;
-(AvnPoint) translateLocalPoint:(AvnPoint)pt; -(AvnPoint) translateLocalPoint:(AvnPoint)pt;
-(void) setSwRenderedFrame: (AvnFramebuffer* _Nonnull) fb dispose: (IUnknown* _Nonnull) dispose;
-(void) onClosed; -(void) onClosed;
-(AvnPlatformResizeReason) getResizeReason; -(AvnPlatformResizeReason) getResizeReason;
-(void) setResizeReason:(AvnPlatformResizeReason)reason; -(void) setResizeReason:(AvnPlatformResizeReason)reason;
-(void) setRenderTarget:(NSObject<IRenderTarget>*)target;
+ (AvnPoint)toAvnPoint:(CGPoint)p; + (AvnPoint)toAvnPoint:(CGPoint)p;
@end @end

46
native/Avalonia.Native/src/OSX/AvnView.mm

@ -17,7 +17,7 @@
NSEvent* _lastMouseDownEvent; NSEvent* _lastMouseDownEvent;
bool _lastKeyHandled; bool _lastKeyHandled;
AvnPixelSize _lastPixelSize; AvnPixelSize _lastPixelSize;
NSObject<IRenderTarget>* _renderTarget; NSObject<IRenderTarget>* _currentRenderTarget;
AvnPlatformResizeReason _resizeReason; AvnPlatformResizeReason _resizeReason;
AvnAccessibilityElement* _accessibilityChild; AvnAccessibilityElement* _accessibilityChild;
NSRect _cursorRect; NSRect _cursorRect;
@ -41,15 +41,39 @@
- (void) updateRenderTarget - (void) updateRenderTarget
{ {
[_renderTarget resize:_lastPixelSize withScale:static_cast<float>([[self window] backingScaleFactor])]; if(_currentRenderTarget) {
[self setNeedsDisplayInRect:[self frame]]; [_currentRenderTarget resize:_lastPixelSize withScale:static_cast<float>([[self window] backingScaleFactor])];
[self setNeedsDisplayInRect:[self frame]];
}
}
-(void) setRenderTarget:(NSObject<IRenderTarget>*)target
{
if([self layer])
{
[self layer].delegate = nil;
}
_currentRenderTarget = target;
auto layer = [target layer];
[self setLayer: layer];
[layer setDelegate: self];
layer.needsDisplayOnBoundsChange = YES;
[self updateRenderTarget];
}
-(void)displayLayer: (CALayer*)layer
{
[self updateLayer];
} }
-(AvnView*) initWithParent: (WindowBaseImpl*) parent -(AvnView*) initWithParent: (WindowBaseImpl*) parent
{ {
self = [super init]; self = [super init];
_renderTarget = parent->renderTarget;
[self setWantsLayer:YES]; [self setWantsLayer:YES];
[self setLayerContentsPlacement: NSViewLayerContentsPlacementTopLeft];
[self setCanDrawSubviewsIntoLayer: NO];
[self setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawDuringViewResize]; [self setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawDuringViewResize];
_parent = parent; _parent = parent;
@ -77,12 +101,6 @@
return YES; return YES;
} }
- (void)setLayer:(CALayer *)layer
{
[_renderTarget setNewLayer: layer];
[super setLayer: layer];
}
- (BOOL)isOpaque - (BOOL)isOpaque
{ {
return YES; return YES;
@ -164,14 +182,6 @@
return; return;
} }
-(void) setSwRenderedFrame: (AvnFramebuffer*) fb dispose: (IUnknown*) dispose
{
@autoreleasepool {
[_renderTarget setSwFrame:fb];
dispose->Release();
}
}
- (AvnPoint) translateLocalPoint:(AvnPoint)pt - (AvnPoint) translateLocalPoint:(AvnPoint)pt
{ {
pt.Y = [self bounds].size.height - pt.Y; pt.Y = [self bounds].size.height - pt.Y;

6
native/Avalonia.Native/src/OSX/PopupImpl.mm

@ -23,7 +23,7 @@ private:
END_INTERFACE_MAP() END_INTERFACE_MAP()
virtual ~PopupImpl(){} virtual ~PopupImpl(){}
ComPtr<IAvnWindowEvents> WindowEvents; ComPtr<IAvnWindowEvents> WindowEvents;
PopupImpl(IAvnWindowEvents* events, IAvnGlContext* gl) : WindowBaseImpl(events, gl) PopupImpl(IAvnWindowEvents* events) : WindowBaseImpl(events)
{ {
WindowEvents = events; WindowEvents = events;
[Window setLevel:NSPopUpMenuWindowLevel]; [Window setLevel:NSPopUpMenuWindowLevel];
@ -47,11 +47,11 @@ public:
}; };
extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events, IAvnGlContext* gl) extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events)
{ {
@autoreleasepool @autoreleasepool
{ {
IAvnPopup* ptr = dynamic_cast<IAvnPopup*>(new PopupImpl(events, gl)); IAvnPopup* ptr = dynamic_cast<IAvnPopup*>(new PopupImpl(events));
return ptr; return ptr;
} }
} }

13
native/Avalonia.Native/src/OSX/WindowBaseImpl.h

@ -27,7 +27,7 @@ BEGIN_INTERFACE_MAP()
virtual ~WindowBaseImpl(); virtual ~WindowBaseImpl();
WindowBaseImpl(IAvnWindowBaseEvents *events, IAvnGlContext *gl, bool usePanel = false); WindowBaseImpl(IAvnWindowBaseEvents *events, bool usePanel = false);
virtual HRESULT ObtainNSWindowHandle(void **ret) override; virtual HRESULT ObtainNSWindowHandle(void **ret) override;
@ -81,13 +81,15 @@ BEGIN_INTERFACE_MAP()
virtual HRESULT PointToScreen(AvnPoint point, AvnPoint *ret) override; virtual HRESULT PointToScreen(AvnPoint point, AvnPoint *ret) override;
virtual HRESULT ThreadSafeSetSwRenderedFrame(AvnFramebuffer *fb, IUnknown *dispose) override;
virtual HRESULT SetCursor(IAvnCursor *cursor) override; virtual HRESULT SetCursor(IAvnCursor *cursor) override;
virtual void UpdateCursor(); virtual void UpdateCursor();
virtual HRESULT CreateGlRenderTarget(IAvnGlSurfaceRenderTarget **ppv) override; virtual HRESULT CreateSoftwareRenderTarget(IAvnSoftwareRenderTarget **ppv) override;
virtual HRESULT CreateGlRenderTarget(IAvnGlContext* glContext, IAvnGlSurfaceRenderTarget **ppv) override;
virtual HRESULT CreateMetalRenderTarget(IAvnMetalDevice* device, IAvnMetalRenderTarget **ppv) override;
virtual HRESULT CreateNativeControlHost(IAvnNativeControlHost **retOut) override; virtual HRESULT CreateNativeControlHost(IAvnNativeControlHost **retOut) override;
@ -118,7 +120,6 @@ private:
void CleanNSWindow (); void CleanNSWindow ();
NSCursor *cursor; NSCursor *cursor;
ComPtr<IAvnGlContext> _glContext;
bool hasPosition; bool hasPosition;
NSSize lastSize; NSSize lastSize;
NSSize lastMinSize; NSSize lastMinSize;
@ -132,7 +133,7 @@ protected:
bool _shown; bool _shown;
public: public:
NSObject <IRenderTarget> *renderTarget; NSObject <IRenderTarget> *currentRenderTarget;
NSWindow * Window; NSWindow * Window;
ComPtr<IAvnWindowBaseEvents> BaseEvents; ComPtr<IAvnWindowBaseEvents> BaseEvents;
ComPtr<AvnTextInputMethod> InputMethod; ComPtr<AvnTextInputMethod> InputMethod;

66
native/Avalonia.Native/src/OSX/WindowBaseImpl.mm

@ -16,6 +16,7 @@
#import "WindowInterfaces.h" #import "WindowInterfaces.h"
#include "WindowBaseImpl.h" #include "WindowBaseImpl.h"
#include "AvnTextInputMethod.h" #include "AvnTextInputMethod.h"
#include "AvnView.h"
WindowBaseImpl::~WindowBaseImpl() { WindowBaseImpl::~WindowBaseImpl() {
@ -23,12 +24,10 @@ WindowBaseImpl::~WindowBaseImpl() {
Window = nullptr; Window = nullptr;
} }
WindowBaseImpl::WindowBaseImpl(IAvnWindowBaseEvents *events, IAvnGlContext *gl, bool usePanel) { WindowBaseImpl::WindowBaseImpl(IAvnWindowBaseEvents *events, bool usePanel) {
_shown = false; _shown = false;
_inResize = false; _inResize = false;
BaseEvents = events; BaseEvents = events;
_glContext = gl;
renderTarget = [[IOSurfaceRenderTarget alloc] initWithOpenGlContext:gl];
View = [[AvnView alloc] initWithParent:this]; View = [[AvnView alloc] initWithParent:this];
InputMethod = new AvnTextInputMethod(View); InputMethod = new AvnTextInputMethod(View);
StandardContainer = [[AutoFitContentView new] initWithContent:View]; StandardContainer = [[AutoFitContentView new] initWithContent:View];
@ -152,6 +151,14 @@ HRESULT WindowBaseImpl::Hide() {
@autoreleasepool { @autoreleasepool {
if (Window != nullptr) { if (Window != nullptr) {
auto frame = [Window frame];
AvnPoint point;
point.X = frame.origin.x;
point.Y = frame.origin.y + frame.size.height;
lastPositionSet = ConvertPointY(point);
hasPosition = true;
[Window orderOut:Window]; [Window orderOut:Window];
} }
@ -448,13 +455,6 @@ HRESULT WindowBaseImpl::PointToScreen(AvnPoint point, AvnPoint *ret) {
} }
} }
HRESULT WindowBaseImpl::ThreadSafeSetSwRenderedFrame(AvnFramebuffer *fb, IUnknown *dispose) {
START_COM_CALL;
[View setSwRenderedFrame:fb dispose:dispose];
return S_OK;
}
HRESULT WindowBaseImpl::SetCursor(IAvnCursor *cursor) { HRESULT WindowBaseImpl::SetCursor(IAvnCursor *cursor) {
START_COM_CALL; START_COM_CALL;
@ -479,13 +479,49 @@ void WindowBaseImpl::UpdateCursor() {
} }
} }
HRESULT WindowBaseImpl::CreateGlRenderTarget(IAvnGlSurfaceRenderTarget **ppv) { HRESULT WindowBaseImpl::CreateSoftwareRenderTarget(IAvnSoftwareRenderTarget **ppv) {
START_COM_CALL;
if(![NSThread isMainThread])
return COR_E_INVALIDOPERATION;
if (View == NULL)
return E_FAIL;
auto target = [[IOSurfaceRenderTarget alloc] initWithOpenGlContext: nil];
*ppv = [target createSoftwareRenderTarget];
[View setRenderTarget: target];
return S_OK;
}
HRESULT WindowBaseImpl::CreateGlRenderTarget(IAvnGlContext* glContext, IAvnGlSurfaceRenderTarget **ppv) {
START_COM_CALL; START_COM_CALL;
if(![NSThread isMainThread])
return COR_E_INVALIDOPERATION;
if (View == NULL) if (View == NULL)
return E_FAIL; return E_FAIL;
*ppv = [renderTarget createSurfaceRenderTarget];
return static_cast<HRESULT>(*ppv == nil ? E_FAIL : S_OK); auto target = [[IOSurfaceRenderTarget alloc] initWithOpenGlContext: glContext];
*ppv = [target createSurfaceRenderTarget];
[View setRenderTarget: target];
return S_OK;
}
HRESULT WindowBaseImpl::CreateMetalRenderTarget(IAvnMetalDevice* device, IAvnMetalRenderTarget **ppv) {
START_COM_CALL;
if(![NSThread isMainThread])
return COR_E_INVALIDOPERATION;
if (View == NULL)
return E_FAIL;
auto target = [[MetalRenderTarget alloc] initWithDevice: device];
[View setRenderTarget: target];
[target getRenderTarget: ppv];
return S_OK;
} }
HRESULT WindowBaseImpl::CreateNativeControlHost(IAvnNativeControlHost **retOut) { HRESULT WindowBaseImpl::CreateNativeControlHost(IAvnNativeControlHost **retOut) {
@ -615,11 +651,11 @@ HRESULT WindowBaseImpl::GetInputMethod(IAvnTextInputMethod **retOut) {
return S_OK; return S_OK;
} }
extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events, IAvnGlContext* gl) extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events)
{ {
@autoreleasepool @autoreleasepool
{ {
IAvnWindow* ptr = (IAvnWindow*)new WindowImpl(events, gl); IAvnWindow* ptr = (IAvnWindow*)new WindowImpl(events);
return ptr; return ptr;
} }
} }

2
native/Avalonia.Native/src/OSX/WindowImpl.h

@ -39,7 +39,7 @@ BEGIN_INTERFACE_MAP()
ComPtr<IAvnWindowEvents> WindowEvents; ComPtr<IAvnWindowEvents> WindowEvents;
WindowImpl(IAvnWindowEvents* events, IAvnGlContext* gl); WindowImpl(IAvnWindowEvents* events);
virtual HRESULT Show (bool activate, bool isDialog) override; virtual HRESULT Show (bool activate, bool isDialog) override;

2
native/Avalonia.Native/src/OSX/WindowImpl.mm

@ -9,7 +9,7 @@
#include "automation.h" #include "automation.h"
#include "WindowProtocol.h" #include "WindowProtocol.h"
WindowImpl::WindowImpl(IAvnWindowEvents *events, IAvnGlContext *gl) : WindowBaseImpl(events, gl) { WindowImpl::WindowImpl(IAvnWindowEvents *events) : WindowBaseImpl(events) {
_isEnabled = true; _isEnabled = true;
_children = std::list<WindowImpl*>(); _children = std::list<WindowImpl*>();
_isClientAreaExtended = false; _isClientAreaExtended = false;

18
native/Avalonia.Native/src/OSX/app.mm

@ -2,6 +2,7 @@
#include "AvnString.h" #include "AvnString.h"
@interface AvnAppDelegate : NSObject<NSApplicationDelegate> @interface AvnAppDelegate : NSObject<NSApplicationDelegate>
-(AvnAppDelegate* _Nonnull) initWithEvents: (IAvnApplicationEvents* _Nonnull) events; -(AvnAppDelegate* _Nonnull) initWithEvents: (IAvnApplicationEvents* _Nonnull) events;
-(void) releaseEvents;
@end @end
NSApplicationActivationPolicy AvnDesiredActivationPolicy = NSApplicationActivationPolicyRegular; NSApplicationActivationPolicy AvnDesiredActivationPolicy = NSApplicationActivationPolicyRegular;
@ -15,6 +16,11 @@ ComPtr<IAvnApplicationEvents> _events;
return self; return self;
} }
- (void)releaseEvents
{
_events = nil;
}
- (void)applicationWillFinishLaunching:(NSNotification *)notification - (void)applicationWillFinishLaunching:(NSNotification *)notification
{ {
if([[NSApplication sharedApplication] activationPolicy] != AvnDesiredActivationPolicy) if([[NSApplication sharedApplication] activationPolicy] != AvnDesiredActivationPolicy)
@ -105,6 +111,18 @@ extern void InitializeAvnApp(IAvnApplicationEvents* events, bool disableAppDeleg
} }
} }
extern void ReleaseAvnAppEvents()
{
NSApplication* app = [AvnApplication sharedApplication];
id delegate = [app delegate];
if ([delegate isMemberOfClass:[AvnAppDelegate class]])
{
AvnAppDelegate* avnDelegate = delegate;
[avnDelegate releaseEvents];
[app setDelegate:nil];
}
}
HRESULT AvnApplicationCommands::HideApp() HRESULT AvnApplicationCommands::HideApp()
{ {
START_COM_CALL; START_COM_CALL;

11
native/Avalonia.Native/src/OSX/automation.mm

@ -73,6 +73,13 @@ private:
if (peer->IsRootProvider()) if (peer->IsRootProvider())
{ {
auto window = peer->RootProvider_GetWindow(); auto window = peer->RootProvider_GetWindow();
if (window == nullptr)
{
NSLog(@"IRootProvider.PlatformImpl returned null or a non-WindowBaseImpl.");
return nil;
}
auto holder = dynamic_cast<INSWindowHolder*>(window); auto holder = dynamic_cast<INSWindowHolder*>(window);
auto view = holder->GetNSView(); auto view = holder->GetNSView();
return [[AvnRootAccessibilityElement alloc] initWithPeer:peer owner:view]; return [[AvnRootAccessibilityElement alloc] initWithPeer:peer owner:view];
@ -284,8 +291,8 @@ private:
- (id)accessibilityWindow - (id)accessibilityWindow
{ {
id topLevel = [self accessibilityTopLevelUIElement]; auto rootPeer = _peer->GetVisualRoot();
return [topLevel isKindOfClass:[NSWindow class]] ? topLevel : nil; return [AvnAccessibilityElement acquire:rootPeer];
} }
- (BOOL)isAccessibilityExpanded - (BOOL)isAccessibilityExpanded

32
native/Avalonia.Native/src/OSX/common.h

@ -6,11 +6,13 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <AppKit/AppKit.h> #import <AppKit/AppKit.h>
#include <pthread.h> #include <pthread.h>
#include "noarc.h"
extern IAvnPlatformThreadingInterface* CreatePlatformThreading(); extern IAvnPlatformThreadingInterface* CreatePlatformThreading();
extern void FreeAvnGCHandle(void* handle); extern void FreeAvnGCHandle(void* handle);
extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events, IAvnGlContext* gl); extern void PostDispatcherCallback(IAvnActionCallback* cb);
extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events, IAvnGlContext* gl); extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events);
extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events);
extern IAvnSystemDialogs* CreateSystemDialogs(); extern IAvnSystemDialogs* CreateSystemDialogs();
extern IAvnScreens* CreateScreens(); extern IAvnScreens* CreateScreens();
extern IAvnClipboard* CreateClipboard(NSPasteboard*, NSPasteboardItem*); extern IAvnClipboard* CreateClipboard(NSPasteboard*, NSPasteboardItem*);
@ -21,6 +23,7 @@ extern NSString* GetAvnCustomDataType();
extern AvnDragDropEffects ConvertDragDropEffects(NSDragOperation nsop); extern AvnDragDropEffects ConvertDragDropEffects(NSDragOperation nsop);
extern IAvnCursorFactory* CreateCursorFactory(); extern IAvnCursorFactory* CreateCursorFactory();
extern IAvnGlDisplay* GetGlDisplay(); extern IAvnGlDisplay* GetGlDisplay();
extern IAvnMetalDisplay* GetMetalDisplay();
extern IAvnMenu* CreateAppMenu(IAvnMenuEvents* events); extern IAvnMenu* CreateAppMenu(IAvnMenuEvents* events);
extern IAvnTrayIcon* CreateTrayIcon(); extern IAvnTrayIcon* CreateTrayIcon();
extern IAvnMenuItem* CreateAppMenuItem(); extern IAvnMenuItem* CreateAppMenuItem();
@ -35,6 +38,7 @@ extern IAvnMenu* GetAppMenu ();
extern NSMenuItem* GetAppMenuItem (); extern NSMenuItem* GetAppMenuItem ();
extern void InitializeAvnApp(IAvnApplicationEvents* events, bool disableAppDelegate); extern void InitializeAvnApp(IAvnApplicationEvents* events, bool disableAppDelegate);
extern void ReleaseAvnAppEvents();
extern NSApplicationActivationPolicy AvnDesiredActivationPolicy; extern NSApplicationActivationPolicy AvnDesiredActivationPolicy;
extern NSPoint ToNSPoint (AvnPoint p); extern NSPoint ToNSPoint (AvnPoint p);
extern NSRect ToNSRect (AvnRect r); extern NSRect ToNSRect (AvnRect r);
@ -56,6 +60,27 @@ template<typename T> inline T* objc_cast(id from) {
return nil; return nil;
} }
template<typename T> class ObjCWrapper {
public:
T* Value;
ObjCWrapper(T* value)
{
Value = value;
}
operator T*() const
{
return Value;
}
T* operator->() const
{
return Value;
}
~ObjCWrapper()
{
Value = nil;
}
};
@interface ActionCallback : NSObject @interface ActionCallback : NSObject
- (ActionCallback*) initWithCallback: (IAvnActionCallback*) callback; - (ActionCallback*) initWithCallback: (IAvnActionCallback*) callback;
- (void) action; - (void) action;
@ -79,5 +104,8 @@ public:
virtual HRESULT ShowAll() override; virtual HRESULT ShowAll() override;
virtual HRESULT HideOthers() override; virtual HRESULT HideOthers() override;
}; };
#define NSApp [NSApplication sharedApplication]
#define START_COM_ARP_CALL START_ARP_CALL; START_COM_CALL
#endif #endif

44
native/Avalonia.Native/src/OSX/main.mm

@ -191,16 +191,28 @@ public:
@end @end
static ComPtr<IAvnGCHandleDeallocatorCallback> _deallocator; static ComPtr<IAvnGCHandleDeallocatorCallback> _deallocator;
static ComPtr<IAvnDispatcher> _dispatcher;
class AvaloniaNative : public ComSingleObject<IAvaloniaNativeFactory, &IID_IAvaloniaNativeFactory> class AvaloniaNative : public ComSingleObject<IAvaloniaNativeFactory, &IID_IAvaloniaNativeFactory>
{ {
public: public:
FORWARD_IUNKNOWN() FORWARD_IUNKNOWN()
virtual HRESULT Initialize(IAvnGCHandleDeallocatorCallback* deallocator, IAvnApplicationEvents* events) override
virtual ~AvaloniaNative() override
{
ReleaseAvnAppEvents();
_deallocator = nullptr;
_dispatcher = nullptr;
}
virtual HRESULT Initialize(IAvnGCHandleDeallocatorCallback* deallocator,
IAvnApplicationEvents* events,
IAvnDispatcher* dispatcher) override
{ {
START_COM_CALL; START_COM_CALL;
_deallocator = deallocator; _deallocator = deallocator;
_dispatcher = dispatcher;
@autoreleasepool{ @autoreleasepool{
[[ThreadingInitializer new] do]; [[ThreadingInitializer new] do];
} }
@ -213,7 +225,7 @@ public:
return (IAvnMacOptions*)new MacOptions(); return (IAvnMacOptions*)new MacOptions();
} }
virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnGlContext* gl, IAvnWindow** ppv) override virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnWindow** ppv) override
{ {
START_COM_CALL; START_COM_CALL;
@ -221,12 +233,12 @@ public:
{ {
if(cb == nullptr || ppv == nullptr) if(cb == nullptr || ppv == nullptr)
return E_POINTER; return E_POINTER;
*ppv = CreateAvnWindow(cb, gl); *ppv = CreateAvnWindow(cb);
return S_OK; return S_OK;
} }
}; };
virtual HRESULT CreatePopup(IAvnWindowEvents* cb, IAvnGlContext* gl, IAvnPopup** ppv) override virtual HRESULT CreatePopup(IAvnWindowEvents* cb, IAvnPopup** ppv) override
{ {
START_COM_CALL; START_COM_CALL;
@ -235,7 +247,7 @@ public:
if(cb == nullptr || ppv == nullptr) if(cb == nullptr || ppv == nullptr)
return E_POINTER; return E_POINTER;
*ppv = CreateAvnPopup(cb, gl); *ppv = CreateAvnPopup(cb);
return S_OK; return S_OK;
} }
} }
@ -320,7 +332,22 @@ public:
return S_OK; return S_OK;
} }
} }
virtual HRESULT ObtainMetalDisplay(IAvnMetalDisplay** ppv) override
{
START_COM_CALL;
@autoreleasepool
{
auto rv = ::GetMetalDisplay();
if(rv == NULL)
return E_FAIL;
rv->AddRef();
*ppv = rv;
return S_OK;
}
}
virtual HRESULT CreateTrayIcon (IAvnTrayIcon** ppv) override virtual HRESULT CreateTrayIcon (IAvnTrayIcon** ppv) override
{ {
START_COM_CALL; START_COM_CALL;
@ -432,6 +459,11 @@ extern void FreeAvnGCHandle(void* handle)
_deallocator->FreeGCHandle(handle); _deallocator->FreeGCHandle(handle);
} }
extern void PostDispatcherCallback(IAvnActionCallback* cb)
{
_dispatcher->Post(cb);
}
NSSize ToNSSize (AvnSize s) NSSize ToNSSize (AvnSize s)
{ {
NSSize result; NSSize result;

161
native/Avalonia.Native/src/OSX/metal.mm

@ -0,0 +1,161 @@
#import <AppKit/AppKit.h>
#import <Metal/Metal.h>
#import <QuartzCore/QuartzCore.h>
#include "common.h"
#include "rendertarget.h"
class AvnMetalDevice : public ComSingleObject<IAvnMetalDevice, &IID_IAvnMetalDevice>
{
public:
id<MTLDevice> device;
id<MTLCommandQueue> queue;
FORWARD_IUNKNOWN()
void *GetDevice() override {
return (__bridge void*) device;
}
void *GetQueue() override {
return (__bridge void*) queue;
}
AvnMetalDevice(id <MTLDevice> device, id <MTLCommandQueue> queue) : device(device), queue(queue) {
}
};
class AvnMetalRenderSession : public ComSingleObject<IAvnMetalRenderingSession, &IID_IAvnMetalRenderingSession>
{
id<CAMetalDrawable> _drawable;
id<MTLCommandQueue> _queue;
id<MTLTexture> _texture;
CAMetalLayer* _layer;
AvnPixelSize _size;
double _scaling;
public:
FORWARD_IUNKNOWN()
AvnMetalRenderSession(AvnMetalDevice* device, CAMetalLayer* layer, id <CAMetalDrawable> drawable, const AvnPixelSize &size, double scaling)
: _drawable(drawable), _size(size), _scaling(scaling), _queue(device->queue),
_texture([drawable texture]) {
_layer = layer;
}
HRESULT GetPixelSize(AvnPixelSize *ret) override {
*ret = _size;
return 0;
}
double GetScaling() override {
return _scaling;
}
void *GetTexture() override {
return (__bridge void*) _texture;
}
~AvnMetalRenderSession()
{
auto buffer = [_queue commandBuffer];
[buffer presentDrawable: _drawable];
[buffer commit];
}
};
class AvnMetalRenderTarget : public ComSingleObject<IAvnMetalRenderTarget, &IID_IAvnMetalRenderTarget>
{
CAMetalLayer* _layer;
double _scaling = 1;
AvnPixelSize _size = {1,1};
ComPtr<AvnMetalDevice> _device;
public:
double PendingScaling = 1;
AvnPixelSize PendingSize = {1,1};
FORWARD_IUNKNOWN()
AvnMetalRenderTarget(CAMetalLayer* layer, ComPtr<AvnMetalDevice> device)
{
_layer = layer;
_device = device;
}
HRESULT BeginDrawing(IAvnMetalRenderingSession **ret) override {
if([NSThread isMainThread])
{
// Flush all existing rendering
auto buffer = [_device->queue commandBuffer];
[buffer commit];
[buffer waitUntilCompleted];
_size = PendingSize;
_scaling= PendingScaling;
CGSize layerSize = {(CGFloat)_size.Width, (CGFloat)_size.Height};
[_layer setDrawableSize: layerSize];
}
auto drawable = [_layer nextDrawable];
if(drawable == nil)
{
ret = nil;
return E_FAIL;
}
*ret = new AvnMetalRenderSession(_device, _layer, drawable, _size, _scaling);
return 0;
}
};
@implementation MetalRenderTarget
{
ComPtr<AvnMetalDevice> _device;
CAMetalLayer* _layer;
ComPtr<AvnMetalRenderTarget> _target;
}
- (MetalRenderTarget *)initWithDevice:(IAvnMetalDevice *)device {
_device = dynamic_cast<AvnMetalDevice*>(device);
_layer = [CAMetalLayer new];
_layer.device = _device->device;
_target.setNoAddRef(new AvnMetalRenderTarget(_layer, _device));
return self;
}
-(void) getRenderTarget: (IAvnMetalRenderTarget**) ppv
{
*ppv = static_cast<IAvnMetalRenderTarget*>(_target.getRetainedReference());
}
- (void)resize:(AvnPixelSize)size withScale:(float)scale {
CGSize layerSize = {(CGFloat)size.Width, (CGFloat)size.Height};
_target->PendingScaling = scale;
_target->PendingSize = size;
[_layer setNeedsDisplay];
}
- (CALayer *)layer {
return _layer;
}
@end
class AvnMetalDisplay : public ComSingleObject<IAvnMetalDisplay, &IID_IAvnMetalDisplay>
{
public:
FORWARD_IUNKNOWN()
HRESULT CreateDevice(IAvnMetalDevice **ret) override {
auto device = MTLCreateSystemDefaultDevice();
if(device == nil) {
ret = nil;
return E_FAIL;
}
auto queue = [device newCommandQueue];
*ret = new AvnMetalDevice(device, queue);
return S_OK;
}
};
static AvnMetalDisplay* _display = new AvnMetalDisplay();
extern IAvnMetalDisplay* GetMetalDisplay()
{
return _display;
}

11
native/Avalonia.Native/src/OSX/noarc.mm

@ -0,0 +1,11 @@
#include "noarc.h"
CppAutoreleasePool::CppAutoreleasePool()
{
_pool = [[NSAutoreleasePool alloc] init];
}
CppAutoreleasePool::~CppAutoreleasePool() {
auto ptr = (NSAutoreleasePool*)_pool;
[ptr release];
}

245
native/Avalonia.Native/src/OSX/rendertarget.mm

@ -5,15 +5,12 @@
#include <OpenGL/glext.h> #include <OpenGL/glext.h>
#include <OpenGL/gl3.h> #include <OpenGL/gl3.h>
#include <queue>
@interface IOSurfaceHolder : NSObject @implementation IOSurfaceHolder : NSObject
@end
@implementation IOSurfaceHolder
{ {
@public IOSurfaceRef surface; @public IOSurfaceRef surface;
@public AvnPixelSize size; @public AvnPixelSize size;
@public bool hasContent;
@public float scale; @public float scale;
ComPtr<IAvnGlContext> _context; ComPtr<IAvnGlContext> _context;
GLuint _framebuffer, _texture, _renderbuffer; GLuint _framebuffer, _texture, _renderbuffer;
@ -42,7 +39,6 @@
self->scale = scale; self->scale = scale;
self->size = size; self->size = size;
self->_context = context; self->_context = context;
self->hasContent = false;
return self; return self;
} }
@ -76,7 +72,7 @@
} }
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_EXT, _texture, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_EXT, _texture, 0);
} }
if(_renderbuffer == 0) if(_renderbuffer == 0)
{ {
glGenRenderbuffers(1, &_renderbuffer); glGenRenderbuffers(1, &_renderbuffer);
@ -84,48 +80,72 @@
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.Width, size.Height); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.Width, size.Height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _renderbuffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _renderbuffer);
} }
return S_OK; return S_OK;
} }
-(void) finishDraw -(void) finishDraw
{ {
ComPtr<IUnknown> release;
_context->MakeCurrent(release.getPPV());
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
if(_framebuffer != 0) {
glDeleteFramebuffers(1, &_framebuffer);
_framebuffer = 0;
}
if(_texture != 0) {
glDeleteTextures(1, &_texture);
_texture = 0;
}
if(_renderbuffer != 0) {
glDeleteRenderbuffers(1, &_renderbuffer);
_renderbuffer = 0;
}
glFlush(); glFlush();
self->hasContent = true;
} }
-(void) dealloc -(void) dealloc
{ {
if(_framebuffer != 0)
{
ComPtr<IUnknown> release;
_context->MakeCurrent(release.getPPV());
glDeleteFramebuffers(1, &_framebuffer);
if(_texture != 0)
glDeleteTextures(1, &_texture);
if(_renderbuffer != 0)
glDeleteRenderbuffers(1, &_renderbuffer);
}
if(surface != nullptr) if(surface != nullptr)
{ {
CFRelease(surface); CFRelease(surface);
surface = nil;
} }
} }
@end @end
static IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(IOSurfaceRenderTarget* target); static IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(IOSurfaceRenderTarget* target);
static IAvnSoftwareRenderTarget* CreateSoftwareRenderTarget(IOSurfaceRenderTarget* target);
static bool SizeEquals(AvnPixelSize& left, AvnPixelSize& right)
{
return left.Width == right.Width && right.Height == left.Height;
}
class ConsumeSurfacesCallback : public ComSingleObject<IAvnActionCallback, &IID_IAvnActionCallback>
{
IOSurfaceRenderTarget* _target;
public:
FORWARD_IUNKNOWN()
ConsumeSurfacesCallback(IOSurfaceRenderTarget* target)
{
_target = target;
}
void Run() override {
[_target consumeSurfaces];
}
};
@implementation IOSurfaceRenderTarget @implementation IOSurfaceRenderTarget
{ {
CALayer* _layer; CALayer* _layer;
@public IOSurfaceHolder* surface;
@public NSObject* lock; @public NSObject* lock;
ComPtr<IAvnGlContext> _glContext; ComPtr<IAvnGlContext> _glContext;
bool _consumeSurfacesScheduled;
std::queue<ObjCWrapper<IOSurfaceHolder>> _surfaces;
IOSurfaceHolder* _activeSurface;
AvnPixelSize _size;
float _scale;
} }
- (IOSurfaceRenderTarget*) initWithOpenGlContext: (IAvnGlContext*) context; - (IOSurfaceRenderTarget*) initWithOpenGlContext: (IAvnGlContext*) context;
@ -133,16 +153,12 @@ static IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(IOSurfaceRenderTarget* ta
self = [super init]; self = [super init];
_glContext = context; _glContext = context;
lock = [NSObject new]; lock = [NSObject new];
surface = nil; _layer = [CALayer new];
[self resize:{1,1} withScale: 1]; [self resize:{1,1} withScale: 1];
return self; return self;
} }
- (AvnPixelSize) pixelSize {
return {1, 1};
}
- (CALayer *)layer { - (CALayer *)layer {
return _layer; return _layer;
} }
@ -155,57 +171,110 @@ static IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(IOSurfaceRenderTarget* ta
size.Width = 1; size.Width = 1;
@synchronized (lock) { @synchronized (lock) {
if(surface == nil _size = size;
|| surface->size.Width != size.Width _scale = scale;
|| surface->size.Height != size.Height
|| surface->scale != scale)
{
surface = [[IOSurfaceHolder alloc] initWithSize:size withScale:scale withOpenGlContext:_glContext.getRaw()];
[self updateLayer];
}
} }
} }
- (void)updateLayer { - (void)setSurfaceInUiThreadContext: (IOSurfaceHolder*) surface
if ([NSThread isMainThread]) {
[CATransaction begin];
if(surface == _activeSurface)
[_layer setContents: nil];
_activeSurface = surface;
[_layer setContentsScale: _activeSurface->scale];
[_layer setContents: (__bridge IOSurface*) _activeSurface->surface];
[CATransaction commit];
}
- (void)consumeSurfaces {
@synchronized (lock) {
_consumeSurfacesScheduled = false;
while(_surfaces.size() > 1)
_surfaces.pop();
if(_surfaces.size() == 0)
return;
auto targetSurface = _surfaces.front();
_surfaces.pop();
[self setSurfaceInUiThreadContext: targetSurface];
}
// This can trigger event processing on the main thread
// which might need to lock the renderer
// which can cause a deadlock. So flush call is outside of the lock
[CATransaction flush];
}
- (IOSurfaceHolder*) getNextSurfaceInSafeContext
{
IOSurfaceHolder* targetSurface = nil;
if([NSThread isMainThread])
{ {
@synchronized (lock) { // Drain the surface queue and try to find a surface usable for rendering
if(_layer == nil) while(_surfaces.size() > 0)
return; {
if(!surface->hasContent) auto front = _surfaces.front();
return; _surfaces.pop();
[CATransaction begin]; if(targetSurface == nil && SizeEquals(front.Value->size, _size))
[_layer setContents: nil];
if(surface != nil)
{ {
[_layer setContentsScale: surface->scale]; targetSurface = front;
[_layer setContents: (__bridge IOSurface*) surface->surface];
} }
[CATransaction commit];
} }
// This can trigger event processing on the main thread if(targetSurface == nil && _activeSurface != nil && SizeEquals(_activeSurface->size, _size))
// which might need to lock the renderer targetSurface = _activeSurface;
// which can cause a deadlock. So flush call is outside of the lock }
[CATransaction flush]; else
{
// Try to reuse an outdated surface that is still not picked up by the UI thread
while(_surfaces.size() > 1)
{
auto front = _surfaces.front();
_surfaces.pop();
// Simply discard the surface on size mismatch
if(SizeEquals(front.Value->size, _size))
targetSurface = front;
}
} }
if(targetSurface == nil)
targetSurface = [[IOSurfaceHolder alloc] initWithSize: _size withScale: _scale withOpenGlContext: _glContext];
return targetSurface;
}
- (void) presentSurfaceInSafeContext: (IOSurfaceHolder*) surface
{
if([NSThread isMainThread])
[self setSurfaceInUiThreadContext: surface];
else else
dispatch_async(dispatch_get_main_queue(), ^{ {
[self updateLayer]; _surfaces.push(surface);
}); if(_consumeSurfacesScheduled)
return;
_consumeSurfacesScheduled = true;
__block auto strongSelf = self;
ComPtr<ConsumeSurfacesCallback> cb(new ConsumeSurfacesCallback(self), true);
PostDispatcherCallback(cb);
}
} }
- (void) setNewLayer:(CALayer *)layer { - (void) presentSurface: (IOSurfaceHolder*) surface
_layer = layer; {
[self updateLayer]; @synchronized(lock)
{
[self presentSurfaceInSafeContext: surface];
}
} }
- (HRESULT)setSwFrame:(AvnFramebuffer *)fb { - (HRESULT)setSwFrame:(AvnFramebuffer *)fb {
@synchronized (lock) { @synchronized (lock) {
if(fb->PixelFormat == AvnPixelFormat::kAvnRgb565) if(fb->PixelFormat == AvnPixelFormat::kAvnRgb565)
return E_INVALIDARG; return E_INVALIDARG;
if(surface == nil) auto surface = [self getNextSurfaceInSafeContext];
return E_FAIL;
IOSurfaceRef surf = surface->surface; IOSurfaceRef surf = surface->surface;
if(IOSurfaceLock(surf, 0, nil)) if(IOSurfaceLock(surf, 0, nil))
return E_FAIL; return E_FAIL;
@ -221,8 +290,7 @@ static IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(IOSurfaceRenderTarget* ta
memcpy(pSurface + y*sstride, pFb + y*fstride, wbytes); memcpy(pSurface + y*sstride, pFb + y*fstride, wbytes);
} }
IOSurfaceUnlock(surf, 0, nil); IOSurfaceUnlock(surf, 0, nil);
surface->hasContent = true; [self presentSurfaceInSafeContext: surface];
[self updateLayer];
return S_OK; return S_OK;
} }
} }
@ -232,6 +300,11 @@ static IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(IOSurfaceRenderTarget* ta
return CreateGlRenderTarget(self); return CreateGlRenderTarget(self);
} }
-(IAvnSoftwareRenderTarget*) createSoftwareRenderTarget
{
return CreateSoftwareRenderTarget(self);
}
@end @end
class AvnGlRenderingSession : public ComSingleObject<IAvnGlSurfaceRenderingSession, &IID_IAvnGlSurfaceRenderingSession> class AvnGlRenderingSession : public ComSingleObject<IAvnGlSurfaceRenderingSession, &IID_IAvnGlSurfaceRenderingSession>
@ -241,12 +314,12 @@ class AvnGlRenderingSession : public ComSingleObject<IAvnGlSurfaceRenderingSessi
IOSurfaceHolder* _surface; IOSurfaceHolder* _surface;
public: public:
FORWARD_IUNKNOWN() FORWARD_IUNKNOWN()
AvnGlRenderingSession(IOSurfaceRenderTarget* target, ComPtr<IUnknown> releaseContext) AvnGlRenderingSession(IOSurfaceRenderTarget* target, IOSurfaceHolder* surface, ComPtr<IUnknown> releaseContext)
{ {
_target = target; _target = target;
// This happens in a synchronized block set up by AvnRenderTarget, so we take the current surface for this // This happens in a synchronized block set up by AvnRenderTarget, so we take the current surface for this
// particular render session // particular render session
_surface = _target->surface; _surface = surface;
_releaseContext = releaseContext; _releaseContext = releaseContext;
} }
@ -272,8 +345,9 @@ public:
virtual ~AvnGlRenderingSession() virtual ~AvnGlRenderingSession()
{ {
START_ARP_CALL;
[_surface finishDraw]; [_surface finishDraw];
[_target updateLayer]; [_target presentSurface: _surface];
_releaseContext = nil; _releaseContext = nil;
} }
}; };
@ -290,17 +364,15 @@ public:
virtual HRESULT BeginDrawing(IAvnGlSurfaceRenderingSession** ret) override virtual HRESULT BeginDrawing(IAvnGlSurfaceRenderingSession** ret) override
{ {
START_COM_CALL; START_COM_ARP_CALL;
ComPtr<IUnknown> releaseContext; ComPtr<IUnknown> releaseContext;
@synchronized (_target->lock) { @synchronized (_target->lock) {
if(_target->surface == nil) auto surface = [_target getNextSurfaceInSafeContext];
return E_FAIL;
_target->_glContext->MakeCurrent(releaseContext.getPPV()); _target->_glContext->MakeCurrent(releaseContext.getPPV());
HRESULT res = [_target->surface prepareForGlRender]; HRESULT res = [surface prepareForGlRender];
if(res) if(res)
return res; return res;
*ret = new AvnGlRenderingSession(_target, releaseContext); *ret = new AvnGlRenderingSession(_target, surface, releaseContext);
return S_OK; return S_OK;
} }
} }
@ -310,4 +382,27 @@ public:
static IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(IOSurfaceRenderTarget* target) static IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(IOSurfaceRenderTarget* target)
{ {
return new AvnGlRenderTarget(target); return new AvnGlRenderTarget(target);
} };
class AvnSoftwareRenderTarget : public ComSingleObject<IAvnSoftwareRenderTarget, &IID_IAvnSoftwareRenderTarget>
{
IOSurfaceRenderTarget* _target;
public:
FORWARD_IUNKNOWN()
AvnSoftwareRenderTarget(IOSurfaceRenderTarget *target) {
_target = target;
}
HRESULT SetFrame(AvnFramebuffer *fb) override {
START_COM_ARP_CALL;
[_target setSwFrame: fb];
return 0;
}
};
static IAvnSoftwareRenderTarget* CreateSoftwareRenderTarget(IOSurfaceRenderTarget* target)
{
return new AvnSoftwareRenderTarget(target);
};

154
nukebuild/ApiDiffValidation.cs

@ -0,0 +1,154 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Nuke.Common.Tooling;
public static class ApiDiffValidation
{
private static readonly HttpClient s_httpClient = new();
public static async Task ValidatePackage(
Tool apiCompatTool, string packagePath, string baselineVersion,
string suppressionFilesFolder, bool updateSuppressionFile)
{
if (baselineVersion is null)
{
throw new InvalidOperationException(
"Build \"api-baseline\" parameter must be set when running Nuke CreatePackages");
}
if (!Directory.Exists(suppressionFilesFolder))
{
Directory.CreateDirectory(suppressionFilesFolder!);
}
await using (var baselineStream = await DownloadBaselinePackage(packagePath, baselineVersion))
using (var target = new ZipArchive(File.Open(packagePath, FileMode.Open, FileAccess.Read), ZipArchiveMode.Read))
using (var baseline = new ZipArchive(baselineStream, ZipArchiveMode.Read))
using (Helpers.UseTempDir(out var tempFolder))
{
var targetDlls = GetDlls(target);
var baselineDlls = GetDlls(baseline);
var left = new List<string>();
var right = new List<string>();
var packageId = GetPackageId(packagePath);
var suppressionFile = Path.Combine(suppressionFilesFolder, packageId + ".nupkg.xml");
// Don't use Path.Combine with these left and right tool parameters.
// Microsoft.DotNet.ApiCompat.Tool is stupid and treats '/' and '\' as different assemblies in suppression files.
// So, always use Unix '/'
foreach (var baselineDll in baselineDlls)
{
var baselineDllPath = $"baseline/{baselineDll.target}/{baselineDll.entry.Name}";
var baselineDllRealPath = Path.Combine(tempFolder, baselineDllPath);
Directory.CreateDirectory(Path.GetDirectoryName(baselineDllRealPath)!);
await using (var baselineDllFile = File.Create(baselineDllRealPath))
{
await baselineDll.entry.Open().CopyToAsync(baselineDllFile);
}
var targetDll = targetDlls.FirstOrDefault(e =>
e.target == baselineDll.target && e.entry.Name == baselineDll.entry.Name);
if (targetDll.entry is null)
{
throw new InvalidOperationException($"Some assemblies are missing in the new package {packageId}: {baselineDll.entry.Name} for {baselineDll.target}");
}
var targetDllPath = $"target/{targetDll.target}/{targetDll.entry.Name}";
var targetDllRealPath = Path.Combine(tempFolder, targetDllPath);
Directory.CreateDirectory(Path.GetDirectoryName(targetDllRealPath)!);
await using (var targetDllFile = File.Create(targetDllRealPath))
{
await targetDll.entry.Open().CopyToAsync(targetDllFile);
}
left.Add(baselineDllPath);
right.Add(targetDllPath);
}
if (left.Any())
{
var args = $""" -l={string.Join(',', left)} -r="{string.Join(',', right)}" """;
if (File.Exists(suppressionFile))
{
args += $""" --suppression-file="{suppressionFile}" """;
}
if (updateSuppressionFile)
{
args += $""" --suppression-output-file="{suppressionFile}" --generate-suppression-file=true """;
}
var result = apiCompatTool(args, tempFolder)
.Where(t => t.Type == OutputType.Err).ToArray();
if (result.Any())
{
throw new AggregateException(
$"ApiDiffValidation task has failed for \"{Path.GetFileName(packagePath)}\" package",
result.Select(r => new Exception(r.Text)));
}
}
}
}
private static IReadOnlyCollection<(string target, ZipArchiveEntry entry)> GetDlls(ZipArchive archive)
{
return archive.Entries
.Where(e => Path.GetExtension(e.FullName) == ".dll"
// Exclude analyzers and build task, as we don't care about breaking changes there
&& !e.FullName.Contains("analyzers/") && !e.FullName.Contains("analyzers\\")
&& !e.Name.Contains("Avalonia.Build.Tasks"))
.Select(e => (
entry: e,
isRef: e.FullName.Contains("ref/") || e.FullName.Contains("ref\\"),
target: Path.GetDirectoryName(e.FullName)!.Split(new [] { '/', '\\' }).Last())
)
.GroupBy(e => (e.target, e.entry.Name))
.Select(g => g.MaxBy(e => e.isRef))
.Select(e => (e.target, e.entry))
.ToArray();
}
static async Task<Stream> DownloadBaselinePackage(string packagePath, string baselineVersion)
{
/*
Gets package name from versions like:
Avalonia.0.10.0-preview1
Avalonia.11.0.999-cibuild0037534-beta
Avalonia.11.0.0
*/
var packageId = GetPackageId(packagePath);
Build.Information("Downloading {0} {1} baseline package", packageId, baselineVersion);
try
{
using var response = await s_httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Get,
$"https://www.nuget.org/api/v2/package/{packageId}/{baselineVersion}"), HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();
await using var stream = await response.Content.ReadAsStreamAsync();
var memoryStream = new MemoryStream();
await stream.CopyToAsync(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
return memoryStream;
}
catch (Exception ex)
{
throw new InvalidOperationException($"Downloading baseline package for {packageId} {baselineVersion} failed.\r" + ex.Message, ex);
}
}
static string GetPackageId(string packagePath)
{
return Regex.Replace(
Path.GetFileNameWithoutExtension(packagePath),
"""(\.\d+\.\d+\.\d+(?:-.+)?)$""", "");
}
}

24
nukebuild/Build.cs

@ -36,6 +36,10 @@ using MicroCom.CodeGenerator;
partial class Build : NukeBuild partial class Build : NukeBuild
{ {
BuildParameters Parameters { get; set; } BuildParameters Parameters { get; set; }
[PackageExecutable("Microsoft.DotNet.ApiCompat.Tool", "Microsoft.DotNet.ApiCompat.Tool.dll", Framework = "net6.0")]
Tool ApiCompatTool;
protected override void OnBuildInitialized() protected override void OnBuildInitialized()
{ {
Parameters = new BuildParameters(this); Parameters = new BuildParameters(this);
@ -275,10 +279,21 @@ partial class Build : NukeBuild
if(!Numerge.NugetPackageMerger.Merge(Parameters.NugetIntermediateRoot, Parameters.NugetRoot, config, if(!Numerge.NugetPackageMerger.Merge(Parameters.NugetIntermediateRoot, Parameters.NugetRoot, config,
new NumergeNukeLogger())) new NumergeNukeLogger()))
throw new Exception("Package merge failed"); throw new Exception("Package merge failed");
RefAssemblyGenerator.GenerateRefAsmsInPackage(Parameters.NugetRoot / "Avalonia." + RefAssemblyGenerator.GenerateRefAsmsInPackage(
Parameters.Version + ".nupkg"); Parameters.NugetRoot / $"Avalonia.{Parameters.Version}.nupkg",
Parameters.NugetRoot / $"Avalonia.{Parameters.Version}.snupkg");
}); });
Target ValidateApiDiff => _ => _
.DependsOn(CreateNugetPackages)
.Executes(async () =>
{
await Task.WhenAll(
Directory.GetFiles(Parameters.NugetRoot, "*.nupkg").Select(nugetPackage => ApiDiffValidation.ValidatePackage(
ApiCompatTool, nugetPackage, Parameters.ApiValidationBaseline,
Parameters.ApiValidationSuppressionFiles, Parameters.UpdateApiValidationSuppression)));
});
Target RunTests => _ => _ Target RunTests => _ => _
.DependsOn(RunCoreLibsTests) .DependsOn(RunCoreLibsTests)
.DependsOn(RunRenderTests) .DependsOn(RunRenderTests)
@ -288,7 +303,8 @@ partial class Build : NukeBuild
Target Package => _ => _ Target Package => _ => _
.DependsOn(RunTests) .DependsOn(RunTests)
.DependsOn(CreateNugetPackages); .DependsOn(CreateNugetPackages)
.DependsOn(ValidateApiDiff);
Target CiAzureLinux => _ => _ Target CiAzureLinux => _ => _
.DependsOn(RunTests); .DependsOn(RunTests);

22
nukebuild/BuildParameters.cs

@ -10,18 +10,24 @@ using static Nuke.Common.IO.PathConstruction;
public partial class Build public partial class Build
{ {
[Parameter("configuration")] [Parameter(Name = "configuration")]
public string Configuration { get; set; } public string Configuration { get; set; }
[Parameter("skip-tests")] [Parameter(Name = "skip-tests")]
public bool SkipTests { get; set; } public bool SkipTests { get; set; }
[Parameter("force-nuget-version")] [Parameter(Name = "force-nuget-version")]
public string ForceNugetVersion { get; set; } public string ForceNugetVersion { get; set; }
[Parameter("skip-previewer")] [Parameter(Name = "skip-previewer")]
public bool SkipPreviewer { get; set; } public bool SkipPreviewer { get; set; }
[Parameter(Name = "api-baseline")]
public string ApiValidationBaseline { get; set; }
[Parameter(Name = "update-api-suppression")]
public bool? UpdateApiValidationSuppression { get; set; }
public class BuildParameters public class BuildParameters
{ {
public string Configuration { get; } public string Configuration { get; }
@ -57,7 +63,9 @@ public partial class Build
public string FileZipSuffix { get; } public string FileZipSuffix { get; }
public AbsolutePath ZipCoreArtifacts { get; } public AbsolutePath ZipCoreArtifacts { get; }
public AbsolutePath ZipNuGetArtifacts { get; } public AbsolutePath ZipNuGetArtifacts { get; }
public string ApiValidationBaseline { get; }
public bool UpdateApiValidationSuppression { get; }
public AbsolutePath ApiValidationSuppressionFiles { get; }
public BuildParameters(Build b) public BuildParameters(Build b)
{ {
@ -103,6 +111,9 @@ public partial class Build
// VERSION // VERSION
Version = b.ForceNugetVersion ?? GetVersion(); Version = b.ForceNugetVersion ?? GetVersion();
ApiValidationBaseline = b.ApiValidationBaseline ?? new Version(new Version(Version).Major, 0).ToString();
UpdateApiValidationSuppression = b.UpdateApiValidationSuppression ?? IsLocalBuild;
if (IsRunningOnAzure) if (IsRunningOnAzure)
{ {
if (!IsNuGetRelease) if (!IsNuGetRelease)
@ -125,6 +136,7 @@ public partial class Build
FileZipSuffix = Version + ".zip"; FileZipSuffix = Version + ".zip";
ZipCoreArtifacts = ZipRoot / ("Avalonia-" + FileZipSuffix); ZipCoreArtifacts = ZipRoot / ("Avalonia-" + FileZipSuffix);
ZipNuGetArtifacts = ZipRoot / ("Avalonia-NuGet-" + FileZipSuffix); ZipNuGetArtifacts = ZipRoot / ("Avalonia-NuGet-" + FileZipSuffix);
ApiValidationSuppressionFiles = RootDirectory / "api";
} }
string GetVersion() string GetVersion()

2
nukebuild/Numerge

@ -1 +1 @@
Subproject commit aef10ae67dc55c95f49b52a505a0be33bfa297a5 Subproject commit 9738c6121fdd143c78d3e25686a7e4e13c00f586

109
nukebuild/RefAssemblyGenerator.cs

@ -1,8 +1,10 @@
#nullable enable
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.Compression; using System.IO.Compression;
using System.Linq; using System.Linq;
using ILRepacking;
using Mono.Cecil; using Mono.Cecil;
using Mono.Cecil.Cil; using Mono.Cecil.Cil;
@ -10,8 +12,8 @@ public class RefAssemblyGenerator
{ {
class Resolver : DefaultAssemblyResolver, IAssemblyResolver class Resolver : DefaultAssemblyResolver, IAssemblyResolver
{ {
private readonly string _dir; readonly string _dir;
Dictionary<string, AssemblyDefinition> _cache = new(); readonly Dictionary<string, AssemblyDefinition> _cache = new();
public Resolver(string dir) public Resolver(string dir)
{ {
@ -31,17 +33,17 @@ public class RefAssemblyGenerator
public static void PatchRefAssembly(string file) public static void PatchRefAssembly(string file)
{ {
var reader = typeof(RefAssemblyGenerator).Assembly.GetManifestResourceStream("avalonia.snk"); var reader = typeof(RefAssemblyGenerator).Assembly.GetManifestResourceStream("avalonia.snk")!;
var snk = new byte[reader.Length]; var snk = new byte[reader.Length];
reader.Read(snk, 0, snk.Length); reader.ReadExactly(snk, 0, snk.Length);
var def = AssemblyDefinition.ReadAssembly(file, new ReaderParameters var def = AssemblyDefinition.ReadAssembly(file, new ReaderParameters
{ {
ReadWrite = true, ReadWrite = true,
InMemory = true, InMemory = true,
ReadSymbols = true, ReadSymbols = true,
SymbolReaderProvider = new DefaultSymbolReaderProvider(false), SymbolReaderProvider = new DefaultSymbolReaderProvider(throwIfNoSymbol: true),
AssemblyResolver = new Resolver(Path.GetDirectoryName(file)) AssemblyResolver = new Resolver(Path.GetDirectoryName(file)!)
}); });
var obsoleteAttribute = def.MainModule.ImportReference(new TypeReference("System", "ObsoleteAttribute", def.MainModule, var obsoleteAttribute = def.MainModule.ImportReference(new TypeReference("System", "ObsoleteAttribute", def.MainModule,
@ -58,7 +60,7 @@ public class RefAssemblyGenerator
{ {
StrongNameKeyBlob = snk, StrongNameKeyBlob = snk,
WriteSymbols = def.MainModule.HasSymbols, WriteSymbols = def.MainModule.HasSymbols,
SymbolWriterProvider = new EmbeddedPortablePdbWriterProvider(), SymbolWriterProvider = new PortablePdbWriterProvider(),
DeterministicMvid = def.MainModule.HasSymbols DeterministicMvid = def.MainModule.HasSymbols
}); });
} }
@ -146,7 +148,7 @@ public class RefAssemblyGenerator
m.Attributes = ((m.Attributes | dflags) ^ dflags) | MethodAttributes.Assembly; m.Attributes = ((m.Attributes | dflags) ^ dflags) | MethodAttributes.Assembly;
} }
static void MarkAsUnstable(IMemberDefinition def, MethodReference obsoleteCtor, ICustomAttribute unstableAttribute) static void MarkAsUnstable(IMemberDefinition def, MethodReference obsoleteCtor, ICustomAttribute? unstableAttribute)
{ {
if (def.CustomAttributes.Any(a => a.AttributeType.FullName == "System.ObsoleteAttribute")) if (def.CustomAttributes.Any(a => a.AttributeType.FullName == "System.ObsoleteAttribute"))
return; return;
@ -172,43 +174,66 @@ public class RefAssemblyGenerator
}); });
} }
public static void GenerateRefAsmsInPackage(string packagePath) public static void GenerateRefAsmsInPackage(string mainPackagePath, string symbolsPackagePath)
{ {
using (var archive = new ZipArchive(File.Open(packagePath, FileMode.Open, FileAccess.ReadWrite), using var mainArchive = OpenPackage(mainPackagePath);
ZipArchiveMode.Update)) using var symbolsArchive = OpenPackage(symbolsPackagePath);
foreach (var entry in mainArchive.Entries
.Where(e => e.FullName.StartsWith("ref/", StringComparison.Ordinal))
.ToArray())
{ {
foreach (var entry in archive.Entries.ToList()) entry.Delete();
{ }
if (entry.FullName.StartsWith("ref/"))
entry.Delete(); foreach (var libEntry in GetLibEntries(mainArchive, ".xml"))
} {
var refEntry = mainArchive.CreateEntry("ref/" + libEntry.FullName.Substring(4), CompressionLevel.Optimal);
foreach (var entry in archive.Entries.ToList()) using var src = libEntry.Open();
using var dst = refEntry.Open();
src.CopyTo(dst);
}
var pdbEntries = GetLibEntries(symbolsArchive, ".pdb").ToDictionary(e => e.FullName);
var libs = GetLibEntries(mainArchive, ".dll")
.Select(e => (NameParts: e.FullName.Split('/'), Entry: e))
.Select(e => (
Tfm: e.NameParts[1],
DllName: e.NameParts[2],
DllEntry: e.Entry,
PdbName: Path.ChangeExtension(e.NameParts[2], ".pdb"),
PdbEntry: pdbEntries.TryGetValue(Path.ChangeExtension(e.Entry.FullName, ".pdb"), out var pdbEntry) ?
pdbEntry :
throw new InvalidOperationException($"Missing symbols for {e.Entry.FullName}")))
.GroupBy(e => e.Tfm);
foreach (var tfm in libs)
{
using var _ = Helpers.UseTempDir(out var temp);
foreach (var lib in tfm)
{ {
if (entry.FullName.StartsWith("lib/") && entry.Name.EndsWith(".xml")) var extractedDllPath = Path.Combine(temp, lib.DllName);
{ var extractedPdbPath = Path.Combine(temp, lib.PdbName);
var newEntry = archive.CreateEntry("ref/" + entry.FullName.Substring(4),
CompressionLevel.Optimal); lib.DllEntry.ExtractToFile(extractedDllPath);
using (var src = entry.Open()) lib.PdbEntry.ExtractToFile(extractedPdbPath);
using (var dst = newEntry.Open())
src.CopyTo(dst);
}
}
var libs = archive.Entries.Where(e => e.FullName.StartsWith("lib/") && e.FullName.EndsWith(".dll")) PatchRefAssembly(extractedDllPath);
.Select((e => new { s = e.FullName.Split('/'), e = e }))
.Select(e => new { Tfm = e.s[1], Name = e.s[2], Entry = e.e }) mainArchive.CreateEntryFromFile(extractedDllPath, $"ref/{lib.Tfm}/{lib.DllName}");
.GroupBy(x => x.Tfm); symbolsArchive.CreateEntryFromFile(extractedPdbPath, $"ref/{lib.Tfm}/{lib.PdbName}");
foreach(var tfm in libs) }
using (Helpers.UseTempDir(out var temp))
{
foreach (var l in tfm)
l.Entry.ExtractToFile(Path.Combine(temp, l.Name));
foreach (var l in tfm)
PatchRefAssembly(Path.Combine(temp, l.Name));
foreach (var l in tfm)
archive.CreateEntryFromFile(Path.Combine(temp, l.Name), $"ref/{l.Tfm}/{l.Name}");
}
} }
static ZipArchive OpenPackage(string packagePath)
=> new(File.Open(packagePath, FileMode.Open, FileAccess.ReadWrite), ZipArchiveMode.Update);
static ZipArchiveEntry[] GetLibEntries(ZipArchive archive, string extension)
=> archive.Entries
.Where(e => e.FullName.StartsWith("lib/", StringComparison.Ordinal)
&& e.FullName.EndsWith(extension, StringComparison.Ordinal))
.ToArray();
} }
} }

4
nukebuild/Shims.cs

@ -9,12 +9,12 @@ using Numerge;
public partial class Build public partial class Build
{ {
static void Information(string info) internal static void Information(string info)
{ {
Logger.Info(info); Logger.Info(info);
} }
static void Information(string info, params object[] args) internal static void Information(string info, params object[] args)
{ {
Logger.Info(info, args); Logger.Info(info, args);
} }

20
nukebuild/_build.csproj

@ -8,8 +8,8 @@
<NukeTelemetryVersion>1</NukeTelemetryVersion> <NukeTelemetryVersion>1</NukeTelemetryVersion>
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<Import Project="..\build\JetBrains.dotMemoryUnit.props" /> <Import Project="..\build\JetBrains.dotMemoryUnit.props" />
<ItemGroup> <ItemGroup>
<PackageReference Include="Nuke.Common" Version="6.2.1" /> <PackageReference Include="Nuke.Common" Version="6.2.1" />
<PackageReference Include="vswhere" Version="2.6.7" Condition=" '$(OS)' == 'Windows_NT' " /> <PackageReference Include="vswhere" Version="2.6.7" Condition=" '$(OS)' == 'Windows_NT' " />
@ -22,6 +22,8 @@
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageDownload Include="Microsoft.DotNet.ApiCompat.Tool" Version="[7.0.305]" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -30,12 +32,16 @@
<!-- Common build related files --> <!-- Common build related files -->
<Compile Remove="Numerge/**/*.*" /> <Compile Remove="Numerge/**/*.*" />
<Compile Include="Numerge/Numerge/**/*.cs" /> <Compile Include="Numerge/Numerge/**/*.cs" Exclude="Numerge/Numerge/obj/**/*.cs" />
<EmbeddedResource Include="$(NuGetPackageRoot)sourcelink/1.1.0/tools/pdbstr.exe"></EmbeddedResource> <EmbeddedResource Include="$(NuGetPackageRoot)sourcelink/1.1.0/tools/pdbstr.exe" />
<EmbeddedResource Include="../build/avalonia.snk"></EmbeddedResource> <EmbeddedResource Include="../build/avalonia.snk" />
<Compile Remove="il-repack\ILRepack\Application.cs" /> <Compile Remove="il-repack\ILRepack\Application.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="..\dirs.proj">
<Link>dirs.proj</Link>
</Content>
</ItemGroup>
</Project> </Project>

2
packages/Avalonia/Avalonia.csproj

@ -5,7 +5,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Avalonia.BuildServices" Version="0.0.16" /> <PackageReference Include="Avalonia.BuildServices" Version="0.0.29" />
<ProjectReference Include="../../src/Avalonia.Remote.Protocol/Avalonia.Remote.Protocol.csproj" /> <ProjectReference Include="../../src/Avalonia.Remote.Protocol/Avalonia.Remote.Protocol.csproj" />
<ProjectReference Include="../../src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj"> <ProjectReference Include="../../src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>

1
packages/Avalonia/Avalonia.targets

@ -1,3 +1,4 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildThisFileDirectory)\AvaloniaBuildTasks.targets"/> <Import Project="$(MSBuildThisFileDirectory)\AvaloniaBuildTasks.targets"/>
<Import Project="$(MSBuildThisFileDirectory)\AvaloniaPrivateApis.targets" />
</Project> </Project>

26
packages/Avalonia/AvaloniaBuildTasks.targets

@ -144,4 +144,30 @@
<UpToDateCheckInput Include="@(AvaloniaResource)" /> <UpToDateCheckInput Include="@(AvaloniaResource)" />
<UpToDateCheckInput Include="@(AvaloniaXaml)" /> <UpToDateCheckInput Include="@(AvaloniaXaml)" />
</ItemGroup> </ItemGroup>
<PropertyGroup>
<AvaloniaFilePreviewDependsOn Condition="'$(SkipBuild)'!='True'">Build</AvaloniaFilePreviewDependsOn>
</PropertyGroup>
<Target Name="AvaloniaFilePreview" DependsOnTargets="$(AvaloniaFilePreviewDependsOn)">
<PropertyGroup>
<APreviewerUrl>http://127.0.0.1:6001</APreviewerUrl>
<APreviewExecutable>$(OutputPath)/$(AssemblyName).dll</APreviewExecutable>
<APreviewFile Condition="$(APreviewFile) == ''">MainWindow.axaml</APreviewFile>
<APreviewAssembly Condition="$(APreviewAssembly) == ''">$(APreviewExecutable)</APreviewAssembly>
<APreviewerDepsJsonPath>$([System.IO.Path]::ChangeExtension('$(APreviewExecutable)', '.deps.json'))</APreviewerDepsJsonPath>
<APreviewerRuntimeConfigPath>$([System.IO.Path]::ChangeExtension('$(APreviewExecutable)', '.runtimeconfig.json'))</APreviewerRuntimeConfigPath>
<APreviewTransportUrl>$([System.IO.Path]::GetFullPath('$(APreviewFile)'))</APreviewTransportUrl>
</PropertyGroup>
<Message Importance="high" Text="Launching previewer for"/>
<Message Importance="high" Text="File (APreviewFile): $(APreviewTransportUrl)"/>
<Message Importance="high" Text="Containing assembly (APreviewAssembly): $(APreviewDefiningAssembly)"/>
<Message Importance="high" Text="Executable: $(APreviewExecutable)"/>
<Message Importance="high" Text="Url (APreviewerUrl): $(APreviewerUrl)"/>
<Exec Command="dotnet exec --runtimeconfig &quot;$(APreviewerRuntimeConfigPath)&quot; --depsfile &quot;$(APreviewerDepsJsonPath)&quot; &quot;$(AvaloniaPreviewerNetCoreToolPath)&quot; --method html --html-url $(APreviewerUrl) --transport $(APreviewTransportUrl) &quot;$(APreviewExecutable)&quot;"/>
</Target>
</Project> </Project>

26
packages/Avalonia/AvaloniaPrivateApis.targets

@ -0,0 +1,26 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="RemoveAvaloniaRefAssemblies" AfterTargets="ResolveTargetingPackAssets" Condition="'$(AvaloniaAccessUnstablePrivateApis.ToLowerInvariant())'=='true'">
<ItemGroup>
<ReferencesToRemove Include="@(Reference)" Condition="'%(Reference.NuGetPackageId)' == 'Avalonia'" />
</ItemGroup>
<ItemGroup>
<Reference Remove="@(ReferencesToRemove)" />
</ItemGroup>
</Target>
<Target Name="PreventPackingAvaloniaUnstableApis" BeforeTargets="Pack">
<Error Condition="'$(IsPackable.ToLowerInvariant())' == 'true' and '$(AvaloniaAccessUnstablePrivateApis.ToLowerInvariant())' == 'true' and '$(Avalonia_I_Want_To_Use_Private_Apis_In_Nuget_Package_And_Promise_To_Pin_The_Exact_Avalonia_Version_In_Package_Dependency)' != 'true'"
Text="It seems that you are using private APIs in a nuget package, please follow this guide https://github.com/AvaloniaUI/Avalonia/wiki/Using-private-apis-in-nuget-packages" />
</Target>
<Target Name="AddReferencePathsToRealAvaloniaAssemblies" BeforeTargets="CoreCompile" Condition="'$(AvaloniaAccessUnstablePrivateApis.ToLowerInvariant())'=='true'">
<PropertyGroup>
<AvaloniaUnstableApiFrameworkToUse>net6.0</AvaloniaUnstableApiFrameworkToUse>
<AvaloniaUnstableApiFrameworkToUse Condition="$(TargetFramework.StartsWith('net4')) == 'true' or $(TargetFramework.StartsWith('net5')) == 'true' or $(TargetFramework.StartsWith('netsta')) == 'true' or $(TargetFramework.StartsWith('netcore')) == 'true'">netstandard2.0</AvaloniaUnstableApiFrameworkToUse>
</PropertyGroup>
<ItemGroup>
<Reference Include="$(MSBuildThisFileDirectory)/../lib/$(AvaloniaUnstableApiFrameworkToUse)/*.dll"/>
<ReferencePath Include="$(MSBuildThisFileDirectory)/../lib/$(AvaloniaUnstableApiFrameworkToUse)/*.dll"/>
<ReferencePathWithRefAssemblies Include="$(MSBuildThisFileDirectory)/../lib/$(AvaloniaUnstableApiFrameworkToUse)/*.dll"/>
</ItemGroup>
<Warning Text="AvaloniaAccessUnstablePrivateApis is Enabled: This means you are using unstable internal APIs, and your code may be depending on APIs which may change or be removed in future versions of Avalonia. Set AvaloniaAccessUnstablePrivateApis to 'False' to disable this warning." />
</Target>
</Project>

6
readme.md

@ -6,18 +6,16 @@
<br /> <br />
[![NuGet](https://img.shields.io/nuget/v/Avalonia.svg)](https://www.nuget.org/packages/Avalonia) [![downloads](https://img.shields.io/nuget/dt/avalonia)](https://www.nuget.org/packages/Avalonia) ![Size](https://img.shields.io/github/repo-size/avaloniaui/avalonia.svg) [![NuGet](https://img.shields.io/nuget/v/Avalonia.svg)](https://www.nuget.org/packages/Avalonia) [![downloads](https://img.shields.io/nuget/dt/avalonia)](https://www.nuget.org/packages/Avalonia) ![Size](https://img.shields.io/github/repo-size/avaloniaui/avalonia.svg)
⚠️ **v11 Update - [Pausing community contributions](https://github.com/AvaloniaUI/Avalonia/discussions/10599)**
## 📖 About ## 📖 About
[Avalonia](https://avaloniaui.net) is a cross-platform UI framework for dotnet, providing a flexible styling system and supporting a wide range of platforms such as Windows, macOS, Linux, iOS, Android and WebAssembly. Avalonia is mature and production ready and is used by companies, including [Schneider Electric](https://avaloniaui.net/showcase#se), [Unity](https://avaloniaui.net/showcase#unity), [JetBrains](https://avaloniaui.net/showcase#rider) and [Github](https://avaloniaui.net/showcase#github). [Avalonia](https://avaloniaui.net) is a cross-platform UI framework for dotnet, providing a flexible styling system and supporting a wide range of platforms such as Windows, macOS, Linux, iOS, Android and WebAssembly. Avalonia is mature and production ready and is used by companies, including [Schneider Electric](https://avaloniaui.net/showcase#se), [Unity](https://avaloniaui.net/showcase#unity), [JetBrains](https://avaloniaui.net/showcase#rider) and [Github](https://avaloniaui.net/showcase#github).
Considered by many to be the spiritual successor to WPF, Avalonia UI provides a familiar, modern development experience for XAML developers creating cross-platform applications. While Avalonia UI is [similar to WPF](https://docs.avaloniaui.net/misc/wpf), it isn't a 1:1 copy, and you'll find plenty of improvements. Considered by many to be the spiritual successor to WPF, Avalonia UI provides a familiar, modern development experience for XAML developers creating cross-platform applications. While Avalonia UI is [similar to WPF](https://docs.avaloniaui.net/docs/next/get-started/wpf/), it isn't a 1:1 copy, and you'll find plenty of improvements.
For those seeking a cross-platform WPF, we have created [Avalonia XPF](https://avaloniaui.net/xpf), enabling WPF applications to run on macOS and Linux with little to no code changes. Avalonia XPF is a commercial product and is licensed per-app, per-platform. For those seeking a cross-platform WPF, we have created [Avalonia XPF](https://avaloniaui.net/xpf), enabling WPF applications to run on macOS and Linux with little to no code changes. Avalonia XPF is a commercial product and is licensed per-app, per-platform.
#### Roadmap #### Roadmap
To see the status of some of our features, please see our [Roadmap](https://github.com/AvaloniaUI/Avalonia/issues/2239). To see the status of some of our features, look at our [Roadmap](https://github.com/AvaloniaUI/Avalonia/issues/2239).
#### Breaking Changes #### Breaking Changes
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. 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.

5
samples/AppWithoutLifetime/MainWindow.axaml.cs

@ -17,10 +17,11 @@ public partial class MainWindow : Window
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
} }
protected override void OnLoaded() /// <inheritdoc/>
protected override void OnLoaded(RoutedEventArgs e)
{ {
this.AttachDevTools(); this.AttachDevTools();
base.OnLoaded(); base.OnLoaded(e);
} }
public void Open(object sender, RoutedEventArgs e) public void Open(object sender, RoutedEventArgs e)

6
samples/AppWithoutLifetime/Sub.axaml.cs

@ -1,5 +1,6 @@
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
namespace AppWithoutLifetime; namespace AppWithoutLifetime;
@ -16,9 +17,10 @@ public partial class Sub : Window
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
} }
protected override void OnLoaded() /// <inheritdoc/>
protected override void OnLoaded(RoutedEventArgs e)
{ {
this.AttachDevTools(); this.AttachDevTools();
base.OnLoaded(); base.OnLoaded(e);
} }
} }

9
samples/ControlCatalog.Android/ControlCatalog.Android.csproj

@ -10,6 +10,11 @@
<AndroidPackageFormat>apk</AndroidPackageFormat> <AndroidPackageFormat>apk</AndroidPackageFormat>
<MSBuildEnableWorkloadResolver>true</MSBuildEnableWorkloadResolver> <MSBuildEnableWorkloadResolver>true</MSBuildEnableWorkloadResolver>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Remove="Resources\drawable-night-v31\avalonia_anim.xml" />
<None Remove="Resources\drawable-v31\avalonia_anim.xml" />
<None Remove="Resources\values-v31\styles.xml" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<AndroidResource Include="..\..\build\Assets\Icon.png"> <AndroidResource Include="..\..\build\Assets\Icon.png">
<Link>Resources\drawable\Icon.png</Link> <Link>Resources\drawable\Icon.png</Link>
@ -37,6 +42,10 @@
<AndroidEnvironment Condition="'$(IsEmulator)'!='True'" Include="environment.device.txt" /> <AndroidEnvironment Condition="'$(IsEmulator)'!='True'" Include="environment.device.txt" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="Xamarin.AndroidX.Core.SplashScreen" Version="1.0.1" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Android\Avalonia.Android\Avalonia.Android.csproj" /> <ProjectReference Include="..\..\src\Android\Avalonia.Android\Avalonia.Android.csproj" />
<ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj" /> <ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj" />

12
samples/ControlCatalog.Android/MainActivity.cs

@ -5,8 +5,16 @@ using Avalonia.Android;
namespace ControlCatalog.Android namespace ControlCatalog.Android
{ {
[Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.Main", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.UiMode)] [Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.UiMode)]
public class MainActivity : AvaloniaMainActivity public class MainActivity : AvaloniaMainActivity<App>
{ {
protected override Avalonia.AppBuilder CustomizeAppBuilder(Avalonia.AppBuilder builder)
{
return base.CustomizeAppBuilder(builder)
.AfterSetup(_ =>
{
Pages.EmbedSample.Implementation = new EmbedSampleAndroid();
});
}
} }
} }

66
samples/ControlCatalog.Android/Resources/drawable-night-v31/avalonia_anim.xml

@ -0,0 +1,66 @@
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:name="vector"
android:width="128dp"
android:height="128dp"
android:viewportWidth="128"
android:viewportHeight="128">
<group
android:name="wrapper"
android:translateX="21"
android:translateY="21">
<group android:name="group">
<path
android:name="path"
android:pathData="M 74.853 85.823 L 75.368 85.823 C 80.735 85.823 85.144 81.803 85.761 76.602 L 85.836 41.76 C 85.225 18.593 66.254 0 42.939 0 C 19.24 0 0.028 19.212 0.028 42.912 C 0.028 66.357 18.831 85.418 42.18 85.823 L 74.853 85.823 Z"
android:strokeWidth="1"/>
<path
android:name="path_1"
android:pathData="M 43.059 14.614 C 29.551 14.614 18.256 24.082 15.445 36.743 C 18.136 37.498 20.109 39.968 20.109 42.899 C 20.109 45.831 18.136 48.301 15.445 49.055 C 18.256 61.716 29.551 71.184 43.059 71.184 C 47.975 71.184 52.599 69.93 56.628 67.723 L 56.628 70.993 L 71.344 70.993 L 71.344 44.072 C 71.357 43.714 71.344 43.26 71.344 42.899 C 71.344 27.278 58.68 14.614 43.059 14.614 Z M 29.51 42.899 C 29.51 35.416 35.576 29.35 43.059 29.35 C 50.541 29.35 56.607 35.416 56.607 42.899 C 56.607 50.382 50.541 56.448 43.059 56.448 C 35.576 56.448 29.51 50.382 29.51 42.899 Z"
android:strokeWidth="1"
android:fillType="evenOdd"/>
<path
android:name="path_2"
android:pathData="M 18.105 42.88 C 18.105 45.38 16.078 47.407 13.579 47.407 C 11.079 47.407 9.052 45.38 9.052 42.88 C 9.052 40.381 11.079 38.354 13.579 38.354 C 16.078 38.354 18.105 40.381 18.105 42.88 Z"
android:strokeWidth="1"/>
</group>
</group>
</vector>
</aapt:attr>
<target android:name="path">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:duration="1000"
android:valueFrom="#00ffffff"
android:valueTo="#161c2d"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
<target android:name="path_1">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:duration="1000"
android:valueFrom="#00ffffff"
android:valueTo="#f9f9fb"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
<target android:name="path_2">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:duration="1000"
android:valueFrom="#00ffffff"
android:valueTo="#f9f9fb"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
</animated-vector>

71
samples/ControlCatalog.Android/Resources/drawable-v31/avalonia_anim.xml

@ -0,0 +1,71 @@
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:name="vector"
android:width="128dp"
android:height="128dp"
android:viewportWidth="128"
android:viewportHeight="128">
<group
android:name="wrapper"
android:translateX="21"
android:translateY="21">
<group android:name="group">
<path
android:name="path"
android:pathData="M 74.853 85.823 L 75.368 85.823 C 80.735 85.823 85.144 81.803 85.761 76.602 L 85.836 41.76 C 85.225 18.593 66.254 0 42.939 0 C 19.24 0 0.028 19.212 0.028 42.912 C 0.028 66.357 18.831 85.418 42.18 85.823 L 74.853 85.823 Z"
android:fillColor="#00ffffff"
android:strokeWidth="1"/>
<path
android:name="path_1"
android:pathData="M 43.059 14.614 C 29.551 14.614 18.256 24.082 15.445 36.743 C 18.136 37.498 20.109 39.968 20.109 42.899 C 20.109 45.831 18.136 48.301 15.445 49.055 C 18.256 61.716 29.551 71.184 43.059 71.184 C 47.975 71.184 52.599 69.93 56.628 67.723 L 56.628 70.993 L 71.344 70.993 L 71.344 44.072 C 71.357 43.714 71.344 43.26 71.344 42.899 C 71.344 27.278 58.68 14.614 43.059 14.614 Z M 29.51 42.899 C 29.51 35.416 35.576 29.35 43.059 29.35 C 50.541 29.35 56.607 35.416 56.607 42.899 C 56.607 50.382 50.541 56.448 43.059 56.448 C 35.576 56.448 29.51 50.382 29.51 42.899 Z"
android:fillColor="#00ffffff"
android:strokeWidth="1"
android:fillType="evenOdd"/>
<path
android:name="path_2"
android:pathData="M 18.105 42.88 C 18.105 45.38 16.078 47.407 13.579 47.407 C 11.079 47.407 9.052 45.38 9.052 42.88 C 9.052 40.381 11.079 38.354 13.579 38.354 C 16.078 38.354 18.105 40.381 18.105 42.88 Z"
android:fillColor="#00ffffff"
android:strokeWidth="1"/>
</group>
</group>
</vector>
</aapt:attr>
<target android:name="path_2">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:startOffset="100"
android:duration="900"
android:valueFrom="#00ffffff"
android:valueTo="#161c2d"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
<target android:name="path">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:duration="500"
android:valueFrom="#00ffffff"
android:valueTo="#f9f9fb"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
<target android:name="path_1">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:startOffset="100"
android:duration="900"
android:valueFrom="#00ffffff"
android:valueTo="#161c2d"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
</animated-vector>

21
samples/ControlCatalog.Android/Resources/values-v31/styles.xml

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="MyTheme">
</style>
<style name="MyTheme.NoActionBar" parent="@style/Theme.AppCompat.NoActionBar">
<item name="android:windowActionBar">false</item>
<item name="android:windowBackground">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowSplashScreenBackground">@color/splash_background</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/avalonia_anim</item>
<item name="android:windowSplashScreenAnimationDuration">1000</item>
<item name="postSplashScreenTheme">@style/MyTheme.Main</item>
</style>
<style name="MyTheme.Main"
parent ="MyTheme.NoActionBar">
<item name="android:windowIsTranslucent">true</item>
</style>
</resources>

11
samples/ControlCatalog.Android/Resources/values/styles.xml

@ -6,16 +6,7 @@
<style name="MyTheme.NoActionBar" parent="@style/Theme.AppCompat.DayNight.NoActionBar"> <style name="MyTheme.NoActionBar" parent="@style/Theme.AppCompat.DayNight.NoActionBar">
<item name="android:windowActionBar">false</item> <item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
<style name="MyTheme.Splash" parent ="MyTheme.NoActionBar">
<item name="android:windowBackground">@drawable/splash_screen</item> <item name="android:windowBackground">@drawable/splash_screen</item>
<item name="android:windowContentOverlay">@null</item> <item name="android:windowNoTitle">true</item>
</style>
<style name="MyTheme.Main" parent ="MyTheme.NoActionBar">
<item name="android:windowIsTranslucent">true</item>
</style> </style>
</resources> </resources>

35
samples/ControlCatalog.Android/SplashActivity.cs

@ -1,35 +0,0 @@
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.OS;
using Avalonia.Android;
namespace ControlCatalog.Android
{
[Activity(Theme = "@style/MyTheme.Splash", MainLauncher = true, NoHistory = true)]
public class SplashActivity : AvaloniaSplashActivity<App>
{
protected override Avalonia.AppBuilder CustomizeAppBuilder(Avalonia.AppBuilder builder)
{
return base.CustomizeAppBuilder(builder)
.AfterSetup(_ =>
{
Pages.EmbedSample.Implementation = new EmbedSampleAndroid();
});
}
protected override void OnCreate(Bundle? savedInstanceState)
{
base.OnCreate(savedInstanceState);
}
protected override void OnResume()
{
base.OnResume();
StartActivity(new Intent(Application.Context, typeof(MainActivity)));
Finish();
}
}
}

7
samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj

@ -4,10 +4,17 @@
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net461</TargetFramework> <TargetFramework>net461</TargetFramework>
<PlatformTarget>x64</PlatformTarget> <PlatformTarget>x64</PlatformTarget>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ApplicationManifest>../ControlCatalog.NetCore/app.manifest</ApplicationManifest>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj" /> <ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\ControlCatalog.NetCore\NativeControls\Win\*.cs" Link="NativeControls\*" />
</ItemGroup> </ItemGroup>
<Import Project="..\..\build\SampleApp.props" /> <Import Project="..\..\build\SampleApp.props" />

11
samples/ControlCatalog.Desktop/Program.cs

@ -3,6 +3,8 @@ using System.Linq;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Platform; using Avalonia.Platform;
using ControlCatalog.NetCore;
using ControlCatalog.Pages;
namespace ControlCatalog namespace ControlCatalog
{ {
@ -18,6 +20,15 @@ namespace ControlCatalog
public static AppBuilder BuildAvaloniaApp() public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>() => AppBuilder.Configure<App>()
.LogToTrace() .LogToTrace()
.AfterSetup(builder =>
{
builder.Instance!.AttachDevTools(new Avalonia.Diagnostics.DevToolsOptions()
{
StartupScreenIndex = 1,
});
EmbedSample.Implementation = new EmbedSampleWin();
})
.UsePlatformDetect(); .UsePlatformDetect();
private static void ConfigureAssetAssembly(AppBuilder builder) private static void ConfigureAssetAssembly(AppBuilder builder)

2
samples/ControlCatalog.NetCore/NativeControls/Win/WinApi.cs

@ -39,7 +39,7 @@ internal unsafe class WinApi
[DllImport("user32.dll", SetLastError = true)] [DllImport("user32.dll", SetLastError = true)]
public static extern bool DestroyWindow(IntPtr hwnd); public static extern bool DestroyWindow(IntPtr hwnd);
[DllImport("kernel32.dll")] [DllImport("kernel32.dll", CharSet = CharSet.Unicode, EntryPoint = "LoadLibraryW", ExactSpelling = true)]
public static extern IntPtr LoadLibrary(string lib); public static extern IntPtr LoadLibrary(string lib);

25
samples/ControlCatalog.NetCore/Program.cs

@ -18,9 +18,16 @@ namespace ControlCatalog.NetCore
{ {
static class Program static class Program
{ {
private static bool s_useFramebuffer;
[STAThread] [STAThread]
static int Main(string[] args) static int Main(string[] args)
{ {
if (args.Contains("--fbdev"))
{
s_useFramebuffer = true;
}
if (args.Contains("--wait-for-attach")) if (args.Contains("--wait-for-attach"))
{ {
Console.WriteLine("Attach debugger and use 'Set next statement'"); Console.WriteLine("Attach debugger and use 'Set next statement'");
@ -42,10 +49,10 @@ namespace ControlCatalog.NetCore
return scaling; return scaling;
return 1; return 1;
} }
if (args.Contains("--fbdev")) if (s_useFramebuffer)
{ {
SilenceConsole(); SilenceConsole();
return builder.StartLinuxFbDev(args, scaling: GetScaling()); return builder.StartLinuxFbDev(args, scaling: GetScaling());
} }
else if (args.Contains("--vnc")) else if (args.Contains("--vnc"))
{ {
@ -103,8 +110,7 @@ namespace ControlCatalog.NetCore
{ {
builder.With(new Win32PlatformOptions() builder.With(new Win32PlatformOptions()
{ {
UseLowLatencyDxgiSwapChain = true, CompositionMode = new [] { Win32CompositionMode.LowLatencyDxgiSwapChain }
UseWindowsUIComposition = false
}); });
return builder.StartWithClassicDesktopLifetime(args); return builder.StartWithClassicDesktopLifetime(args);
} }
@ -128,10 +134,13 @@ namespace ControlCatalog.NetCore
.WithInterFont() .WithInterFont()
.AfterSetup(builder => .AfterSetup(builder =>
{ {
builder.Instance!.AttachDevTools(new Avalonia.Diagnostics.DevToolsOptions() if (!s_useFramebuffer)
{ {
StartupScreenIndex = 1, builder.Instance!.AttachDevTools(new Avalonia.Diagnostics.DevToolsOptions()
}); {
StartupScreenIndex = 1,
});
}
EmbedSample.Implementation = OperatingSystem.IsWindows() ? (INativeDemoControl)new EmbedSampleWin() EmbedSample.Implementation = OperatingSystem.IsWindows() ? (INativeDemoControl)new EmbedSampleWin()
: OperatingSystem.IsMacOS() ? new EmbedSampleMac() : OperatingSystem.IsMacOS() ? new EmbedSampleMac()

3
samples/ControlCatalog/App.xaml

@ -28,6 +28,9 @@
</ResourceDictionary.ThemeDictionaries> </ResourceDictionary.ThemeDictionaries>
<!-- Styles attached dynamically depending on current theme (simple or fluent) --> <!-- Styles attached dynamically depending on current theme (simple or fluent) -->
<FluentTheme x:Key="FluentTheme">
</FluentTheme>
<SimpleTheme x:Key="SimpleTheme" />
<StyleInclude x:Key="DataGridFluent" Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml" /> <StyleInclude x:Key="DataGridFluent" Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml" />
<StyleInclude x:Key="DataGridSimple" Source="avares://Avalonia.Controls.DataGrid/Themes/Simple.xaml" /> <StyleInclude x:Key="DataGridSimple" Source="avares://Avalonia.Controls.DataGrid/Themes/Simple.xaml" />
<StyleInclude x:Key="ColorPickerFluent" Source="avares://Avalonia.Controls.ColorPicker/Themes/Fluent/Fluent.xaml" /> <StyleInclude x:Key="ColorPickerFluent" Source="avares://Avalonia.Controls.ColorPicker/Themes/Fluent/Fluent.xaml" />

4
samples/ControlCatalog/App.xaml.cs

@ -30,8 +30,8 @@ namespace ControlCatalog
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
_fluentTheme = new FluentTheme(); _fluentTheme = (FluentTheme)Resources["FluentTheme"]!;
_simpleTheme = new SimpleTheme(); _simpleTheme = (SimpleTheme)Resources["SimpleTheme"]!;
_colorPickerFluent = (IStyle)Resources["ColorPickerFluent"]!; _colorPickerFluent = (IStyle)Resources["ColorPickerFluent"]!;
_colorPickerSimple = (IStyle)Resources["ColorPickerSimple"]!; _colorPickerSimple = (IStyle)Resources["ColorPickerSimple"]!;
_dataGridFluent = (IStyle)Resources["DataGridFluent"]!; _dataGridFluent = (IStyle)Resources["DataGridFluent"]!;

31
samples/ControlCatalog/Models/GDPdLengthConverter.cs

@ -0,0 +1,31 @@
using System;
using System.Globalization;
using Avalonia.Data.Converters;
namespace ControlCatalog.Models;
internal class GDPdLengthConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is double d)
{
return new Avalonia.Controls.DataGridLength(d,Avalonia.Controls.DataGridLengthUnitType.Pixel,d,d);
}
else if (value is decimal d2)
{
var dv =System.Convert.ToDouble(d2);
return new Avalonia.Controls.DataGridLength(dv, Avalonia.Controls.DataGridLengthUnitType.Pixel, dv, dv);
}
return value;
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is Avalonia.Controls.DataGridLength width)
{
return System.Convert.ToDecimal(width.DisplayValue);
}
return value;
}
}

5
samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml

@ -18,6 +18,10 @@
<Setter Property="Margin" Value="8" /> <Setter Property="Margin" Value="8" />
</Style> </Style>
</UniformGrid.Styles> </UniformGrid.Styles>
<StackPanel>
<TextBlock Text="MinimumPrefixLength: 0" />
<AutoCompleteBox MinimumPrefixLength="0" />
</StackPanel>
<StackPanel> <StackPanel>
<TextBlock Text="MinimumPrefixLength: 1" /> <TextBlock Text="MinimumPrefixLength: 1" />
<AutoCompleteBox MinimumPrefixLength="1" /> <AutoCompleteBox MinimumPrefixLength="1" />
@ -42,7 +46,6 @@
<TextBlock Text="Disabled" /> <TextBlock Text="Disabled" />
<AutoCompleteBox IsEnabled="False" /> <AutoCompleteBox IsEnabled="False" />
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<TextBlock Text="ValueMemberBinding" /> <TextBlock Text="ValueMemberBinding" />
<AutoCompleteBox ValueMemberBinding="{Binding Capital, x:DataType=models:StateData}" /> <AutoCompleteBox ValueMemberBinding="{Binding Capital, x:DataType=models:StateData}" />

10
samples/ControlCatalog/Pages/CompositionPage.axaml.cs

@ -144,8 +144,8 @@ public partial class CompositionPage : UserControl
{ {
if(_solidVisual == null) if(_solidVisual == null)
return; return;
_solidVisual.Size = new Vector2((float)v.Bounds.Width / 3, (float)v.Bounds.Height / 3); _solidVisual.Size = new (v.Bounds.Width / 3, v.Bounds.Height / 3);
_solidVisual.Offset = new Vector3((float)v.Bounds.Width / 3, (float)v.Bounds.Height / 3, 0); _solidVisual.Offset = new (v.Bounds.Width / 3, v.Bounds.Height / 3, 0);
} }
v.AttachedToVisualTree += delegate v.AttachedToVisualTree += delegate
{ {
@ -164,7 +164,7 @@ public partial class CompositionPage : UserControl
animation.Direction = PlaybackDirection.Alternate; animation.Direction = PlaybackDirection.Alternate;
_solidVisual.StartAnimation("Color", animation); _solidVisual.StartAnimation("Color", animation);
_solidVisual.AnchorPoint = new Vector2(0, 0); _solidVisual.AnchorPoint = new (0, 0);
var scale = _solidVisual.Compositor.CreateVector3KeyFrameAnimation(); var scale = _solidVisual.Compositor.CreateVector3KeyFrameAnimation();
scale.Duration = TimeSpan.FromSeconds(5); scale.Duration = TimeSpan.FromSeconds(5);
@ -195,8 +195,8 @@ public partial class CompositionPage : UserControl
if (_customVisual == null) if (_customVisual == null)
return; return;
var h = (float)Math.Min(v.Bounds.Height, v.Bounds.Width / 3); var h = (float)Math.Min(v.Bounds.Height, v.Bounds.Width / 3);
_customVisual.Size = new Vector2((float)v.Bounds.Width, h); _customVisual.Size = new (v.Bounds.Width, h);
_customVisual.Offset = new Vector3(0, (float)(v.Bounds.Height - h) / 2, 0); _customVisual.Offset = new (0, (v.Bounds.Height - h) / 2, 0);
} }
v.AttachedToVisualTree += delegate v.AttachedToVisualTree += delegate
{ {

25
samples/ControlCatalog/Pages/DataGridPage.xaml

@ -1,11 +1,14 @@
<UserControl xmlns="https://github.com/avaloniaui" <UserControl xmlns="https://github.com/avaloniaui"
xmlns:local="using:ControlCatalog.Models" xmlns:local="using:ControlCatalog.Models"
xmlns:lc="using:ControlCatalog.Converter"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:pages="clr-namespace:ControlCatalog.Pages" xmlns:pages="clr-namespace:ControlCatalog.Pages"
x:Class="ControlCatalog.Pages.DataGridPage" x:Class="ControlCatalog.Pages.DataGridPage"
x:DataType="pages:DataGridPage"> x:DataType="pages:DataGridPage">
<UserControl.Resources> <UserControl.Resources>
<local:GDPValueConverter x:Key="GDPConverter" /> <local:GDPValueConverter x:Key="GDPConverter" />
<local:GDPdLengthConverter x:Key="GDPWidthConverter"/>
<DataTemplate x:Key="Demo.DataTemplates.CountryHeader" x:DataType="local:Country"> <DataTemplate x:Key="Demo.DataTemplates.CountryHeader" x:DataType="local:Country">
<StackPanel Orientation="Horizontal" Spacing="5"> <StackPanel Orientation="Horizontal" Spacing="5">
<PathIcon Height="12" Data="M 255 116 A 1 1 0 0 0 254 117 L 254 130 A 1 1 0 0 0 255 131 A 1 1 0 0 0 256 130 L 256 123.87109 C 256.1125 123.90694 256.2187 123.94195 256.33984 123.97852 C 257.18636 124.23404 258.19155 124.5 259 124.5 C 259.80845 124.5 260.52133 124.2168 261.17773 123.9668 C 261.83414 123.7168 262.43408 123.5 263 123.5 C 263.56592 123.5 264.5612 123.73404 265.37109 123.97852 C 266.18098 124.22299 266.82227 124.4668 266.82227 124.4668 A 0.50005 0.50005 0 0 0 267.5 124 L 267.5 118 A 0.50005 0.50005 0 0 0 267.17773 117.5332 C 267.17773 117.5332 266.50667 117.27701 265.66016 117.02148 C 264.81364 116.76596 263.80845 116.5 263 116.5 C 262.19155 116.5 261.47867 116.7832 260.82227 117.0332 C 260.16586 117.2832 259.56592 117.5 259 117.5 C 258.43408 117.5 257.4388 117.26596 256.62891 117.02148 C 256.39123 116.94974 256.17716 116.87994 255.98047 116.81445 A 1 1 0 0 0 255 116 z M 263 117.5 C 263.56592 117.5 264.5612 117.73404 265.37109 117.97852 C 266.00097 118.16865 266.29646 118.28239 266.5 118.35742 L 266.5 120.29297 C 266.25708 120.21012 265.97978 120.11797 265.66016 120.02148 C 264.81364 119.76596 263.80845 119.5 263 119.5 C 262.19155 119.5 261.47867 119.7832 260.82227 120.0332 C 260.16586 120.2832 259.56592 120.5 259 120.5 C 258.43408 120.5 257.4388 120.26596 256.62891 120.02148 C 256.39971 119.9523 256.19148 119.88388 256 119.82031 L 256 117.87109 C 256.1125 117.90694 256.2187 117.94195 256.33984 117.97852 C 257.18636 118.23404 258.19155 118.5 259 118.5 C 259.80845 118.5 260.52133 118.2168 261.17773 117.9668 C 261.83414 117.7168 262.43408 117.5 263 117.5 z M 263 120.5 C 263.56592 120.5 264.5612 120.73404 265.37109 120.97852 C 265.8714 121.12954 266.2398 121.25641 266.5 121.34961 L 266.5 123.30469 C 266.22286 123.20649 266.12863 123.1629 265.66016 123.02148 C 264.81364 122.76596 263.80845 122.5 263 122.5 C 262.19155 122.5 261.47867 122.7832 260.82227 123.0332 C 260.16586 123.2832 259.56592 123.5 259 123.5 C 258.43408 123.5 257.4388 123.26596 256.62891 123.02148 C 256.39971 122.9523 256.19148 122.88388 256 122.82031 L 256 120.87109 C 256.1125 120.90694 256.2187 120.94195 256.33984 120.97852 C 257.18636 121.23404 258.19155 121.5 259 121.5 C 259.80845 121.5 260.52133 121.2168 261.17773 120.9668 C 261.83414 120.7168 262.43408 120.5 263 120.5 z" /> <PathIcon Height="12" Data="M 255 116 A 1 1 0 0 0 254 117 L 254 130 A 1 1 0 0 0 255 131 A 1 1 0 0 0 256 130 L 256 123.87109 C 256.1125 123.90694 256.2187 123.94195 256.33984 123.97852 C 257.18636 124.23404 258.19155 124.5 259 124.5 C 259.80845 124.5 260.52133 124.2168 261.17773 123.9668 C 261.83414 123.7168 262.43408 123.5 263 123.5 C 263.56592 123.5 264.5612 123.73404 265.37109 123.97852 C 266.18098 124.22299 266.82227 124.4668 266.82227 124.4668 A 0.50005 0.50005 0 0 0 267.5 124 L 267.5 118 A 0.50005 0.50005 0 0 0 267.17773 117.5332 C 267.17773 117.5332 266.50667 117.27701 265.66016 117.02148 C 264.81364 116.76596 263.80845 116.5 263 116.5 C 262.19155 116.5 261.47867 116.7832 260.82227 117.0332 C 260.16586 117.2832 259.56592 117.5 259 117.5 C 258.43408 117.5 257.4388 117.26596 256.62891 117.02148 C 256.39123 116.94974 256.17716 116.87994 255.98047 116.81445 A 1 1 0 0 0 255 116 z M 263 117.5 C 263.56592 117.5 264.5612 117.73404 265.37109 117.97852 C 266.00097 118.16865 266.29646 118.28239 266.5 118.35742 L 266.5 120.29297 C 266.25708 120.21012 265.97978 120.11797 265.66016 120.02148 C 264.81364 119.76596 263.80845 119.5 263 119.5 C 262.19155 119.5 261.47867 119.7832 260.82227 120.0332 C 260.16586 120.2832 259.56592 120.5 259 120.5 C 258.43408 120.5 257.4388 120.26596 256.62891 120.02148 C 256.39971 119.9523 256.19148 119.88388 256 119.82031 L 256 117.87109 C 256.1125 117.90694 256.2187 117.94195 256.33984 117.97852 C 257.18636 118.23404 258.19155 118.5 259 118.5 C 259.80845 118.5 260.52133 118.2168 261.17773 117.9668 C 261.83414 117.7168 262.43408 117.5 263 117.5 z M 263 120.5 C 263.56592 120.5 264.5612 120.73404 265.37109 120.97852 C 265.8714 121.12954 266.2398 121.25641 266.5 121.34961 L 266.5 123.30469 C 266.22286 123.20649 266.12863 123.1629 265.66016 123.02148 C 264.81364 122.76596 263.80845 122.5 263 122.5 C 262.19155 122.5 261.47867 122.7832 260.82227 123.0332 C 260.16586 123.2832 259.56592 123.5 259 123.5 C 258.43408 123.5 257.4388 123.26596 256.62891 123.02148 C 256.39971 122.9523 256.19148 122.88388 256 122.82031 L 256 120.87109 C 256.1125 120.90694 256.2187 120.94195 256.33984 120.97852 C 257.18636 121.23404 258.19155 121.5 259 121.5 C 259.80845 121.5 260.52133 121.2168 261.17773 120.9668 C 261.83414 120.7168 262.43408 120.5 263 120.5 z" />
@ -28,19 +31,31 @@
<TabControl Grid.Row="2"> <TabControl Grid.Row="2">
<TabItem Header="DataGrid"> <TabItem Header="DataGrid">
<DockPanel> <DockPanel>
<CheckBox x:Name="ShowGDP" IsChecked="True" Content="Toggle GDP Column Visibility" <StackPanel Orientation="Horizontal"
DockPanel.Dock="Top"/> DockPanel.Dock="Top"
Spacing="5">
<CheckBox x:Name="ShowGDP" IsChecked="True" Content="Toggle GDP Column Visibility"/>
<TextBlock Text="GDP Width:" VerticalAlignment="Center"/>
<NumericUpDown x:Name="GDPWidth"
Minimum="200"
Maximum="350"
Width="200"
Increment="10"
Value="200"/>
</StackPanel>
<DataGrid Name="dataGrid1" Margin="12" CanUserResizeColumns="True" CanUserReorderColumns="True" CanUserSortColumns="True" HeadersVisibility="All" <DataGrid Name="dataGrid1" Margin="12" CanUserResizeColumns="True" CanUserReorderColumns="True" CanUserSortColumns="True" HeadersVisibility="All"
RowBackground="#1000"> RowBackground="#1000">
<DataGrid.Columns> <DataGrid.Columns>
<!-- Using HeaderTemplate --> <!-- Using HeaderTemplate -->
<DataGridTextColumn Header="Country" HeaderTemplate="{StaticResource Demo.DataTemplates.CountryHeader}" Binding="{Binding Name}" Width="6*" x:DataType="local:Country" /> <DataGridTextColumn Header="Country or Region" HeaderTemplate="{StaticResource Demo.DataTemplates.CountryHeader}" Binding="{Binding Name}" Width="6*" x:DataType="local:Country" />
<DataGridTextColumn Header="Region" Binding="{Binding Region}" Width="4*" x:DataType="local:Country" /> <DataGridTextColumn Header="Region" Binding="{Binding Region}" Width="4*" x:DataType="local:Country" />
<DataGridTextColumn Header="Population" Binding="{Binding Population}" Width="3*" x:DataType="local:Country" /> <DataGridTextColumn Header="Population" Binding="{Binding Population}" Width="3*" x:DataType="local:Country" />
<DataGridTextColumn Header="Area" Binding="{Binding Area}" Width="3*" x:DataType="local:Country" /> <DataGridTextColumn Header="Area" Binding="{Binding Area}" Width="3*" x:DataType="local:Country" />
<DataGridTextColumn Header="GDP" Binding="{Binding GDP}" Width="3*" <DataGridTextColumn Header="GDP" Binding="{Binding GDP}"
Width="{Binding #GDPWidth.Value, Mode=TwoWay, Converter={StaticResource GDPWidthConverter}}"
CellTheme="{StaticResource GdpCell}" CellTheme="{StaticResource GdpCell}"
MinWidth="200" MinWidth="200"
MaxWidth="350"
IsVisible="{Binding #ShowGDP.IsChecked}" IsVisible="{Binding #ShowGDP.IsChecked}"
x:DataType="local:Country" /> x:DataType="local:Country" />
</DataGrid.Columns> </DataGrid.Columns>
@ -68,7 +83,7 @@
<TabItem Header="Grouping"> <TabItem Header="Grouping">
<DataGrid Name="dataGridGrouping" Margin="12"> <DataGrid Name="dataGridGrouping" Margin="12">
<DataGrid.Columns> <DataGrid.Columns>
<DataGridTextColumn Header="Country" Binding="{Binding Name}" Width="6*" x:DataType="local:Country" /> <DataGridTextColumn Header="Country or Region" Binding="{Binding Name}" Width="6*" x:DataType="local:Country" />
<DataGridTextColumn Header="Region" Binding="{Binding Region}" Width="4*" x:DataType="local:Country" /> <DataGridTextColumn Header="Region" Binding="{Binding Region}" Width="4*" x:DataType="local:Country" />
<DataGridTextColumn DisplayIndex="3" Header="Population" Binding="{Binding Population}" Width="3*" x:DataType="local:Country" /> <DataGridTextColumn DisplayIndex="3" Header="Population" Binding="{Binding Population}" Width="3*" x:DataType="local:Country" />
<DataGridTextColumn DisplayIndex="2" Header="Area" Binding="{Binding Area}" Width="3*" x:DataType="local:Country" /> <DataGridTextColumn DisplayIndex="2" Header="Area" Binding="{Binding Area}" Width="3*" x:DataType="local:Country" />

16
samples/ControlCatalog/Pages/GesturePage.cs

@ -13,7 +13,7 @@ namespace ControlCatalog.Pages
public class GesturePage : UserControl public class GesturePage : UserControl
{ {
private bool _isInit; private bool _isInit;
private float _currentScale; private double _currentScale;
public GesturePage() public GesturePage()
{ {
@ -53,7 +53,7 @@ namespace ControlCatalog.Pages
if(compositionVisual!= null) if(compositionVisual!= null)
{ {
_currentScale = 1; _currentScale = 1;
compositionVisual.Scale = new Vector3(1,1,1); compositionVisual.Scale = new (1,1,1);
compositionVisual.Offset = default; compositionVisual.Offset = default;
image.InvalidateMeasure(); image.InvalidateMeasure();
} }
@ -69,7 +69,7 @@ namespace ControlCatalog.Pages
} }
_currentScale = 1; _currentScale = 1;
Vector3 currentOffset = default; Vector3D currentOffset = default;
CompositionVisual? compositionVisual = null; CompositionVisual? compositionVisual = null;
@ -133,11 +133,11 @@ namespace ControlCatalog.Pages
if (compositionVisual != null && _currentScale != 1) if (compositionVisual != null && _currentScale != 1)
{ {
currentOffset += new Vector3((float)e.Delta.X, (float)e.Delta.Y, 0); currentOffset += new Vector3D(e.Delta.X, e.Delta.Y, 0);
var currentSize = control.Bounds.Size * _currentScale; var currentSize = control.Bounds.Size * _currentScale;
currentOffset = new Vector3((float)MathUtilities.Clamp(currentOffset.X, 0, currentSize.Width - control.Bounds.Width), currentOffset = new Vector3D(MathUtilities.Clamp(currentOffset.X, 0, currentSize.Width - control.Bounds.Width),
(float)MathUtilities.Clamp(currentOffset.Y, 0, currentSize.Height - control.Bounds.Height), (float)MathUtilities.Clamp(currentOffset.Y, 0, currentSize.Height - control.Bounds.Height),
0); 0);
@ -157,7 +157,7 @@ namespace ControlCatalog.Pages
var ball = control.FindLogicalDescendantOfType<Border>(); var ball = control.FindLogicalDescendantOfType<Border>();
Vector3 defaultOffset = default; Vector3D defaultOffset = default;
CompositionVisual? ballCompositionVisual = null; CompositionVisual? ballCompositionVisual = null;
@ -181,11 +181,11 @@ namespace ControlCatalog.Pages
control.AddHandler(Gestures.PullGestureEvent, (s, e) => control.AddHandler(Gestures.PullGestureEvent, (s, e) =>
{ {
Vector3 center = new((float)control.Bounds.Center.X, (float)control.Bounds.Center.Y, 0); Vector3D center = new((float)control.Bounds.Center.X, (float)control.Bounds.Center.Y, 0);
InitComposition(ball!); InitComposition(ball!);
if (ballCompositionVisual != null) if (ballCompositionVisual != null)
{ {
ballCompositionVisual.Offset = defaultOffset + new System.Numerics.Vector3((float)e.Delta.X * 0.4f, (float)e.Delta.Y * 0.4f, 0) * (inverse ? -1 : 1); ballCompositionVisual.Offset = defaultOffset + new Vector3D(e.Delta.X * 0.4f, e.Delta.Y * 0.4f, 0) * (inverse ? -1 : 1);
e.Handled = true; e.Handled = true;
} }

12
samples/ControlCatalog/ViewModels/ListBoxPageViewModel.cs

@ -21,7 +21,7 @@ namespace ControlCatalog.ViewModels
public ListBoxPageViewModel() public ListBoxPageViewModel()
{ {
Items = new ObservableCollection<ItemModel>(Enumerable.Range(1, 10000).Select(i => GenerateItem())); Items = new ObservableCollection<ItemModel>(Enumerable.Range(1, 10000).Select(i => GenerateItem()));
Selection = new SelectionModel<ItemModel>(); Selection = new SelectionModel<ItemModel>();
Selection.Select(1); Selection.Select(1);
@ -34,7 +34,13 @@ namespace ControlCatalog.ViewModels
(t ? Avalonia.Controls.SelectionMode.Toggle : 0) | (t ? Avalonia.Controls.SelectionMode.Toggle : 0) |
(a ? Avalonia.Controls.SelectionMode.AlwaysSelected : 0)); (a ? Avalonia.Controls.SelectionMode.AlwaysSelected : 0));
AddItemCommand = MiniCommand.Create(() => Items.Add(GenerateItem())); AddItemCommand = MiniCommand.Create(() =>
{
var item = GenerateItem();
Items.Add(item);
Selection.Clear();
Selection.Select(Items.Count - 1);
});
RemoveItemCommand = MiniCommand.Create(() => RemoveItemCommand = MiniCommand.Create(() =>
{ {
@ -96,7 +102,7 @@ namespace ControlCatalog.ViewModels
public MiniCommand RemoveItemCommand { get; } public MiniCommand RemoveItemCommand { get; }
public MiniCommand SelectRandomItemCommand { get; } public MiniCommand SelectRandomItemCommand { get; }
private ItemModel GenerateItem() => new ItemModel(_counter ++); private ItemModel GenerateItem() => new ItemModel(_counter++);
} }
/// <summary> /// <summary>

4
samples/GpuInterop/DrawingSurfaceDemoBase.cs

@ -48,7 +48,7 @@ public abstract class DrawingSurfaceDemoBase : Control, IGpuDemo
Surface = _compositor.CreateDrawingSurface(); Surface = _compositor.CreateDrawingSurface();
_visual = _compositor.CreateSurfaceVisual(); _visual = _compositor.CreateSurfaceVisual();
_visual.Size = new Vector2((float)Bounds.Width, (float)Bounds.Height); _visual.Size = new (Bounds.Width, Bounds.Height);
_visual.Surface = Surface; _visual.Surface = Surface;
ElementComposition.SetElementChildVisual(this, _visual); ElementComposition.SetElementChildVisual(this, _visual);
var (res, info) = await DoInitialize(_compositor, Surface); var (res, info) = await DoInitialize(_compositor, Surface);
@ -72,7 +72,7 @@ public abstract class DrawingSurfaceDemoBase : Control, IGpuDemo
if (root == null) if (root == null)
return; return;
_visual!.Size = new Vector2((float)Bounds.Width, (float)Bounds.Height); _visual!.Size = new (Bounds.Width, Bounds.Height);
var size = PixelSize.FromSize(Bounds.Size, root.RenderScaling); var size = PixelSize.FromSize(Bounds.Size, root.RenderScaling);
RenderFrame(size); RenderFrame(size);
if (SupportsDisco && Disco > 0) if (SupportsDisco && Disco > 0)

8
samples/MobileSandbox.Android/MainActivity.cs

@ -1,12 +1,14 @@
using Android.App; using System;
using Android.App;
using Android.Content.PM; using Android.Content.PM;
using Android.OS;
using Avalonia; using Avalonia;
using Avalonia.Android; using Avalonia.Android;
namespace MobileSandbox.Android namespace MobileSandbox.Android
{ {
[Activity(Label = "MobileSandbox.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)] [Activity(Label = "MobileSandbox.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)]
public class MainActivity : AvaloniaMainActivity public class MainActivity : AvaloniaMainActivity<App>
{ {
} }
} }

10
samples/MobileSandbox.Android/MobileSandbox.Android.csproj

@ -10,6 +10,12 @@
<AndroidPackageFormat>apk</AndroidPackageFormat> <AndroidPackageFormat>apk</AndroidPackageFormat>
<MSBuildEnableWorkloadResolver>true</MSBuildEnableWorkloadResolver> <MSBuildEnableWorkloadResolver>true</MSBuildEnableWorkloadResolver>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Remove="Resources\drawable-night-v31\avalonia_anim.xml" />
<None Remove="Resources\drawable-v31\avalonia_anim.xml" />
<None Remove="Resources\values-v31\styles.xml" />
<None Remove="Resources\values-night\colors.xml" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<AndroidResource Include="..\..\build\Assets\Icon.png"> <AndroidResource Include="..\..\build\Assets\Icon.png">
<Link>Resources\drawable\Icon.png</Link> <Link>Resources\drawable\Icon.png</Link>
@ -37,6 +43,10 @@
<AndroidEnvironment Condition="'$(IsEmulator)'!='True'" Include="environment.device.txt" /> <AndroidEnvironment Condition="'$(IsEmulator)'!='True'" Include="environment.device.txt" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="Xamarin.AndroidX.Core.SplashScreen" Version="1.0.1" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Android\Avalonia.Android\Avalonia.Android.csproj" /> <ProjectReference Include="..\..\src\Android\Avalonia.Android\Avalonia.Android.csproj" />
<ProjectReference Include="..\MobileSandbox\MobileSandbox.csproj" /> <ProjectReference Include="..\MobileSandbox\MobileSandbox.csproj" />

66
samples/MobileSandbox.Android/Resources/drawable-night-v31/avalonia_anim.xml

@ -0,0 +1,66 @@
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:name="vector"
android:width="128dp"
android:height="128dp"
android:viewportWidth="128"
android:viewportHeight="128">
<group
android:name="wrapper"
android:translateX="21"
android:translateY="21">
<group android:name="group">
<path
android:name="path"
android:pathData="M 74.853 85.823 L 75.368 85.823 C 80.735 85.823 85.144 81.803 85.761 76.602 L 85.836 41.76 C 85.225 18.593 66.254 0 42.939 0 C 19.24 0 0.028 19.212 0.028 42.912 C 0.028 66.357 18.831 85.418 42.18 85.823 L 74.853 85.823 Z"
android:strokeWidth="1"/>
<path
android:name="path_1"
android:pathData="M 43.059 14.614 C 29.551 14.614 18.256 24.082 15.445 36.743 C 18.136 37.498 20.109 39.968 20.109 42.899 C 20.109 45.831 18.136 48.301 15.445 49.055 C 18.256 61.716 29.551 71.184 43.059 71.184 C 47.975 71.184 52.599 69.93 56.628 67.723 L 56.628 70.993 L 71.344 70.993 L 71.344 44.072 C 71.357 43.714 71.344 43.26 71.344 42.899 C 71.344 27.278 58.68 14.614 43.059 14.614 Z M 29.51 42.899 C 29.51 35.416 35.576 29.35 43.059 29.35 C 50.541 29.35 56.607 35.416 56.607 42.899 C 56.607 50.382 50.541 56.448 43.059 56.448 C 35.576 56.448 29.51 50.382 29.51 42.899 Z"
android:strokeWidth="1"
android:fillType="evenOdd"/>
<path
android:name="path_2"
android:pathData="M 18.105 42.88 C 18.105 45.38 16.078 47.407 13.579 47.407 C 11.079 47.407 9.052 45.38 9.052 42.88 C 9.052 40.381 11.079 38.354 13.579 38.354 C 16.078 38.354 18.105 40.381 18.105 42.88 Z"
android:strokeWidth="1"/>
</group>
</group>
</vector>
</aapt:attr>
<target android:name="path">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:duration="1000"
android:valueFrom="#00ffffff"
android:valueTo="#161c2d"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
<target android:name="path_1">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:duration="1000"
android:valueFrom="#00ffffff"
android:valueTo="#f9f9fb"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
<target android:name="path_2">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:duration="1000"
android:valueFrom="#00ffffff"
android:valueTo="#f9f9fb"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
</animated-vector>

71
samples/MobileSandbox.Android/Resources/drawable-v31/avalonia_anim.xml

@ -0,0 +1,71 @@
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:name="vector"
android:width="128dp"
android:height="128dp"
android:viewportWidth="128"
android:viewportHeight="128">
<group
android:name="wrapper"
android:translateX="21"
android:translateY="21">
<group android:name="group">
<path
android:name="path"
android:pathData="M 74.853 85.823 L 75.368 85.823 C 80.735 85.823 85.144 81.803 85.761 76.602 L 85.836 41.76 C 85.225 18.593 66.254 0 42.939 0 C 19.24 0 0.028 19.212 0.028 42.912 C 0.028 66.357 18.831 85.418 42.18 85.823 L 74.853 85.823 Z"
android:fillColor="#00ffffff"
android:strokeWidth="1"/>
<path
android:name="path_1"
android:pathData="M 43.059 14.614 C 29.551 14.614 18.256 24.082 15.445 36.743 C 18.136 37.498 20.109 39.968 20.109 42.899 C 20.109 45.831 18.136 48.301 15.445 49.055 C 18.256 61.716 29.551 71.184 43.059 71.184 C 47.975 71.184 52.599 69.93 56.628 67.723 L 56.628 70.993 L 71.344 70.993 L 71.344 44.072 C 71.357 43.714 71.344 43.26 71.344 42.899 C 71.344 27.278 58.68 14.614 43.059 14.614 Z M 29.51 42.899 C 29.51 35.416 35.576 29.35 43.059 29.35 C 50.541 29.35 56.607 35.416 56.607 42.899 C 56.607 50.382 50.541 56.448 43.059 56.448 C 35.576 56.448 29.51 50.382 29.51 42.899 Z"
android:fillColor="#00ffffff"
android:strokeWidth="1"
android:fillType="evenOdd"/>
<path
android:name="path_2"
android:pathData="M 18.105 42.88 C 18.105 45.38 16.078 47.407 13.579 47.407 C 11.079 47.407 9.052 45.38 9.052 42.88 C 9.052 40.381 11.079 38.354 13.579 38.354 C 16.078 38.354 18.105 40.381 18.105 42.88 Z"
android:fillColor="#00ffffff"
android:strokeWidth="1"/>
</group>
</group>
</vector>
</aapt:attr>
<target android:name="path_2">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:startOffset="100"
android:duration="900"
android:valueFrom="#00ffffff"
android:valueTo="#161c2d"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
<target android:name="path">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:duration="500"
android:valueFrom="#00ffffff"
android:valueTo="#f9f9fb"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
<target android:name="path_1">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:startOffset="100"
android:duration="900"
android:valueFrom="#00ffffff"
android:valueTo="#161c2d"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
</animated-vector>

4
samples/MobileSandbox.Android/Resources/values-night/colors.xml

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="splash_background">#212121</color>
</resources>

16
samples/MobileSandbox.Android/Resources/values-v31/styles.xml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="MyTheme">
</style>
<style name="MyTheme.NoActionBar" parent="@style/Theme.AppCompat.NoActionBar">
<item name="android:windowActionBar">false</item>
<item name="android:windowBackground">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowSplashScreenBackground">@color/splash_background</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/avalonia_anim</item>
<item name="android:windowSplashScreenAnimationDuration">1000</item>
</style>
</resources>

7
samples/MobileSandbox.Android/Resources/values/styles.xml

@ -6,12 +6,7 @@
<style name="MyTheme.NoActionBar" parent="@style/Theme.AppCompat.NoActionBar"> <style name="MyTheme.NoActionBar" parent="@style/Theme.AppCompat.NoActionBar">
<item name="android:windowActionBar">false</item> <item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
<style name="MyTheme.Splash" parent ="MyTheme.NoActionBar">
<item name="android:windowBackground">@drawable/splash_screen</item> <item name="android:windowBackground">@drawable/splash_screen</item>
<item name="android:windowContentOverlay">@null</item> <item name="android:windowNoTitle">true</item>
</style> </style>
</resources> </resources>

17
samples/MobileSandbox.Android/SplashActivity.cs

@ -1,17 +0,0 @@
using Android.App;
using Android.Content;
using Avalonia.Android;
namespace MobileSandbox.Android
{
[Activity(Theme = "@style/MyTheme.Splash", MainLauncher = true, NoHistory = true)]
public class SplashActivity : AvaloniaSplashActivity<App>
{
protected override void OnResume()
{
base.OnResume();
StartActivity(new Intent(Application.Context, typeof(MainActivity)));
}
}
}

5
samples/MobileSandbox.Browser/Logo.svg

@ -0,0 +1,5 @@
<svg width="35" height="35" viewBox="0 0 35 35" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30.4661 34.928C30.5364 34.928 30.6052 34.928 30.6754 34.928C32.8596 34.928 34.654 33.2918 34.9053 31.1752L34.9356 16.9955C34.6872 7.56697 26.9662 0 17.4777 0C7.83263 0 0.0137329 7.8189 0.0137329 17.464C0.0137329 27.0059 7.66618 34.7631 17.1687 34.928H30.4661Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.5239 5.948C12.0268 5.948 7.42967 9.80117 6.286 14.954C7.38092 15.2609 8.18385 16.2664 8.18385 17.4593C8.18385 18.6523 7.38092 19.6577 6.286 19.9647C7.42966 25.1175 12.0268 28.9706 17.5239 28.9706C19.525 28.9706 21.4068 28.4601 23.0462 27.562V28.8927H29.0352V17.9365C29.0407 17.7908 29.0352 17.6063 29.0352 17.4593C29.0352 11.1018 23.8814 5.948 17.5239 5.948ZM12.0098 17.4593C12.0098 14.414 14.4786 11.9452 17.5239 11.9452C20.5693 11.9452 23.038 14.414 23.038 17.4593C23.038 20.5047 20.5693 22.9734 17.5239 22.9734C14.4786 22.9734 12.0098 20.5047 12.0098 17.4593Z" fill="#8B44AC"/>
<path d="M7.36841 17.4517C7.36841 18.4691 6.54368 19.2938 5.52631 19.2938C4.50894 19.2938 3.6842 18.4691 3.6842 17.4517C3.6842 16.4343 4.50894 15.6096 5.52631 15.6096C6.54368 15.6096 7.36841 16.4343 7.36841 17.4517Z" fill="#8B44AC"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

43
samples/MobileSandbox.Browser/MobileSandbox.Browser.csproj

@ -0,0 +1,43 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
<WasmMainJSPath>main.js</WasmMainJSPath>
<OutputType>Exe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<MSBuildEnableWorkloadResolver>true</MSBuildEnableWorkloadResolver>
<WasmBuildNative>true</WasmBuildNative>
<EmccFlags>-sVERBOSE -sERROR_ON_UNDEFINED_SYMBOLS=0</EmccFlags>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<RunAOTCompilation>true</RunAOTCompilation>
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>full</TrimMode>
<WasmBuildNative>true</WasmBuildNative>
<InvariantGlobalization>true</InvariantGlobalization>
<EmccCompileOptimizationFlag>-O2</EmccCompileOptimizationFlag>
<EmccLinkOptimizationFlag>-O2</EmccLinkOptimizationFlag>
</PropertyGroup>
<ItemGroup>
<TrimmerRootDescriptor Include="Roots.xml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Skia\Avalonia.Skia\Avalonia.Skia.csproj" />
<ProjectReference Include="..\..\src\Browser\Avalonia.Browser\Avalonia.Browser.csproj" />
<ProjectReference Include="..\MobileSandbox\MobileSandbox.csproj" />
</ItemGroup>
<ItemGroup>
<WasmExtraFilesToDeploy Include="index.html" />
<WasmExtraFilesToDeploy Include="main.js" />
<WasmExtraFilesToDeploy Include="favicon.ico" />
<WasmExtraFilesToDeploy Include="Logo.svg" />
<WasmExtraFilesToDeploy Include="app.css" />
</ItemGroup>
<Import Project="..\..\src\Browser\Avalonia.Browser\Avalonia.Browser.props" />
<Import Project="..\..\src\Browser\Avalonia.Browser\Avalonia.Browser.targets" />
</Project>

19
samples/MobileSandbox.Browser/Program.cs

@ -0,0 +1,19 @@
using System.Runtime.Versioning;
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Browser;
using MobileSandbox;
[assembly:SupportedOSPlatform("browser")]
internal partial class Program
{
public static async Task Main(string[] args)
{
await BuildAvaloniaApp()
.StartBrowserAppAsync("out");
}
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>();
}

12
samples/MobileSandbox.Browser/Properties/launchSettings.json

@ -0,0 +1,12 @@
{
"profiles": {
"MobileSandbox.Browser": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:65312;http://localhost:65313;"
}
}
}

7
samples/MobileSandbox.Browser/Roots.xml

@ -0,0 +1,7 @@
<linker>
<assembly fullname="MobileSandbox" preserve="All" />
<assembly fullname="MobileSandbox.Browser" preserve="All" />
<assembly fullname="Avalonia.Themes.Fluent" preserve="All" />
<assembly fullname="Avalonia.Themes.Simple" preserve="All" />
<assembly fullname="Avalonia.Controls.ColorPicker" preserve="All" />
</linker>

56
samples/MobileSandbox.Browser/app.css

@ -0,0 +1,56 @@
:root {
--sat: env(safe-area-inset-top);
--sar: env(safe-area-inset-right);
--sab: env(safe-area-inset-bottom);
--sal: env(safe-area-inset-left);
}
#out {
height: 100vh;
width: 100vw
}
#avalonia-splash {
position: relative;
height: 100%;
width: 100%;
color: whitesmoke;
background: #171C2C;
font-family: 'Nunito', sans-serif;
background-position: center;
background-size: cover;
background-repeat: no-repeat;
}
#avalonia-splash a{
color: whitesmoke;
text-decoration: none;
}
.center {
display: flex;
justify-content: center;
height: 250px;
}
.splash-close {
animation: slide 0.5s linear 1s forwards;
}
@keyframes slide {
0% {
top: 0%;
}
50% {
opacity: 80%;
}
100% {
top: 100%;
overflow: hidden;
opacity: 0;
display: none;
visibility: collapse;
}
}

BIN
samples/MobileSandbox.Browser/favicon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

31
samples/MobileSandbox.Browser/index.html

@ -0,0 +1,31 @@
<!DOCTYPE html>
<!-- Licensed to the .NET Foundation under one or more agreements. -->
<!-- The .NET Foundation licenses this file to you under the MIT license. -->
<html>
<head>
<title>Mobile Sandbox</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="modulepreload" href="./main.js" />
<link rel="modulepreload" href="./dotnet.js" />
<link rel="modulepreload" href="./avalonia.js" />
<link rel="stylesheet" href="./app.css" />
</head>
<body style="margin: 0px">
<div id="out">
<div id="avalonia-splash">
<div class="center">
<h2>Powered by</h2>
<a class="navbar-brand" href="https://www.avaloniaui.net/" target="_blank">
<img src="Logo.svg" alt="Avalonia Logo" width="30" height="24" />
Avalonia
</a>
</div>
</div>
</div>
<script type='module' src="./main.js"></script>
</body>
</html>

16
samples/MobileSandbox.Browser/main.js

@ -0,0 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
import { dotnet } from './dotnet.js'
const is_browser = typeof window != "undefined";
if (!is_browser) throw new Error(`Expected to be running in a browser`);
const dotnetRuntime = await dotnet
.withDiagnosticTracing(false)
.withApplicationArgumentsFromQuery()
.create();
const config = dotnetRuntime.getConfig();
await dotnetRuntime.runMainAndExit(config.mainAssemblyName, ["dotnet", "is", "great!"]);

11
samples/MobileSandbox.Browser/runtimeconfig.template.json

@ -0,0 +1,11 @@
{
"wasmHostProperties": {
"perHostConfig": [
{
"name": "browser",
"html-path": "index.html",
"Host": "browser"
}
]
}
}

5
samples/RenderDemo/Pages/CustomStringAnimator.cs

@ -1,9 +1,10 @@
using Avalonia.Animation; using System;
using Avalonia.Animation;
using Avalonia.Animation.Animators; using Avalonia.Animation.Animators;
namespace RenderDemo.Pages namespace RenderDemo.Pages
{ {
public class CustomStringAnimator : CustomAnimatorBase<string> public class CustomStringAnimator : InterpolatingAnimator<string>
{ {
public override string Interpolate(double progress, string oldValue, string newValue) public override string Interpolate(double progress, string oldValue, string newValue)
{ {

4
samples/SafeAreaDemo.Android/MainActivity.cs

@ -4,8 +4,8 @@ using Avalonia.Android;
namespace SafeAreaDemo.Android namespace SafeAreaDemo.Android
{ {
[Activity(Label = "SafeAreaDemo.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.UiMode)] [Activity(Label = "SafeAreaDemo.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.UiMode)]
public class MainActivity : AvaloniaMainActivity public class MainActivity : AvaloniaMainActivity<App>
{ {
} }
} }

66
samples/SafeAreaDemo.Android/Resources/drawable-night-v31/avalonia_anim.xml

@ -0,0 +1,66 @@
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:name="vector"
android:width="128dp"
android:height="128dp"
android:viewportWidth="128"
android:viewportHeight="128">
<group
android:name="wrapper"
android:translateX="21"
android:translateY="21">
<group android:name="group">
<path
android:name="path"
android:pathData="M 74.853 85.823 L 75.368 85.823 C 80.735 85.823 85.144 81.803 85.761 76.602 L 85.836 41.76 C 85.225 18.593 66.254 0 42.939 0 C 19.24 0 0.028 19.212 0.028 42.912 C 0.028 66.357 18.831 85.418 42.18 85.823 L 74.853 85.823 Z"
android:strokeWidth="1"/>
<path
android:name="path_1"
android:pathData="M 43.059 14.614 C 29.551 14.614 18.256 24.082 15.445 36.743 C 18.136 37.498 20.109 39.968 20.109 42.899 C 20.109 45.831 18.136 48.301 15.445 49.055 C 18.256 61.716 29.551 71.184 43.059 71.184 C 47.975 71.184 52.599 69.93 56.628 67.723 L 56.628 70.993 L 71.344 70.993 L 71.344 44.072 C 71.357 43.714 71.344 43.26 71.344 42.899 C 71.344 27.278 58.68 14.614 43.059 14.614 Z M 29.51 42.899 C 29.51 35.416 35.576 29.35 43.059 29.35 C 50.541 29.35 56.607 35.416 56.607 42.899 C 56.607 50.382 50.541 56.448 43.059 56.448 C 35.576 56.448 29.51 50.382 29.51 42.899 Z"
android:strokeWidth="1"
android:fillType="evenOdd"/>
<path
android:name="path_2"
android:pathData="M 18.105 42.88 C 18.105 45.38 16.078 47.407 13.579 47.407 C 11.079 47.407 9.052 45.38 9.052 42.88 C 9.052 40.381 11.079 38.354 13.579 38.354 C 16.078 38.354 18.105 40.381 18.105 42.88 Z"
android:strokeWidth="1"/>
</group>
</group>
</vector>
</aapt:attr>
<target android:name="path">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:duration="1000"
android:valueFrom="#00ffffff"
android:valueTo="#161c2d"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
<target android:name="path_1">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:duration="1000"
android:valueFrom="#00ffffff"
android:valueTo="#f9f9fb"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
<target android:name="path_2">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:duration="1000"
android:valueFrom="#00ffffff"
android:valueTo="#f9f9fb"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
</animated-vector>

71
samples/SafeAreaDemo.Android/Resources/drawable-v31/avalonia_anim.xml

@ -0,0 +1,71 @@
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:name="vector"
android:width="128dp"
android:height="128dp"
android:viewportWidth="128"
android:viewportHeight="128">
<group
android:name="wrapper"
android:translateX="21"
android:translateY="21">
<group android:name="group">
<path
android:name="path"
android:pathData="M 74.853 85.823 L 75.368 85.823 C 80.735 85.823 85.144 81.803 85.761 76.602 L 85.836 41.76 C 85.225 18.593 66.254 0 42.939 0 C 19.24 0 0.028 19.212 0.028 42.912 C 0.028 66.357 18.831 85.418 42.18 85.823 L 74.853 85.823 Z"
android:fillColor="#00ffffff"
android:strokeWidth="1"/>
<path
android:name="path_1"
android:pathData="M 43.059 14.614 C 29.551 14.614 18.256 24.082 15.445 36.743 C 18.136 37.498 20.109 39.968 20.109 42.899 C 20.109 45.831 18.136 48.301 15.445 49.055 C 18.256 61.716 29.551 71.184 43.059 71.184 C 47.975 71.184 52.599 69.93 56.628 67.723 L 56.628 70.993 L 71.344 70.993 L 71.344 44.072 C 71.357 43.714 71.344 43.26 71.344 42.899 C 71.344 27.278 58.68 14.614 43.059 14.614 Z M 29.51 42.899 C 29.51 35.416 35.576 29.35 43.059 29.35 C 50.541 29.35 56.607 35.416 56.607 42.899 C 56.607 50.382 50.541 56.448 43.059 56.448 C 35.576 56.448 29.51 50.382 29.51 42.899 Z"
android:fillColor="#00ffffff"
android:strokeWidth="1"
android:fillType="evenOdd"/>
<path
android:name="path_2"
android:pathData="M 18.105 42.88 C 18.105 45.38 16.078 47.407 13.579 47.407 C 11.079 47.407 9.052 45.38 9.052 42.88 C 9.052 40.381 11.079 38.354 13.579 38.354 C 16.078 38.354 18.105 40.381 18.105 42.88 Z"
android:fillColor="#00ffffff"
android:strokeWidth="1"/>
</group>
</group>
</vector>
</aapt:attr>
<target android:name="path_2">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:startOffset="100"
android:duration="900"
android:valueFrom="#00ffffff"
android:valueTo="#161c2d"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
<target android:name="path">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:duration="500"
android:valueFrom="#00ffffff"
android:valueTo="#f9f9fb"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
<target android:name="path_1">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:startOffset="100"
android:duration="900"
android:valueFrom="#00ffffff"
android:valueTo="#161c2d"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
</animated-vector>

4
samples/SafeAreaDemo.Android/Resources/values-night/colors.xml

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="splash_background">#212121</color>
</resources>

16
samples/SafeAreaDemo.Android/Resources/values-v31/styles.xml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="MyTheme">
</style>
<style name="MyTheme.NoActionBar" parent="@style/Theme.AppCompat.NoActionBar">
<item name="android:windowActionBar">false</item>
<item name="android:windowBackground">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowSplashScreenBackground">@color/splash_background</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/avalonia_anim</item>
<item name="android:windowSplashScreenAnimationDuration">1000</item>
</style>
</resources>

7
samples/SafeAreaDemo.Android/Resources/values/styles.xml

@ -6,12 +6,7 @@
<style name="MyTheme.NoActionBar" parent="@style/Theme.AppCompat.NoActionBar"> <style name="MyTheme.NoActionBar" parent="@style/Theme.AppCompat.NoActionBar">
<item name="android:windowActionBar">false</item> <item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
<style name="MyTheme.Splash" parent ="MyTheme.NoActionBar">
<item name="android:windowBackground">@drawable/splash_screen</item> <item name="android:windowBackground">@drawable/splash_screen</item>
<item name="android:windowContentOverlay">@null</item> <item name="android:windowNoTitle">true</item>
</style> </style>
</resources> </resources>

13
samples/SafeAreaDemo.Android/SafeAreaDemo.Android.csproj

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net7.0-android</TargetFramework> <TargetFramework>net7.0-android</TargetFramework>
@ -12,13 +12,14 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<AndroidResource Include="Icon.png"> <ProjectReference Include="..\SafeAreaDemo\SafeAreaDemo.csproj" />
<Link>Resources\drawable\Icon.png</Link> <ProjectReference Include="..\..\src\Android\Avalonia.Android\Avalonia.Android.csproj" />
</AndroidResource>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\SafeAreaDemo\SafeAreaDemo.csproj" /> <AndroidResource Include="..\..\build\Assets\Icon.png">
<ProjectReference Include="..\..\src\Android\Avalonia.Android\Avalonia.Android.csproj" /> <Link>Resources\drawable\Icon.png</Link>
</AndroidResource>
</ItemGroup> </ItemGroup>
</Project> </Project>

30
samples/SafeAreaDemo.Android/SplashActivity.cs

@ -1,30 +0,0 @@
using Android.App;
using Android.Content;
using Android.OS;
using Avalonia;
using Avalonia.Android;
using Application = Android.App.Application;
namespace SafeAreaDemo.Android
{
[Activity(Theme = "@style/MyTheme.Splash", MainLauncher = true, NoHistory = true)]
public class SplashActivity : AvaloniaSplashActivity<App>
{
protected override AppBuilder CustomizeAppBuilder(AppBuilder builder)
{
return base.CustomizeAppBuilder(builder);
}
protected override void OnCreate(Bundle? savedInstanceState)
{
base.OnCreate(savedInstanceState);
}
protected override void OnResume()
{
base.OnResume();
StartActivity(new Intent(Application.Context, typeof(MainActivity)));
}
}
}

6
samples/SafeAreaDemo/Views/MainView.xaml.cs

@ -1,4 +1,5 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using SafeAreaDemo.ViewModels; using SafeAreaDemo.ViewModels;
@ -11,9 +12,10 @@ namespace SafeAreaDemo.Views
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
} }
protected override void OnLoaded() /// <inheritdoc/>
protected override void OnLoaded(RoutedEventArgs e)
{ {
base.OnLoaded(); base.OnLoaded(e);
var insetsManager = TopLevel.GetTopLevel(this)?.InsetsManager; var insetsManager = TopLevel.GetTopLevel(this)?.InsetsManager;
if (insetsManager != null && DataContext is MainViewModel viewModel) if (insetsManager != null && DataContext is MainViewModel viewModel)

4
samples/interop/WindowsInteropTest/EmbedToWinFormsDemo.Designer.cs

@ -1,4 +1,4 @@
using Avalonia.Win32.Embedding; using Avalonia.Win32.Interoperability;
namespace WindowsInteropTest namespace WindowsInteropTest
{ {
@ -116,4 +116,4 @@ namespace WindowsInteropTest
private System.Windows.Forms.GroupBox groupBox2; private System.Windows.Forms.GroupBox groupBox2;
private WinFormsAvaloniaControlHost avaloniaHost; private WinFormsAvaloniaControlHost avaloniaHost;
} }
} }

23
samples/interop/WindowsInteropTest/EmbedToWinFormsDemo.cs

@ -1,35 +1,14 @@
using System; using System.Windows.Forms;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Avalonia.Controls;
using Avalonia.Rendering;
using Avalonia.VisualTree;
using ControlCatalog; using ControlCatalog;
namespace WindowsInteropTest namespace WindowsInteropTest
{ {
public partial class EmbedToWinFormsDemo : Form public partial class EmbedToWinFormsDemo : Form
{ {
private readonly IRenderer _renderer;
public EmbedToWinFormsDemo() public EmbedToWinFormsDemo()
{ {
InitializeComponent(); InitializeComponent();
avaloniaHost.Content = new MainView(); avaloniaHost.Content = new MainView();
_renderer = ((TopLevel)avaloniaHost.Content.GetVisualRoot()).Renderer;
_renderer.Start();
}
protected override void OnClosed(EventArgs e)
{
_renderer.Stop();
base.OnClosed(e);
} }
} }
} }

33
samples/interop/WindowsInteropTest/EmbedToWpfDemo.xaml

@ -1,33 +0,0 @@
<Window x:Class="WindowsInteropTest.EmbedToWpfDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:av="clr-namespace:Avalonia.Controls;assembly=Avalonia.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WindowsInteropTest"
xmlns:embedding="clr-namespace:Avalonia.Win32.Embedding;assembly=Avalonia.Win32"
xmlns:wpf="clr-namespace:Avalonia.Win32.Interop.Wpf;assembly=Avalonia.Win32.Interop"
mc:Ignorable="d"
d:DesignHeight="400" d:DesignWidth="400" MinWidth="500" MinHeight="400">
<DockPanel>
<GroupBox DockPanel.Dock="Left" Header="WPF">
<StackPanel>
<Slider/>
<Calendar/>
</StackPanel>
</GroupBox>
<GroupBox Header="Avalonia button" DockPanel.Dock="Bottom">
<wpf:WpfAvaloniaHost >
<av:Button Content="Avalonia button"/>
</wpf:WpfAvaloniaHost>
</GroupBox>
<GroupBox Header="AvBtn" DockPanel.Dock="Right">
<wpf:WpfAvaloniaHost x:Name="RightBtn">
<av:Button Content="Avalonia button 2"/>
</wpf:WpfAvaloniaHost>
</GroupBox>
<GroupBox Header="Avalonia">
<wpf:WpfAvaloniaHost x:Name="Host"/>
</GroupBox>
</DockPanel>
</Window>

52
samples/interop/WindowsInteropTest/EmbedToWpfDemo.xaml.cs

@ -1,52 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Rendering;
using Avalonia.VisualTree;
using ControlCatalog;
using Window = System.Windows.Window;
namespace WindowsInteropTest
{
/// <summary>
/// Interaction logic for EmbedToWpfDemo.xaml
/// </summary>
public partial class EmbedToWpfDemo : Window
{
private IRenderer _renderer;
public EmbedToWpfDemo()
{
InitializeComponent();
var view = new MainView();
Host.Content = view;
var tl = (TopLevel)view.GetVisualRoot();
tl.AttachDevTools();
_renderer = tl.Renderer;
_renderer.Start();
var btn = (Avalonia.Controls.Button) RightBtn.Content;
btn.Click += delegate
{
btn.Content += "!";
};
}
protected override void OnClosed(EventArgs e)
{
_renderer.Stop();
base.OnClosed(e);
}
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save