diff --git a/.editorconfig b/.editorconfig index 62a533e468..d5b2badfd5 100644 --- a/.editorconfig +++ b/.editorconfig @@ -208,6 +208,12 @@ dotnet_diagnostic.AVA2001.severity = error # Xaml files [*.{xaml,axaml}] indent_size = 2 +# DuplicateSetterError +avalonia_xaml_diagnostic.AVLN2203.severity = error +# StyleInMergedDictionaries +avalonia_xaml_diagnostic.AVLN2204.severity = error +# Obsolete +avalonia_xaml_diagnostic.AVLN5001.severity = error # Xml project files [*.{csproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}] diff --git a/api/Avalonia.Themes.Fluent.nupkg.xml b/api/Avalonia.Themes.Fluent.nupkg.xml index f35bf5a629..a5be5ceeb9 100644 --- a/api/Avalonia.Themes.Fluent.nupkg.xml +++ b/api/Avalonia.Themes.Fluent.nupkg.xml @@ -403,6 +403,12 @@ baseline/netstandard2.0/Avalonia.Themes.Fluent.dll target/netstandard2.0/Avalonia.Themes.Fluent.dll + + CP0001 + T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/UserControl.xaml + baseline/netstandard2.0/Avalonia.Themes.Fluent.dll + target/netstandard2.0/Avalonia.Themes.Fluent.dll + CP0001 T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Window.xaml diff --git a/api/Avalonia.Themes.Simple.nupkg.xml b/api/Avalonia.Themes.Simple.nupkg.xml index 78d8c4b332..e6a62495d9 100644 --- a/api/Avalonia.Themes.Simple.nupkg.xml +++ b/api/Avalonia.Themes.Simple.nupkg.xml @@ -391,6 +391,12 @@ baseline/netstandard2.0/Avalonia.Themes.Simple.dll target/netstandard2.0/Avalonia.Themes.Simple.dll + + CP0001 + T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/UserControl.xaml + baseline/netstandard2.0/Avalonia.Themes.Simple.dll + target/netstandard2.0/Avalonia.Themes.Simple.dll + CP0001 T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Window.xaml diff --git a/api/Avalonia.nupkg.xml b/api/Avalonia.nupkg.xml index 2230532c05..9b8e28783f 100644 --- a/api/Avalonia.nupkg.xml +++ b/api/Avalonia.nupkg.xml @@ -1003,6 +1003,72 @@ baseline/designer/Avalonia.Designer.HostApp.dll target/designer/Avalonia.Designer.HostApp.dll + + CP0001 + T:Avalonia.AvaloniaLocator.RegistrationHelper`1 + baseline/netstandard2.0/Avalonia.Base.dll + target/netstandard2.0/Avalonia.Base.dll + + + CP0001 + T:Avalonia.AvaloniaLocator.ResolverDisposable + baseline/netstandard2.0/Avalonia.Base.dll + target/netstandard2.0/Avalonia.Base.dll + + + CP0001 + T:Avalonia.Input.FocusManager.<GetFocusScopeAncestors>d__18 + baseline/netstandard2.0/Avalonia.Base.dll + target/netstandard2.0/Avalonia.Base.dll + + + CP0001 + T:Avalonia.Layout.LayoutManager.<>c + baseline/netstandard2.0/Avalonia.Base.dll + target/netstandard2.0/Avalonia.Base.dll + + + CP0001 + T:Avalonia.Layout.LayoutManager.ArrangeResult + baseline/netstandard2.0/Avalonia.Base.dll + target/netstandard2.0/Avalonia.Base.dll + + + CP0001 + T:Avalonia.Layout.LayoutManager.EffectiveViewportChangedListener + baseline/netstandard2.0/Avalonia.Base.dll + target/netstandard2.0/Avalonia.Base.dll + + + CP0001 + T:Avalonia.Rendering.DefaultRenderTimer.<>c__DisplayClass13_0 + baseline/netstandard2.0/Avalonia.Base.dll + target/netstandard2.0/Avalonia.Base.dll + + + CP0001 + T:Avalonia.Rendering.UiThreadRenderTimer.<>c__DisplayClass3_0 + baseline/netstandard2.0/Avalonia.Base.dll + target/netstandard2.0/Avalonia.Base.dll + + + CP0001 + T:Avalonia.Controls.Primitives.PopupPositioning.ManagedPopupPositioner.<>c__DisplayClass5_0 + baseline/netstandard2.0/Avalonia.Controls.dll + target/netstandard2.0/Avalonia.Controls.dll + + + CP0001 + T:Avalonia.Controls.Primitives.PopupPositioning.ManagedPopupPositionerPopupImplHelper.<>c + baseline/netstandard2.0/Avalonia.Controls.dll + target/netstandard2.0/Avalonia.Controls.dll + + + CP0001 + T:Avalonia.Controls.Primitives.PopupPositioning.ManagedPopupPositionerPopupImplHelper.MoveResizeDelegate + baseline/netstandard2.0/Avalonia.Controls.dll + target/netstandard2.0/Avalonia.Controls.dll + CP0006 P:Avalonia.Rendering.Composition.ICompositionGpuImportedObject.ImportCompleted diff --git a/azure-pipelines-integrationtests.yml b/azure-pipelines-integrationtests.yml index 39923ca781..3613518dc1 100644 --- a/azure-pipelines-integrationtests.yml +++ b/azure-pipelines-integrationtests.yml @@ -5,14 +5,16 @@ jobs: steps: - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 6.0.415' + displayName: 'Use .NET 6.0 Runtime' inputs: - version: 6.0.415 + packageType: runtime + version: 6.0.x - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 7.0.402' + displayName: 'Use .NET 7.0 SDK' inputs: - version: 7.0.402 + packageType: sdk + useGlobalJson: true - script: system_profiler SPDisplaysDataType |grep Resolution displayName: 'Get Resolution' @@ -57,14 +59,16 @@ jobs: steps: - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 6.0.404' + displayName: 'Use .NET 6.0 Runtime' inputs: - version: 6.0.404 + packageType: runtime + version: 6.0.x - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 7.0.101' + displayName: 'Use .NET 7.0 SDK' inputs: - version: 7.0.101 + packageType: sdk + useGlobalJson: true - task: Windows Application Driver@0 inputs: diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 345378dbf2..a306e22355 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -30,14 +30,16 @@ jobs: vmImage: 'ubuntu-20.04' steps: - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 6.0.415' + displayName: 'Use .NET 6.0 Runtime' inputs: - version: 6.0.415 + packageType: runtime + version: 6.0.x - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 7.0.402' + displayName: 'Use .NET 7.0 SDK' inputs: - version: 7.0.402 + packageType: sdk + useGlobalJson: true - task: CmdLine@2 displayName: 'Install Workloads' @@ -74,14 +76,16 @@ jobs: vmImage: 'macos-12' steps: - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 6.0.404' + displayName: 'Use .NET 6.0 Runtime' inputs: - version: 6.0.404 + packageType: runtime + version: 6.0.x - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 7.0.101' + displayName: 'Use .NET 7.0 SDK' inputs: - version: 7.0.101 + packageType: sdk + useGlobalJson: true - task: CmdLine@2 displayName: 'Install Workloads' @@ -152,14 +156,16 @@ jobs: SolutionDir: '$(Build.SourcesDirectory)' steps: - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 6.0.404' + displayName: 'Use .NET 6.0 Runtime' inputs: - version: 6.0.404 + packageType: runtime + version: 6.0.x - task: UseDotNet@2 - displayName: 'Use .NET Core SDK 7.0.101' + displayName: 'Use .NET 7.0 SDK' inputs: - version: 7.0.101 + packageType: sdk + useGlobalJson: true - task: CmdLine@2 displayName: 'Install Workloads' diff --git a/build/BuildTargets.targets b/build/BuildTargets.targets index 481dbf06b2..13b002d523 100644 --- a/build/BuildTargets.targets +++ b/build/BuildTargets.targets @@ -4,6 +4,7 @@ true true true + true diff --git a/build/DevAnalyzers.props b/build/DevAnalyzers.props index dffd3098c3..fd416e3291 100644 --- a/build/DevAnalyzers.props +++ b/build/DevAnalyzers.props @@ -3,12 +3,10 @@ + OutputItemType="Analyzer" /> + OutputItemType="Analyzer" /> diff --git a/build/TrimmingEnable.props b/build/TrimmingEnable.props index 3f873e3345..fcd4b45e4b 100644 --- a/build/TrimmingEnable.props +++ b/build/TrimmingEnable.props @@ -1,10 +1,12 @@ + false true false true + true @@ -13,4 +15,11 @@ $(WarningsAsErrors);IL3050;IL3051;IL3052;IL3053;IL3054;IL3055;IL3056 + + + + true + false + + diff --git a/build/XUnit.props b/build/XUnit.props index 3c89c8b52b..8f991ae442 100644 --- a/build/XUnit.props +++ b/build/XUnit.props @@ -6,12 +6,13 @@ - + $(MSBuildThisFileDirectory)\avalonia.snk False + $(NoWarn);CS8002 diff --git a/global.json b/global.json index 8536535b51..13a6c6d6ad 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "7.0.101", + "version": "7.0.404", "rollForward": "latestFeature" }, "msbuild-sdks": { diff --git a/nukebuild/.editorconfig b/nukebuild/.editorconfig index d6009b3c0f..c11849c8e9 100644 --- a/nukebuild/.editorconfig +++ b/nukebuild/.editorconfig @@ -6,3 +6,12 @@ root = false # C# files [*.cs] dotnet_style_require_accessibility_modifiers = never + +[{il-repack,Numerge}/**/*.cs] +dotnet_diagnostic.CA1304.severity = none +dotnet_diagnostic.CA1815.severity = none +dotnet_diagnostic.CA1820.severity = none +dotnet_diagnostic.CA1825.severity = none +dotnet_diagnostic.CA1829.severity = none +dotnet_diagnostic.CA1847.severity = none +dotnet_diagnostic.SYSLIB0017.severity = none diff --git a/nukebuild/ApiDiffValidation.cs b/nukebuild/ApiDiffValidation.cs index c8115a8113..3c58215d26 100644 --- a/nukebuild/ApiDiffValidation.cs +++ b/nukebuild/ApiDiffValidation.cs @@ -8,6 +8,7 @@ using System.Net.Http; using System.Text.RegularExpressions; using System.Threading.Tasks; using Nuke.Common.Tooling; +using static Serilog.Log; public static class ApiDiffValidation { @@ -142,7 +143,7 @@ public static class ApiDiffValidation Avalonia.11.0.0 */ var packageId = GetPackageId(packagePath); - Build.Information("Downloading {0} {1} baseline package", packageId, baselineVersion); + Information("Downloading {0} {1} baseline package", packageId, baselineVersion); try { diff --git a/nukebuild/Build.cs b/nukebuild/Build.cs index f8fbf64e83..8b5cc4292a 100644 --- a/nukebuild/Build.cs +++ b/nukebuild/Build.cs @@ -1,21 +1,14 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Runtime.InteropServices; -using System.Threading; using System.Threading.Tasks; using System.Xml.Linq; using Nuke.Common; -using Nuke.Common.Git; -using Nuke.Common.ProjectModel; using Nuke.Common.Tooling; using Nuke.Common.Tools.DotNet; -using Nuke.Common.Tools.MSBuild; using Nuke.Common.Tools.Npm; -using Nuke.Common.Utilities; -using Nuke.Common.Utilities.Collections; using static Nuke.Common.EnvironmentInfo; using static Nuke.Common.IO.FileSystemTasks; using static Nuke.Common.IO.PathConstruction; @@ -23,6 +16,7 @@ using static Nuke.Common.Tools.MSBuild.MSBuildTasks; using static Nuke.Common.Tools.DotNet.DotNetTasks; using static Nuke.Common.Tools.Xunit.XunitTasks; using static Nuke.Common.Tools.VSWhere.VSWhereTasks; +using static Serilog.Log; using MicroCom.CodeGenerator; /* diff --git a/nukebuild/RefAssemblyGenerator.cs b/nukebuild/RefAssemblyGenerator.cs index e93070e2f0..f103f16919 100644 --- a/nukebuild/RefAssemblyGenerator.cs +++ b/nukebuild/RefAssemblyGenerator.cs @@ -70,9 +70,6 @@ public class RefAssemblyGenerator static void ProcessType(TypeDefinition type, MethodReference obsoleteCtor) { - foreach (var nested in type.NestedTypes) - ProcessType(nested, obsoleteCtor); - var hideMembers = (type.IsInterface && type.Name.EndsWith("Impl")) || HasPrivateApi(type.CustomAttributes); @@ -97,7 +94,7 @@ public class RefAssemblyGenerator foreach (var m in type.Methods) { - if (hideMembers || HasPrivateApi(m.CustomAttributes)) + if (!m.IsPrivate && (hideMembers || HasPrivateApi(m.CustomAttributes))) { HideMethod(m); } @@ -108,30 +105,27 @@ public class RefAssemblyGenerator { if (HasPrivateApi(p.CustomAttributes)) { - if (p.SetMethod != null) - HideMethod(p.SetMethod); - if (p.GetMethod != null) - HideMethod(p.GetMethod); + if (p.SetMethod is { IsPrivate: false } setMethod) + HideMethod(setMethod); + if (p.GetMethod is { IsPrivate: false } getMethod) + HideMethod(getMethod); } } foreach (var f in type.Fields) { - if (hideMembers || HasPrivateApi(f.CustomAttributes)) + if (!f.IsPrivate && (hideMembers || HasPrivateApi(f.CustomAttributes))) { - var dflags = FieldAttributes.Public | FieldAttributes.Family | FieldAttributes.FamORAssem | - FieldAttributes.FamANDAssem | FieldAttributes.Assembly; - f.Attributes = ((f.Attributes | dflags) ^ dflags) | FieldAttributes.Assembly; + f.IsAssembly = true; } } foreach (var cl in type.NestedTypes) { ProcessType(cl, obsoleteCtor); - if (hideMembers) + if (hideMembers && cl.IsNestedPublic) { - var dflags = TypeAttributes.Public; - cl.Attributes = ((cl.Attributes | dflags) ^ dflags) | TypeAttributes.NotPublic; + cl.IsNestedAssembly = true; } } @@ -143,9 +137,7 @@ public class RefAssemblyGenerator static void HideMethod(MethodDefinition m) { - var dflags = MethodAttributes.Public | MethodAttributes.Family | MethodAttributes.FamORAssem | - MethodAttributes.FamANDAssem | MethodAttributes.Assembly; - m.Attributes = ((m.Attributes | dflags) ^ dflags) | MethodAttributes.Assembly; + m.IsAssembly = true; } static void MarkAsUnstable(IMemberDefinition def, MethodReference obsoleteCtor, ICustomAttribute? unstableAttribute) diff --git a/nukebuild/Shims.cs b/nukebuild/Shims.cs index eecfcf6da1..cd8d43a35e 100644 --- a/nukebuild/Shims.cs +++ b/nukebuild/Shims.cs @@ -1,24 +1,13 @@ -using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; -using Nuke.Common; using Nuke.Common.IO; using Numerge; +using static Serilog.Log; public partial class Build { - internal static void Information(string info) - { - Logger.Info(info); - } - - internal static void Information(string info, params object[] args) - { - Logger.Info(info, args); - } - private void Zip(AbsolutePath target, params string[] paths) => Zip(target, paths.AsEnumerable()); private void Zip(AbsolutePath target, IEnumerable paths) @@ -44,16 +33,12 @@ public partial class Build if (Directory.Exists(path)) { var dirInfo = new DirectoryInfo(path); - var rootPath = Path.GetDirectoryName(dirInfo.FullName); + var rootPath = Path.GetDirectoryName(dirInfo.FullName)!; foreach(var fsEntry in dirInfo.EnumerateFileSystemInfos("*", SearchOption.AllDirectories)) { if (fsEntry is FileInfo) { -#if NET6 var relPath = Path.GetRelativePath(rootPath, fsEntry.FullName); -#else - var relPath = GetRelativePath(rootPath, fsEntry.FullName); -#endif AddFile(fsEntry.FullName, relPath); } } @@ -82,27 +67,16 @@ public partial class Build } } - private static string GetRelativePath(string relativeTo, string path) - { - var uri = new Uri(relativeTo); - var rel = Uri.UnescapeDataString(uri.MakeRelativeUri(new Uri(path)).ToString()).Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); - if (rel.Contains(Path.DirectorySeparatorChar.ToString()) == false) - { - rel = $".{Path.DirectorySeparatorChar}{rel}"; - } - return rel; - } - class NumergeNukeLogger : INumergeLogger { public void Log(NumergeLogLevel level, string message) { if(level == NumergeLogLevel.Error) - Logger.Error(message); + Error(message); else if (level == NumergeLogLevel.Warning) - Logger.Warn(message); + Warning(message); else - Logger.Info(message); + Information(message); } } } diff --git a/packages/Avalonia/AvaloniaBuildTasks.targets b/packages/Avalonia/AvaloniaBuildTasks.targets index ee9d8c6dfe..2232ea35af 100644 --- a/packages/Avalonia/AvaloniaBuildTasks.targets +++ b/packages/Avalonia/AvaloniaBuildTasks.targets @@ -130,6 +130,7 @@ $(IntermediateOutputPath)/Avalonia/original.dll false false + false + DefaultCompileBindings="$(AvaloniaUseCompiledBindingsByDefault)" + VerboseExceptions="$(AvaloniaXamlVerboseExceptions)" + AnalyzerConfigFiles="@(EditorConfigFiles)"> - - - + DisplayName="Debug XAML Compiler" + Description="Allow debug XAML compilation" + Category="Debug" /> + + + - + diff --git a/samples/ControlCatalog.Browser/Logo.svg b/samples/ControlCatalog.Browser/AppBundle/Logo.svg similarity index 100% rename from samples/ControlCatalog.Browser/Logo.svg rename to samples/ControlCatalog.Browser/AppBundle/Logo.svg diff --git a/samples/ControlCatalog.Browser/AppBundle/app.css b/samples/ControlCatalog.Browser/AppBundle/app.css new file mode 100644 index 0000000000..e14dfe4487 --- /dev/null +++ b/samples/ControlCatalog.Browser/AppBundle/app.css @@ -0,0 +1,74 @@ +:root { + --sat: env(safe-area-inset-top); + --sar: env(safe-area-inset-right); + --sab: env(safe-area-inset-bottom); + --sal: env(safe-area-inset-left); +} + +/* HTML styles for the splash screen */ + +.highlight { + color: white; + font-size: 2.5rem; + display: block; +} + +.purple { + color: #8b44ac; +} + +.icon { + opacity: 0.05; + height: 35%; + width: 35%; + position: absolute; + background-repeat: no-repeat; + right: 0px; + bottom: 0px; + margin-right: 3%; + margin-bottom: 5%; + z-index: 5000; + background-position: right bottom; + pointer-events: none; +} + +#avalonia-splash a { + color: whitesmoke; + text-decoration: none; +} + +.center { + display: flex; + justify-content: center; + align-items: center; + height: 100vh; +} + +#avalonia-splash { + position: relative; + height: 100%; + width: 100%; + color: whitesmoke; + background: #1b2a4e; + font-family: 'Nunito', sans-serif; + background-position: center; + background-size: cover; + background-repeat: no-repeat; + justify-content: center; + align-items: center; +} + +.splash-close { + animation: fadeout 0.25s linear forwards; +} + +@keyframes fadeout { + 0% { + opacity: 100%; + } + + 100% { + opacity: 0; + visibility: collapse; + } +} diff --git a/samples/ControlCatalog.Browser/embed.js b/samples/ControlCatalog.Browser/AppBundle/embed.js similarity index 100% rename from samples/ControlCatalog.Browser/embed.js rename to samples/ControlCatalog.Browser/AppBundle/embed.js diff --git a/samples/ControlCatalog.Browser/favicon.ico b/samples/ControlCatalog.Browser/AppBundle/favicon.ico similarity index 100% rename from samples/ControlCatalog.Browser/favicon.ico rename to samples/ControlCatalog.Browser/AppBundle/favicon.ico diff --git a/samples/ControlCatalog.Browser/AppBundle/index.html b/samples/ControlCatalog.Browser/AppBundle/index.html new file mode 100644 index 0000000000..b35acaed5c --- /dev/null +++ b/samples/ControlCatalog.Browser/AppBundle/index.html @@ -0,0 +1,28 @@ + + + + + + + AvaloniaUI - ControlCatalog + + + + + + +
+
+
+

+ Powered by + Avalonia UI +

+
+ Avalonia Logo +
+
+ + + + diff --git a/samples/ControlCatalog.Browser/main.js b/samples/ControlCatalog.Browser/AppBundle/main.js similarity index 68% rename from samples/ControlCatalog.Browser/main.js rename to samples/ControlCatalog.Browser/AppBundle/main.js index 9d90db8bd2..9eae9fd740 100644 --- a/samples/ControlCatalog.Browser/main.js +++ b/samples/ControlCatalog.Browser/AppBundle/main.js @@ -1,7 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { dotnet } from './dotnet.js' +import { dotnet } from './dotnet.js' // NET 7 +//import { dotnet } from './_framework/dotnet.js' // NET 8+ const is_browser = typeof window != "undefined"; if (!is_browser) throw new Error(`Expected to be running in a browser`); @@ -13,4 +14,4 @@ const dotnetRuntime = await dotnet const config = dotnetRuntime.getConfig(); -await dotnetRuntime.runMainAndExit(config.mainAssemblyName, ["dotnet", "is", "great!"]); +await dotnetRuntime.runMainAndExit(config.mainAssemblyName, [globalThis.location.href]); diff --git a/samples/ControlCatalog.Browser/ControlCatalog.Browser.csproj b/samples/ControlCatalog.Browser/ControlCatalog.Browser.csproj index c4278459f3..12338d615e 100644 --- a/samples/ControlCatalog.Browser/ControlCatalog.Browser.csproj +++ b/samples/ControlCatalog.Browser/ControlCatalog.Browser.csproj @@ -1,44 +1,24 @@  + + net7.0 browser-wasm - main.js + AppBundle/main.js Exe true true - true - -sVERBOSE -sERROR_ON_UNDEFINED_SYMBOLS=0 - - - - true - true - full - true - true - -O2 - -O2 - - - - - - - + + + - - - - - - + - - + diff --git a/samples/ControlCatalog.Browser/EmbedSample.Browser.cs b/samples/ControlCatalog.Browser/EmbedSample.Browser.cs index c367230ddf..1bd226d578 100644 --- a/samples/ControlCatalog.Browser/EmbedSample.Browser.cs +++ b/samples/ControlCatalog.Browser/EmbedSample.Browser.cs @@ -4,6 +4,7 @@ using Avalonia.Platform; using Avalonia.Browser; using ControlCatalog.Pages; +using System.Threading.Tasks; namespace ControlCatalog.Browser; @@ -25,7 +26,7 @@ public class EmbedSampleWeb : INativeDemoControl _ = JSHost.ImportAsync("embed.js", "./embed.js").ContinueWith(_ => { EmbedInterop.AddAppButton(defaultHandle.Object); - }); + }, TaskScheduler.FromCurrentSynchronizationContext()); return defaultHandle; } diff --git a/samples/ControlCatalog.Browser/Program.cs b/samples/ControlCatalog.Browser/Program.cs index e1a4500173..919df5103c 100644 --- a/samples/ControlCatalog.Browser/Program.cs +++ b/samples/ControlCatalog.Browser/Program.cs @@ -1,8 +1,9 @@ +using System.Diagnostics; using System.Runtime.Versioning; using System.Threading.Tasks; using Avalonia; using Avalonia.Browser; -using Avalonia.Controls; +using Avalonia.Logging; using ControlCatalog; using ControlCatalog.Browser; @@ -12,7 +13,10 @@ internal partial class Program { public static async Task Main(string[] args) { + Trace.Listeners.Add(new ConsoleTraceListener()); + await BuildAvaloniaApp() + .LogToTrace(LogEventLevel.Warning) .AfterSetup(_ => { ControlCatalog.Pages.EmbedSample.Implementation = new EmbedSampleWeb(); diff --git a/samples/ControlCatalog.Browser/Roots.xml b/samples/ControlCatalog.Browser/Roots.xml deleted file mode 100644 index b07fd86fa2..0000000000 --- a/samples/ControlCatalog.Browser/Roots.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/samples/ControlCatalog.Browser/app.css b/samples/ControlCatalog.Browser/app.css deleted file mode 100644 index 0e6ab12461..0000000000 --- a/samples/ControlCatalog.Browser/app.css +++ /dev/null @@ -1,56 +0,0 @@ -:root { - --sat: env(safe-area-inset-top); - --sar: env(safe-area-inset-right); - --sab: env(safe-area-inset-bottom); - --sal: env(safe-area-inset-left); -} - -#out { - height: 100vh; - width: 100vw -} - -#avalonia-splash { - position: relative; - height: 100%; - width: 100%; - color: whitesmoke; - background: #171C2C; - font-family: 'Nunito', sans-serif; - background-position: center; - background-size: cover; - background-repeat: no-repeat; -} - -#avalonia-splash a{ - color: whitesmoke; - text-decoration: none; -} - -.center { - display: flex; - justify-content: center; - height: 250px; -} - -.splash-close { - animation: slide 0.5s linear 1s forwards; -} - -@keyframes slide { - 0% { - top: 0%; - } - - 50% { - opacity: 80%; - } - - 100% { - top: 100%; - overflow: hidden; - opacity: 0; - display: none; - visibility: collapse; - } -} diff --git a/samples/ControlCatalog.Browser/index.html b/samples/ControlCatalog.Browser/index.html deleted file mode 100644 index 226ae70695..0000000000 --- a/samples/ControlCatalog.Browser/index.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - AvaloniaUI - ControlCatalog - - - - - - - - - -
-
-
-

Powered by

- - Avalonia Logo - Avalonia - -
-
-
- - - - diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml index 2120b03b20..e19b563fb7 100644 --- a/samples/ControlCatalog/MainView.xaml +++ b/samples/ControlCatalog/MainView.xaml @@ -74,6 +74,9 @@ ScrollViewer.VerticalScrollBarVisibility="Disabled"> + + + diff --git a/samples/ControlCatalog/MainView.xaml.cs b/samples/ControlCatalog/MainView.xaml.cs index 801844a43c..31fa54a23a 100644 --- a/samples/ControlCatalog/MainView.xaml.cs +++ b/samples/ControlCatalog/MainView.xaml.cs @@ -59,7 +59,7 @@ namespace ControlCatalog { if (flowDirections.SelectedItem is FlowDirection flowDirection) { - TopLevel.GetTopLevel(this).FlowDirection = flowDirection; + TopLevel.GetTopLevel(this)!.FlowDirection = flowDirection; } }; diff --git a/samples/ControlCatalog/Pages/DataValidationPage.axaml b/samples/ControlCatalog/Pages/DataValidationPage.axaml new file mode 100644 index 0000000000..d46562addd --- /dev/null +++ b/samples/ControlCatalog/Pages/DataValidationPage.axaml @@ -0,0 +1,42 @@ + + + + + + + + diff --git a/samples/ControlCatalog/Pages/DataValidationPage.axaml.cs b/samples/ControlCatalog/Pages/DataValidationPage.axaml.cs new file mode 100644 index 0000000000..e38f85fec4 --- /dev/null +++ b/samples/ControlCatalog/Pages/DataValidationPage.axaml.cs @@ -0,0 +1,14 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace ControlCatalog.Pages; + +public partial class DataValidationPage : UserControl +{ + public DataValidationPage() + { + InitializeComponent(); + } +} + diff --git a/samples/ControlCatalog/Pages/DialogsPage.xaml.cs b/samples/ControlCatalog/Pages/DialogsPage.xaml.cs index 1521108278..143db003cd 100644 --- a/samples/ControlCatalog/Pages/DialogsPage.xaml.cs +++ b/samples/ControlCatalog/Pages/DialogsPage.xaml.cs @@ -160,7 +160,7 @@ namespace ControlCatalog.Pages } else { - SetFolder(await GetStorageProvider().TryGetFolderFromPathAsync(result)); + SetFolder(await GetStorageProvider().TryGetFolderFromPathAsync(result!)); results.ItemsSource = new[] { result }; resultsVisible.IsVisible = true; } @@ -238,7 +238,7 @@ namespace ControlCatalog.Pages SuggestedStartLocation = lastSelectedDirectory, SuggestedFileName = "FileName", DefaultExtension = fileTypes?.Any() == true ? "txt" : null, - ShowOverwritePrompt = false + ShowOverwritePrompt = true }); if (file is not null) @@ -436,7 +436,7 @@ CanPickFolder: {storageProvider.CanPickFolder}"; { var forceManaged = this.Get("ForceManaged").IsChecked ?? false; return forceManaged - ? new ManagedStorageProvider(GetWindow(), null) + ? new ManagedStorageProvider(GetWindow()) : GetTopLevel().StorageProvider; } diff --git a/samples/ControlCatalog/Pages/DragAndDropPage.xaml.cs b/samples/ControlCatalog/Pages/DragAndDropPage.xaml.cs index aef82768c8..b242d020b0 100644 --- a/samples/ControlCatalog/Pages/DragAndDropPage.xaml.cs +++ b/samples/ControlCatalog/Pages/DragAndDropPage.xaml.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Reflection; +using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Input; using Avalonia.Markup.Xaml; @@ -14,26 +15,54 @@ namespace ControlCatalog.Pages private const string CustomFormat = "application/xxx-avalonia-controlcatalog-custom"; public DragAndDropPage() { - this.InitializeComponent(); + InitializeComponent(); _dropState = this.Get("DropState"); int textCount = 0; - SetupDnd("Text", d => d.Set(DataFormats.Text, - $"Text was dragged {++textCount} times"), DragDropEffects.Copy | DragDropEffects.Move | DragDropEffects.Link); - SetupDnd("Custom", d => d.Set(CustomFormat, "Test123"), DragDropEffects.Move); - SetupDnd("Files", async d => d.Set(DataFormats.Files, new[] { await (VisualRoot as TopLevel)!.StorageProvider.TryGetFileFromPathAsync(Assembly.GetEntryAssembly()?.GetModules().FirstOrDefault()?.FullyQualifiedName) }), DragDropEffects.Copy); + SetupDnd( + "Text", + d => d.Set(DataFormats.Text, $"Text was dragged {++textCount} times"), + DragDropEffects.Copy | DragDropEffects.Move | DragDropEffects.Link); + + SetupDnd( + "Custom", + d => d.Set(CustomFormat, "Test123"), + DragDropEffects.Move); + + SetupDnd( + "Files", + async d => + { + if (Assembly.GetEntryAssembly()?.GetModules().FirstOrDefault()?.FullyQualifiedName is { } name && + TopLevel.GetTopLevel(this) is { } topLevel && + await topLevel.StorageProvider.TryGetFileFromPathAsync(name) is { } storageFile) + { + d.Set(DataFormats.Files, new[] { storageFile }); + } + }, + DragDropEffects.Copy); } - void SetupDnd(string suffix, Action factory, DragDropEffects effects) + private void SetupDnd(string suffix, Action factory, DragDropEffects effects) => + SetupDnd( + suffix, + o => + { + factory(o); + return Task.CompletedTask; + }, + effects); + + private void SetupDnd(string suffix, Func factory, DragDropEffects effects) { var dragMe = this.Get("DragMe" + suffix); var dragState = this.Get("DragState" + suffix); - async void DoDrag(object? sender, Avalonia.Input.PointerPressedEventArgs e) + async void DoDrag(object? sender, PointerPressedEventArgs e) { var dragData = new DataObject(); - factory(dragData); + await factory(dragData); var result = await DragDrop.DoDragDrop(e, dragData, effects); switch (result) diff --git a/samples/ControlCatalog/Pages/GesturePage.cs b/samples/ControlCatalog/Pages/GesturePage.cs index c81ba4fb17..9164384eae 100644 --- a/samples/ControlCatalog/Pages/GesturePage.cs +++ b/samples/ControlCatalog/Pages/GesturePage.cs @@ -41,12 +41,12 @@ namespace ControlCatalog.Pages SetPullHandlers(this.Find("RightPullZone"), true); SetPullHandlers(this.Find("LeftPullZone"), false); - var image = this.Find("PinchImage"); + var image = this.Get("PinchImage"); SetPinchHandlers(image); - var reset = this.Find + + - Pinch/Zoom Gexture (Multi Touch) - - - - - - - - - - + + + Pinch/Rotation Gexture (Multi Touch) + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/ControlCatalog/Pages/ScrollViewerPage.xaml b/samples/ControlCatalog/Pages/ScrollViewerPage.xaml index 4af61c3399..f931542a04 100644 --- a/samples/ControlCatalog/Pages/ScrollViewerPage.xaml +++ b/samples/ControlCatalog/Pages/ScrollViewerPage.xaml @@ -17,6 +17,9 @@ Content="Allow auto hide" /> + diff --git a/samples/ControlCatalog/ViewModels/ComboBoxPageViewModel.cs b/samples/ControlCatalog/ViewModels/ComboBoxPageViewModel.cs index 6ab7bb02e3..791c759cd9 100644 --- a/samples/ControlCatalog/ViewModels/ComboBoxPageViewModel.cs +++ b/samples/ControlCatalog/ViewModels/ComboBoxPageViewModel.cs @@ -29,7 +29,7 @@ namespace ControlCatalog.ViewModels public class IdAndName { - public string Id { get; set; } - public string Name { get; set; } + public string? Id { get; set; } + public string? Name { get; set; } } } diff --git a/samples/ControlCatalog/ViewModels/DataValidationViewModel.cs b/samples/ControlCatalog/ViewModels/DataValidationViewModel.cs new file mode 100644 index 0000000000..3b2c37699c --- /dev/null +++ b/samples/ControlCatalog/ViewModels/DataValidationViewModel.cs @@ -0,0 +1,45 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using MiniMvvm; + +namespace ControlCatalog.ViewModels; + +public class DataValidationViewModel : ViewModelBase +{ + private string? _DataAnnotationsSample; + + [Required] + [EmailAddress] + [MinLength(5)] + public string? DataAnnotationsSample + { + get => _DataAnnotationsSample; + set => RaiseAndSetIfChanged(ref _DataAnnotationsSample, value); + } + + public Func Converter { get; } = new Func(o => + { + return $"Error: {o}"; + }); + + + private string? _ExceptionInsideSetterSample; + + public string? ExceptionInsideSetterSample + { + get => _ExceptionInsideSetterSample; + set + { + if (value is null || value.Length < 5) + throw new ArgumentOutOfRangeException(nameof(value), "Give me 5 or more letter please :-)"); + + RaiseAndSetIfChanged(ref _ExceptionInsideSetterSample, value); + } + } + + public Func ExceptionConverter { get; } = new Func(o => + { + return o is Exception ex ? $"Huh, there was an Exception: {ex.Message}" : "Something went really wrong!"; + }); +} diff --git a/samples/ControlCatalog/ViewModels/ListBoxPageViewModel.cs b/samples/ControlCatalog/ViewModels/ListBoxPageViewModel.cs index 9c30992624..a1dd17af58 100644 --- a/samples/ControlCatalog/ViewModels/ListBoxPageViewModel.cs +++ b/samples/ControlCatalog/ViewModels/ListBoxPageViewModel.cs @@ -48,7 +48,7 @@ namespace ControlCatalog.ViewModels foreach (var item in items) { - Items.Remove(item); + Items.Remove(item!); } }); diff --git a/samples/ControlCatalog/ViewModels/PlatformInformationViewModel.cs b/samples/ControlCatalog/ViewModels/PlatformInformationViewModel.cs index 60f1f84cc9..42eac2f96a 100644 --- a/samples/ControlCatalog/ViewModels/PlatformInformationViewModel.cs +++ b/samples/ControlCatalog/ViewModels/PlatformInformationViewModel.cs @@ -1,11 +1,9 @@ -using System; using System.Runtime.InteropServices; using Avalonia; using Avalonia.Platform; using MiniMvvm; namespace ControlCatalog.ViewModels; -#nullable enable public class PlatformInformationViewModel : ViewModelBase { @@ -46,11 +44,7 @@ public class PlatformInformationViewModel : ViewModelBase } } } - else - { - - } } - public string PlatformInfo { get; } + public string? PlatformInfo { get; } } diff --git a/samples/Directory.Build.props b/samples/Directory.Build.props index ac78d9c739..c8216c3031 100644 --- a/samples/Directory.Build.props +++ b/samples/Directory.Build.props @@ -1,10 +1,14 @@ + - false - $(MSBuildThisFileDirectory)..\src\tools\Avalonia.Designer.HostApp\bin\Debug\netcoreapp2.0\Avalonia.Designer.HostApp.dll - false - 11 + false + $(MSBuildThisFileDirectory)..\src\tools\Avalonia.Designer.HostApp\bin\Debug\netcoreapp2.0\Avalonia.Designer.HostApp.dll + false + 11 + $(NoWarn);CS8002 - - + + + + diff --git a/samples/Generators.Sandbox/Controls/CustomTextBox.cs b/samples/Generators.Sandbox/Controls/CustomTextBox.cs index 68ee925986..1325c4cf64 100644 --- a/samples/Generators.Sandbox/Controls/CustomTextBox.cs +++ b/samples/Generators.Sandbox/Controls/CustomTextBox.cs @@ -1,10 +1,9 @@ using System; using Avalonia.Controls; -using Avalonia.Styling; namespace Generators.Sandbox.Controls; -public class CustomTextBox : TextBox, IStyleable +public class CustomTextBox : TextBox { - Type IStyleable.StyleKey => typeof(TextBox); -} \ No newline at end of file + protected override Type StyleKeyOverride => typeof(TextBox); +} diff --git a/samples/GpuInterop/D3DDemo/D3D11DemoControl.cs b/samples/GpuInterop/D3DDemo/D3D11DemoControl.cs index 8b1347e1d8..887ddaf654 100644 --- a/samples/GpuInterop/D3DDemo/D3D11DemoControl.cs +++ b/samples/GpuInterop/D3DDemo/D3D11DemoControl.cs @@ -20,21 +20,21 @@ namespace GpuInterop.D3DDemo; public class D3D11DemoControl : DrawingSurfaceDemoBase { - private D3DDevice _device; - private D3D11Swapchain _swapchain; - private SharpDX.Direct3D11.DeviceContext _context; + private D3DDevice? _device; + private D3D11Swapchain? _swapchain; + private DeviceContext? _context; private Matrix _view; private PixelSize _lastSize; - private Texture2D _depthBuffer; - private DepthStencilView _depthView; + private Texture2D? _depthBuffer; + private DepthStencilView? _depthView; private Matrix _proj; - private Buffer _constantBuffer; - private Stopwatch _st = Stopwatch.StartNew(); + private Buffer? _constantBuffer; + private readonly Stopwatch _st = Stopwatch.StartNew(); protected override (bool success, string info) InitializeGraphicsResources(Compositor compositor, CompositionDrawingSurface surface, ICompositionGpuInterop interop) { - if (interop?.SupportedImageHandleTypes.Contains(KnownPlatformGraphicsExternalImageHandleTypes + if (interop.SupportedImageHandleTypes.Contains(KnownPlatformGraphicsExternalImageHandleTypes .D3D11TextureGlobalSharedHandle) != true) return (false, "DXGI shared handle import is not supported by the current graphics backend"); @@ -60,8 +60,12 @@ public class D3D11DemoControl : DrawingSurfaceDemoBase protected override void FreeGraphicsResources() { - _swapchain.DisposeAsync(); - _swapchain = null!; + if (_swapchain is not null) + { + _swapchain.DisposeAsync().GetAwaiter().GetResult(); + _swapchain = null; + } + Utilities.Dispose(ref _depthView); Utilities.Dispose(ref _depthBuffer); Utilities.Dispose(ref _constantBuffer); @@ -80,10 +84,10 @@ public class D3D11DemoControl : DrawingSurfaceDemoBase _lastSize = pixelSize; Resize(pixelSize); } - using (_swapchain.BeginDraw(pixelSize, out var renderView)) + using (_swapchain!.BeginDraw(pixelSize, out var renderView)) { - _device.ImmediateContext.OutputMerger.SetTargets(_depthView, renderView); + _device!.ImmediateContext.OutputMerger.SetTargets(_depthView, renderView); var viewProj = Matrix.Multiply(_view, _proj); var context = _device.ImmediateContext; @@ -101,10 +105,10 @@ public class D3D11DemoControl : DrawingSurfaceDemoBase var ypr = Matrix4x4.CreateFromYawPitchRoll(Yaw, Pitch, Roll); // Update WorldViewProj Matrix - var worldViewProj = Matrix.RotationX((float)Yaw) * Matrix.RotationY((float)Pitch) - * Matrix.RotationZ((float)Roll) - * Matrix.Scaling(new Vector3(scaleX, scaleY, 1)) - * viewProj; + var worldViewProj = Matrix.RotationX(Yaw) * Matrix.RotationY(Pitch) + * Matrix.RotationZ(Roll) + * Matrix.Scaling(new Vector3(scaleX, scaleY, 1)) + * viewProj; worldViewProj.Transpose(); context.UpdateSubresource(ref worldViewProj, _constantBuffer); @@ -112,21 +116,25 @@ public class D3D11DemoControl : DrawingSurfaceDemoBase context.Draw(36, 0); - _context.Flush(); + _context!.Flush(); } } private void Resize(PixelSize size) { Utilities.Dispose(ref _depthBuffer); + + if (_device is null) + return; + _depthBuffer = new Texture2D(_device, new Texture2DDescription() { Format = Format.D32_Float_S8X24_UInt, ArraySize = 1, MipLevels = 1, - Width = (int)size.Width, - Height = (int)size.Height, + Width = size.Width, + Height = size.Height, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, @@ -138,9 +146,9 @@ public class D3D11DemoControl : DrawingSurfaceDemoBase _depthView = new DepthStencilView(_device, _depthBuffer); // Setup targets and viewport for rendering - _device.ImmediateContext.Rasterizer.SetViewport(new Viewport(0, 0, (int)size.Width, (int)size.Height, 0.0f, 1.0f)); + _device.ImmediateContext.Rasterizer.SetViewport(new Viewport(0, 0, size.Width, size.Height, 0.0f, 1.0f)); // Setup new projection matrix with correct aspect ratio - _proj = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, (float)(size.Width / size.Height), 0.1f, 100.0f); + _proj = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, size.Width / (float) size.Height, 0.1f, 100.0f); } } diff --git a/samples/GpuInterop/DrawingSurfaceDemoBase.cs b/samples/GpuInterop/DrawingSurfaceDemoBase.cs index 367436e5a5..be5d920b89 100644 --- a/samples/GpuInterop/DrawingSurfaceDemoBase.cs +++ b/samples/GpuInterop/DrawingSurfaceDemoBase.cs @@ -1,5 +1,4 @@ using System; -using System.Numerics; using System.Threading.Tasks; using Avalonia; using Avalonia.Controls; @@ -13,12 +12,12 @@ public abstract class DrawingSurfaceDemoBase : Control, IGpuDemo { private CompositionSurfaceVisual? _visual; private Compositor? _compositor; - private Action _update; - private string _info; + private readonly Action _update; + private string _info = string.Empty; private bool _updateQueued; private bool _initialized; - protected CompositionDrawingSurface Surface { get; private set; } + protected CompositionDrawingSurface? Surface { get; private set; } public DrawingSurfaceDemoBase() { @@ -113,7 +112,7 @@ public abstract class DrawingSurfaceDemoBase : Control, IGpuDemo protected abstract void RenderFrame(PixelSize pixelSize); protected virtual bool SupportsDisco => false; - public void Update(GpuDemo parent, float yaw, float pitch, float roll, float disco) + public void Update(GpuDemo? parent, float yaw, float pitch, float roll, float disco) { ParentControl = parent; if (ParentControl != null) diff --git a/samples/GpuInterop/GpuDemo.axaml.cs b/samples/GpuInterop/GpuDemo.axaml.cs index f7acac09e1..5a4b252fe8 100644 --- a/samples/GpuInterop/GpuDemo.axaml.cs +++ b/samples/GpuInterop/GpuDemo.axaml.cs @@ -80,13 +80,13 @@ public class GpuDemo : UserControl set => SetAndRaise(DiscoVisibleProperty, ref _discoVisible, value); } - private IGpuDemo _demo; + private IGpuDemo? _demo; - public static readonly DirectProperty DemoProperty = - AvaloniaProperty.RegisterDirect("Demo", o => o.Demo, + public static readonly DirectProperty DemoProperty = + AvaloniaProperty.RegisterDirect("Demo", o => o.Demo, (o, v) => o._demo = v); - public IGpuDemo Demo + public IGpuDemo? Demo { get => _demo; set => SetAndRaise(DemoProperty, ref _demo, value); @@ -102,7 +102,7 @@ public class GpuDemo : UserControl ) { if (change.Property == DemoProperty) - ((IGpuDemo)change.OldValue)?.Update(null, 0, 0, 0, 0); + ((IGpuDemo?)change.OldValue)?.Update(null, 0, 0, 0, 0); _demo?.Update(this, Yaw, Pitch, Roll, Disco); } @@ -112,5 +112,5 @@ public class GpuDemo : UserControl public interface IGpuDemo { - void Update(GpuDemo parent, float yaw, float pitch, float roll, float disco); + void Update(GpuDemo? parent, float yaw, float pitch, float roll, float disco); } diff --git a/samples/GpuInterop/VulkanDemo/VulkanCommandBufferPool.cs b/samples/GpuInterop/VulkanDemo/VulkanCommandBufferPool.cs index 2f018171dc..f89de4719f 100644 --- a/samples/GpuInterop/VulkanDemo/VulkanCommandBufferPool.cs +++ b/samples/GpuInterop/VulkanDemo/VulkanCommandBufferPool.cs @@ -13,7 +13,7 @@ namespace Avalonia.Vulkan private readonly CommandPool _commandPool; private readonly List _usedCommandBuffers = new(); - private object _lock = new object(); + private readonly object _lock = new(); public unsafe VulkanCommandBufferPool(Vk api, Device device, Queue queue, uint queueFamilyIndex) { @@ -167,7 +167,7 @@ namespace Avalonia.Vulkan ReadOnlySpan waitDstStageMask = default, ReadOnlySpan signalSemaphores = default, Fence? fence = null, - KeyedMutexSubmitInfo keyedMutex = null) + KeyedMutexSubmitInfo? keyedMutex = null) { EndRecording(); diff --git a/samples/GpuInterop/VulkanDemo/VulkanContent.cs b/samples/GpuInterop/VulkanDemo/VulkanContent.cs index 5805604f1b..a9a668d10b 100644 --- a/samples/GpuInterop/VulkanDemo/VulkanContent.cs +++ b/samples/GpuInterop/VulkanDemo/VulkanContent.cs @@ -39,7 +39,7 @@ unsafe class VulkanContent : IDisposable { _context = context; var name = typeof(VulkanContent).Assembly.GetManifestResourceNames().First(x => x.Contains("teapot.bin")); - using (var sr = new BinaryReader(typeof(VulkanContent).Assembly.GetManifestResourceStream(name))) + using (var sr = new BinaryReader(typeof(VulkanContent).Assembly.GetManifestResourceStream(name)!)) { var buf = new byte[sr.ReadInt32()]; sr.Read(buf, 0, buf.Length); @@ -115,7 +115,7 @@ unsafe class VulkanContent : IDisposable { var name = typeof(VulkanContent).Assembly.GetManifestResourceNames() .First(x => x.Contains((fragment ? "frag" : "vert") + ".spirv")); - using (var sr = typeof(VulkanContent).Assembly.GetManifestResourceStream(name)) + using (var sr = typeof(VulkanContent).Assembly.GetManifestResourceStream(name)!) { using (var mem = new MemoryStream()) { @@ -158,7 +158,7 @@ unsafe class VulkanContent : IDisposable var commandBuffer = _context.Pool.CreateCommandBuffer(); commandBuffer.BeginRecording(); - _colorAttachment.TransitionLayout(commandBuffer.InternalHandle, + _colorAttachment!.TransitionLayout(commandBuffer.InternalHandle, ImageLayout.Undefined, AccessFlags.None, ImageLayout.ColorAttachmentOptimal, AccessFlags.ColorAttachmentWriteBit); @@ -251,9 +251,9 @@ unsafe class VulkanContent : IDisposable } }; - api.CmdBlitImage(commandBuffer.InternalHandle, _colorAttachment.InternalHandle.Value, + api.CmdBlitImage(commandBuffer.InternalHandle, _colorAttachment.InternalHandle, ImageLayout.TransferSrcOptimal, - image.InternalHandle.Value, ImageLayout.TransferDstOptimal, 1, srcBlitRegion, Filter.Linear); + image.InternalHandle, ImageLayout.TransferDstOptimal, 1, srcBlitRegion, Filter.Linear); commandBuffer.Submit(); } @@ -393,7 +393,7 @@ unsafe class VulkanContent : IDisposable var view = Matrix4x4.CreateLookAt(new Vector3(25, 25, 25), new Vector3(), new Vector3(0, -1, 0)); var projection = - Matrix4x4.CreatePerspectiveFieldOfView((float)(Math.PI / 4), (float)((float)size.Width / size.Height), + Matrix4x4.CreatePerspectiveFieldOfView((float)(Math.PI / 4), (float)size.Width / size.Height, 0.01f, 1000); _colorAttachment = new VulkanImage(_context, (uint)Format.R8G8B8A8Unorm, size, false); @@ -808,7 +808,7 @@ unsafe class VulkanContent : IDisposable static Stopwatch St = Stopwatch.StartNew(); private bool _isInit; - private VulkanImage _colorAttachment; + private VulkanImage? _colorAttachment; private DescriptorSet _descriptorSet; [StructLayout(LayoutKind.Sequential, Pack = 4)] diff --git a/samples/GpuInterop/VulkanDemo/VulkanContext.cs b/samples/GpuInterop/VulkanDemo/VulkanContext.cs index a810a4b9f7..0983a373f3 100644 --- a/samples/GpuInterop/VulkanDemo/VulkanContext.cs +++ b/samples/GpuInterop/VulkanDemo/VulkanContext.cs @@ -2,34 +2,31 @@ using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; -using Avalonia; using Avalonia.Platform; using Avalonia.Rendering.Composition; using Avalonia.Vulkan; using Silk.NET.Core; -using Silk.NET.Core.Native; using Silk.NET.Vulkan; using Silk.NET.Vulkan.Extensions.EXT; using Silk.NET.Vulkan.Extensions.KHR; using SilkNetDemo; using SkiaSharp; using D3DDevice = SharpDX.Direct3D11.Device; -using DxgiDevice = SharpDX.DXGI.Device; namespace GpuInterop.VulkanDemo; public unsafe class VulkanContext : IDisposable { - public Vk Api { get; init; } - public Instance Instance { get; init; } - public PhysicalDevice PhysicalDevice { get; init; } - public Device Device { get; init; } - public Queue Queue { get; init; } - public uint QueueFamilyIndex { get; init; } - public VulkanCommandBufferPool Pool { get; init; } - public GRContext GrContext { get; init; } - public DescriptorPool DescriptorPool { get; init; } - public D3DDevice? D3DDevice { get; init; } + public required Vk Api { get; init; } + public required Instance Instance { get; init; } + public required PhysicalDevice PhysicalDevice { get; init; } + public required Device Device { get; init; } + public required Queue Queue { get; init; } + public required uint QueueFamilyIndex { get; init; } + public required VulkanCommandBufferPool Pool { get; init; } + public required GRContext GrContext { get; init; } + public required DescriptorPool DescriptorPool { get; init; } + public required D3DDevice? D3DDevice { get; init; } public static (VulkanContext? result, string info) TryCreate(ICompositionGpuInterop gpuInterop) { @@ -58,10 +55,8 @@ public unsafe class VulkanContext : IDisposable enabledExtensions.Add("VK_EXT_debug_utils"); if (IsLayerAvailable(api, "VK_LAYER_KHRONOS_validation")) enabledLayers.Add("VK_LAYER_KHRONOS_validation"); - - Instance vkInstance = default; - Silk.NET.Vulkan.PhysicalDevice physicalDevice = default; + Device device = default; DescriptorPool descriptorPool = default; VulkanCommandBufferPool? pool = null; @@ -78,7 +73,7 @@ public unsafe class VulkanContext : IDisposable EnabledExtensionCount = pRequiredExtensions.UCount, PpEnabledLayerNames = pEnabledLayers, EnabledLayerCount = pEnabledLayers.UCount - }, null, out vkInstance).ThrowOnError(); + }, null, out var vkInstance).ThrowOnError(); if (api.TryGetInstanceExtension(vkInstance, out ExtDebugUtils debugUtils)) @@ -95,7 +90,7 @@ public unsafe class VulkanContext : IDisposable PfnUserCallback = new PfnDebugUtilsMessengerCallbackEXT(LogCallback), }; - debugUtils.CreateDebugUtilsMessenger(vkInstance, debugCreateInfo, null, out var messenger); + debugUtils.CreateDebugUtilsMessenger(vkInstance, debugCreateInfo, null, out _); } var requireDeviceExtensions = new List @@ -158,11 +153,11 @@ public unsafe class VulkanContext : IDisposable else if (gpuInterop.DeviceUuid != null) { if (!new Span(physicalDeviceIDProperties.DeviceUuid, 16) - .SequenceEqual(gpuInterop?.DeviceUuid)) + .SequenceEqual(gpuInterop.DeviceUuid)) continue; } - physicalDevice = physicalDevices[c]; + var physicalDevice = physicalDevices[c]; var name = Marshal.PtrToStringAnsi(new IntPtr(physicalDeviceProperties2.Properties.DeviceName))!; @@ -251,8 +246,7 @@ public unsafe class VulkanContext : IDisposable RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) d3dDevice = D3DMemoryHelper.CreateDeviceByLuid( new Span(physicalDeviceIDProperties.DeviceLuid, 8)); - - var dxgiDevice = d3dDevice?.QueryInterface(); + return (new VulkanContext { Api = api, diff --git a/samples/GpuInterop/VulkanDemo/VulkanImage.cs b/samples/GpuInterop/VulkanDemo/VulkanImage.cs index c1865a817d..a385468b26 100644 --- a/samples/GpuInterop/VulkanDemo/VulkanImage.cs +++ b/samples/GpuInterop/VulkanDemo/VulkanImage.cs @@ -24,23 +24,23 @@ public unsafe class VulkanImage : IDisposable private ImageLayout _currentLayout; private AccessFlags _currentAccessFlags; private ImageUsageFlags _imageUsageFlags { get; } - private ImageView? _imageView { get; set; } + private ImageView _imageView { get; set; } private DeviceMemory _imageMemory { get; set; } - private SharpDX.Direct3D11.Texture2D? _d3dTexture2D; + private readonly SharpDX.Direct3D11.Texture2D? _d3dTexture2D; - internal Image? InternalHandle { get; private set; } + internal Image InternalHandle { get; private set; } internal Format Format { get; } - internal ImageAspectFlags AspectFlags { get; private set; } + internal ImageAspectFlags AspectFlags { get; } - public ulong Handle => InternalHandle?.Handle ?? 0; - public ulong ViewHandle => _imageView?.Handle ?? 0; + public ulong Handle => InternalHandle.Handle; + public ulong ViewHandle => _imageView.Handle; public uint UsageFlags => (uint) _imageUsageFlags; public ulong MemoryHandle => _imageMemory.Handle; public DeviceMemory DeviceMemory => _imageMemory; - public uint MipLevels { get; private set; } + public uint MipLevels { get; } public Vk Api { get; } public PixelSize Size { get; } - public ulong MemorySize { get; private set; } + public ulong MemorySize { get; } public uint CurrentLayout => (uint) _currentLayout; public VulkanImage(VulkanContext vk, uint format, PixelSize size, @@ -93,7 +93,7 @@ public unsafe class VulkanImage : IDisposable .CreateImage(_device, imageCreateInfo, null, out var image).ThrowOnError(); InternalHandle = image; - Api.GetImageMemoryRequirements(_device, InternalHandle.Value, + Api.GetImageMemoryRequirements(_device, InternalHandle, out var memoryRequirements); @@ -109,7 +109,7 @@ public unsafe class VulkanImage : IDisposable ImportMemoryWin32HandleInfoKHR handleImport = default; if (exportable && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - _d3dTexture2D = D3DMemoryHelper.CreateMemoryHandle(vk.D3DDevice, size, Format); + _d3dTexture2D = D3DMemoryHelper.CreateMemoryHandle(vk.D3DDevice!, size, Format); using var dxgi = _d3dTexture2D.QueryInterface(); handleImport = new ImportMemoryWin32HandleInfoKHR @@ -141,7 +141,7 @@ public unsafe class VulkanImage : IDisposable MemorySize = memoryRequirements.Size; - Api.BindImageMemory(_device, InternalHandle.Value, _imageMemory, 0).ThrowOnError(); + Api.BindImageMemory(_device, InternalHandle, _imageMemory, 0).ThrowOnError(); var componentMapping = new ComponentMapping( ComponentSwizzle.Identity, ComponentSwizzle.Identity, @@ -155,7 +155,7 @@ public unsafe class VulkanImage : IDisposable var imageViewCreateInfo = new ImageViewCreateInfo { SType = StructureType.ImageViewCreateInfo, - Image = InternalHandle.Value, + Image = InternalHandle, ViewType = ImageViewType.Type2D, Format = Format, Components = componentMapping, @@ -209,7 +209,7 @@ public unsafe class VulkanImage : IDisposable ImageLayout fromLayout, AccessFlags fromAccessFlags, ImageLayout destinationLayout, AccessFlags destinationAccessFlags) { - VulkanMemoryHelper.TransitionLayout(Api, commandBuffer, InternalHandle.Value, + VulkanMemoryHelper.TransitionLayout(Api, commandBuffer, InternalHandle, fromLayout, fromAccessFlags, destinationLayout, destinationAccessFlags, @@ -241,8 +241,8 @@ public unsafe class VulkanImage : IDisposable public unsafe void Dispose() { - Api.DestroyImageView(_device, _imageView.Value, null); - Api.DestroyImage(_device, InternalHandle.Value, null); + Api.DestroyImageView(_device, _imageView, null); + Api.DestroyImage(_device, InternalHandle, null); Api.FreeMemory(_device, _imageMemory, null); _imageView = default; diff --git a/samples/GpuInterop/VulkanDemo/VulkanSwapchain.cs b/samples/GpuInterop/VulkanDemo/VulkanSwapchain.cs index fc0e98b3e0..cd026b3972 100644 --- a/samples/GpuInterop/VulkanDemo/VulkanSwapchain.cs +++ b/samples/GpuInterop/VulkanDemo/VulkanSwapchain.cs @@ -146,6 +146,6 @@ class VulkanSwapchainImage : ISwapchainImage if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) _lastPresent = _target.UpdateWithKeyedMutexAsync(_importedImage, 1, 0); else - _lastPresent = _target.UpdateWithSemaphoresAsync(_importedImage, _renderCompletedSemaphore, _availableSemaphore); + _lastPresent = _target.UpdateWithSemaphoresAsync(_importedImage, _renderCompletedSemaphore!, _availableSemaphore!); } } diff --git a/samples/IntegrationTestApp/MainWindow.axaml.cs b/samples/IntegrationTestApp/MainWindow.axaml.cs index a858686ffb..170936f50d 100644 --- a/samples/IntegrationTestApp/MainWindow.axaml.cs +++ b/samples/IntegrationTestApp/MainWindow.axaml.cs @@ -42,23 +42,20 @@ namespace IntegrationTestApp private void InitializeViewMenu() { var mainTabs = this.Get("MainTabs"); - var viewMenu = (NativeMenuItem)NativeMenu.GetMenu(this).Items[1]; + var viewMenu = (NativeMenuItem?)NativeMenu.GetMenu(this)?.Items[1]; - if (mainTabs.Items is not null) + foreach (var tabItem in mainTabs.Items.Cast()) { - foreach (TabItem tabItem in mainTabs.Items) + var menuItem = new NativeMenuItem { - var menuItem = new NativeMenuItem - { - Header = (string)tabItem.Header!, - ToolTip = (string)tabItem.Header!, - IsChecked = tabItem.IsSelected, - ToggleType = NativeMenuItemToggleType.Radio, - }; - - menuItem.Click += (s, e) => tabItem.IsSelected = true; - viewMenu?.Menu?.Items.Add(menuItem); - } + Header = (string?)tabItem.Header, + ToolTip = (string?)tabItem.Header, + IsChecked = tabItem.IsSelected, + ToggleType = NativeMenuItemToggleType.Radio, + }; + + menuItem.Click += (_, _) => tabItem.IsSelected = true; + viewMenu?.Menu?.Items.Add(menuItem); } } @@ -77,7 +74,7 @@ namespace IntegrationTestApp var window = new ShowWindowTest { WindowStartupLocation = (WindowStartupLocation)locationComboBox.SelectedIndex, - CanResize = canResizeCheckBox.IsChecked.Value, + CanResize = canResizeCheckBox.IsChecked ?? false, }; if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime lifetime) @@ -227,9 +224,9 @@ namespace IntegrationTestApp var gestureBorder2 = this.GetControl("GestureBorder2"); var lastGesture = this.GetControl("LastGesture"); var resetGestures = this.GetControl