diff --git a/.editorconfig b/.editorconfig index 30edee1633..9ae52b8bbd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -134,9 +134,26 @@ csharp_space_between_parentheses = false csharp_space_between_square_brackets = false space_within_single_line_array_initializer_braces = true +#Net Analyzer +dotnet_analyzer_diagnostic.category-Performance.severity = none #error - Uncomment when all violations are fixed. + +# CA1802: Use literals where appropriate +dotnet_diagnostic.CA1802.severity = warning +# CA1820: Test for empty strings using string length +dotnet_diagnostic.CA1820.severity = warning +# CA1821: Remove empty finalizers +dotnet_diagnostic.CA1821.severity = warning +# CA1825: Avoid zero-length array allocations +dotnet_diagnostic.CA1825.severity = warning +#CA1847: Use string.Contains(char) instead of string.Contains(string) with single characters +dotnet_diagnostic.CA1847.severity = warning + # Wrapping preferences csharp_wrap_before_ternary_opsigns = false +# Avalonia DevAnalyzer preferences +dotnet_diagnostic.AVADEV2001.severity = error + # Xaml files [*.{xaml,axaml}] indent_size = 2 diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index c5a719ce90..df070c35cf 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1,2 @@ +github: avaloniaui open_collective: avalonia diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 46e8665945..2f63750cdc 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -21,7 +21,7 @@ - [ ] Consider submitting a PR to https://github.com/AvaloniaUI/Documentation with user documentation ## Breaking changes - + ## Obsoletions / Deprecations diff --git a/.gitignore b/.gitignore index 44fe5e4ba4..61a3b53de1 100644 --- a/.gitignore +++ b/.gitignore @@ -212,3 +212,7 @@ coc-settings.json *.map src/Web/Avalonia.Web.Blazor/wwwroot/*.js src/Web/Avalonia.Web.Blazor/Interop/Typescript/*.js +node_modules +src/Web/Avalonia.Web.Blazor/webapp/package-lock.json +src/Web/Avalonia.Web.Blazor/wwwroot +src/Web/Avalonia.Web/wwwroot diff --git a/.gitmodules b/.gitmodules index 2d11fdfa9e..032bc879cc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github"] path = src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github url = https://github.com/kekekeks/XamlX.git +[submodule "nukebuild/il-repack"] + path = nukebuild/il-repack + url = https://github.com/Gillibald/il-repack diff --git a/.nuke b/.nuke deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json new file mode 100644 index 0000000000..5bbc3d6915 --- /dev/null +++ b/.nuke/build.schema.json @@ -0,0 +1,148 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Build Schema", + "$ref": "#/definitions/build", + "definitions": { + "build": { + "type": "object", + "properties": { + "Configuration": { + "type": "string", + "description": "configuration" + }, + "Continue": { + "type": "boolean", + "description": "Indicates to continue a previously failed build attempt" + }, + "ForceNugetVersion": { + "type": "string", + "description": "force-nuget-version" + }, + "Help": { + "type": "boolean", + "description": "Shows the help text for this build assembly" + }, + "Host": { + "type": "string", + "description": "Host for execution. Default is 'automatic'", + "enum": [ + "AppVeyor", + "AzurePipelines", + "Bamboo", + "Bitbucket", + "Bitrise", + "GitHubActions", + "GitLab", + "Jenkins", + "Rider", + "SpaceAutomation", + "TeamCity", + "Terminal", + "TravisCI", + "VisualStudio", + "VSCode" + ] + }, + "NoLogo": { + "type": "boolean", + "description": "Disables displaying the NUKE logo" + }, + "Partition": { + "type": "string", + "description": "Partition to use on CI" + }, + "Plan": { + "type": "boolean", + "description": "Shows the execution plan (HTML)" + }, + "Profile": { + "type": "array", + "description": "Defines the profiles to load", + "items": { + "type": "string" + } + }, + "Root": { + "type": "string", + "description": "Root directory during build execution" + }, + "Skip": { + "type": "array", + "description": "List of targets to be skipped. Empty list skips all dependencies", + "items": { + "type": "string", + "enum": [ + "CiAzureLinux", + "CiAzureOSX", + "CiAzureWindows", + "Clean", + "Compile", + "CompileHtmlPreviewer", + "CompileNative", + "CreateIntermediateNugetPackages", + "CreateNugetPackages", + "GenerateCppHeaders", + "Package", + "RunCoreLibsTests", + "RunDesignerTests", + "RunHtmlPreviewerTests", + "RunLeakTests", + "RunRenderTests", + "RunTests", + "ZipFiles" + ] + } + }, + "SkipPreviewer": { + "type": "boolean", + "description": "skip-previewer" + }, + "SkipTests": { + "type": "boolean", + "description": "skip-tests" + }, + "Solution": { + "type": "string", + "description": "Path to a solution file that is automatically loaded. Default is Avalonia.sln" + }, + "Target": { + "type": "array", + "description": "List of targets to be invoked. Default is '{default_target}'", + "items": { + "type": "string", + "enum": [ + "CiAzureLinux", + "CiAzureOSX", + "CiAzureWindows", + "Clean", + "Compile", + "CompileHtmlPreviewer", + "CompileNative", + "CreateIntermediateNugetPackages", + "CreateNugetPackages", + "GenerateCppHeaders", + "Package", + "RunCoreLibsTests", + "RunDesignerTests", + "RunHtmlPreviewerTests", + "RunLeakTests", + "RunRenderTests", + "RunTests", + "ZipFiles" + ] + } + }, + "Verbosity": { + "type": "string", + "description": "Logging verbosity during build execution. Default is 'Normal'", + "enum": [ + "Minimal", + "Normal", + "Quiet", + "Verbose" + ] + } + } + } + } +} \ No newline at end of file diff --git a/.nuke/parameters.json b/.nuke/parameters.json new file mode 100644 index 0000000000..42521bb7dd --- /dev/null +++ b/.nuke/parameters.json @@ -0,0 +1,4 @@ +{ + "$schema": "./build.schema.json", + "Solution": "" +} \ No newline at end of file diff --git a/Avalonia.sln b/Avalonia.sln index 35b6b2108a..c000f56d09 100644 --- a/Avalonia.sln +++ b/Avalonia.sln @@ -90,6 +90,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1-27F5-4255-9AFC-04ABFD11683A}" ProjectSection(SolutionItems) = preProject build\ApiDiff.props = build\ApiDiff.props + build\AvaloniaPublicKey.props = build\AvaloniaPublicKey.props build\Base.props = build\Base.props build\Binding.props = build\Binding.props build\CoreLibraries.props = build\CoreLibraries.props @@ -102,8 +103,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1 build\Microsoft.CSharp.props = build\Microsoft.CSharp.props build\Microsoft.Reactive.Testing.props = build\Microsoft.Reactive.Testing.props build\Moq.props = build\Moq.props + build\NetAnalyzers.props = build\NetAnalyzers.props build\NetCore.props = build\NetCore.props build\NetFX.props = build\NetFX.props + build\NullableEnable.props = build\NullableEnable.props build\ReactiveUI.props = build\ReactiveUI.props build\ReferenceCoreLibraries.props = build\ReferenceCoreLibraries.props build\Rx.props = build\Rx.props @@ -198,8 +201,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web", "Web", "{86A3F706-DC3 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Web.Blazor", "src\Web\Avalonia.Web.Blazor\Avalonia.Web.Blazor.csproj", "{25831348-EB2A-483E-9576-E8F6528674A5}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Web", "samples\ControlCatalog.Web\ControlCatalog.Web.csproj", "{C08E9894-AA92-426E-BF56-033E262CAD3E}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WindowsInteropTest", "samples\interop\WindowsInteropTest\WindowsInteropTest.csproj", "{26A98DA1-D89D-4A95-8152-349F404DA2E2}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlSamples", "samples\SampleControls\ControlSamples.csproj", "{A0D0A6A4-5C72-4ADA-9B27-621C7D94F270}" @@ -212,7 +213,21 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Controls.ColorPick EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.DesignerSupport.Tests", "tests\Avalonia.DesignerSupport.Tests\Avalonia.DesignerSupport.Tests.csproj", "{EABE2161-989B-42BF-BD8D-1E34B20C21F1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevGenerators", "src\tools\DevGenerators\DevGenerators.csproj", "{1BBFAD42-B99E-47E0-B00A-A4BC6B6BB4BB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevGenerators", "src\tools\DevGenerators\DevGenerators.csproj", "{1BBFAD42-B99E-47E0-B00A-A4BC6B6BB4BB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Web", "src\Web\Avalonia.Web\Avalonia.Web.csproj", "{76D39FF6-6B4F-46C4-93CD-E6FC4665739E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MobileSandbox", "samples\MobileSandbox\MobileSandbox.csproj", "{3B8519C1-2F51-4F12-A348-120AB91D4532}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MobileSandbox.Android", "samples\MobileSandbox.Android\MobileSandbox.Android.csproj", "{C90FE60B-B01E-4F35-91D6-379D6966030F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MobileSandbox.iOS", "samples\MobileSandbox.iOS\MobileSandbox.iOS.csproj", "{FED9A71D-00D7-4F40-A9E4-1229EEA28EEB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MobileSandbox.Desktop", "samples\MobileSandbox.Desktop\MobileSandbox.Desktop.csproj", "{62D392C9-81CF-487F-92E8-598B2AF3FDCE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Blazor.Web", "samples\ControlCatalog.Blazor.Web\ControlCatalog.Blazor.Web.csproj", "{6A710364-AE6D-40BD-968B-024311527AC2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Web", "samples\ControlCatalog.Web\ControlCatalog.Web.csproj", "{8B3E8405-DE18-4048-A459-9CA4AC3319A2}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -399,9 +414,7 @@ Global {BF28998D-072C-439A-AFBB-2FE5021241E0}.Release|Any CPU.ActiveCfg = Release|Any CPU {BF28998D-072C-439A-AFBB-2FE5021241E0}.Release|Any CPU.Build.0 = Release|Any CPU {3F00BC43-5095-477F-93D8-E65B08179A00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3F00BC43-5095-477F-93D8-E65B08179A00}.Debug|Any CPU.Build.0 = Debug|Any CPU {3F00BC43-5095-477F-93D8-E65B08179A00}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3F00BC43-5095-477F-93D8-E65B08179A00}.Release|Any CPU.Build.0 = Release|Any CPU {41B02319-965D-4945-8005-C1A3D1224165}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {41B02319-965D-4945-8005-C1A3D1224165}.Debug|Any CPU.Build.0 = Debug|Any CPU {41B02319-965D-4945-8005-C1A3D1224165}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -470,10 +483,6 @@ Global {25831348-EB2A-483E-9576-E8F6528674A5}.Debug|Any CPU.Build.0 = Debug|Any CPU {25831348-EB2A-483E-9576-E8F6528674A5}.Release|Any CPU.ActiveCfg = Release|Any CPU {25831348-EB2A-483E-9576-E8F6528674A5}.Release|Any CPU.Build.0 = Release|Any CPU - {C08E9894-AA92-426E-BF56-033E262CAD3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C08E9894-AA92-426E-BF56-033E262CAD3E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C08E9894-AA92-426E-BF56-033E262CAD3E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C08E9894-AA92-426E-BF56-033E262CAD3E}.Release|Any CPU.Build.0 = Release|Any CPU {26A98DA1-D89D-4A95-8152-349F404DA2E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {26A98DA1-D89D-4A95-8152-349F404DA2E2}.Debug|Any CPU.Build.0 = Debug|Any CPU {26A98DA1-D89D-4A95-8152-349F404DA2E2}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -502,6 +511,34 @@ Global {1BBFAD42-B99E-47E0-B00A-A4BC6B6BB4BB}.Debug|Any CPU.Build.0 = Debug|Any CPU {1BBFAD42-B99E-47E0-B00A-A4BC6B6BB4BB}.Release|Any CPU.ActiveCfg = Release|Any CPU {1BBFAD42-B99E-47E0-B00A-A4BC6B6BB4BB}.Release|Any CPU.Build.0 = Release|Any CPU + {76D39FF6-6B4F-46C4-93CD-E6FC4665739E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {76D39FF6-6B4F-46C4-93CD-E6FC4665739E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {76D39FF6-6B4F-46C4-93CD-E6FC4665739E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {76D39FF6-6B4F-46C4-93CD-E6FC4665739E}.Release|Any CPU.Build.0 = Release|Any CPU + {3B8519C1-2F51-4F12-A348-120AB91D4532}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3B8519C1-2F51-4F12-A348-120AB91D4532}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3B8519C1-2F51-4F12-A348-120AB91D4532}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3B8519C1-2F51-4F12-A348-120AB91D4532}.Release|Any CPU.Build.0 = Release|Any CPU + {C90FE60B-B01E-4F35-91D6-379D6966030F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C90FE60B-B01E-4F35-91D6-379D6966030F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C90FE60B-B01E-4F35-91D6-379D6966030F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C90FE60B-B01E-4F35-91D6-379D6966030F}.Release|Any CPU.Build.0 = Release|Any CPU + {FED9A71D-00D7-4F40-A9E4-1229EEA28EEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FED9A71D-00D7-4F40-A9E4-1229EEA28EEB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FED9A71D-00D7-4F40-A9E4-1229EEA28EEB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FED9A71D-00D7-4F40-A9E4-1229EEA28EEB}.Release|Any CPU.Build.0 = Release|Any CPU + {62D392C9-81CF-487F-92E8-598B2AF3FDCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62D392C9-81CF-487F-92E8-598B2AF3FDCE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62D392C9-81CF-487F-92E8-598B2AF3FDCE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62D392C9-81CF-487F-92E8-598B2AF3FDCE}.Release|Any CPU.Build.0 = Release|Any CPU + {6A710364-AE6D-40BD-968B-024311527AC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6A710364-AE6D-40BD-968B-024311527AC2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6A710364-AE6D-40BD-968B-024311527AC2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6A710364-AE6D-40BD-968B-024311527AC2}.Release|Any CPU.Build.0 = Release|Any CPU + {8B3E8405-DE18-4048-A459-9CA4AC3319A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8B3E8405-DE18-4048-A459-9CA4AC3319A2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8B3E8405-DE18-4048-A459-9CA4AC3319A2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8B3E8405-DE18-4048-A459-9CA4AC3319A2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -545,6 +582,7 @@ Global {41B02319-965D-4945-8005-C1A3D1224165} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B} {D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B} = {9B9E3891-2366-4253-A952-D08BCEB71098} {AF915D5C-AB00-4EA0-B5E6-001F4AE84E68} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} + {4D36CEC8-53F2-40A5-9A37-79AAE356E2DA} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B} {351337F5-D66F-461B-A957-4EF60BDB4BA6} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {909A8CBD-7D0E-42FD-B841-022AD8925820} = {8B6A8209-894F-4BA1-B880-965FD453982C} {11BE52AF-E2DD-4CF0-B19A-05285ACAF571} = {9B9E3891-2366-4253-A952-D08BCEB71098} @@ -552,14 +590,19 @@ Global {676D6BFD-029D-4E43-BFC7-3892265CE251} = {9B9E3891-2366-4253-A952-D08BCEB71098} {F2CE566B-E7F6-447A-AB1A-3F574A6FE43A} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {25831348-EB2A-483E-9576-E8F6528674A5} = {86A3F706-DC3C-43C6-BE1B-B98F5BAAA268} - {C08E9894-AA92-426E-BF56-033E262CAD3E} = {9B9E3891-2366-4253-A952-D08BCEB71098} {26A98DA1-D89D-4A95-8152-349F404DA2E2} = {A0CC0258-D18C-4AB3-854F-7101680FC3F9} {A0D0A6A4-5C72-4ADA-9B27-621C7D94F270} = {9B9E3891-2366-4253-A952-D08BCEB71098} {70B9F5CC-E2F9-4314-9514-EDE762ACCC4B} = {9B9E3891-2366-4253-A952-D08BCEB71098} {2B390431-288C-435C-BB6B-A374033BD8D1} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637} {EABE2161-989B-42BF-BD8D-1E34B20C21F1} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B} {1BBFAD42-B99E-47E0-B00A-A4BC6B6BB4BB} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637} - {4D36CEC8-53F2-40A5-9A37-79AAE356E2DA} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B} + {76D39FF6-6B4F-46C4-93CD-E6FC4665739E} = {86A3F706-DC3C-43C6-BE1B-B98F5BAAA268} + {3B8519C1-2F51-4F12-A348-120AB91D4532} = {9B9E3891-2366-4253-A952-D08BCEB71098} + {C90FE60B-B01E-4F35-91D6-379D6966030F} = {9B9E3891-2366-4253-A952-D08BCEB71098} + {FED9A71D-00D7-4F40-A9E4-1229EEA28EEB} = {9B9E3891-2366-4253-A952-D08BCEB71098} + {62D392C9-81CF-487F-92E8-598B2AF3FDCE} = {9B9E3891-2366-4253-A952-D08BCEB71098} + {6A710364-AE6D-40BD-968B-024311527AC2} = {9B9E3891-2366-4253-A952-D08BCEB71098} + {8B3E8405-DE18-4048-A459-9CA4AC3319A2} = {9B9E3891-2366-4253-A952-D08BCEB71098} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A} diff --git a/NOTICE.md b/NOTICE.md index 92fd725957..e97fc654c9 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -111,7 +111,7 @@ DEALINGS IN THE SOFTWARE. # Metsys.Bson -Copyright (c) 2010, Karl Seguin - http://www.openmymind.net/ +Copyright (c) 2010, Karl Seguin - https://www.openmymind.net/ All rights reserved. Redistribution and use in source and binary forms, with or without @@ -302,4 +302,4 @@ https://github.com/chromium/chromium // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/azure-pipelines-integrationtests.yml b/azure-pipelines-integrationtests.yml index 0b79758c76..4fba4ca36f 100644 --- a/azure-pipelines-integrationtests.yml +++ b/azure-pipelines-integrationtests.yml @@ -12,6 +12,16 @@ jobs: name: 'AvaloniaMacPool' steps: + - task: UseDotNet@2 + displayName: 'Use .NET Core SDK 6.0.401' + inputs: + version: 6.0.401 + + - task: UseDotNet@2 + displayName: 'Use .NET Core SDK 7.0.100-rc.2.22477.23' + inputs: + version: 7.0.100-rc.2.22477.23 + - script: system_profiler SPDisplaysDataType |grep Resolution - script: | @@ -41,9 +51,14 @@ jobs: steps: - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 6.0.202' + displayName: 'Use .NET Core SDK 6.0.401' + inputs: + version: 6.0.401 + + - task: UseDotNet@2 + displayName: 'Use .NET Core SDK 7.0.100-rc.2.22477.23' inputs: - version: 6.0.202 + version: 7.0.100-rc.2.22477.23 - task: Windows Application Driver@0 inputs: @@ -57,6 +72,7 @@ jobs: projects: 'samples/IntegrationTestApp/IntegrationTestApp.csproj' - task: DotNetCoreCLI@2 + retryCountOnTaskFailure: 3 inputs: command: 'test' projects: 'tests/Avalonia.IntegrationTests.Appium/Avalonia.IntegrationTests.Appium.csproj' diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 52fc8db53c..903f9e3843 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -6,7 +6,6 @@ jobs: variables: SolutionDir: '$(Build.SourcesDirectory)' steps: - - task: PowerShell@2 displayName: Get PR Number inputs: @@ -31,14 +30,20 @@ jobs: vmImage: 'ubuntu-20.04' steps: - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 3.1.418' + displayName: 'Use .NET Core SDK 6.0.401' inputs: - version: 3.1.418 + version: 6.0.401 - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 6.0.202' + displayName: 'Use .NET Core SDK 7.0.100-rc.2.22477.23' + inputs: + version: 7.0.100-rc.2.22477.23 + + - task: CmdLine@2 + displayName: 'Install Workloads' inputs: - version: 6.0.202 + script: | + dotnet workload install wasm-tools wasm-experimental - task: CmdLine@2 displayName: 'Run Build' @@ -62,22 +67,21 @@ jobs: vmImage: 'macos-12' steps: - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 3.1.418' + displayName: 'Use .NET Core SDK 6.0.401' inputs: - version: 3.1.418 + version: 6.0.401 - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 6.0.202' + displayName: 'Use .NET Core SDK 7.0.100-rc.2.22477.23' inputs: - version: 6.0.202 - + version: 7.0.100-rc.2.22477.23 + - task: CmdLine@2 - displayName: 'Install Mono 5.18' + displayName: 'Install Workloads' inputs: script: | - curl -o ./mono.pkg https://download.mono-project.com/archive/5.18.0/macos-10-universal/MonoFramework-MDK-5.18.0.225.macos10.xamarin.universal.pkg - sudo installer -verbose -pkg ./mono.pkg -target / - + dotnet workload install wasm-tools wasm-experimental + - task: CmdLine@2 displayName: 'Generate avalonia-native' inputs: @@ -134,26 +138,26 @@ jobs: SolutionDir: '$(Build.SourcesDirectory)' steps: - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 3.1.418' + displayName: 'Use .NET Core SDK 6.0.401' inputs: - version: 3.1.418 + version: 6.0.401 - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 6.0.202' + displayName: 'Use .NET Core SDK 7.0.100-rc.2.22477.23' inputs: - version: 6.0.202 + version: 7.0.100-rc.2.22477.23 - task: CmdLine@2 displayName: 'Install Workloads' inputs: script: | - dotnet workload install android ios + dotnet workload install android ios wasm-tools wasm-experimental - task: CmdLine@2 displayName: 'Install Nuke' inputs: script: | - dotnet tool install --global Nuke.GlobalTool --version 0.24.0 + dotnet tool install --global Nuke.GlobalTool --version 6.2.1 - task: CmdLine@2 displayName: 'Run Nuke' diff --git a/build.cmd b/build.cmd new file mode 100644 index 0000000000..b08cc590f4 --- /dev/null +++ b/build.cmd @@ -0,0 +1,7 @@ +:; set -eo pipefail +:; SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) +:; ${SCRIPT_DIR}/build.sh "$@" +:; exit $? + +@ECHO OFF +powershell -ExecutionPolicy ByPass -NoProfile -File "%~dp0build.ps1" %* diff --git a/build.ps1 b/build.ps1 index 985e8abcee..997e5b423f 100644 --- a/build.ps1 +++ b/build.ps1 @@ -1,13 +1,12 @@ [CmdletBinding()] Param( - #[switch]$CustomParam, [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] [string[]]$BuildArguments ) -Write-Output "Windows PowerShell $($Host.Version)" +Write-Output "PowerShell $($PSVersionTable.PSEdition) version $($PSVersionTable.PSVersion)" -Set-StrictMode -Version 2.0; $ErrorActionPreference = "Stop"; $ConfirmPreference = "None"; trap { exit 1 } +Set-StrictMode -Version 2.0; $ErrorActionPreference = "Stop"; $ConfirmPreference = "None"; trap { Write-Error $_ -ErrorAction Continue; exit 1 } $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent ########################################################################### @@ -15,15 +14,15 @@ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent ########################################################################### $BuildProjectFile = "$PSScriptRoot\nukebuild\_build.csproj" -$TempDirectory = "$PSScriptRoot\\.tmp" +$TempDirectory = "$PSScriptRoot\\.nuke\temp" $DotNetGlobalFile = "$PSScriptRoot\\global.json" -$DotNetInstallUrl = "https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.ps1" +$DotNetInstallUrl = "https://dot.net/v1/dotnet-install.ps1" $DotNetChannel = "Current" $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = 1 $env:DOTNET_CLI_TELEMETRY_OPTOUT = 1 -$env:NUGET_XMLDOC_MODE = "skip" +$env:DOTNET_MULTILEVEL_LOOKUP = 0 ########################################################################### # EXECUTION @@ -34,38 +33,37 @@ function ExecSafe([scriptblock] $cmd) { if ($LASTEXITCODE) { exit $LASTEXITCODE } } -# If global.json exists, load expected version -if (Test-Path $DotNetGlobalFile) { - $DotNetGlobal = $(Get-Content $DotNetGlobalFile | Out-String | ConvertFrom-Json) - if ($DotNetGlobal.PSObject.Properties["sdk"] -and $DotNetGlobal.sdk.PSObject.Properties["version"]) { - $DotNetVersion = $DotNetGlobal.sdk.version - } -} - -# If dotnet is installed locally, and expected version is not set or installation matches the expected version +# If dotnet CLI is installed globally and it matches requested version, use for execution if ($null -ne (Get-Command "dotnet" -ErrorAction SilentlyContinue) -and ` - (!(Test-Path variable:DotNetVersion) -or $(& dotnet --version) -eq $DotNetVersion)) { + $(dotnet --version) -and $LASTEXITCODE -eq 0) { $env:DOTNET_EXE = (Get-Command "dotnet").Path } else { - $DotNetDirectory = "$TempDirectory\dotnet-win" - $env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe" - # Download install script $DotNetInstallFile = "$TempDirectory\dotnet-install.ps1" - mkdir -force $TempDirectory > $null + New-Item -ItemType Directory -Path $TempDirectory -Force | Out-Null + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 (New-Object System.Net.WebClient).DownloadFile($DotNetInstallUrl, $DotNetInstallFile) + # If global.json exists, load expected version + if (Test-Path $DotNetGlobalFile) { + $DotNetGlobal = $(Get-Content $DotNetGlobalFile | Out-String | ConvertFrom-Json) + if ($DotNetGlobal.PSObject.Properties["sdk"] -and $DotNetGlobal.sdk.PSObject.Properties["version"]) { + $DotNetVersion = $DotNetGlobal.sdk.version + } + } + # Install by channel or version + $DotNetDirectory = "$TempDirectory\dotnet-win" if (!(Test-Path variable:DotNetVersion)) { - ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Channel $DotNetChannel -NoPath } + ExecSafe { & powershell $DotNetInstallFile -InstallDir $DotNetDirectory -Channel $DotNetChannel -NoPath } } else { - ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath } + ExecSafe { & powershell $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath } } - - $env:PATH="$DotNetDirectory;$env:PATH" + $env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe" } -Write-Output "Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)" +Write-Output "Microsoft (R) .NET SDK version $(& $env:DOTNET_EXE --version)" -ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile -- $BuildArguments } +ExecSafe { & $env:DOTNET_EXE build $BuildProjectFile /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet } +ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile --no-build -- $BuildArguments } diff --git a/build.sh b/build.sh index 9532b4fbe0..76919a5351 100755 --- a/build.sh +++ b/build.sh @@ -1,16 +1,6 @@ #!/usr/bin/env bash -echo $(bash --version 2>&1 | head -n 1) - -#CUSTOMPARAM=0 -BUILD_ARGUMENTS=() -for i in "$@"; do - case $(echo $1 | awk '{print tolower($0)}') in - # -custom-param) CUSTOMPARAM=1;; - *) BUILD_ARGUMENTS+=("$1") ;; - esac - shift -done +bash --version 2>&1 | head -n 1 set -eo pipefail SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) @@ -20,11 +10,53 @@ SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) ########################################################################### BUILD_PROJECT_FILE="$SCRIPT_DIR/nukebuild/_build.csproj" +TEMP_DIRECTORY="$SCRIPT_DIR//.nuke/temp" + +DOTNET_GLOBAL_FILE="$SCRIPT_DIR//global.json" +DOTNET_INSTALL_URL="https://dot.net/v1/dotnet-install.sh" +DOTNET_CHANNEL="Current" export DOTNET_CLI_TELEMETRY_OPTOUT=1 export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 -export NUGET_XMLDOC_MODE="skip" +export DOTNET_MULTILEVEL_LOOKUP=0 -dotnet --info +########################################################################### +# EXECUTION +########################################################################### -dotnet run --project "$BUILD_PROJECT_FILE" -- ${BUILD_ARGUMENTS[@]} +function FirstJsonValue { + perl -nle 'print $1 if m{"'"$1"'": "([^"]+)",?}' <<< "${@:2}" +} + +# If dotnet CLI is installed globally and it matches requested version, use for execution +if [ -x "$(command -v dotnet)" ] && dotnet --version &>/dev/null; then + export DOTNET_EXE="$(command -v dotnet)" +else + # Download install script + DOTNET_INSTALL_FILE="$TEMP_DIRECTORY/dotnet-install.sh" + mkdir -p "$TEMP_DIRECTORY" + curl -Lsfo "$DOTNET_INSTALL_FILE" "$DOTNET_INSTALL_URL" + chmod +x "$DOTNET_INSTALL_FILE" + + # If global.json exists, load expected version + if [[ -f "$DOTNET_GLOBAL_FILE" ]]; then + DOTNET_VERSION=$(FirstJsonValue "version" "$(cat "$DOTNET_GLOBAL_FILE")") + if [[ "$DOTNET_VERSION" == "" ]]; then + unset DOTNET_VERSION + fi + fi + + # Install by channel or version + DOTNET_DIRECTORY="$TEMP_DIRECTORY/dotnet-unix" + if [[ -z ${DOTNET_VERSION+x} ]]; then + "$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --channel "$DOTNET_CHANNEL" --no-path + else + "$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --version "$DOTNET_VERSION" --no-path + fi + export DOTNET_EXE="$DOTNET_DIRECTORY/dotnet" +fi + +echo "Microsoft (R) .NET SDK version $("$DOTNET_EXE" --version)" + +"$DOTNET_EXE" build "$BUILD_PROJECT_FILE" /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet +"$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" --no-build -- "$@" diff --git a/build/HarfBuzzSharp.props b/build/HarfBuzzSharp.props index 85e7a1f34d..620ec58ff3 100644 --- a/build/HarfBuzzSharp.props +++ b/build/HarfBuzzSharp.props @@ -1,7 +1,7 @@  - - - + + + diff --git a/build/NetAnalyzers.props b/build/NetAnalyzers.props new file mode 100644 index 0000000000..dfca9ecf9e --- /dev/null +++ b/build/NetAnalyzers.props @@ -0,0 +1,5 @@ + + + true + + diff --git a/build/ReactiveUI.props b/build/ReactiveUI.props index c3b136d41d..1911c02677 100644 --- a/build/ReactiveUI.props +++ b/build/ReactiveUI.props @@ -1,5 +1,5 @@ - + diff --git a/build/SharedVersion.props b/build/SharedVersion.props index 3d9548ab9d..1b60bb4df9 100644 --- a/build/SharedVersion.props +++ b/build/SharedVersion.props @@ -2,7 +2,7 @@ xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> Avalonia - 0.10.999 + 11.0.999 Copyright 2022 © The AvaloniaUI Project https://avaloniaui.net https://github.com/AvaloniaUI/Avalonia/ diff --git a/build/SkiaSharp.props b/build/SkiaSharp.props index d54cffba08..31619399f9 100644 --- a/build/SkiaSharp.props +++ b/build/SkiaSharp.props @@ -1,7 +1,7 @@  - - - + + + diff --git a/dirs.proj b/dirs.proj index 396e0c915c..f1eaae8a4a 100644 --- a/dirs.proj +++ b/dirs.proj @@ -9,17 +9,17 @@ - - - - - + + + + + @@ -27,6 +27,6 @@ - + diff --git a/global.json b/global.json index a6792b05c7..dc6da556b3 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "6.0.202", + "version": "7.0.100-rc.2.22477.23", "rollForward": "latestFeature" }, "msbuild-sdks": { diff --git a/native/Avalonia.Native/src/OSX/Screens.mm b/native/Avalonia.Native/src/OSX/Screens.mm index b9c75ed742..83ab1bfd01 100644 --- a/native/Avalonia.Native/src/OSX/Screens.mm +++ b/native/Avalonia.Native/src/OSX/Screens.mm @@ -41,9 +41,9 @@ public: ret->WorkingArea.X = [screen visibleFrame].origin.x; ret->WorkingArea.Y = ConvertPointY(ToAvnPoint([screen visibleFrame].origin)).Y - ret->WorkingArea.Height; - ret->PixelDensity = [screen backingScaleFactor]; + ret->Scaling = [screen backingScaleFactor]; - ret->Primary = index == 0; + ret->IsPrimary = index == 0; return S_OK; } diff --git a/native/Avalonia.Native/src/OSX/WindowImpl.mm b/native/Avalonia.Native/src/OSX/WindowImpl.mm index 95f61422cb..ddc50c26b6 100644 --- a/native/Avalonia.Native/src/OSX/WindowImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowImpl.mm @@ -91,8 +91,6 @@ HRESULT WindowImpl::SetParent(IAvnWindow *parent) { if(_parent != nullptr) { _parent->_children.remove(this); - - _parent->BringToFront(); } auto cparent = dynamic_cast(parent); @@ -121,7 +119,7 @@ void WindowImpl::BringToFront() { if(Window != nullptr) { - if (![Window isMiniaturized]) + if ([Window isVisible] && ![Window isMiniaturized]) { if(IsDialog()) { diff --git a/nukebuild/Build.cs b/nukebuild/Build.cs index 9fcb9d6b7f..7425c344c3 100644 --- a/nukebuild/Build.cs +++ b/nukebuild/Build.cs @@ -23,6 +23,7 @@ using static Nuke.Common.Tools.MSBuild.MSBuildTasks; using static Nuke.Common.Tools.DotNet.DotNetTasks; using static Nuke.Common.Tools.Xunit.XunitTasks; using static Nuke.Common.Tools.VSWhere.VSWhereTasks; +using MicroCom.CodeGenerator; /* Before editing this file, install support plugin for your IDE, @@ -36,25 +37,6 @@ partial class Build : NukeBuild { [Solution("Avalonia.sln")] readonly Solution Solution; - static Lazy MsBuildExe = new Lazy(() => - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - return null; - - var msBuildDirectory = VSWhere("-latest -nologo -property installationPath -format value -prerelease").FirstOrDefault().Text; - - if (!string.IsNullOrWhiteSpace(msBuildDirectory)) - { - string msBuildExe = Path.Combine(msBuildDirectory, @"MSBuild\Current\Bin\MSBuild.exe"); - if (!System.IO.File.Exists(msBuildExe)) - msBuildExe = Path.Combine(msBuildDirectory, @"MSBuild\15.0\Bin\MSBuild.exe"); - - return msBuildExe; - } - - return null; - }, false); - BuildParameters Parameters { get; set; } protected override void OnBuildInitialized() { @@ -89,25 +71,28 @@ partial class Build : NukeBuild } ExecWait("dotnet version:", "dotnet", "--info"); ExecWait("dotnet workloads:", "dotnet", "workload list"); + Information("Processor count: " + Environment.ProcessorCount); + Information("Available RAM: " + GC.GetGCMemoryInfo().TotalAvailableMemoryBytes / 0x100000 + "MB"); } - IReadOnlyCollection MsBuildCommon( - string projectFile, - Configure configurator = null) + DotNetConfigHelper ApplySettingCore(DotNetConfigHelper c) { - return MSBuild(c => c - .SetProjectFile(projectFile) - // This is required for VS2019 image on Azure Pipelines - .When(Parameters.IsRunningOnWindows && - Parameters.IsRunningOnAzure, _ => _ - .AddProperty("JavaSdkDirectory", GetVariable("JAVA_HOME_11_X64"))) - .AddProperty("PackageVersion", Parameters.Version) + if (Parameters.IsRunningOnAzure) + c.AddProperty("JavaSdkDirectory", GetVariable("JAVA_HOME_11_X64")); + c.AddProperty("PackageVersion", Parameters.Version) .AddProperty("iOSRoslynPathHackRequired", true) - .SetProcessToolPath(MsBuildExe.Value) .SetConfiguration(Parameters.Configuration) - .SetVerbosity(MSBuildVerbosity.Minimal) - .Apply(configurator)); + .SetVerbosity(DotNetVerbosity.Minimal); + return c; } + DotNetBuildSettings ApplySetting(DotNetBuildSettings c, Configure configurator = null) => + ApplySettingCore(c).Build.Apply(configurator); + + DotNetPackSettings ApplySetting(DotNetPackSettings c, Configure configurator = null) => + ApplySettingCore(c).Pack.Apply(configurator); + + DotNetTestSettings ApplySetting(DotNetTestSettings c, Configure configurator = null) => + ApplySettingCore(c).Test.Apply(configurator); Target Clean => _ => _.Executes(() => { @@ -149,20 +134,11 @@ partial class Build : NukeBuild Target Compile => _ => _ .DependsOn(Clean, CompileNative) .DependsOn(CompileHtmlPreviewer) - .Executes(async () => + .Executes(() => { - if (Parameters.IsRunningOnWindows) - MsBuildCommon(Parameters.MSBuildSolution, c => c - .SetProcessArgumentConfigurator(a => a.Add("/r")) - .AddTargets("Build") - ); - - else - DotNetBuild(c => c - .SetProjectFile(Parameters.MSBuildSolution) - .AddProperty("PackageVersion", Parameters.Version) - .SetConfiguration(Parameters.Configuration) - ); + DotNetBuild(c => ApplySetting(c) + .SetProjectFile(Parameters.MSBuildSolution) + ); }); void RunCoreTest(string projectName) @@ -182,14 +158,13 @@ partial class Build : NukeBuild Information($"Running for {projectName} ({fw}) ..."); - DotNetTest(c => c + DotNetTest(c => ApplySetting(c) .SetProjectFile(project) - .SetConfiguration(Parameters.Configuration) .SetFramework(fw) .EnableNoBuild() .EnableNoRestore() .When(Parameters.PublishTestResults, _ => _ - .SetLogger("trx") + .SetLoggers("trx") .SetResultsDirectory(Parameters.TestResultsRoot))); } } @@ -241,8 +216,6 @@ partial class Build : NukeBuild RunCoreTest("Avalonia.DesignerSupport.Tests"); }); - [PackageExecutable("JetBrains.dotMemoryUnit", "dotMemoryUnit.exe")] readonly Tool DotMemoryUnit; - Target RunLeakTests => _ => _ .OnlyWhenStatic(() => !Parameters.SkipTests && Parameters.IsRunningOnWindows) .DependsOn(Compile) @@ -250,12 +223,9 @@ partial class Build : NukeBuild { void DoMemoryTest() { - var testAssembly = "tests\\Avalonia.LeakTests\\bin\\Release\\net461\\Avalonia.LeakTests.dll"; - DotMemoryUnit( - $"{XunitPath.DoubleQuoteIfNeeded()} --propagate-exit-code -- {testAssembly}", - timeout: 120_000); + RunCoreTest("Avalonia.LeakTests"); } - ControlFlow.ExecuteWithRetry(DoMemoryTest, waitInSeconds: 3); + ControlFlow.ExecuteWithRetry(DoMemoryTest, delay: TimeSpan.FromMilliseconds(3)); }); Target ZipFiles => _ => _ @@ -263,19 +233,7 @@ partial class Build : NukeBuild .Executes(() => { var data = Parameters; - var pathToProjectSource = RootDirectory / "samples" / "ControlCatalog.NetCore"; - var pathToPublish = pathToProjectSource / "bin" / data.Configuration / "publish"; - - DotNetPublish(c => c - .SetProject(pathToProjectSource / "ControlCatalog.NetCore.csproj") - .EnableNoBuild() - .SetConfiguration(data.Configuration) - .AddProperty("PackageVersion", data.Version) - .AddProperty("PublishDir", pathToPublish)); - - Zip(data.ZipCoreArtifacts, data.BinRoot); Zip(data.ZipNuGetArtifacts, data.NugetRoot); - Zip(data.ZipTargetControlCatalogNetCoreDir, pathToPublish); }); Target CreateIntermediateNugetPackages => _ => _ @@ -283,15 +241,7 @@ partial class Build : NukeBuild .After(RunTests) .Executes(() => { - if (Parameters.IsRunningOnWindows) - - MsBuildCommon(Parameters.MSBuildSolution, c => c - .AddTargets("Pack")); - else - DotNetPack(c => c - .SetProject(Parameters.MSBuildSolution) - .SetConfiguration(Parameters.Configuration) - .AddProperty("PackageVersion", Parameters.Version)); + DotNetPack(c => ApplySetting(c).SetProject(Parameters.MSBuildSolution)); }); Target CreateNugetPackages => _ => _ @@ -329,6 +279,14 @@ partial class Build : NukeBuild .DependsOn(Package) .DependsOn(ZipFiles); + Target GenerateCppHeaders => _ => _.Executes(() => + { + var file = MicroComCodeGenerator.Parse( + File.ReadAllText(RootDirectory / "src" / "Avalonia.Native" / "avn.idl")); + File.WriteAllText(RootDirectory / "native" / "Avalonia.Native" / "inc" / "avalonia-native.h", + file.GenerateCppHeader()); + }); + public static int Main() => RuntimeInformation.IsOSPlatform(OSPlatform.Windows) diff --git a/nukebuild/BuildParameters.cs b/nukebuild/BuildParameters.cs index a92c988fbd..dfa914d1db 100644 --- a/nukebuild/BuildParameters.cs +++ b/nukebuild/BuildParameters.cs @@ -51,14 +51,12 @@ public partial class Build public AbsolutePath NugetIntermediateRoot { get; } public AbsolutePath NugetRoot { get; } public AbsolutePath ZipRoot { get; } - public AbsolutePath BinRoot { get; } public AbsolutePath TestResultsRoot { get; } public string DirSuffix { get; } public List BuildDirs { get; } public string FileZipSuffix { get; } public AbsolutePath ZipCoreArtifacts { get; } public AbsolutePath ZipNuGetArtifacts { get; } - public AbsolutePath ZipTargetControlCatalogNetCoreDir { get; } public BuildParameters(Build b) @@ -76,11 +74,11 @@ public partial class Build MSBuildSolution = RootDirectory / "dirs.proj"; // PARAMETERS - IsLocalBuild = Host == HostType.Console; + IsLocalBuild = NukeBuild.IsLocalBuild; IsRunningOnUnix = Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX; IsRunningOnWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); - IsRunningOnAzure = Host == HostType.AzurePipelines || + IsRunningOnAzure = Host is AzurePipelines || Environment.GetEnvironmentVariable("LOGNAME") == "vsts"; if (IsRunningOnAzure) @@ -121,14 +119,12 @@ public partial class Build NugetRoot = ArtifactsDir / "nuget"; NugetIntermediateRoot = RootDirectory / "build-intermediate" / "nuget"; ZipRoot = ArtifactsDir / "zip"; - BinRoot = ArtifactsDir / "bin"; TestResultsRoot = ArtifactsDir / "test-results"; BuildDirs = GlobDirectories(RootDirectory, "**bin").Concat(GlobDirectories(RootDirectory, "**obj")).ToList(); DirSuffix = Configuration; FileZipSuffix = Version + ".zip"; ZipCoreArtifacts = ZipRoot / ("Avalonia-" + FileZipSuffix); ZipNuGetArtifacts = ZipRoot / ("Avalonia-NuGet-" + FileZipSuffix); - ZipTargetControlCatalogNetCoreDir = ZipRoot / ("ControlCatalog.NetCore-" + FileZipSuffix); } string GetVersion() diff --git a/nukebuild/BuildTasksPatcher.cs b/nukebuild/BuildTasksPatcher.cs index e3766ae23f..5fd331035a 100644 --- a/nukebuild/BuildTasksPatcher.cs +++ b/nukebuild/BuildTasksPatcher.cs @@ -17,8 +17,12 @@ public class BuildTasksPatcher { if (entry.Name == "Avalonia.Build.Tasks.dll") { - var temp = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".dll"); + var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + Directory.CreateDirectory(tempDir); + var temp = Path.Combine(tempDir, Guid.NewGuid() + ".dll"); var output = temp + ".output"; + File.Copy(typeof(Microsoft.Build.Framework.ITask).Assembly.GetModules()[0].FullyQualifiedName, + Path.Combine(tempDir, "Microsoft.Build.Framework.dll")); var patched = new MemoryStream(); try { @@ -57,10 +61,8 @@ public class BuildTasksPatcher { try { - if (File.Exists(temp)) - File.Delete(temp); - if (File.Exists(output)) - File.Delete(output); + if(Directory.Exists(tempDir)) + Directory.Delete(tempDir, true); } catch { diff --git a/nukebuild/DotNetConfigHelper.cs b/nukebuild/DotNetConfigHelper.cs new file mode 100644 index 0000000000..eca1e2684d --- /dev/null +++ b/nukebuild/DotNetConfigHelper.cs @@ -0,0 +1,57 @@ +using System.Globalization; +using JetBrains.Annotations; +using Nuke.Common.Tools.DotNet; +// ReSharper disable ReturnValueOfPureMethodIsNotUsed + +public class DotNetConfigHelper +{ + public DotNetBuildSettings Build; + public DotNetPackSettings Pack; + public DotNetTestSettings Test; + + public DotNetConfigHelper(DotNetBuildSettings s) + { + Build = s; + } + + public DotNetConfigHelper(DotNetPackSettings s) + { + Pack = s; + } + + public DotNetConfigHelper(DotNetTestSettings s) + { + Test = s; + } + + public DotNetConfigHelper AddProperty(string key, bool value) => + AddProperty(key, value.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()); + public DotNetConfigHelper AddProperty(string key, string value) + { + Build = Build?.AddProperty(key, value); + Pack = Pack?.AddProperty(key, value); + Test = Test?.AddProperty(key, value); + + return this; + } + + public DotNetConfigHelper SetConfiguration(string configuration) + { + Build = Build?.SetConfiguration(configuration); + Pack = Pack?.SetConfiguration(configuration); + Test = Test?.SetConfiguration(configuration); + return this; + } + + public DotNetConfigHelper SetVerbosity(DotNetVerbosity verbosity) + { + Build = Build?.SetVerbosity(verbosity); + Pack = Pack?.SetVerbosity(verbosity); + Test = Test?.SetVerbosity(verbosity); + return this; + } + + public static implicit operator DotNetConfigHelper(DotNetBuildSettings s) => new DotNetConfigHelper(s); + public static implicit operator DotNetConfigHelper(DotNetPackSettings s) => new DotNetConfigHelper(s); + public static implicit operator DotNetConfigHelper(DotNetTestSettings s) => new DotNetConfigHelper(s); +} diff --git a/nukebuild/MicroComGen.cs b/nukebuild/MicroComGen.cs deleted file mode 100644 index b1e546cb97..0000000000 --- a/nukebuild/MicroComGen.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.IO; -using MicroCom.CodeGenerator; -using Nuke.Common; - -partial class Build : NukeBuild -{ - Target GenerateCppHeaders => _ => _.Executes(() => - { - var file = MicroComCodeGenerator.Parse( - File.ReadAllText(RootDirectory / "src" / "Avalonia.Native" / "avn.idl")); - File.WriteAllText(RootDirectory / "native" / "Avalonia.Native" / "inc" / "avalonia-native.h", - file.GenerateCppHeader()); - }); -} \ No newline at end of file diff --git a/nukebuild/Shims.cs b/nukebuild/Shims.cs index 1ac14bf622..6f79972ad6 100644 --- a/nukebuild/Shims.cs +++ b/nukebuild/Shims.cs @@ -49,7 +49,11 @@ public partial class Build { if (fsEntry is FileInfo) { +#if NET6 var relPath = Path.GetRelativePath(rootPath, fsEntry.FullName); +#else + var relPath = GetRelativePath(rootPath, fsEntry.FullName); +#endif AddFile(fsEntry.FullName, relPath); } } @@ -78,6 +82,17 @@ public partial class Build } } + private static string GetRelativePath(string relativeTo, string path) + { + var uri = new Uri(relativeTo); + var rel = Uri.UnescapeDataString(uri.MakeRelativeUri(new Uri(path)).ToString()).Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); + if (rel.Contains(Path.DirectorySeparatorChar.ToString()) == false) + { + rel = $".{Path.DirectorySeparatorChar}{rel}"; + } + return rel; + } + class NumergeNukeLogger : INumergeLogger { public void Log(NumergeLogLevel level, string message) diff --git a/nukebuild/_build.csproj b/nukebuild/_build.csproj index b2c58e2292..8c0d824298 100644 --- a/nukebuild/_build.csproj +++ b/nukebuild/_build.csproj @@ -1,41 +1,48 @@  - Exe - netcoreapp3.1 false False - CS0649;CS0169 + CS0649;CS0169;SYSLIB0011 + 1 + net7.0 + - - + - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + - - - - - - - - - - + + + + + + + + + + + + diff --git a/nukebuild/il-repack b/nukebuild/il-repack new file mode 160000 index 0000000000..892f079ea8 --- /dev/null +++ b/nukebuild/il-repack @@ -0,0 +1 @@ +Subproject commit 892f079ea8cb0c178f0a68f53a7a7eac13acdda9 diff --git a/packages/Avalonia/AvaloniaBuildTasks.targets b/packages/Avalonia/AvaloniaBuildTasks.targets index d43a5c1624..4b9e33ffe8 100644 --- a/packages/Avalonia/AvaloniaBuildTasks.targets +++ b/packages/Avalonia/AvaloniaBuildTasks.targets @@ -3,7 +3,6 @@ <_AvaloniaUseExternalMSBuild>$(AvaloniaUseExternalMSBuild) <_AvaloniaUseExternalMSBuild Condition="'$(_AvaloniaForceInternalMSBuild)' == 'true'">false low - <_AvaloniaPatchComInterop Condition="'$(_AvaloniaPatchComInterop)' == ''">false <_AvaloniaSkipXamlCompilation Condition="'$(_AvaloniaSkipXamlCompilation)' == ''">false @@ -71,7 +70,6 @@ Output="$(AvaloniaResourcesTemporaryFilePath)" Root="$(MSBuildProjectDirectory)" Resources="@(AvaloniaResource)" - EmbeddedResources="@(EmbeddedResources)" ReportImportance="$(AvaloniaXamlReportImportance)"/> diff --git a/samples/ControlCatalog.Android/MainActivity.cs b/samples/ControlCatalog.Android/MainActivity.cs index 33ca511340..62c582610c 100644 --- a/samples/ControlCatalog.Android/MainActivity.cs +++ b/samples/ControlCatalog.Android/MainActivity.cs @@ -5,16 +5,8 @@ using Avalonia.Android; namespace ControlCatalog.Android { - [Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleInstance, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)] - public class MainActivity : AvaloniaActivity + [Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)] + public class MainActivity : AvaloniaMainActivity { - protected override AppBuilder CustomizeAppBuilder(AppBuilder builder) - { - return base.CustomizeAppBuilder(builder) - .AfterSetup(_ => - { - Pages.EmbedSample.Implementation = new EmbedSampleAndroid(); - }); - } } } diff --git a/samples/ControlCatalog.Android/SplashActivity.cs b/samples/ControlCatalog.Android/SplashActivity.cs index dc292fd37b..908b5f082a 100644 --- a/samples/ControlCatalog.Android/SplashActivity.cs +++ b/samples/ControlCatalog.Android/SplashActivity.cs @@ -1,12 +1,23 @@ 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 : Activity + public class SplashActivity : AvaloniaSplashActivity { + 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); diff --git a/samples/ControlCatalog.Web/App.razor b/samples/ControlCatalog.Blazor.Web/App.razor similarity index 100% rename from samples/ControlCatalog.Web/App.razor rename to samples/ControlCatalog.Blazor.Web/App.razor diff --git a/samples/ControlCatalog.Blazor.Web/App.razor.cs b/samples/ControlCatalog.Blazor.Web/App.razor.cs new file mode 100644 index 0000000000..8cc0095f20 --- /dev/null +++ b/samples/ControlCatalog.Blazor.Web/App.razor.cs @@ -0,0 +1,17 @@ +using Avalonia; +using Avalonia.Web.Blazor; + +namespace ControlCatalog.Blazor.Web; + +public partial class App +{ + protected override void OnParametersSet() + { + AppBuilder.Configure() + .UseBlazor() + // .With(new SkiaOptions { CustomGpuFactory = null }) // uncomment to disable GPU/GL rendering + .SetupWithSingleViewLifetime(); + + base.OnParametersSet(); + } +} diff --git a/samples/ControlCatalog.Blazor.Web/ControlCatalog.Blazor.Web.csproj b/samples/ControlCatalog.Blazor.Web/ControlCatalog.Blazor.Web.csproj new file mode 100644 index 0000000000..03fb31f0d3 --- /dev/null +++ b/samples/ControlCatalog.Blazor.Web/ControlCatalog.Blazor.Web.csproj @@ -0,0 +1,29 @@ + + + net7.0 + browser-wasm + enable + 16777216 + false + false + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/ControlCatalog.Web/Pages/Index.razor b/samples/ControlCatalog.Blazor.Web/Pages/Index.razor similarity index 100% rename from samples/ControlCatalog.Web/Pages/Index.razor rename to samples/ControlCatalog.Blazor.Web/Pages/Index.razor diff --git a/samples/ControlCatalog.Blazor.Web/Program.cs b/samples/ControlCatalog.Blazor.Web/Program.cs new file mode 100644 index 0000000000..d71b125fa1 --- /dev/null +++ b/samples/ControlCatalog.Blazor.Web/Program.cs @@ -0,0 +1,29 @@ +using System; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +using Microsoft.Extensions.DependencyInjection; +using ControlCatalog.Blazor.Web; + +public class Program +{ + public static async Task Main(string[] args) + { + await CreateHostBuilder(args).Build().RunAsync(); + } + + public static WebAssemblyHostBuilder CreateHostBuilder(string[] args) + { + var builder = WebAssemblyHostBuilder.CreateDefault(args); + + builder.RootComponents.Add("#app"); + + builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); + + return builder; + } +} + + + + diff --git a/samples/ControlCatalog.Web/Properties/launchSettings.json b/samples/ControlCatalog.Blazor.Web/Properties/launchSettings.json similarity index 100% rename from samples/ControlCatalog.Web/Properties/launchSettings.json rename to samples/ControlCatalog.Blazor.Web/Properties/launchSettings.json diff --git a/samples/ControlCatalog.Web/Shared/MainLayout.razor b/samples/ControlCatalog.Blazor.Web/Shared/MainLayout.razor similarity index 100% rename from samples/ControlCatalog.Web/Shared/MainLayout.razor rename to samples/ControlCatalog.Blazor.Web/Shared/MainLayout.razor diff --git a/samples/ControlCatalog.Web/_Imports.razor b/samples/ControlCatalog.Blazor.Web/_Imports.razor similarity index 85% rename from samples/ControlCatalog.Web/_Imports.razor rename to samples/ControlCatalog.Blazor.Web/_Imports.razor index 04c7a8690e..0e6d11b419 100644 --- a/samples/ControlCatalog.Web/_Imports.razor +++ b/samples/ControlCatalog.Blazor.Web/_Imports.razor @@ -6,6 +6,5 @@ @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.AspNetCore.Components.WebAssembly.Http @using Microsoft.JSInterop -@using ControlCatalog.Web -@using ControlCatalog.Web.Shared +@using ControlCatalog.Blazor.Web.Shared @using SkiaSharp diff --git a/samples/ControlCatalog.Web/wwwroot/css/app.css b/samples/ControlCatalog.Blazor.Web/wwwroot/css/app.css similarity index 100% rename from samples/ControlCatalog.Web/wwwroot/css/app.css rename to samples/ControlCatalog.Blazor.Web/wwwroot/css/app.css diff --git a/samples/ControlCatalog.Web/wwwroot/favicon.ico b/samples/ControlCatalog.Blazor.Web/wwwroot/favicon.ico similarity index 100% rename from samples/ControlCatalog.Web/wwwroot/favicon.ico rename to samples/ControlCatalog.Blazor.Web/wwwroot/favicon.ico diff --git a/samples/ControlCatalog.Web/wwwroot/index.html b/samples/ControlCatalog.Blazor.Web/wwwroot/index.html similarity index 93% rename from samples/ControlCatalog.Web/wwwroot/index.html rename to samples/ControlCatalog.Blazor.Web/wwwroot/index.html index 7ea600673a..cad9123836 100644 --- a/samples/ControlCatalog.Web/wwwroot/index.html +++ b/samples/ControlCatalog.Blazor.Web/wwwroot/index.html @@ -17,7 +17,6 @@ Reload 🗙 - diff --git a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj b/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj index 0667644643..6c17e9ac43 100644 --- a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj +++ b/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj @@ -5,6 +5,7 @@ net6.0 true true + 6.0.9 diff --git a/samples/ControlCatalog.NetCore/Program.cs b/samples/ControlCatalog.NetCore/Program.cs index d98a068d84..b1bacc6483 100644 --- a/samples/ControlCatalog.NetCore/Program.cs +++ b/samples/ControlCatalog.NetCore/Program.cs @@ -115,10 +115,6 @@ namespace ControlCatalog.NetCore UseDBusMenu = true, EnableIme = true }) - .With(new Win32PlatformOptions - { - EnableMultitouch = true - }) .UseSkia() .AfterSetup(builder => { diff --git a/samples/ControlCatalog.Web/App.razor.cs b/samples/ControlCatalog.Web/App.razor.cs deleted file mode 100644 index 560e8079a6..0000000000 --- a/samples/ControlCatalog.Web/App.razor.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Avalonia.Web.Blazor; - -namespace ControlCatalog.Web; - -public partial class App -{ - protected override void OnParametersSet() - { - WebAppBuilder.Configure() - .AfterSetup(_ => - { - ControlCatalog.Pages.EmbedSample.Implementation = new EmbedSampleWeb(); - }) - //.With(new SkiaOptions { CustomGpuFactory = null }) // uncomment to disable GPU/GL rendering - .SetupWithSingleViewLifetime(); - - base.OnParametersSet(); - } -} diff --git a/samples/ControlCatalog.Web/ControlCatalog.Web.csproj b/samples/ControlCatalog.Web/ControlCatalog.Web.csproj index b2c9ec72eb..06a5466619 100644 --- a/samples/ControlCatalog.Web/ControlCatalog.Web.csproj +++ b/samples/ControlCatalog.Web/ControlCatalog.Web.csproj @@ -1,57 +1,44 @@ - + - net6.0 - enable - - true - 16777216 - false - false + net7.0 + browser-wasm + main.js + Exe + true + true + true + -sVERBOSE -sERROR_ON_UNDEFINED_SYMBOLS=0 - - - false - -O1 - false - - - - true - true - -O3 - -O3 - false - false - false - false - false - false - true - false - true - true + + true true - link - true + full + true + true + -O2 + -O2 - - + - + - - - - - + + + + + + + + + + - diff --git a/samples/ControlCatalog.Web/EmbedSample.Browser.cs b/samples/ControlCatalog.Web/EmbedSample.Browser.cs index 5fe14409de..5cfbb608cc 100644 --- a/samples/ControlCatalog.Web/EmbedSample.Browser.cs +++ b/samples/ControlCatalog.Web/EmbedSample.Browser.cs @@ -1,34 +1,42 @@ using System; - -using Avalonia; +using System.Runtime.InteropServices.JavaScript; using Avalonia.Platform; -using Avalonia.Web.Blazor; +using Avalonia.Web; using ControlCatalog.Pages; -using Microsoft.JSInterop; - namespace ControlCatalog.Web; public class EmbedSampleWeb : INativeDemoControl { public IPlatformHandle CreateControl(bool isSecond, IPlatformHandle parent, Func createDefault) { - var runtime = AvaloniaLocator.Current.GetRequiredService(); - if (isSecond) { - var iframe = runtime.Invoke("document.createElement", "iframe"); - iframe.InvokeVoid("setAttribute", "src", "https://www.youtube.com/embed/kZCIporjJ70"); + var iframe = EmbedInterop.CreateElement("iframe"); + iframe.SetProperty("src", "https://www.youtube.com/embed/kZCIporjJ70"); return new JSObjectControlHandle(iframe); } else { - // window.createAppButton source is defined in "app.js" file. - var button = runtime.Invoke("window.createAppButton"); + var defaultHandle = (JSObjectControlHandle)createDefault(); + + _ = JSHost.ImportAsync("embed.js", "./embed.js").ContinueWith(_ => + { + EmbedInterop.AddAppButton(defaultHandle.Object); + }); - return new JSObjectControlHandle(button); + return defaultHandle; } } } + +internal static partial class EmbedInterop +{ + [JSImport("globalThis.document.createElement")] + public static partial JSObject CreateElement(string tagName); + + [JSImport("addAppButton", "embed.js")] + public static partial void AddAppButton(JSObject parentObject); +} diff --git a/samples/ControlCatalog.Web/Logo.svg b/samples/ControlCatalog.Web/Logo.svg new file mode 100644 index 0000000000..9685a23af1 --- /dev/null +++ b/samples/ControlCatalog.Web/Logo.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/samples/ControlCatalog.Web/Program.cs b/samples/ControlCatalog.Web/Program.cs index d1a7925813..7d05c8e462 100644 --- a/samples/ControlCatalog.Web/Program.cs +++ b/samples/ControlCatalog.Web/Program.cs @@ -1,29 +1,22 @@ -using System; -using System.Net.Http; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Components.WebAssembly.Hosting; -using Microsoft.Extensions.DependencyInjection; +using System.Runtime.Versioning; +using Avalonia; +using Avalonia.Web; +using ControlCatalog; using ControlCatalog.Web; -public class Program +[assembly:SupportedOSPlatform("browser")] + +internal partial class Program { - public static async Task Main(string[] args) + private static void Main(string[] args) { - await CreateHostBuilder(args).Build().RunAsync(); + BuildAvaloniaApp() + .AfterSetup(_ => + { + ControlCatalog.Pages.EmbedSample.Implementation = new EmbedSampleWeb(); + }).SetupBrowserApp("out"); } - public static WebAssemblyHostBuilder CreateHostBuilder(string[] args) - { - var builder = WebAssemblyHostBuilder.CreateDefault(args); - - builder.RootComponents.Add("#app"); - - builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); - - return builder; - } + public static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure(); } - - - - diff --git a/samples/ControlCatalog.Web/Roots.xml b/samples/ControlCatalog.Web/Roots.xml new file mode 100644 index 0000000000..b07fd86fa2 --- /dev/null +++ b/samples/ControlCatalog.Web/Roots.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/samples/ControlCatalog.Web/app.css b/samples/ControlCatalog.Web/app.css new file mode 100644 index 0000000000..27680f6e1a --- /dev/null +++ b/samples/ControlCatalog.Web/app.css @@ -0,0 +1,49 @@ +#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; + } +} diff --git a/samples/ControlCatalog.Web/wwwroot/js/app.js b/samples/ControlCatalog.Web/embed.js similarity index 59% rename from samples/ControlCatalog.Web/wwwroot/js/app.js rename to samples/ControlCatalog.Web/embed.js index 29697661a6..f393c80314 100644 --- a/samples/ControlCatalog.Web/wwwroot/js/app.js +++ b/samples/ControlCatalog.Web/embed.js @@ -1,10 +1,11 @@ -window.createAppButton = function () { - var button = document.createElement('button'); +export function addAppButton(parent) { + var button = globalThis.document.createElement('button'); button.innerText = 'Hello world'; var clickCount = 0; button.onclick = () => { clickCount++; button.innerText = 'Click count ' + clickCount; }; + parent.appendChild(button); return button; } diff --git a/samples/ControlCatalog.Web/favicon.ico b/samples/ControlCatalog.Web/favicon.ico new file mode 100644 index 0000000000..da8d49ff9b Binary files /dev/null and b/samples/ControlCatalog.Web/favicon.ico differ diff --git a/samples/ControlCatalog.Web/index.html b/samples/ControlCatalog.Web/index.html new file mode 100644 index 0000000000..226ae70695 --- /dev/null +++ b/samples/ControlCatalog.Web/index.html @@ -0,0 +1,31 @@ + + + + + + + AvaloniaUI - ControlCatalog + + + + + + + + + +
+
+
+

Powered by

+ + Avalonia Logo + Avalonia + +
+
+
+ + + + diff --git a/samples/ControlCatalog.Web/main.js b/samples/ControlCatalog.Web/main.js new file mode 100644 index 0000000000..87f8a4f943 --- /dev/null +++ b/samples/ControlCatalog.Web/main.js @@ -0,0 +1,19 @@ +// 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' +import { registerAvaloniaModule } from './avalonia.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(); + +await registerAvaloniaModule(dotnetRuntime); + +const config = dotnetRuntime.getConfig(); + +await dotnetRuntime.runMainAndExit(config.mainAssemblyName, ["dotnet", "is", "great!"]); diff --git a/samples/ControlCatalog.Web/runtimeconfig.template.json b/samples/ControlCatalog.Web/runtimeconfig.template.json new file mode 100644 index 0000000000..8f0557352c --- /dev/null +++ b/samples/ControlCatalog.Web/runtimeconfig.template.json @@ -0,0 +1,11 @@ +{ + "wasmHostProperties": { + "perHostConfig": [ + { + "name": "browser", + "html-path": "index.html", + "Host": "browser" + } + ] + } +} diff --git a/samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj b/samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj index 513ac44f83..74d5b2fd8c 100644 --- a/samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj +++ b/samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj @@ -9,6 +9,9 @@ iossimulator-x64
+ + iPhone Developer + diff --git a/samples/ControlCatalog/Converter/HexConverter.cs b/samples/ControlCatalog/Converter/HexConverter.cs new file mode 100644 index 0000000000..31cce5ba67 --- /dev/null +++ b/samples/ControlCatalog/Converter/HexConverter.cs @@ -0,0 +1,34 @@ +using System; +using System.Globalization; +using Avalonia; +using Avalonia.Data.Converters; + +namespace ControlCatalog.Converter; + +public class HexConverter : IValueConverter +{ + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + var str = value?.ToString(); + if (str == null) + return AvaloniaProperty.UnsetValue; + if (int.TryParse(str, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int x)) + return (decimal)x; + return AvaloniaProperty.UnsetValue; + + } + + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + try + { + if (value is decimal d) + return ((int)d).ToString("X8"); + return AvaloniaProperty.UnsetValue; + } + catch + { + return AvaloniaProperty.UnsetValue; + } + } +} diff --git a/samples/ControlCatalog/DecoratedWindow.xaml b/samples/ControlCatalog/DecoratedWindow.xaml index 5251a2fa55..c778b31c42 100644 --- a/samples/ControlCatalog/DecoratedWindow.xaml +++ b/samples/ControlCatalog/DecoratedWindow.xaml @@ -2,7 +2,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="ControlCatalog.DecoratedWindow" Title="Avalonia Control Gallery" - xmlns:local="clr-namespace:ControlCatalog" HasSystemDecorations="False" Name="Window"> + xmlns:local="clr-namespace:ControlCatalog" SystemDecorations="None" Name="Window"> diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml index 7f5a191519..ec198c6bba 100644 --- a/samples/ControlCatalog/MainView.xaml +++ b/samples/ControlCatalog/MainView.xaml @@ -19,6 +19,9 @@ + + + diff --git a/samples/ControlCatalog/MainView.xaml.cs b/samples/ControlCatalog/MainView.xaml.cs index 58433f13ce..7001eb41ea 100644 --- a/samples/ControlCatalog/MainView.xaml.cs +++ b/samples/ControlCatalog/MainView.xaml.cs @@ -2,10 +2,10 @@ using System; using System.Collections; using Avalonia; using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using Avalonia.Media; using Avalonia.Media.Immutable; -using Avalonia.Platform; using Avalonia.Themes.Fluent; using ControlCatalog.Models; using ControlCatalog.Pages; @@ -20,15 +20,14 @@ namespace ControlCatalog var sideBar = this.Get("Sidebar"); - if (AvaloniaLocator.Current?.GetService()?.GetRuntimeInfo().IsDesktop == true) + if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime) { - IList tabItems = ((IList)sideBar.Items); - tabItems.Add(new TabItem() + var tabItems = (sideBar.Items as IList); + tabItems?.Add(new TabItem() { Header = "Screens", Content = new ScreenPage() }); - } var themes = this.Get("Themes"); @@ -36,7 +35,7 @@ namespace ControlCatalog { if (themes.SelectedItem is CatalogTheme theme) { - var themeStyle = Application.Current.Styles[0]; + var themeStyle = Application.Current!.Styles[0]; if (theme == CatalogTheme.FluentLight) { if (App.Fluent.Mode != FluentThemeMode.Light) diff --git a/samples/ControlCatalog/MainWindow.xaml b/samples/ControlCatalog/MainWindow.xaml index 1e4bf2de38..d5513904c0 100644 --- a/samples/ControlCatalog/MainWindow.xaml +++ b/samples/ControlCatalog/MainWindow.xaml @@ -18,15 +18,15 @@ - - + + + Click="OnCloseClicked" /> diff --git a/samples/ControlCatalog/Models/Person.cs b/samples/ControlCatalog/Models/Person.cs index 2dfa02c7ed..99bc50250b 100644 --- a/samples/ControlCatalog/Models/Person.cs +++ b/samples/ControlCatalog/Models/Person.cs @@ -85,7 +85,7 @@ namespace ControlCatalog.Models } else { - if (_errorLookup.TryGetValue(propertyName, out List errorList)) + if (_errorLookup.TryGetValue(propertyName, out var errorList)) { errorList.Clear(); errorList.Add(error!); @@ -114,12 +114,12 @@ namespace ControlCatalog.Models PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } - public IEnumerable? GetErrors(string propertyName) + public IEnumerable GetErrors(string? propertyName) { - if (_errorLookup.TryGetValue(propertyName, out List errorList)) + if (propertyName is { } && _errorLookup.TryGetValue(propertyName, out var errorList)) return errorList; else - return null; + return Array.Empty(); } } } diff --git a/samples/ControlCatalog/Pages/AdornerLayerPage.xaml b/samples/ControlCatalog/Pages/AdornerLayerPage.xaml new file mode 100644 index 0000000000..598844d695 --- /dev/null +++ b/samples/ControlCatalog/Pages/AdornerLayerPage.xaml @@ -0,0 +1,66 @@ + + + + + Rotation + + + + + + + + + + + diff --git a/samples/ControlCatalog/Pages/AdornerLayerPage.xaml.cs b/samples/ControlCatalog/Pages/AdornerLayerPage.xaml.cs new file mode 100644 index 0000000000..0cf4a6633c --- /dev/null +++ b/samples/ControlCatalog/Pages/AdornerLayerPage.xaml.cs @@ -0,0 +1,48 @@ +using Avalonia.Controls; +using Avalonia.Controls.Primitives; +using Avalonia.Interactivity; +using Avalonia.Markup.Xaml; + +namespace ControlCatalog.Pages +{ + public class AdornerLayerPage : UserControl + { + private Control? _adorner; + + public AdornerLayerPage() + { + this.InitializeComponent(); + } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } + + private void RemoveAdorner_OnClick(object? sender, RoutedEventArgs e) + { + var adornerButton = this.FindControl