diff --git a/.editorconfig b/.editorconfig
index 1583d3e469..3620896f34 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -140,6 +140,8 @@ dotnet_analyzer_diagnostic.category-Performance.severity = none #error - Uncomme
# CS1591: Missing XML comment for publicly visible type or member
dotnet_diagnostic.CS1591.severity = suggestion
+# CS0162: Remove unreachable code
+dotnet_diagnostic.CS0162.severity = error
# CA1304: Specify CultureInfo
dotnet_diagnostic.CA1304.severity = warning
# CA1802: Use literals where appropriate
@@ -152,6 +154,8 @@ dotnet_diagnostic.CA1820.severity = warning
dotnet_diagnostic.CA1821.severity = warning
# CA1822: Mark members as static
dotnet_diagnostic.CA1822.severity = suggestion
+# CA1823: Avoid unused private fields
+dotnet_diagnostic.CA1823.severity = warning
dotnet_code_quality.CA1822.api_surface = private, internal
# CA1825: Avoid zero-length array allocations
dotnet_diagnostic.CA1825.severity = warning
@@ -165,6 +169,8 @@ dotnet_diagnostic.CA1828.severity = warning
dotnet_diagnostic.CA1829.severity = warning
#CA1847: Use string.Contains(char) instead of string.Contains(string) with single characters
dotnet_diagnostic.CA1847.severity = warning
+#CACA2211:Non-constant fields should not be visible
+dotnet_diagnostic.CA2211.severity = error
# Wrapping preferences
csharp_wrap_before_ternary_opsigns = false
diff --git a/Avalonia.sln b/Avalonia.sln
index 7efb294b64..fc42a5d63b 100644
--- a/Avalonia.sln
+++ b/Avalonia.sln
@@ -100,7 +100,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1
build\EmbedXaml.props = build\EmbedXaml.props
build\HarfBuzzSharp.props = build\HarfBuzzSharp.props
build\ImageSharp.props = build\ImageSharp.props
- build\JetBrains.Annotations.props = build\JetBrains.Annotations.props
build\JetBrains.dotMemoryUnit.props = build\JetBrains.dotMemoryUnit.props
build\Microsoft.CSharp.props = build\Microsoft.CSharp.props
build\Microsoft.Reactive.Testing.props = build\Microsoft.Reactive.Testing.props
@@ -136,8 +135,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Linux", "Linux", "{86C53C40
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.LinuxFramebuffer", "src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj", "{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Direct3DInteropSample", "samples\interop\Direct3DInteropSample\Direct3DInteropSample.csproj", "{638580B0-7910-40EF-B674-DCB34DA308CD}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Win32.Interop", "src\Windows\Avalonia.Win32.Interop\Avalonia.Win32.Interop.csproj", "{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia.RenderTests", "tests\Avalonia.Skia.RenderTests\Avalonia.Skia.RenderTests.csproj", "{E1582370-37B3-403C-917F-8209551B1634}"
@@ -228,9 +225,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Browser", "src\Bro
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "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}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Browser", "samples\ControlCatalog.Browser\ControlCatalog.Browser.csproj", "{15B93A4C-1B46-43F6-B534-7B25B6E99932}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.Browser.Blazor", "samples\ControlCatalog.Browser.Blazor\ControlCatalog.Browser.Blazor.csproj", "{90B08091-9BBD-4362-B712-E9F2CC62B218}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.Browser.Blazor", "samples\ControlCatalog.Browser.Blazor\ControlCatalog.Browser.Blazor.csproj", "{90B08091-9BBD-4362-B712-E9F2CC62B218}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveUIDemo", "samples\ReactiveUIDemo\ReactiveUIDemo.csproj", "{75C47156-C5D8-44BC-A5A7-E8657C2248D6}"
EndProject
@@ -366,10 +363,6 @@ Global
{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|Any CPU.Build.0 = Release|Any CPU
- {638580B0-7910-40EF-B674-DCB34DA308CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {638580B0-7910-40EF-B674-DCB34DA308CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {638580B0-7910-40EF-B674-DCB34DA308CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {638580B0-7910-40EF-B674-DCB34DA308CD}.Release|Any CPU.Build.0 = Release|Any CPU
{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -580,7 +573,6 @@ Global
{7D2D3083-71DD-4CC9-8907-39A0D86FB322} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E}
{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{854568D5-13D1-4B4F-B50D-534DC7EFD3C9} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B}
- {638580B0-7910-40EF-B674-DCB34DA308CD} = {A0CC0258-D18C-4AB3-854F-7101680FC3F9}
{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E} = {B39A8919-9F95-48FE-AD7B-76E08B509888}
{E1582370-37B3-403C-917F-8209551B1634} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{E2999E4A-9086-401F-898C-AEB0AD38E676} = {9B9E3891-2366-4253-A952-D08BCEB71098}
diff --git a/Directory.Build.props b/Directory.Build.props
index 42daa2df7f..c19a55e8ea 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -7,5 +7,6 @@
false
false
False
+ 11
diff --git a/NOTICE.md b/NOTICE.md
index e97fc654c9..7083706c3e 100644
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -81,14 +81,14 @@ A "contributor" is any person that distributes its contribution under this licen
https://github.com/wayland-project/wayland-protocols
-Copyright 2008-2013 Kristian Hgsberg
-Copyright 2010-2013 Intel Corporation
-Copyright 2013 Rafael Antognolli
-Copyright 2013 Jasper St. Pierre
-Copyright 2014 Jonas dahl
-Copyright 2014 Jason Ekstrand
-Copyright 2014-2015 Collabora, Ltd.
-Copyright 2015 Red Hat Inc.
+Copyright © 2008-2013 Kristian Høgsberg
+Copyright © 2010-2013 Intel Corporation
+Copyright © 2013 Rafael Antognolli
+Copyright © 2013 Jasper St. Pierre
+Copyright © 2014 Jonas Ådahl
+Copyright © 2014 Jason Ekstrand
+Copyright © 2014-2015 Collabora, Ltd.
+Copyright © 2015 Red Hat Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -140,7 +140,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
https://github.com/toptensoftware/RichTextKit
-Copyright 2019 Topten Software. All Rights Reserved.
+Copyright © 2019 Topten Software. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this product except in compliance with the License. You may obtain
@@ -303,3 +303,62 @@ https://github.com/chromium/chromium
// 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.
+
+# Flutter
+
+https://github.com/flutter/flutter
+
+//Copyright 2014 The Flutter Authors. All rights reserved.
+
+//Redistribution and use in source and binary forms, with or without modification,
+//are permitted provided that the following conditions are met:
+
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+//WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+//DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+//ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+//(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+//LOSS OF USE, DATA, OR PROFITS;
+//OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+//ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+//(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Reactive Extensions
+
+https://github.com/dotnet/reactive
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/azure-pipelines-integrationtests.yml b/azure-pipelines-integrationtests.yml
index 43253ac6be..5735da19ab 100644
--- a/azure-pipelines-integrationtests.yml
+++ b/azure-pipelines-integrationtests.yml
@@ -13,14 +13,14 @@ jobs:
steps:
- task: UseDotNet@2
- displayName: 'Use .NET Core SDK 6.0.401'
+ displayName: 'Use .NET Core SDK 6.0.404'
inputs:
- version: 6.0.401
+ version: 6.0.404
- task: UseDotNet@2
- displayName: 'Use .NET Core SDK 7.0.100'
+ displayName: 'Use .NET Core SDK 7.0.101'
inputs:
- version: 7.0.100
+ version: 7.0.101
- script: system_profiler SPDisplaysDataType |grep Resolution
@@ -51,14 +51,14 @@ jobs:
steps:
- task: UseDotNet@2
- displayName: 'Use .NET Core SDK 6.0.401'
+ displayName: 'Use .NET Core SDK 6.0.404'
inputs:
- version: 6.0.401
+ version: 6.0.404
- task: UseDotNet@2
- displayName: 'Use .NET Core SDK 7.0.100'
+ displayName: 'Use .NET Core SDK 7.0.101'
inputs:
- version: 7.0.100
+ version: 7.0.101
- task: Windows Application Driver@0
inputs:
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index a3bbc33418..8bab6e68e2 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -30,14 +30,14 @@ jobs:
vmImage: 'ubuntu-20.04'
steps:
- task: UseDotNet@2
- displayName: 'Use .NET Core SDK 6.0.401'
+ displayName: 'Use .NET Core SDK 6.0.404'
inputs:
- version: 6.0.401
+ version: 6.0.404
- task: UseDotNet@2
- displayName: 'Use .NET Core SDK 7.0'
+ displayName: 'Use .NET Core SDK 7.0.101'
inputs:
- version: 7.0.100
+ version: 7.0.101
- task: CmdLine@2
displayName: 'Install Workloads'
@@ -67,14 +67,14 @@ jobs:
vmImage: 'macos-12'
steps:
- task: UseDotNet@2
- displayName: 'Use .NET Core SDK 6.0.401'
+ displayName: 'Use .NET Core SDK 6.0.404'
inputs:
- version: 6.0.401
+ version: 6.0.404
- task: UseDotNet@2
- displayName: 'Use .NET Core SDK 7.0.100'
+ displayName: 'Use .NET Core SDK 7.0.101'
inputs:
- version: 7.0.100
+ version: 7.0.101
- task: CmdLine@2
displayName: 'Install Workloads'
@@ -138,14 +138,14 @@ jobs:
SolutionDir: '$(Build.SourcesDirectory)'
steps:
- task: UseDotNet@2
- displayName: 'Use .NET Core SDK 6.0.401'
+ displayName: 'Use .NET Core SDK 6.0.404'
inputs:
- version: 6.0.401
+ version: 6.0.404
- task: UseDotNet@2
- displayName: 'Use .NET Core SDK 7.0.100'
+ displayName: 'Use .NET Core SDK 7.0.101'
inputs:
- version: 7.0.100
+ version: 7.0.101
- task: CmdLine@2
displayName: 'Install Workloads'
diff --git a/build/Base.props b/build/Base.props
index 100c9088cd..26f19e3abc 100644
--- a/build/Base.props
+++ b/build/Base.props
@@ -1,6 +1,7 @@
-
+
+
diff --git a/build/JetBrains.Annotations.props b/build/JetBrains.Annotations.props
deleted file mode 100644
index 7bc12cbd84..0000000000
--- a/build/JetBrains.Annotations.props
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/build/SharedVersion.props b/build/SharedVersion.props
index e9c3d65b41..eca3ba37b0 100644
--- a/build/SharedVersion.props
+++ b/build/SharedVersion.props
@@ -8,7 +8,6 @@
https://github.com/AvaloniaUI/Avalonia/
true
$(NoWarn);CS1591
- 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/build/System.Memory.props b/build/System.Memory.props
index b36998a780..a413e18927 100644
--- a/build/System.Memory.props
+++ b/build/System.Memory.props
@@ -1,5 +1,5 @@
-
+
diff --git a/global.json b/global.json
index a9318b212f..8536535b51 100644
--- a/global.json
+++ b/global.json
@@ -1,11 +1,9 @@
{
"sdk": {
- "version": "7.0.100",
+ "version": "7.0.101",
"rollForward": "latestFeature"
},
"msbuild-sdks": {
- "Microsoft.Build.Traversal": "1.0.43",
- "MSBuild.Sdk.Extras": "3.0.22",
- "AggregatePackage.NuGet.Sdk" : "0.1.12"
+ "Microsoft.Build.Traversal": "3.2.0"
}
}
diff --git a/nukebuild/DotNetConfigHelper.cs b/nukebuild/DotNetConfigHelper.cs
index eca1e2684d..9d43261616 100644
--- a/nukebuild/DotNetConfigHelper.cs
+++ b/nukebuild/DotNetConfigHelper.cs
@@ -1,5 +1,4 @@
using System.Globalization;
-using JetBrains.Annotations;
using Nuke.Common.Tools.DotNet;
// ReSharper disable ReturnValueOfPureMethodIsNotUsed
diff --git a/packages/Avalonia/AvaloniaBuildTasks.targets b/packages/Avalonia/AvaloniaBuildTasks.targets
index ca2d4b66ed..33f22f4d02 100644
--- a/packages/Avalonia/AvaloniaBuildTasks.targets
+++ b/packages/Avalonia/AvaloniaBuildTasks.targets
@@ -48,8 +48,12 @@
+
+ <_AvaloniaResourcesInputsCacheFilePath>$(IntermediateOutputPath)/Avalonia/Resources.Inputs.cache
+
+
-
+
@@ -57,7 +61,11 @@
-
+
+
+
+
+
-
+
+
+
+
@@ -103,6 +114,9 @@
File="$(AvaloniaXamlReferencesTemporaryFilePath)"
Lines="@(ReferencePathWithRefAssemblies)"
Overwrite="true" />
+
+
+
+ DefaultCompileBindings="$(AvaloniaUseCompiledBindingsByDefault)">
+
+
diff --git a/samples/ControlCatalog.Android/MainActivity.cs b/samples/ControlCatalog.Android/MainActivity.cs
index 62c582610c..f6fa07dbde 100644
--- a/samples/ControlCatalog.Android/MainActivity.cs
+++ b/samples/ControlCatalog.Android/MainActivity.cs
@@ -5,7 +5,7 @@ using Avalonia.Android;
namespace ControlCatalog.Android
{
- [Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)]
+ [Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.Main", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)]
public class MainActivity : AvaloniaMainActivity
{
}
diff --git a/samples/ControlCatalog.Android/Resources/values/styles.xml b/samples/ControlCatalog.Android/Resources/values/styles.xml
index 2759d2904a..49e079a719 100644
--- a/samples/ControlCatalog.Android/Resources/values/styles.xml
+++ b/samples/ControlCatalog.Android/Resources/values/styles.xml
@@ -14,4 +14,8 @@
- @null
+
+
diff --git a/samples/ControlCatalog.Android/SplashActivity.cs b/samples/ControlCatalog.Android/SplashActivity.cs
index 908b5f082a..a0b68b129b 100644
--- a/samples/ControlCatalog.Android/SplashActivity.cs
+++ b/samples/ControlCatalog.Android/SplashActivity.cs
@@ -28,6 +28,8 @@ namespace ControlCatalog.Android
base.OnResume();
StartActivity(new Intent(Application.Context, typeof(MainActivity)));
+
+ Finish();
}
}
}
diff --git a/samples/ControlCatalog.Browser/Properties/launchSettings.json b/samples/ControlCatalog.Browser/Properties/launchSettings.json
new file mode 100644
index 0000000000..76c1834e3c
--- /dev/null
+++ b/samples/ControlCatalog.Browser/Properties/launchSettings.json
@@ -0,0 +1,13 @@
+{
+ "profiles": {
+ "ControlCatalog.Browser": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "https://localhost:5001;http://localhost:5000",
+ "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/debug?browser={browserInspectUri}"
+ }
+ }
+}
diff --git a/samples/ControlCatalog.Desktop/Program.cs b/samples/ControlCatalog.Desktop/Program.cs
index 7b8b27fff7..4d28f15e2c 100644
--- a/samples/ControlCatalog.Desktop/Program.cs
+++ b/samples/ControlCatalog.Desktop/Program.cs
@@ -23,7 +23,7 @@ namespace ControlCatalog
private static void ConfigureAssetAssembly(AppBuilder builder)
{
AvaloniaLocator.CurrentMutable
- .GetService()
+ .GetRequiredService()
.SetDefaultAssembly(typeof(App).Assembly);
}
}
diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml
index 4a5f5bc96c..166b98436e 100644
--- a/samples/ControlCatalog/MainView.xaml
+++ b/samples/ControlCatalog/MainView.xaml
@@ -92,6 +92,9 @@
+
+
+
@@ -206,8 +209,7 @@
+ HorizontalAlignment="Stretch">
None
Transparent
diff --git a/samples/ControlCatalog/MainView.xaml.cs b/samples/ControlCatalog/MainView.xaml.cs
index 15e666ae7b..f3c1a68e72 100644
--- a/samples/ControlCatalog/MainView.xaml.cs
+++ b/samples/ControlCatalog/MainView.xaml.cs
@@ -6,6 +6,7 @@ using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using Avalonia.Media.Immutable;
+using Avalonia.VisualTree;
using ControlCatalog.Models;
using ControlCatalog.Pages;
@@ -59,17 +60,25 @@ namespace ControlCatalog
};
var transparencyLevels = this.Get("TransparencyLevels");
- IDisposable? backgroundSetter = null, paneBackgroundSetter = null;
+ IDisposable? topLevelBackgroundSideSetter = null, sideBarBackgroundSetter = null, paneBackgroundSetter = null;
transparencyLevels.SelectionChanged += (sender, e) =>
{
- backgroundSetter?.Dispose();
+ topLevelBackgroundSideSetter?.Dispose();
+ sideBarBackgroundSetter?.Dispose();
paneBackgroundSetter?.Dispose();
- if (transparencyLevels.SelectedItem is WindowTransparencyLevel selected
- && selected != WindowTransparencyLevel.None)
+ if (transparencyLevels.SelectedItem is WindowTransparencyLevel selected)
{
- var semiTransparentBrush = new ImmutableSolidColorBrush(Colors.Gray, 0.5);
- backgroundSetter = sideBar.SetValue(BackgroundProperty, semiTransparentBrush, Avalonia.Data.BindingPriority.Style);
- paneBackgroundSetter = sideBar.SetValue(SplitView.PaneBackgroundProperty, semiTransparentBrush, Avalonia.Data.BindingPriority.Style);
+ var topLevel = (TopLevel)this.GetVisualRoot()!;
+ topLevel.TransparencyLevelHint = selected;
+
+ if (selected != WindowTransparencyLevel.None)
+ {
+ var transparentBrush = new ImmutableSolidColorBrush(Colors.White, 0);
+ var semiTransparentBrush = new ImmutableSolidColorBrush(Colors.Gray, 0.2);
+ topLevelBackgroundSideSetter = topLevel.SetValue(BackgroundProperty, transparentBrush, Avalonia.Data.BindingPriority.Style);
+ sideBarBackgroundSetter = sideBar.SetValue(BackgroundProperty, semiTransparentBrush, Avalonia.Data.BindingPriority.Style);
+ paneBackgroundSetter = sideBar.SetValue(SplitView.PaneBackgroundProperty, semiTransparentBrush, Avalonia.Data.BindingPriority.Style);
+ }
}
};
}
diff --git a/samples/ControlCatalog/MainWindow.xaml b/samples/ControlCatalog/MainWindow.xaml
index cebb3e0916..442c1d37b0 100644
--- a/samples/ControlCatalog/MainWindow.xaml
+++ b/samples/ControlCatalog/MainWindow.xaml
@@ -10,7 +10,6 @@
ExtendClientAreaToDecorationsHint="{Binding ExtendClientAreaEnabled}"
ExtendClientAreaChromeHints="{Binding ChromeHints}"
ExtendClientAreaTitleBarHeightHint="{Binding TitleBarHeight}"
- TransparencyLevelHint="{Binding TransparencyLevel}"
x:Name="MainWindow"
Background="Transparent"
x:Class="ControlCatalog.MainWindow" WindowState="{Binding WindowState, Mode=TwoWay}"
diff --git a/samples/ControlCatalog/Models/StateData.cs b/samples/ControlCatalog/Models/StateData.cs
index bd6d186252..a7ea655cd2 100644
--- a/samples/ControlCatalog/Models/StateData.cs
+++ b/samples/ControlCatalog/Models/StateData.cs
@@ -6,10 +6,10 @@ public class StateData
public string Abbreviation { get; private set; }
public string Capital { get; private set; }
- public StateData(string name, string abbreviatoin, string capital)
+ public StateData(string name, string abbreviation, string capital)
{
Name = name;
- Abbreviation = abbreviatoin;
+ Abbreviation = abbreviation;
Capital = capital;
}
@@ -17,4 +17,4 @@ public class StateData
{
return Name;
}
-}
\ No newline at end of file
+}
diff --git a/samples/ControlCatalog/Pages/CompositionPage.axaml b/samples/ControlCatalog/Pages/CompositionPage.axaml
index 403f45b8eb..602b9b768d 100644
--- a/samples/ControlCatalog/Pages/CompositionPage.axaml
+++ b/samples/ControlCatalog/Pages/CompositionPage.axaml
@@ -2,44 +2,57 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:pages="using:ControlCatalog.Pages"
x:Class="ControlCatalog.Pages.CompositionPage">
-
- Implicit animations
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Resize me
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Resize me
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/CompositionPage.axaml.cs b/samples/ControlCatalog/Pages/CompositionPage.axaml.cs
index c70675b606..8b12a2d663 100644
--- a/samples/ControlCatalog/Pages/CompositionPage.axaml.cs
+++ b/samples/ControlCatalog/Pages/CompositionPage.axaml.cs
@@ -1,28 +1,39 @@
using System;
using System.Collections.Generic;
+using System.Numerics;
+using System.Threading;
using Avalonia;
+using Avalonia.Animation;
using Avalonia.Controls;
+using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
+using Avalonia.Media.Immutable;
using Avalonia.Rendering.Composition;
using Avalonia.Rendering.Composition.Animations;
using Avalonia.VisualTree;
+using Math = System.Math;
namespace ControlCatalog.Pages;
public partial class CompositionPage : UserControl
{
private ImplicitAnimationCollection? _implicitAnimations;
+ private CompositionCustomVisual? _customVisual;
+ private CompositionSolidColorVisual? _solidVisual;
public CompositionPage()
{
AvaloniaXamlLoader.Load(this);
+ AttachAnimatedSolidVisual(this.FindControl("SolidVisualHost")!);
+ AttachCustomVisual(this.FindControl("CustomVisualHost")!);
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
this.Get("Items").Items = CreateColorItems();
+
}
private static List CreateColorItems()
@@ -126,6 +137,167 @@ public partial class CompositionPage : UserControl
compositionVisual.ImplicitAnimations = page._implicitAnimations;
}
}
+
+ void AttachAnimatedSolidVisual(Visual v)
+ {
+ void Update()
+ {
+ if(_solidVisual == null)
+ return;
+ _solidVisual.Size = new Vector2((float)v.Bounds.Width / 3, (float)v.Bounds.Height / 3);
+ _solidVisual.Offset = new Vector3((float)v.Bounds.Width / 3, (float)v.Bounds.Height / 3, 0);
+ }
+ v.AttachedToVisualTree += delegate
+ {
+ var compositor = ElementComposition.GetElementVisual(v)?.Compositor;
+ if(compositor == null || _solidVisual?.Compositor == compositor)
+ return;
+ _solidVisual = compositor.CreateSolidColorVisual();
+ ElementComposition.SetElementChildVisual(v, _solidVisual);
+ _solidVisual.Color = Colors.Red;
+ var animation = _solidVisual.Compositor.CreateColorKeyFrameAnimation();
+ animation.InsertKeyFrame(0, Colors.Red);
+ animation.InsertKeyFrame(0.5f, Colors.Blue);
+ animation.InsertKeyFrame(1, Colors.Green);
+ animation.Duration = TimeSpan.FromSeconds(5);
+ animation.IterationBehavior = AnimationIterationBehavior.Forever;
+ animation.Direction = PlaybackDirection.Alternate;
+ _solidVisual.StartAnimation("Color", animation);
+
+ _solidVisual.AnchorPoint = new Vector2(0, 0);
+
+ var scale = _solidVisual.Compositor.CreateVector3KeyFrameAnimation();
+ scale.Duration = TimeSpan.FromSeconds(5);
+ scale.IterationBehavior = AnimationIterationBehavior.Forever;
+ scale.InsertKeyFrame(0, new Vector3(1, 1, 0));
+ scale.InsertKeyFrame(0.5f, new Vector3(1.5f, 1.5f, 0));
+ scale.InsertKeyFrame(1, new Vector3(1, 1, 0));
+
+ _solidVisual.StartAnimation("Scale", scale);
+
+ var center =
+ _solidVisual.Compositor.CreateExpressionAnimation(
+ "Vector3(this.Target.Size.X * 0.5, this.Target.Size.Y * 0.5, 1)");
+ _solidVisual.StartAnimation("CenterPoint", center);
+ Update();
+ };
+ v.PropertyChanged += (_, a) =>
+ {
+ if (a.Property == BoundsProperty)
+ Update();
+ };
+ }
+
+ void AttachCustomVisual(Visual v)
+ {
+ void Update()
+ {
+ if (_customVisual == null)
+ return;
+ var h = (float)Math.Min(v.Bounds.Height, v.Bounds.Width / 3);
+ _customVisual.Size = new Vector2((float)v.Bounds.Width, h);
+ _customVisual.Offset = new Vector3(0, (float)(v.Bounds.Height - h) / 2, 0);
+ }
+ v.AttachedToVisualTree += delegate
+ {
+ var compositor = ElementComposition.GetElementVisual(v)?.Compositor;
+ if(compositor == null || _customVisual?.Compositor == compositor)
+ return;
+ _customVisual = compositor.CreateCustomVisual(new CustomVisualHandler());
+ ElementComposition.SetElementChildVisual(v, _customVisual);
+ _customVisual.SendHandlerMessage(CustomVisualHandler.StartMessage);
+ Update();
+ };
+
+ v.PropertyChanged += (_, a) =>
+ {
+ if (a.Property == BoundsProperty)
+ Update();
+ };
+ }
+
+ class CustomVisualHandler : CompositionCustomVisualHandler
+ {
+ private TimeSpan _animationElapsed;
+ private TimeSpan? _lastServerTime;
+ private bool _running;
+
+ public static readonly object StopMessage = new(), StartMessage = new();
+
+ public override void OnRender(ImmediateDrawingContext drawingContext)
+ {
+ if (_running)
+ {
+ if (_lastServerTime.HasValue) _animationElapsed += (CompositionNow - _lastServerTime.Value);
+ _lastServerTime = CompositionNow;
+ }
+
+ const int cnt = 20;
+ var maxPointSizeX = EffectiveSize.X / (cnt * 1.6);
+ var maxPointSizeY = EffectiveSize.Y / 4;
+ var pointSize = Math.Min(maxPointSizeX, maxPointSizeY);
+ var animationLength = TimeSpan.FromSeconds(4);
+ var animationStage = _animationElapsed.TotalSeconds / animationLength.TotalSeconds;
+
+ var sinOffset = Math.Cos(_animationElapsed.TotalSeconds) * 1.5;
+
+ for (var c = 0; c < cnt; c++)
+ {
+ var stage = (animationStage + (double)c / cnt) % 1;
+ var colorStage =
+ (animationStage + (Math.Sin(_animationElapsed.TotalSeconds * 2) + 1) / 2 + (double)c / cnt) % 1;
+ var posX = (EffectiveSize.X + pointSize * 3) * stage - pointSize;
+ var posY = (EffectiveSize.Y - pointSize) * (1 + Math.Sin(stage * 3.14 * 3 + sinOffset)) / 2 + pointSize / 2;
+ var opacity = Math.Sin(stage * 3.14);
+
+
+ drawingContext.DrawEllipse(new ImmutableSolidColorBrush(Color.FromArgb(
+ 255,
+ (byte)(255 - 255 * colorStage),
+ (byte)(255 * Math.Abs(0.5 - colorStage) * 2),
+ (byte)(255 * colorStage)
+ ), opacity), null,
+ new Point(posX, posY), pointSize / 2, pointSize / 2);
+ }
+
+ }
+
+ public override void OnMessage(object message)
+ {
+ if (message == StartMessage)
+ {
+ _running = true;
+ _lastServerTime = null;
+ RegisterForNextAnimationFrameUpdate();
+ }
+ else if (message == StopMessage)
+ _running = false;
+ }
+
+ public override void OnAnimationFrameUpdate()
+ {
+ if (_running)
+ {
+ Invalidate();
+ RegisterForNextAnimationFrameUpdate();
+ }
+ }
+ }
+
+ private void ButtonThreadSleep(object? sender, RoutedEventArgs e)
+ {
+ Thread.Sleep(10000);
+ }
+
+ private void ButtonStartCustomVisual(object? sender, RoutedEventArgs e)
+ {
+ _customVisual?.SendHandlerMessage(CustomVisualHandler.StartMessage);
+ }
+
+ private void ButtonStopCustomVisual(object? sender, RoutedEventArgs e)
+ {
+ _customVisual?.SendHandlerMessage(CustomVisualHandler.StopMessage);
+ }
}
public class CompositionPageColorItem
diff --git a/samples/ControlCatalog/Pages/DateTimePickerPage.xaml.cs b/samples/ControlCatalog/Pages/DateTimePickerPage.xaml.cs
index 11f504f4db..7520dabf37 100644
--- a/samples/ControlCatalog/Pages/DateTimePickerPage.xaml.cs
+++ b/samples/ControlCatalog/Pages/DateTimePickerPage.xaml.cs
@@ -17,7 +17,7 @@ namespace ControlCatalog.Pages
this.Get("TimePickerDesc").Text = "Use a TimePicker to let users set a time in your app, for example " +
"to set a reminder. The TimePicker displays three controls for hour, minute, and AM / PM(if necessary).These controls " +
"are easy to use with touch or mouse, and they can be styled and configured in several different ways. " +
- "12 - hour or 24 - hour clock and visiblility of AM / PM is dynamically set based on user time settings, or can be overridden.";
+ "12 - hour or 24 - hour clock and visibility of AM / PM is dynamically set based on user time settings, or can be overridden.";
}
diff --git a/samples/ControlCatalog/Pages/DialogsPage.xaml.cs b/samples/ControlCatalog/Pages/DialogsPage.xaml.cs
index 67e9ef4e40..8db6e76dca 100644
--- a/samples/ControlCatalog/Pages/DialogsPage.xaml.cs
+++ b/samples/ControlCatalog/Pages/DialogsPage.xaml.cs
@@ -396,8 +396,8 @@ CanPickFolder: {storageProvider.CanPickFolder}";
return item.TryGetUri(out var uri) ? uri.ToString() : item.Name;
}
- Window GetWindow() => this.VisualRoot as Window ?? throw new NullReferenceException("Invalid Owner");
- TopLevel GetTopLevel() => this.VisualRoot as TopLevel ?? throw new NullReferenceException("Invalid Owner");
+ Window GetWindow() => TopLevel.GetTopLevel(this) as Window ?? throw new NullReferenceException("Invalid Owner");
+ TopLevel GetTopLevel() => TopLevel.GetTopLevel(this) ?? throw new NullReferenceException("Invalid Owner");
private void InitializeComponent()
{
diff --git a/samples/ControlCatalog/Pages/GesturePage.cs b/samples/ControlCatalog/Pages/GesturePage.cs
new file mode 100644
index 0000000000..ee10f21317
--- /dev/null
+++ b/samples/ControlCatalog/Pages/GesturePage.cs
@@ -0,0 +1,212 @@
+using System;
+using System.Numerics;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Input;
+using Avalonia.LogicalTree;
+using Avalonia.Markup.Xaml;
+using Avalonia.Rendering.Composition;
+
+namespace ControlCatalog.Pages
+{
+ public class GesturePage : UserControl
+ {
+ private bool _isInit;
+ private float _currentScale;
+
+ public GesturePage()
+ {
+ this.InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+
+ protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
+ {
+ base.OnAttachedToVisualTree(e);
+
+ if(_isInit)
+ {
+ return;
+ }
+
+ _isInit = true;
+
+ SetPullHandlers(this.Find("TopPullZone"), false);
+ SetPullHandlers(this.Find("BottomPullZone"), true);
+ SetPullHandlers(this.Find("RightPullZone"), true);
+ SetPullHandlers(this.Find("LeftPullZone"), false);
+
+ var image = this.Find("PinchImage");
+ SetPinchHandlers(image);
+
+ var reset = this.Find