diff --git a/.editorconfig b/.editorconfig index a3f524f8b0..9ae52b8bbd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -137,8 +137,16 @@ space_within_single_line_array_initializer_braces = true #Net Analyzer dotnet_analyzer_diagnostic.category-Performance.severity = none #error - Uncomment when all violations are fixed. -#CA1825: Avoid zero-length array allocations +# 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 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/.gitignore b/.gitignore index 61a3b53de1..bbf358b8f4 100644 --- a/.gitignore +++ b/.gitignore @@ -210,9 +210,9 @@ coc-settings.json .ccls-cache .ccls *.map -src/Web/Avalonia.Web.Blazor/wwwroot/*.js -src/Web/Avalonia.Web.Blazor/Interop/Typescript/*.js +src/Browser/Avalonia.Browser.Blazor/wwwroot/*.js +src/Browser/Avalonia.Browser.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 +src/Browser/Avalonia.Browser.Blazor/webapp/package-lock.json +src/Browser/Avalonia.Browser.Blazor/wwwroot +src/Browser/Avalonia.Browser/wwwroot diff --git a/.ncrunch/Avalonia.Web.Blazor.v3.ncrunchproject b/.ncrunch/Avalonia.Web.Blazor.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/Avalonia.Web.Blazor.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/Avalonia.Web.v3.ncrunchproject b/.ncrunch/Avalonia.Web.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/Avalonia.Web.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/Avalonia.Win32.net6.0.v3.ncrunchproject b/.ncrunch/Avalonia.Win32.net6.0.v3.ncrunchproject index 28b692bb51..95a483b433 100644 --- a/.ncrunch/Avalonia.Win32.net6.0.v3.ncrunchproject +++ b/.ncrunch/Avalonia.Win32.net6.0.v3.ncrunchproject @@ -1,7 +1,3 @@  - - - ..\..\tools\MicroComGenerator\bin\Debug\net6.0\**.* - - + \ No newline at end of file diff --git a/.ncrunch/Avalonia.Win32.netstandard2.0.v3.ncrunchproject b/.ncrunch/Avalonia.Win32.netstandard2.0.v3.ncrunchproject index 28b692bb51..95a483b433 100644 --- a/.ncrunch/Avalonia.Win32.netstandard2.0.v3.ncrunchproject +++ b/.ncrunch/Avalonia.Win32.netstandard2.0.v3.ncrunchproject @@ -1,7 +1,3 @@  - - - ..\..\tools\MicroComGenerator\bin\Debug\net6.0\**.* - - + \ No newline at end of file diff --git a/.ncrunch/ControlCatalog.Blazor.Web.v3.ncrunchproject b/.ncrunch/ControlCatalog.Blazor.Web.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/ControlCatalog.Blazor.Web.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/MobileSandbox.Android.v3.ncrunchproject b/.ncrunch/MobileSandbox.Android.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/MobileSandbox.Android.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/MobileSandbox.Desktop.v3.ncrunchproject b/.ncrunch/MobileSandbox.Desktop.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/MobileSandbox.Desktop.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/MobileSandbox.iOS.v3.ncrunchproject b/.ncrunch/MobileSandbox.iOS.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/MobileSandbox.iOS.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/MobileSandbox.net6.0.v3.ncrunchproject b/.ncrunch/MobileSandbox.net6.0.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/MobileSandbox.net6.0.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/MobileSandbox.netstandard2.0.v3.ncrunchproject b/.ncrunch/MobileSandbox.netstandard2.0.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/MobileSandbox.netstandard2.0.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/_build.v3.ncrunchproject b/.ncrunch/_build.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/_build.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/Avalonia.Desktop.slnf b/Avalonia.Desktop.slnf new file mode 100644 index 0000000000..6ba05332be --- /dev/null +++ b/Avalonia.Desktop.slnf @@ -0,0 +1,60 @@ +{ + "solution": { + "path": "Avalonia.sln", + "projects": [ + "packages\\Avalonia\\Avalonia.csproj", + "samples\\ControlCatalog.NetCore\\ControlCatalog.NetCore.csproj", + "samples\\ControlCatalog\\ControlCatalog.csproj", + "samples\\IntegrationTestApp\\IntegrationTestApp.csproj", + "samples\\MiniMvvm\\MiniMvvm.csproj", + "samples\\SampleControls\\ControlSamples.csproj", + "samples\\Sandbox\\Sandbox.csproj", + "src\\Avalonia.Base\\Avalonia.Base.csproj", + "src\\Avalonia.Build.Tasks\\Avalonia.Build.Tasks.csproj", + "src\\Avalonia.Controls.ColorPicker\\Avalonia.Controls.ColorPicker.csproj", + "src\\Avalonia.Controls.DataGrid\\Avalonia.Controls.DataGrid.csproj", + "src\\Avalonia.Controls\\Avalonia.Controls.csproj", + "src\\Avalonia.DesignerSupport\\Avalonia.DesignerSupport.csproj", + "src\\Avalonia.Desktop\\Avalonia.Desktop.csproj", + "src\\Avalonia.Diagnostics\\Avalonia.Diagnostics.csproj", + "src\\Avalonia.Dialogs\\Avalonia.Dialogs.csproj", + "src\\Avalonia.FreeDesktop\\Avalonia.FreeDesktop.csproj", + "src\\Avalonia.Headless.Vnc\\Avalonia.Headless.Vnc.csproj", + "src\\Avalonia.Headless\\Avalonia.Headless.csproj", + "src\\Avalonia.MicroCom\\Avalonia.MicroCom.csproj", + "src\\Avalonia.Native\\Avalonia.Native.csproj", + "src\\Avalonia.OpenGL\\Avalonia.OpenGL.csproj", + "src\\Avalonia.ReactiveUI\\Avalonia.ReactiveUI.csproj", + "src\\Avalonia.Remote.Protocol\\Avalonia.Remote.Protocol.csproj", + "src\\Avalonia.Themes.Fluent\\Avalonia.Themes.Fluent.csproj", + "src\\Avalonia.Themes.Simple\\Avalonia.Themes.Simple.csproj", + "src\\Avalonia.X11\\Avalonia.X11.csproj", + "src\\Linux\\Avalonia.LinuxFramebuffer\\Avalonia.LinuxFramebuffer.csproj", + "src\\Markup\\Avalonia.Markup.Xaml.Loader\\Avalonia.Markup.Xaml.Loader.csproj", + "src\\Markup\\Avalonia.Markup.Xaml\\Avalonia.Markup.Xaml.csproj", + "src\\Markup\\Avalonia.Markup\\Avalonia.Markup.csproj", + "src\\Skia\\Avalonia.Skia\\Avalonia.Skia.csproj", + "src\\Windows\\Avalonia.Direct2D1\\Avalonia.Direct2D1.csproj", + "src\\Windows\\Avalonia.Win32.Interop\\Avalonia.Win32.Interop.csproj", + "src\\Windows\\Avalonia.Win32\\Avalonia.Win32.csproj", + "src\\tools\\DevAnalyzers\\DevAnalyzers.csproj", + "src\\tools\\DevGenerators\\DevGenerators.csproj", + "tests\\Avalonia.Base.UnitTests\\Avalonia.Base.UnitTests.csproj", + "tests\\Avalonia.Benchmarks\\Avalonia.Benchmarks.csproj", + "tests\\Avalonia.Controls.DataGrid.UnitTests\\Avalonia.Controls.DataGrid.UnitTests.csproj", + "tests\\Avalonia.Controls.UnitTests\\Avalonia.Controls.UnitTests.csproj", + "tests\\Avalonia.DesignerSupport.TestApp\\Avalonia.DesignerSupport.TestApp.csproj", + "tests\\Avalonia.DesignerSupport.Tests\\Avalonia.DesignerSupport.Tests.csproj", + "tests\\Avalonia.Direct2D1.RenderTests\\Avalonia.Direct2D1.RenderTests.csproj", + "tests\\Avalonia.Direct2D1.UnitTests\\Avalonia.Direct2D1.UnitTests.csproj", + "tests\\Avalonia.IntegrationTests.Appium\\Avalonia.IntegrationTests.Appium.csproj", + "tests\\Avalonia.LeakTests\\Avalonia.LeakTests.csproj", + "tests\\Avalonia.Markup.UnitTests\\Avalonia.Markup.UnitTests.csproj", + "tests\\Avalonia.Markup.Xaml.UnitTests\\Avalonia.Markup.Xaml.UnitTests.csproj", + "tests\\Avalonia.ReactiveUI.UnitTests\\Avalonia.ReactiveUI.UnitTests.csproj", + "tests\\Avalonia.Skia.RenderTests\\Avalonia.Skia.RenderTests.csproj", + "tests\\Avalonia.Skia.UnitTests\\Avalonia.Skia.UnitTests.csproj", + "tests\\Avalonia.UnitTests\\Avalonia.UnitTests.csproj" + ] + } +} \ No newline at end of file diff --git a/Avalonia.sln b/Avalonia.sln index c000f56d09..34b5596119 100644 --- a/Avalonia.sln +++ b/Avalonia.sln @@ -41,6 +41,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{A689DE src\Shared\IsExternalInit.cs = src\Shared\IsExternalInit.cs src\Shared\ModuleInitializer.cs = src\Shared\ModuleInitializer.cs src\Shared\SourceGeneratorAttributes.cs = src\Shared\SourceGeneratorAttributes.cs + src\Avalonia.Base\Compatibility\StringCompatibilityExtensions.cs = src\Avalonia.Base\Compatibility\StringCompatibilityExtensions.cs EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.ReactiveUI", "src\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj", "{6417B24E-49C2-4985-8DB2-3AB9D898EC91}" @@ -197,9 +198,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationTestApp", "sampl EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.IntegrationTests.Appium", "tests\Avalonia.IntegrationTests.Appium\Avalonia.IntegrationTests.Appium.csproj", "{F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web", "Web", "{86A3F706-DC3C-43C6-BE1B-B98F5BAAA268}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Web.Blazor", "src\Web\Avalonia.Web.Blazor\Avalonia.Web.Blazor.csproj", "{25831348-EB2A-483E-9576-E8F6528674A5}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Browser", "Browser", "{86A3F706-DC3C-43C6-BE1B-B98F5BAAA268}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WindowsInteropTest", "samples\interop\WindowsInteropTest\WindowsInteropTest.csproj", "{26A98DA1-D89D-4A95-8152-349F404DA2E2}" EndProject @@ -215,8 +214,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.DesignerSupport.Te EndProject 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}" @@ -225,9 +222,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MobileSandbox.iOS", "sample 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}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Browser", "src\Browser\Avalonia.Browser\Avalonia.Browser.csproj", "{4A39637C-9338-4925-A4DB-D072E292EC78}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Browser.Blazor", "src\Browser\Avalonia.Browser.Blazor\Avalonia.Browser.Blazor.csproj", "{47F8530C-F19B-4B1A-B4D6-EB231522AE5D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.Browser", "samples\ControlCatalog.Browser\ControlCatalog.Browser.csproj", "{15B93A4C-1B46-43F6-B534-7B25B6E99932}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Web", "samples\ControlCatalog.Web\ControlCatalog.Web.csproj", "{8B3E8405-DE18-4048-A459-9CA4AC3319A2}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.Browser.Blazor", "samples\ControlCatalog.Browser.Blazor\ControlCatalog.Browser.Blazor.csproj", "{90B08091-9BBD-4362-B712-E9F2CC62B218}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -479,10 +480,6 @@ Global {F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Debug|Any CPU.Build.0 = Debug|Any CPU {F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Release|Any CPU.ActiveCfg = Release|Any CPU {F2CE566B-E7F6-447A-AB1A-3F574A6FE43A}.Release|Any CPU.Build.0 = Release|Any CPU - {25831348-EB2A-483E-9576-E8F6528674A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {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 {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 @@ -511,16 +508,13 @@ 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}.Debug|Any CPU.Deploy.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 @@ -531,14 +525,22 @@ Global {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 + {4A39637C-9338-4925-A4DB-D072E292EC78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A39637C-9338-4925-A4DB-D072E292EC78}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4A39637C-9338-4925-A4DB-D072E292EC78}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A39637C-9338-4925-A4DB-D072E292EC78}.Release|Any CPU.Build.0 = Release|Any CPU + {47F8530C-F19B-4B1A-B4D6-EB231522AE5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {47F8530C-F19B-4B1A-B4D6-EB231522AE5D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {47F8530C-F19B-4B1A-B4D6-EB231522AE5D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {47F8530C-F19B-4B1A-B4D6-EB231522AE5D}.Release|Any CPU.Build.0 = Release|Any CPU + {15B93A4C-1B46-43F6-B534-7B25B6E99932}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {15B93A4C-1B46-43F6-B534-7B25B6E99932}.Debug|Any CPU.Build.0 = Debug|Any CPU + {15B93A4C-1B46-43F6-B534-7B25B6E99932}.Release|Any CPU.ActiveCfg = Release|Any CPU + {15B93A4C-1B46-43F6-B534-7B25B6E99932}.Release|Any CPU.Build.0 = Release|Any CPU + {90B08091-9BBD-4362-B712-E9F2CC62B218}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {90B08091-9BBD-4362-B712-E9F2CC62B218}.Debug|Any CPU.Build.0 = Debug|Any CPU + {90B08091-9BBD-4362-B712-E9F2CC62B218}.Release|Any CPU.ActiveCfg = Release|Any CPU + {90B08091-9BBD-4362-B712-E9F2CC62B218}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -589,20 +591,20 @@ Global {BC594FD5-4AF2-409E-A1E6-04123F54D7C5} = {9B9E3891-2366-4253-A952-D08BCEB71098} {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} {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} - {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} + {4A39637C-9338-4925-A4DB-D072E292EC78} = {86A3F706-DC3C-43C6-BE1B-B98F5BAAA268} + {47F8530C-F19B-4B1A-B4D6-EB231522AE5D} = {86A3F706-DC3C-43C6-BE1B-B98F5BAAA268} + {15B93A4C-1B46-43F6-B534-7B25B6E99932} = {9B9E3891-2366-4253-A952-D08BCEB71098} + {90B08091-9BBD-4362-B712-E9F2CC62B218} = {9B9E3891-2366-4253-A952-D08BCEB71098} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A} diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 0000000000..73954c7f4d --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,5 @@ + + + $(DefineConstants);NET7SDK + + diff --git a/Documentation/build.md b/Documentation/build.md index ddd38be887..fd6b26337c 100644 --- a/Documentation/build.md +++ b/Documentation/build.md @@ -1,8 +1,8 @@ # Windows -Avalonia requires at least Visual Studio 2022 and dotnet 6 SDK 6.0.100 to build on all platforms. +Avalonia requires at least Visual Studio 2022 and dotnet 7-rc2 SDK 7.0.100-rc.2 to build on all platforms. -### Clone the Avalonia repository +## Clone the Avalonia repository ``` git clone https://github.com/AvaloniaUI/Avalonia.git @@ -10,15 +10,30 @@ cd Avalonia git submodule update --init ``` -### Install the required version of the .NET Core SDK +## Install the required version of the .NET Core SDK 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). -### Open in Visual Studio +## Build and Run Avalonia -Open the `Avalonia.sln` solution in Visual Studio 2022 or newer. The free Visual Studio Community edition works fine. Build and run the `Samples\ControlCatalog.Desktop` or `ControlCatalog.NetCore` project to see the sample application. +``` +cd samples\ControlCatalog.NetCore +dotnet restore +dotnet run +``` + +## Opening in Visual Studio -### Troubleshooting +If you want to open Avalonia in Visual Studio you have two options: + +- Avalonia.sln: This contains the whole of Avalonia in including desktop, mobile and web. You must have a number of dotnet workloads installed in order to build everything in this solution +- Avalonia.Desktop.slnf: This solution filter opens only the parts of Avalonia required to run on desktop. This requires no extra workloads to be installed. + +Avalonia requires Visual Studio 2022 or newer. The free Visual Studio Community edition works fine. + +Build and run `ControlCatalog.NetCore` project to see the sample application. + +### Visual Studio Troubleshooting * **Error CS0006: Avalonia.DesktopRuntime.dll could not be found** @@ -35,16 +50,15 @@ It's *not* possible to build the *whole* project on Linux/macOS. You can only bu MonoDevelop, Xamarin Studio and Visual Studio for Mac aren't capable of properly opening our solution. You can use Rider (at least 2017.2 EAP) or VSCode instead. They will fail to load most of platform specific projects, but you don't need them to run on .NET Core. -### Install the latest version of the .NET Core SDK +## Install the latest version of the .NET Core SDK Go to https://www.microsoft.com/net/core and follow the instructions for your OS. Make sure to download the SDK (not just the "runtime") package. -### Additional requirements for macOS +## Additional requirements for macOS The build process needs [Xcode](https://developer.apple.com/xcode/) to build the native library. Following the install instructions at the [Xcode](https://developer.apple.com/xcode/) website to properly install. - -### Clone the Avalonia repository +## Clone the Avalonia repository ``` git clone https://github.com/AvaloniaUI/Avalonia.git @@ -52,7 +66,7 @@ cd Avalonia git submodule update --init --recursive ``` -### Build native libraries (macOS only) +## Build native libraries (macOS only) On macOS it is necessary to build and manually install the respective native libraries using [Xcode](https://developer.apple.com/xcode/). Execute the build script in the root project with the `CompileNative` task. It will build the headers, build the libraries, and place them in the appropriate place to allow .NET to find them at compilation and run time. @@ -60,7 +74,7 @@ On macOS it is necessary to build and manually install the respective native lib ./build.sh CompileNative ``` -### Build and Run Avalonia +## Build and Run Avalonia ``` cd samples/ControlCatalog.NetCore diff --git a/azure-pipelines-integrationtests.yml b/azure-pipelines-integrationtests.yml index ee8abb75c1..43253ac6be 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' + inputs: + version: 7.0.100 + - script: system_profiler SPDisplaysDataType |grep Resolution - script: | @@ -22,7 +32,7 @@ jobs: rm -rf $(osascript -e "POSIX path of (path to application id \"net.avaloniaui.avalonia.integrationtestapp\")") pkill IntegrationTestApp ./samples/IntegrationTestApp/bundle.sh - open -n ./samples/IntegrationTestApp/bin/Debug/net6.0/osx-arm64/publish/IntegrationTestApp.app + open -n ./samples/IntegrationTestApp/bin/Debug/net7.0/osx-arm64/publish/IntegrationTestApp.app pkill IntegrationTestApp - task: DotNetCoreCLI@2 @@ -45,6 +55,11 @@ jobs: inputs: version: 6.0.401 + - task: UseDotNet@2 + displayName: 'Use .NET Core SDK 7.0.100' + inputs: + version: 7.0.100 + - task: Windows Application Driver@0 inputs: OperationType: 'Start' diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 33b2dc670a..a3bbc33418 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -35,9 +35,9 @@ jobs: version: 6.0.401 - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 7.0.100-rc.1.22431.12' + displayName: 'Use .NET Core SDK 7.0' inputs: - version: 7.0.100-rc.1.22431.12 + version: 7.0.100 - task: CmdLine@2 displayName: 'Install Workloads' @@ -72,9 +72,9 @@ jobs: version: 6.0.401 - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 7.0.100-rc.1.22431.12' + displayName: 'Use .NET Core SDK 7.0.100' inputs: - version: 7.0.100-rc.1.22431.12 + version: 7.0.100 - task: CmdLine@2 displayName: 'Install Workloads' @@ -143,9 +143,9 @@ jobs: version: 6.0.401 - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 7.0.100-rc.1.22431.12' + displayName: 'Use .NET Core SDK 7.0.100' inputs: - version: 7.0.100-rc.1.22431.12 + version: 7.0.100 - task: CmdLine@2 displayName: 'Install Workloads' diff --git a/build/BuildTargets.targets b/build/BuildTargets.targets index a5543cd050..481dbf06b2 100644 --- a/build/BuildTargets.targets +++ b/build/BuildTargets.targets @@ -3,6 +3,7 @@ $(MSBuildThisFileDirectory)\..\src\Avalonia.Build.Tasks\bin\$(Configuration)\netstandard2.0\Avalonia.Build.Tasks.dll true true + true diff --git a/build/SharedVersion.props b/build/SharedVersion.props index 1b60bb4df9..5838519596 100644 --- a/build/SharedVersion.props +++ b/build/SharedVersion.props @@ -8,7 +8,7 @@ https://github.com/AvaloniaUI/Avalonia/ true CS1591 - latest + preview MIT Icon.png Avalonia is a cross-platform UI framework for .NET providing a flexible styling system and supporting a wide range of Operating Systems such as Windows, Linux, macOS and with experimental support for Android, iOS and WebAssembly. diff --git a/dirs.proj b/dirs.proj index a2544ef951..f1eaae8a4a 100644 --- a/dirs.proj +++ b/dirs.proj @@ -9,21 +9,18 @@ - - - - - - - + + + + - + diff --git a/global.json b/global.json index 44d4e10dbf..a9318b212f 100644 --- a/global.json +++ b/global.json @@ -1,4 +1,8 @@ { + "sdk": { + "version": "7.0.100", + "rollForward": "latestFeature" + }, "msbuild-sdks": { "Microsoft.Build.Traversal": "1.0.43", "MSBuild.Sdk.Extras": "3.0.22", diff --git a/native/Avalonia.Native/src/OSX/AvnWindow.mm b/native/Avalonia.Native/src/OSX/AvnWindow.mm index ebd9f39d30..6611dcc73f 100644 --- a/native/Avalonia.Native/src/OSX/AvnWindow.mm +++ b/native/Avalonia.Native/src/OSX/AvnWindow.mm @@ -171,9 +171,7 @@ _closed = false; _isEnabled = true; - [self backingScaleFactor]; [self setOpaque:NO]; - [self setBackgroundColor: [NSColor clearColor]]; _isExtended = false; _isTransitioningToFullScreen = false; @@ -385,7 +383,7 @@ return true; } --(void)resignKeyWindow +-(void)windowDidResignKey:(NSNotification *)notification { if(_parent) _parent->BaseEvents->Deactivated(); @@ -393,8 +391,6 @@ [self showAppMenuOnly]; [self invalidateShadow]; - - [super resignKeyWindow]; } - (void)windowDidMove:(NSNotification *_Nonnull)notification 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/WindowBaseImpl.h b/native/Avalonia.Native/src/OSX/WindowBaseImpl.h index 2baf3b09b5..7fb002e54f 100644 --- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.h +++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.h @@ -90,7 +90,7 @@ BEGIN_INTERFACE_MAP() virtual HRESULT CreateNativeControlHost(IAvnNativeControlHost **retOut) override; - virtual HRESULT SetBlurEnabled(bool enable) override; + virtual HRESULT SetTransparencyMode(AvnWindowTransparencyMode mode) override; virtual HRESULT BeginDragAndDropOperation(AvnDragDropEffects effects, AvnPoint point, IAvnClipboard *clipboard, IAvnDndResultCallback *cb, diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm index 77f53332cd..9946ad9b10 100644 --- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm @@ -489,10 +489,11 @@ HRESULT WindowBaseImpl::CreateNativeControlHost(IAvnNativeControlHost **retOut) return S_OK; } -HRESULT WindowBaseImpl::SetBlurEnabled(bool enable) { +HRESULT WindowBaseImpl::SetTransparencyMode(AvnWindowTransparencyMode mode) { START_COM_CALL; - [StandardContainer ShowBlur:enable]; + [Window setBackgroundColor: (mode != Transparent ? [NSColor windowBackgroundColor] : [NSColor clearColor])]; + [StandardContainer ShowBlur: mode == Blur]; return S_OK; } diff --git a/native/Avalonia.Native/src/OSX/WindowImpl.mm b/native/Avalonia.Native/src/OSX/WindowImpl.mm index ddc50c26b6..2443965957 100644 --- a/native/Avalonia.Native/src/OSX/WindowImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowImpl.mm @@ -63,7 +63,7 @@ HRESULT WindowImpl::Show(bool activate, bool isDialog) { START_COM_CALL; @autoreleasepool { - _isDialog = isDialog; + _isDialog = isDialog || _parent != nullptr; WindowBaseImpl::Show(activate, isDialog); @@ -96,6 +96,8 @@ HRESULT WindowImpl::SetParent(IAvnWindow *parent) { auto cparent = dynamic_cast(parent); _parent = cparent; + + _isDialog = _parent != nullptr; if(_parent != nullptr && Window != nullptr){ // If one tries to show a child window with a minimized parent window, then the parent window will be diff --git a/native/Avalonia.Native/src/OSX/app.mm b/native/Avalonia.Native/src/OSX/app.mm index a15d0c9601..9cc9fc9523 100644 --- a/native/Avalonia.Native/src/OSX/app.mm +++ b/native/Avalonia.Native/src/OSX/app.mm @@ -95,11 +95,14 @@ ComPtr _events; } @end -extern void InitializeAvnApp(IAvnApplicationEvents* events) +extern void InitializeAvnApp(IAvnApplicationEvents* events, bool disableAppDelegate) { - NSApplication* app = [AvnApplication sharedApplication]; - id delegate = [[AvnAppDelegate alloc] initWithEvents:events]; - [app setDelegate:delegate]; + if(!disableAppDelegate) + { + NSApplication* app = [AvnApplication sharedApplication]; + id delegate = [[AvnAppDelegate alloc] initWithEvents:events]; + [app setDelegate:delegate]; + } } HRESULT AvnApplicationCommands::HideApp() diff --git a/native/Avalonia.Native/src/OSX/common.h b/native/Avalonia.Native/src/OSX/common.h index a90a235b9d..7ee7205776 100644 --- a/native/Avalonia.Native/src/OSX/common.h +++ b/native/Avalonia.Native/src/OSX/common.h @@ -32,7 +32,7 @@ extern void SetServicesMenu (IAvnMenu* menu); extern IAvnMenu* GetAppMenu (); extern NSMenuItem* GetAppMenuItem (); -extern void InitializeAvnApp(IAvnApplicationEvents* events); +extern void InitializeAvnApp(IAvnApplicationEvents* events, bool disableAppDelegate); extern NSApplicationActivationPolicy AvnDesiredActivationPolicy; extern NSPoint ToNSPoint (AvnPoint p); extern NSRect ToNSRect (AvnRect r); diff --git a/native/Avalonia.Native/src/OSX/main.mm b/native/Avalonia.Native/src/OSX/main.mm index 6ee86b21ae..c29d4108d0 100644 --- a/native/Avalonia.Native/src/OSX/main.mm +++ b/native/Avalonia.Native/src/OSX/main.mm @@ -3,6 +3,8 @@ #include "common.h" static NSString* s_appTitle = @"Avalonia"; +static int disableSetProcessName = 0; +static bool disableAppDelegate = false; // Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -111,11 +113,17 @@ public: @autoreleasepool { auto appTitle = [NSString stringWithUTF8String: utf8String]; - - [[NSProcessInfo processInfo] setProcessName:appTitle]; - - - SetProcessName(appTitle); + if (disableSetProcessName == 0) + { + [[NSProcessInfo processInfo] setProcessName:appTitle]; + + SetProcessName(appTitle); + } + if (disableSetProcessName == 1) + { + auto rootMenu = [NSApp mainMenu]; + [rootMenu setTitle:appTitle]; + } return S_OK; } @@ -133,6 +141,27 @@ public: } } + virtual HRESULT SetDisableSetProcessName(int disable) override + { + START_COM_CALL; + + @autoreleasepool + { + disableSetProcessName = disable; + return S_OK; + } + } + + virtual HRESULT SetDisableAppDelegate(int disable) override + { + START_COM_CALL; + + @autoreleasepool { + disableAppDelegate = disable; + return S_OK; + } + } + }; /// See "Using POSIX Threads in a Cocoa Application" section here: @@ -175,7 +204,7 @@ public: @autoreleasepool{ [[ThreadingInitializer new] do]; } - InitializeAvnApp(events); + InitializeAvnApp(events, disableAppDelegate); return S_OK; }; diff --git a/native/Avalonia.Native/src/OSX/menu.h b/native/Avalonia.Native/src/OSX/menu.h index ce46ac11e0..405938318c 100644 --- a/native/Avalonia.Native/src/OSX/menu.h +++ b/native/Avalonia.Native/src/OSX/menu.h @@ -59,11 +59,20 @@ public: void RaiseOnClicked(); }; +class AvnAppMenu; + +@interface AvnMenuDelegate : NSObject +- (id) initWithParent: (AvnAppMenu*) parent; +- (void) parentDestroyed; +@end + + class AvnAppMenu : public ComSingleObject { private: AvnMenu* _native; ComPtr _baseEvents; + AvnMenuDelegate* _delegate; public: FORWARD_IUNKNOWN() @@ -83,12 +92,10 @@ public: virtual HRESULT SetTitle (char* utf8String) override; virtual HRESULT Clear () override; + virtual ~AvnAppMenu() override; }; -@interface AvnMenuDelegate : NSObject -- (id) initWithParent: (AvnAppMenu*) parent; -@end #endif diff --git a/native/Avalonia.Native/src/OSX/menu.mm b/native/Avalonia.Native/src/OSX/menu.mm index b05588a441..cd1871de21 100644 --- a/native/Avalonia.Native/src/OSX/menu.mm +++ b/native/Avalonia.Native/src/OSX/menu.mm @@ -292,8 +292,13 @@ void AvnAppMenuItem::RaiseOnClicked() AvnAppMenu::AvnAppMenu(IAvnMenuEvents* events) { _baseEvents = events; - id del = [[AvnMenuDelegate alloc] initWithParent: this]; - _native = [[AvnMenu alloc] initWithDelegate: del]; + _delegate = [[AvnMenuDelegate alloc] initWithParent: this]; + _native = [[AvnMenu alloc] initWithDelegate: _delegate]; +} + +AvnAppMenu::~AvnAppMenu() +{ + [_delegate parentDestroyed]; } @@ -394,7 +399,7 @@ HRESULT AvnAppMenu::Clear() @implementation AvnMenuDelegate { - ComPtr _parent; + AvnAppMenu* _parent; } - (id) initWithParent:(AvnAppMenu *)parent { @@ -402,6 +407,12 @@ HRESULT AvnAppMenu::Clear() _parent = parent; return self; } + +- (void) parentDestroyed +{ + _parent = nullptr; +} + - (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel { if(shouldCancel) @@ -416,17 +427,20 @@ HRESULT AvnAppMenu::Clear() - (void)menuNeedsUpdate:(NSMenu *)menu { - _parent->RaiseNeedsUpdate(); + if(_parent) + _parent->RaiseNeedsUpdate(); } - (void)menuWillOpen:(NSMenu *)menu { - _parent->RaiseOpening(); + if(_parent) + _parent->RaiseOpening(); } - (void)menuDidClose:(NSMenu *)menu { - _parent->RaiseClosed(); + if(_parent) + _parent->RaiseClosed(); } @end diff --git a/native/Avalonia.Native/src/OSX/rendertarget.mm b/native/Avalonia.Native/src/OSX/rendertarget.mm index 2075cc85ab..1c22c91207 100644 --- a/native/Avalonia.Native/src/OSX/rendertarget.mm +++ b/native/Avalonia.Native/src/OSX/rendertarget.mm @@ -183,8 +183,11 @@ static IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(IOSurfaceRenderTarget* ta [_layer setContents: (__bridge IOSurface*) surface->surface]; } [CATransaction commit]; - [CATransaction flush]; } + // 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]; } else dispatch_async(dispatch_get_main_queue(), ^{ diff --git a/nukebuild/Build.cs b/nukebuild/Build.cs index 7425c344c3..2295c0beda 100644 --- a/nukebuild/Build.cs +++ b/nukebuild/Build.cs @@ -145,8 +145,25 @@ partial class Build : NukeBuild { Information($"Running tests from {projectName}"); var project = Solution.GetProject(projectName).NotNull("project != null"); + // Nuke and MSBuild tools have build-in helpers to get target frameworks from the project. + // Unfortunately, it gets broken with every second SDK update, so we had to do it manually. + var fileXml = XDocument.Parse(File.ReadAllText(project.Path)); + var targetFrameworks = fileXml.Descendants("TargetFrameworks") + .FirstOrDefault()?.Value.Split(';').Select(f => f.Trim()); + if (targetFrameworks is null) + { + var targetFramework = fileXml.Descendants("TargetFramework").FirstOrDefault()?.Value; + if (targetFramework is not null) + { + targetFrameworks = new[] { targetFramework }; + } + } + if (targetFrameworks is null) + { + throw new InvalidOperationException("No target frameworks were found in the test project"); + } - foreach (var fw in project.GetTargetFrameworks()) + foreach (var fw in targetFrameworks) { if (fw.StartsWith("net4") && RuntimeInformation.IsOSPlatform(OSPlatform.Linux) diff --git a/nukebuild/_build.csproj b/nukebuild/_build.csproj index 8c0d824298..92d9732e91 100644 --- a/nukebuild/_build.csproj +++ b/nukebuild/_build.csproj @@ -13,11 +13,11 @@ - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/packages/Avalonia/AvaloniaBuildTasks.targets b/packages/Avalonia/AvaloniaBuildTasks.targets index d43a5c1624..4f9c4d7720 100644 --- a/packages/Avalonia/AvaloniaBuildTasks.targets +++ b/packages/Avalonia/AvaloniaBuildTasks.targets @@ -3,8 +3,8 @@ <_AvaloniaUseExternalMSBuild>$(AvaloniaUseExternalMSBuild) <_AvaloniaUseExternalMSBuild Condition="'$(_AvaloniaForceInternalMSBuild)' == 'true'">false low - <_AvaloniaPatchComInterop Condition="'$(_AvaloniaPatchComInterop)' == ''">false <_AvaloniaSkipXamlCompilation Condition="'$(_AvaloniaSkipXamlCompilation)' == ''">false + false @@ -44,7 +44,7 @@ $(BuildAvaloniaResourcesDependsOn);AddAvaloniaResources;ResolveReferences;_GenerateAvaloniaResourcesDependencyCache - + @@ -71,7 +71,6 @@ Output="$(AvaloniaResourcesTemporaryFilePath)" Root="$(MSBuildProjectDirectory)" Resources="@(AvaloniaResource)" - EmbeddedResources="@(EmbeddedResources)" ReportImportance="$(AvaloniaXamlReportImportance)"/> - + diff --git a/samples/BindingDemo/TestItemView.xaml b/samples/BindingDemo/TestItemView.xaml index 46c34c6507..6edade34b2 100644 --- a/samples/BindingDemo/TestItemView.xaml +++ b/samples/BindingDemo/TestItemView.xaml @@ -1,8 +1,10 @@ + xmlns:viewModels="using:BindingDemo.ViewModels" + x:Class="BindingDemo.TestItemView" + x:DataType="viewModels:TestItem"> - \ No newline at end of file + diff --git a/samples/ControlCatalog.Blazor.Web/App.razor b/samples/ControlCatalog.Browser.Blazor/App.razor similarity index 100% rename from samples/ControlCatalog.Blazor.Web/App.razor rename to samples/ControlCatalog.Browser.Blazor/App.razor diff --git a/samples/ControlCatalog.Blazor.Web/App.razor.cs b/samples/ControlCatalog.Browser.Blazor/App.razor.cs similarity index 83% rename from samples/ControlCatalog.Blazor.Web/App.razor.cs rename to samples/ControlCatalog.Browser.Blazor/App.razor.cs index 8cc0095f20..f38db2b055 100644 --- a/samples/ControlCatalog.Blazor.Web/App.razor.cs +++ b/samples/ControlCatalog.Browser.Blazor/App.razor.cs @@ -1,7 +1,7 @@ using Avalonia; -using Avalonia.Web.Blazor; +using Avalonia.Browser.Blazor; -namespace ControlCatalog.Blazor.Web; +namespace ControlCatalog.Browser.Blazor; public partial class App { diff --git a/samples/ControlCatalog.Blazor.Web/ControlCatalog.Blazor.Web.csproj b/samples/ControlCatalog.Browser.Blazor/ControlCatalog.Browser.Blazor.csproj similarity index 79% rename from samples/ControlCatalog.Blazor.Web/ControlCatalog.Blazor.Web.csproj rename to samples/ControlCatalog.Browser.Blazor/ControlCatalog.Browser.Blazor.csproj index 03fb31f0d3..d0fb614840 100644 --- a/samples/ControlCatalog.Blazor.Web/ControlCatalog.Blazor.Web.csproj +++ b/samples/ControlCatalog.Browser.Blazor/ControlCatalog.Browser.Blazor.csproj @@ -15,15 +15,15 @@ - + - - + + diff --git a/samples/ControlCatalog.Blazor.Web/Pages/Index.razor b/samples/ControlCatalog.Browser.Blazor/Pages/Index.razor similarity index 50% rename from samples/ControlCatalog.Blazor.Web/Pages/Index.razor rename to samples/ControlCatalog.Browser.Blazor/Pages/Index.razor index 93ca07f9f1..7480e4c5e9 100644 --- a/samples/ControlCatalog.Blazor.Web/Pages/Index.razor +++ b/samples/ControlCatalog.Browser.Blazor/Pages/Index.razor @@ -1,5 +1,5 @@ @page "/" -@using Avalonia.Web.Blazor +@using Avalonia.Browser.Blazor diff --git a/samples/ControlCatalog.Blazor.Web/Program.cs b/samples/ControlCatalog.Browser.Blazor/Program.cs similarity index 94% rename from samples/ControlCatalog.Blazor.Web/Program.cs rename to samples/ControlCatalog.Browser.Blazor/Program.cs index d71b125fa1..eb99ca518e 100644 --- a/samples/ControlCatalog.Blazor.Web/Program.cs +++ b/samples/ControlCatalog.Browser.Blazor/Program.cs @@ -3,7 +3,7 @@ using System.Net.Http; using System.Threading.Tasks; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Microsoft.Extensions.DependencyInjection; -using ControlCatalog.Blazor.Web; +using ControlCatalog.Browser.Blazor; public class Program { diff --git a/samples/ControlCatalog.Blazor.Web/Properties/launchSettings.json b/samples/ControlCatalog.Browser.Blazor/Properties/launchSettings.json similarity index 66% rename from samples/ControlCatalog.Blazor.Web/Properties/launchSettings.json rename to samples/ControlCatalog.Browser.Blazor/Properties/launchSettings.json index e4da60f7ca..ad2b1e30f6 100644 --- a/samples/ControlCatalog.Blazor.Web/Properties/launchSettings.json +++ b/samples/ControlCatalog.Browser.Blazor/Properties/launchSettings.json @@ -8,14 +8,6 @@ } }, "profiles": { - "ControlCatalog.Web - IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, "ControlCatalog.Web": { "commandName": "Project", "dotnetRunMessages": "true", diff --git a/samples/ControlCatalog.Blazor.Web/Shared/MainLayout.razor b/samples/ControlCatalog.Browser.Blazor/Shared/MainLayout.razor similarity index 100% rename from samples/ControlCatalog.Blazor.Web/Shared/MainLayout.razor rename to samples/ControlCatalog.Browser.Blazor/Shared/MainLayout.razor diff --git a/samples/ControlCatalog.Blazor.Web/_Imports.razor b/samples/ControlCatalog.Browser.Blazor/_Imports.razor similarity index 88% rename from samples/ControlCatalog.Blazor.Web/_Imports.razor rename to samples/ControlCatalog.Browser.Blazor/_Imports.razor index 0e6d11b419..dc4f778352 100644 --- a/samples/ControlCatalog.Blazor.Web/_Imports.razor +++ b/samples/ControlCatalog.Browser.Blazor/_Imports.razor @@ -6,5 +6,5 @@ @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.AspNetCore.Components.WebAssembly.Http @using Microsoft.JSInterop -@using ControlCatalog.Blazor.Web.Shared +@using ControlCatalog.Browser.Blazor.Shared @using SkiaSharp diff --git a/samples/ControlCatalog.Blazor.Web/wwwroot/css/app.css b/samples/ControlCatalog.Browser.Blazor/wwwroot/css/app.css similarity index 100% rename from samples/ControlCatalog.Blazor.Web/wwwroot/css/app.css rename to samples/ControlCatalog.Browser.Blazor/wwwroot/css/app.css diff --git a/samples/ControlCatalog.Blazor.Web/wwwroot/favicon.ico b/samples/ControlCatalog.Browser.Blazor/wwwroot/favicon.ico similarity index 100% rename from samples/ControlCatalog.Blazor.Web/wwwroot/favicon.ico rename to samples/ControlCatalog.Browser.Blazor/wwwroot/favicon.ico diff --git a/samples/ControlCatalog.Blazor.Web/wwwroot/index.html b/samples/ControlCatalog.Browser.Blazor/wwwroot/index.html similarity index 100% rename from samples/ControlCatalog.Blazor.Web/wwwroot/index.html rename to samples/ControlCatalog.Browser.Blazor/wwwroot/index.html diff --git a/samples/ControlCatalog.Web/ControlCatalog.Web.csproj b/samples/ControlCatalog.Browser/ControlCatalog.Browser.csproj similarity index 78% rename from samples/ControlCatalog.Web/ControlCatalog.Web.csproj rename to samples/ControlCatalog.Browser/ControlCatalog.Browser.csproj index 0ddec3444b..c4278459f3 100644 --- a/samples/ControlCatalog.Web/ControlCatalog.Web.csproj +++ b/samples/ControlCatalog.Browser/ControlCatalog.Browser.csproj @@ -16,9 +16,8 @@ full true true - true - -O3 - -O3 + -O2 + -O2 @@ -27,7 +26,7 @@ - + @@ -40,6 +39,6 @@ - - + + diff --git a/samples/ControlCatalog.Web/EmbedSample.Browser.cs b/samples/ControlCatalog.Browser/EmbedSample.Browser.cs similarity index 95% rename from samples/ControlCatalog.Web/EmbedSample.Browser.cs rename to samples/ControlCatalog.Browser/EmbedSample.Browser.cs index 5cfbb608cc..c367230ddf 100644 --- a/samples/ControlCatalog.Web/EmbedSample.Browser.cs +++ b/samples/ControlCatalog.Browser/EmbedSample.Browser.cs @@ -1,11 +1,11 @@ using System; using System.Runtime.InteropServices.JavaScript; using Avalonia.Platform; -using Avalonia.Web; +using Avalonia.Browser; using ControlCatalog.Pages; -namespace ControlCatalog.Web; +namespace ControlCatalog.Browser; public class EmbedSampleWeb : INativeDemoControl { diff --git a/samples/ControlCatalog.Web/Logo.svg b/samples/ControlCatalog.Browser/Logo.svg similarity index 100% rename from samples/ControlCatalog.Web/Logo.svg rename to samples/ControlCatalog.Browser/Logo.svg diff --git a/samples/ControlCatalog.Web/Program.cs b/samples/ControlCatalog.Browser/Program.cs similarity index 90% rename from samples/ControlCatalog.Web/Program.cs rename to samples/ControlCatalog.Browser/Program.cs index 7d05c8e462..53b7c60a6f 100644 --- a/samples/ControlCatalog.Web/Program.cs +++ b/samples/ControlCatalog.Browser/Program.cs @@ -1,8 +1,8 @@ using System.Runtime.Versioning; using Avalonia; -using Avalonia.Web; +using Avalonia.Browser; using ControlCatalog; -using ControlCatalog.Web; +using ControlCatalog.Browser; [assembly:SupportedOSPlatform("browser")] diff --git a/samples/ControlCatalog.Web/Roots.xml b/samples/ControlCatalog.Browser/Roots.xml similarity index 78% rename from samples/ControlCatalog.Web/Roots.xml rename to samples/ControlCatalog.Browser/Roots.xml index 3c13098159..b07fd86fa2 100644 --- a/samples/ControlCatalog.Web/Roots.xml +++ b/samples/ControlCatalog.Browser/Roots.xml @@ -3,4 +3,5 @@ + diff --git a/samples/ControlCatalog.Web/app.css b/samples/ControlCatalog.Browser/app.css similarity index 100% rename from samples/ControlCatalog.Web/app.css rename to samples/ControlCatalog.Browser/app.css diff --git a/samples/ControlCatalog.Web/embed.js b/samples/ControlCatalog.Browser/embed.js similarity index 100% rename from samples/ControlCatalog.Web/embed.js rename to samples/ControlCatalog.Browser/embed.js diff --git a/samples/ControlCatalog.Web/favicon.ico b/samples/ControlCatalog.Browser/favicon.ico similarity index 100% rename from samples/ControlCatalog.Web/favicon.ico rename to samples/ControlCatalog.Browser/favicon.ico diff --git a/samples/ControlCatalog.Web/index.html b/samples/ControlCatalog.Browser/index.html similarity index 100% rename from samples/ControlCatalog.Web/index.html rename to samples/ControlCatalog.Browser/index.html diff --git a/samples/ControlCatalog.Web/main.js b/samples/ControlCatalog.Browser/main.js similarity index 100% rename from samples/ControlCatalog.Web/main.js rename to samples/ControlCatalog.Browser/main.js diff --git a/samples/ControlCatalog.Web/runtimeconfig.template.json b/samples/ControlCatalog.Browser/runtimeconfig.template.json similarity index 100% rename from samples/ControlCatalog.Web/runtimeconfig.template.json rename to samples/ControlCatalog.Browser/runtimeconfig.template.json diff --git a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj b/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj index 0667644643..e4c83dca49 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.8 diff --git a/samples/ControlCatalog/App.xaml b/samples/ControlCatalog/App.xaml index b228e72f72..8f32fa01dd 100644 --- a/samples/ControlCatalog/App.xaml +++ b/samples/ControlCatalog/App.xaml @@ -2,7 +2,6 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vm="using:ControlCatalog.ViewModels" x:DataType="vm:ApplicationViewModel" - x:CompileBindings="True" Name="Avalonia ControlCatalog" x:Class="ControlCatalog.App"> @@ -10,6 +9,15 @@ + + + + + + + + + diff --git a/samples/ControlCatalog/App.xaml.cs b/samples/ControlCatalog/App.xaml.cs index 750c1082a6..6c99eb5289 100644 --- a/samples/ControlCatalog/App.xaml.cs +++ b/samples/ControlCatalog/App.xaml.cs @@ -3,85 +3,46 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; -using Avalonia.Markup.Xaml.Styling; using Avalonia.Styling; using Avalonia.Themes.Simple; using Avalonia.Themes.Fluent; +using ControlCatalog.Models; using ControlCatalog.ViewModels; namespace ControlCatalog { public class App : Application { + private readonly Styles _themeStylesContainer = new(); + private FluentTheme? _fluentTheme; + private SimpleTheme? _simpleTheme; + private IResourceDictionary? _fluentBaseLightColors, _fluentBaseDarkColors; + private IStyle? _colorPickerFluent, _colorPickerSimple; + private IStyle? _dataGridFluent, _dataGridSimple; + public App() { DataContext = new ApplicationViewModel(); } - public static readonly StyleInclude ColorPickerFluent = new StyleInclude(new Uri("avares://ControlCatalog/Styles")) - { - Source = new Uri("avares://Avalonia.Controls.ColorPicker/Themes/Fluent/Fluent.xaml") - }; - - public static readonly StyleInclude ColorPickerSimple = new StyleInclude(new Uri("avares://ControlCatalog/Styles")) - { - Source = new Uri("avares://Avalonia.Controls.ColorPicker/Themes/Simple/Simple.xaml") - }; - - public static readonly StyleInclude DataGridFluent = new StyleInclude(new Uri("avares://ControlCatalog/Styles")) - { - Source = new Uri("avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml") - }; - - public static readonly StyleInclude DataGridSimple = new StyleInclude(new Uri("avares://ControlCatalog/Styles")) - { - Source = new Uri("avares://Avalonia.Controls.DataGrid/Themes/Simple.xaml") - }; - - public static FluentTheme Fluent = new FluentTheme(new Uri("avares://ControlCatalog/Styles")); - - public static SimpleTheme Simple = new SimpleTheme(new Uri("avares://ControlCatalog/Styles")); - - public static Styles SimpleLight = new Styles - { - new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog")) - { - Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/AccentColors.xaml") - }, - new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog")) - { - Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/Base.xaml") - }, - new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog")) - { - Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/BaseLight.xaml") - }, - Simple - }; - - public static Styles SimpleDark = new Styles - { - new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog")) - { - Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/AccentColors.xaml") - }, - new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog")) - { - Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/Base.xaml") - }, - new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog")) - { - Source = new Uri("avares://Avalonia.Themes.Fluent/Accents/BaseDark.xaml") - }, - Simple - }; - public override void Initialize() { - Styles.Insert(0, Fluent); - Styles.Insert(1, ColorPickerFluent); - Styles.Insert(2, DataGridFluent); + Styles.Add(_themeStylesContainer); + AvaloniaXamlLoader.Load(this); + + _fluentTheme = new FluentTheme(); + _simpleTheme = new SimpleTheme(); + _simpleTheme.Resources.MergedDictionaries.Add((IResourceDictionary)Resources["FluentAccentColors"]!); + _simpleTheme.Resources.MergedDictionaries.Add((IResourceDictionary)Resources["FluentBaseColors"]!); + _colorPickerFluent = (IStyle)Resources["ColorPickerFluent"]!; + _colorPickerSimple = (IStyle)Resources["ColorPickerSimple"]!; + _dataGridFluent = (IStyle)Resources["DataGridFluent"]!; + _dataGridSimple = (IStyle)Resources["DataGridSimple"]!; + _fluentBaseLightColors = (IResourceDictionary)Resources["FluentBaseLightColors"]!; + _fluentBaseDarkColors = (IResourceDictionary)Resources["FluentBaseDarkColors"]!; + + SetThemeVariant(CatalogTheme.FluentLight); } public override void OnFrameworkInitializationCompleted() @@ -97,5 +58,78 @@ namespace ControlCatalog base.OnFrameworkInitializationCompleted(); } + + private CatalogTheme _prevTheme; + public static CatalogTheme CurrentTheme => ((App)Current!)._prevTheme; + public static void SetThemeVariant(CatalogTheme theme) + { + var app = (App)Current!; + var prevTheme = app._prevTheme; + app._prevTheme = theme; + var shouldReopenWindow = theme switch + { + CatalogTheme.FluentLight => prevTheme is CatalogTheme.SimpleDark or CatalogTheme.SimpleLight, + CatalogTheme.FluentDark => prevTheme is CatalogTheme.SimpleDark or CatalogTheme.SimpleLight, + CatalogTheme.SimpleLight => prevTheme is CatalogTheme.FluentDark or CatalogTheme.FluentLight, + CatalogTheme.SimpleDark => prevTheme is CatalogTheme.FluentDark or CatalogTheme.FluentLight, + _ => throw new ArgumentOutOfRangeException(nameof(theme), theme, null) + }; + + if (app._themeStylesContainer.Count == 0) + { + app._themeStylesContainer.Add(new Style()); + app._themeStylesContainer.Add(new Style()); + app._themeStylesContainer.Add(new Style()); + } + + if (theme == CatalogTheme.FluentLight) + { + app._fluentTheme!.Mode = FluentThemeMode.Light; + app._themeStylesContainer[0] = app._fluentTheme; + app._themeStylesContainer[1] = app._colorPickerFluent!; + app._themeStylesContainer[2] = app._dataGridFluent!; + } + else if (theme == CatalogTheme.FluentDark) + { + app._fluentTheme!.Mode = FluentThemeMode.Dark; + app._themeStylesContainer[0] = app._fluentTheme; + app._themeStylesContainer[1] = app._colorPickerFluent!; + app._themeStylesContainer[2] = app._dataGridFluent!; + } + else if (theme == CatalogTheme.SimpleLight) + { + app._simpleTheme!.Mode = SimpleThemeMode.Light; + app._simpleTheme.Resources.MergedDictionaries.Remove(app._fluentBaseDarkColors!); + app._simpleTheme.Resources.MergedDictionaries.Add(app._fluentBaseLightColors!); + app._themeStylesContainer[0] = app._simpleTheme; + app._themeStylesContainer[1] = app._colorPickerSimple!; + app._themeStylesContainer[2] = app._dataGridSimple!; + } + else if (theme == CatalogTheme.SimpleDark) + { + app._simpleTheme!.Mode = SimpleThemeMode.Dark; + app._simpleTheme.Resources.MergedDictionaries.Remove(app._fluentBaseLightColors!); + app._simpleTheme.Resources.MergedDictionaries.Add(app._fluentBaseDarkColors!); + app._themeStylesContainer[0] = app._simpleTheme; + app._themeStylesContainer[1] = app._colorPickerSimple!; + app._themeStylesContainer[2] = app._dataGridSimple!; + } + + if (shouldReopenWindow) + { + if (app.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktopLifetime) + { + var oldWindow = desktopLifetime.MainWindow; + var newWindow = new MainWindow(); + desktopLifetime.MainWindow = newWindow; + newWindow.Show(); + oldWindow?.Close(); + } + else if (app.ApplicationLifetime is ISingleViewApplicationLifetime singleViewLifetime) + { + singleViewLifetime.MainView = new MainView(); + } + } + } } } diff --git a/samples/ControlCatalog/ControlCatalog.csproj b/samples/ControlCatalog/ControlCatalog.csproj index 2654574a3e..6b550a30be 100644 --- a/samples/ControlCatalog/ControlCatalog.csproj +++ b/samples/ControlCatalog/ControlCatalog.csproj @@ -14,9 +14,6 @@ - - - @@ -35,17 +32,5 @@ - - - MSBuild:Compile - - - - - - %(Filename) - - - diff --git a/samples/ControlCatalog/DecoratedWindow.xaml b/samples/ControlCatalog/DecoratedWindow.xaml index c778b31c42..997ae54f41 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" SystemDecorations="None" Name="Window"> + SystemDecorations="None" Name="Window"> @@ -43,8 +43,13 @@ Hello world! - Decorated - + + + None + BorderOnly + Full + + CanResize diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml index ec198c6bba..b5a09b5fbd 100644 --- a/samples/ControlCatalog/MainView.xaml +++ b/samples/ControlCatalog/MainView.xaml @@ -1,9 +1,11 @@ + xmlns:controls="using:ControlSamples" + xmlns:models="using:ControlCatalog.Models" + xmlns:pages="using:ControlCatalog.Pages" + xmlns:viewModels="using:ControlCatalog.ViewModels" + x:DataType="viewModels:MainWindowViewModel"> - - + + @@ -118,6 +120,9 @@ + + + @@ -130,7 +135,7 @@ - + diff --git a/samples/ControlCatalog/MainView.xaml.cs b/samples/ControlCatalog/MainView.xaml.cs index 7001eb41ea..15e666ae7b 100644 --- a/samples/ControlCatalog/MainView.xaml.cs +++ b/samples/ControlCatalog/MainView.xaml.cs @@ -6,7 +6,6 @@ using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using Avalonia.Media; using Avalonia.Media.Immutable; -using Avalonia.Themes.Fluent; using ControlCatalog.Models; using ControlCatalog.Pages; @@ -31,46 +30,12 @@ namespace ControlCatalog } var themes = this.Get("Themes"); + themes.SelectedItem = App.CurrentTheme; themes.SelectionChanged += (sender, e) => { if (themes.SelectedItem is CatalogTheme theme) { - var themeStyle = Application.Current!.Styles[0]; - if (theme == CatalogTheme.FluentLight) - { - if (App.Fluent.Mode != FluentThemeMode.Light) - { - App.Fluent.Mode = FluentThemeMode.Light; - } - Application.Current.Styles[0] = App.Fluent; - Application.Current.Styles[1] = App.ColorPickerFluent; - Application.Current.Styles[2] = App.DataGridFluent; - } - else if (theme == CatalogTheme.FluentDark) - { - - if (App.Fluent.Mode != FluentThemeMode.Dark) - { - App.Fluent.Mode = FluentThemeMode.Dark; - } - Application.Current.Styles[0] = App.Fluent; - Application.Current.Styles[1] = App.ColorPickerFluent; - Application.Current.Styles[2] = App.DataGridFluent; - } - else if (theme == CatalogTheme.SimpleLight) - { - App.Simple.Mode = Avalonia.Themes.Simple.SimpleThemeMode.Light; - Application.Current.Styles[0] = App.SimpleLight; - Application.Current.Styles[1] = App.ColorPickerSimple; - Application.Current.Styles[2] = App.DataGridSimple; - } - else if (theme == CatalogTheme.SimpleDark) - { - App.Simple.Mode = Avalonia.Themes.Simple.SimpleThemeMode.Dark; - Application.Current.Styles[0] = App.SimpleDark; - Application.Current.Styles[1] = App.ColorPickerSimple; - Application.Current.Styles[2] = App.DataGridSimple; - } + App.SetThemeVariant(theme); } }; diff --git a/samples/ControlCatalog/MainWindow.xaml b/samples/ControlCatalog/MainWindow.xaml index d5513904c0..cebb3e0916 100644 --- a/samples/ControlCatalog/MainWindow.xaml +++ b/samples/ControlCatalog/MainWindow.xaml @@ -1,19 +1,20 @@  + x:Class="ControlCatalog.MainWindow" WindowState="{Binding WindowState, Mode=TwoWay}" + x:DataType="vm:MainWindowViewModel"> diff --git a/samples/ControlCatalog/MainWindow.xaml.cs b/samples/ControlCatalog/MainWindow.xaml.cs index c61296ac8f..c589f41442 100644 --- a/samples/ControlCatalog/MainWindow.xaml.cs +++ b/samples/ControlCatalog/MainWindow.xaml.cs @@ -11,23 +11,13 @@ namespace ControlCatalog { public class MainWindow : Window { - private WindowNotificationManager _notificationArea; private NativeMenu? _recentMenu; public MainWindow() { this.InitializeComponent(); - //Renderer.DrawFps = true; - //Renderer.DrawDirtyRects = Renderer.DrawFps = true; - - _notificationArea = new WindowNotificationManager(this) - { - Position = NotificationPosition.TopRight, - MaxItems = 3 - }; - - DataContext = new MainWindowViewModel(_notificationArea); + DataContext = new MainWindowViewModel(); _recentMenu = ((NativeMenu.GetMenu(this)?.Items[0] as NativeMenuItem)?.Menu?.Items[2] as NativeMenuItem)?.Menu; } diff --git a/samples/ControlCatalog/Models/StateData.cs b/samples/ControlCatalog/Models/StateData.cs new file mode 100644 index 0000000000..bd6d186252 --- /dev/null +++ b/samples/ControlCatalog/Models/StateData.cs @@ -0,0 +1,20 @@ +namespace ControlCatalog.Models; + +public class StateData +{ + public string Name { get; private set; } + public string Abbreviation { get; private set; } + public string Capital { get; private set; } + + public StateData(string name, string abbreviatoin, string capital) + { + Name = name; + Abbreviation = abbreviatoin; + Capital = capital; + } + + public override string ToString() + { + return Name; + } +} \ No newline at end of file diff --git a/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml b/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml index faa12bc8da..a492808f1d 100644 --- a/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml +++ b/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml @@ -2,8 +2,8 @@ xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:sys="clr-namespace:System;assembly=netstandard" + xmlns:sys="using:System" + xmlns:models="using:ControlCatalog.Models" d:DesignHeight="600" d:DesignWidth="400"> - + diff --git a/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml.cs b/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml.cs index bc18327f12..8d9cd74ea7 100644 --- a/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml.cs +++ b/samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml.cs @@ -8,30 +8,12 @@ using System.Threading; using System.Threading.Tasks; using Avalonia.Data.Converters; using Avalonia.Data; +using ControlCatalog.Models; namespace ControlCatalog.Pages { public class AutoCompleteBoxPage : UserControl { - public class StateData - { - public string Name { get; private set; } - public string Abbreviation { get; private set; } - public string Capital { get; private set; } - - public StateData(string name, string abbreviatoin, string capital) - { - Name = name; - Abbreviation = abbreviatoin; - Capital = capital; - } - - public override string ToString() - { - return Name; - } - } - private StateData[] BuildAllStates() { return new StateData[] diff --git a/samples/ControlCatalog/Pages/BorderPage.xaml b/samples/ControlCatalog/Pages/BorderPage.xaml index bfc4f86698..7ec7e81e80 100644 --- a/samples/ControlCatalog/Pages/BorderPage.xaml +++ b/samples/ControlCatalog/Pages/BorderPage.xaml @@ -1,7 +1,6 @@ diff --git a/samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml b/samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml index 323d6d36e9..900e304559 100644 --- a/samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml +++ b/samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml @@ -1,7 +1,7 @@  + xmlns:sys="using:System"> The ButtonSpinner control allows you to add button spinners to any element and then respond to the Spin event to manipulate that element. diff --git a/samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml b/samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml index aef96802f4..7a22c0ddab 100644 --- a/samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml +++ b/samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml @@ -1,6 +1,6 @@ diff --git a/samples/ControlCatalog/Pages/ColorPickerPage.xaml b/samples/ControlCatalog/Pages/ColorPickerPage.xaml index ad54eb95fc..649256ba83 100644 --- a/samples/ControlCatalog/Pages/ColorPickerPage.xaml +++ b/samples/ControlCatalog/Pages/ColorPickerPage.xaml @@ -2,39 +2,39 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:controls="clr-namespace:Avalonia.Controls;assembly=Avalonia.Controls.ColorPicker" - xmlns:primitives="clr-namespace:Avalonia.Controls.Primitives;assembly=Avalonia.Controls" - xmlns:pc="clr-namespace:Avalonia.Controls.Primitives.Converters;assembly=Avalonia.Controls.ColorPicker" + xmlns:controls="using:Avalonia.Controls" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="ControlCatalog.Pages.ColorPickerPage"> - - - + + RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto"> + - + + - - diff --git a/samples/ControlCatalog/Pages/ColorPickerPage.xaml.cs b/samples/ControlCatalog/Pages/ColorPickerPage.xaml.cs index 6e017e381f..52d63ded32 100644 --- a/samples/ControlCatalog/Pages/ColorPickerPage.xaml.cs +++ b/samples/ControlCatalog/Pages/ColorPickerPage.xaml.cs @@ -1,6 +1,8 @@ using Avalonia; using Avalonia.Controls; +using Avalonia.Layout; using Avalonia.Markup.Xaml; +using Avalonia.Media; namespace ControlCatalog.Pages { @@ -9,6 +11,21 @@ namespace ControlCatalog.Pages public ColorPickerPage() { InitializeComponent(); + + var layoutRoot = this.GetControl("LayoutRoot"); + + // ColorPicker added from code-behind + var colorPicker = new ColorPicker() + { + Color = Colors.Blue, + Margin = new Thickness(0, 50, 0, 0), + HorizontalAlignment = HorizontalAlignment.Center, + Palette = new MaterialHalfColorPalette(), + }; + Grid.SetColumn(colorPicker, 2); + Grid.SetRow(colorPicker, 1); + + layoutRoot.Children.Add(colorPicker); } private void InitializeComponent() diff --git a/samples/ControlCatalog/Pages/ComboBoxPage.xaml b/samples/ControlCatalog/Pages/ComboBoxPage.xaml index 9f2fbb88f3..748a46c447 100644 --- a/samples/ControlCatalog/Pages/ComboBoxPage.xaml +++ b/samples/ControlCatalog/Pages/ComboBoxPage.xaml @@ -3,7 +3,9 @@ xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:col="using:System.Collections" - xmlns:sys="using:System"> + xmlns:sys="using:System" + xmlns:viewModels="using:ControlCatalog.ViewModels" + x:DataType="viewModels:ComboBoxPageViewModel"> A drop-down list. @@ -39,7 +41,7 @@ - + @@ -71,7 +73,7 @@ SelectedIndex="0" WrapSelection="{Binding WrapSelection}"> - + diff --git a/samples/ControlCatalog/Pages/CompositionPage.axaml b/samples/ControlCatalog/Pages/CompositionPage.axaml index 22c5c88941..403f45b8eb 100644 --- a/samples/ControlCatalog/Pages/CompositionPage.axaml +++ b/samples/ControlCatalog/Pages/CompositionPage.axaml @@ -1,6 +1,6 @@ Implicit animations @@ -42,4 +42,4 @@ - \ No newline at end of file + diff --git a/samples/ControlCatalog/Pages/ContextFlyoutPage.xaml b/samples/ControlCatalog/Pages/ContextFlyoutPage.xaml index 871efa5b7a..6ef6a202b6 100644 --- a/samples/ControlCatalog/Pages/ContextFlyoutPage.xaml +++ b/samples/ControlCatalog/Pages/ContextFlyoutPage.xaml @@ -3,9 +3,11 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:viewModels="using:ControlCatalog.ViewModels" d:DesignHeight="450" d:DesignWidth="800" - mc:Ignorable="d"> + mc:Ignorable="d" + x:DataType="viewModels:ContextPageViewModel"> diff --git a/samples/ControlCatalog/Pages/DataGridPage.xaml b/samples/ControlCatalog/Pages/DataGridPage.xaml index 5a5af65464..4c3c211ca5 100644 --- a/samples/ControlCatalog/Pages/DataGridPage.xaml +++ b/samples/ControlCatalog/Pages/DataGridPage.xaml @@ -4,13 +4,13 @@ x:Class="ControlCatalog.Pages.DataGridPage"> - + - + @@ -32,15 +32,15 @@ RowBackground="#1000"> - - + - - + + + IsVisible="{Binding #ShowGDP.IsChecked}" + x:DataType="local:Country" /> @@ -66,11 +66,11 @@ - - - - - + + + + + @@ -92,9 +92,9 @@ - - - + + + diff --git a/samples/ControlCatalog/Pages/DateTimePickerPage.xaml b/samples/ControlCatalog/Pages/DateTimePickerPage.xaml index 29cd939520..47753f56b6 100644 --- a/samples/ControlCatalog/Pages/DateTimePickerPage.xaml +++ b/samples/ControlCatalog/Pages/DateTimePickerPage.xaml @@ -2,7 +2,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:sys="clr-namespace:System;assembly=netstandard" + xmlns:sys="using:System" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="ControlCatalog.Pages.DateTimePickerPage"> @@ -13,17 +13,17 @@ Margin="16" HorizontalAlignment="Stretch" Spacing="16"> - A simple DatePicker with a header + A simple DatePicker - + - <DatePicker Header="Pick a date" /> + <DatePicker/> @@ -33,7 +33,7 @@ - + @@ -79,24 +79,24 @@ - + - A TimePicker with a header and minute increments specified. + A TimePicker with minute increments specified. - + - <TimePicker Header="Arrival time" MinuteIncrement="15" /> + <TimePicker MinuteIncrement="15" /> @@ -107,13 +107,13 @@ - + - <TimePicker ClockIdentifier="12HourClock" Header="12 hour clock" /> + <TimePicker ClockIdentifier="12HourClock" /> @@ -124,13 +124,13 @@ - + - <TimePicker ClockIdentifier="24HourClock" Header="24 hour clock" /> + <TimePicker ClockIdentifier="24HourClock" /> diff --git a/samples/ControlCatalog/Pages/ExpanderPage.xaml b/samples/ControlCatalog/Pages/ExpanderPage.xaml index f9ae1c7a3c..f0a80fd7ab 100644 --- a/samples/ControlCatalog/Pages/ExpanderPage.xaml +++ b/samples/ControlCatalog/Pages/ExpanderPage.xaml @@ -1,6 +1,8 @@ + xmlns:viewModels="using:ControlCatalog.ViewModels" + x:Class="ControlCatalog.Pages.ExpanderPage" + x:DataType="viewModels:ExpanderPageViewModel"> Expands to show nested content @@ -32,6 +34,23 @@ Expanded content + + + + + + + + + + + + @@ -109,6 +128,12 @@ CenterScreen CenterOwner + + Normal + Minimized + Maximized + FullScreen + diff --git a/samples/IntegrationTestApp/MainWindow.axaml.cs b/samples/IntegrationTestApp/MainWindow.axaml.cs index f72f83fcb8..c1acc7ca88 100644 --- a/samples/IntegrationTestApp/MainWindow.axaml.cs +++ b/samples/IntegrationTestApp/MainWindow.axaml.cs @@ -4,6 +4,7 @@ using Avalonia; using Avalonia.Automation; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.Markup.Xaml; using Avalonia.VisualTree; @@ -17,6 +18,7 @@ namespace IntegrationTestApp { InitializeComponent(); InitializeViewMenu(); + InitializeGesturesTab(); this.AttachDevTools(); AddHandler(Button.ClickEvent, OnButtonClick); ListBoxItems = Enumerable.Range(0, 100).Select(x => "Item " + x).ToList(); @@ -57,6 +59,7 @@ namespace IntegrationTestApp var sizeTextBox = this.GetControl("ShowWindowSize"); var modeComboBox = this.GetControl("ShowWindowMode"); var locationComboBox = this.GetControl("ShowWindowLocation"); + var stateComboBox = this.GetControl("ShowWindowState"); var size = !string.IsNullOrWhiteSpace(sizeTextBox.Text) ? Size.Parse(sizeTextBox.Text) : (Size?)null; var owner = (Window)this.GetVisualRoot()!; @@ -83,6 +86,7 @@ namespace IntegrationTestApp } sizeTextBox.Text = string.Empty; + window.WindowState = (WindowState)stateComboBox.SelectedIndex; switch (modeComboBox.SelectedIndex) { @@ -120,6 +124,38 @@ namespace IntegrationTestApp } } + private void InitializeGesturesTab() + { + var gestureBorder = this.GetControl("GestureBorder"); + var gestureBorder2 = this.GetControl("GestureBorder2"); + var lastGesture = this.GetControl("LastGesture"); + var resetGestures = this.GetControl